chore: fix test breaking changes
All checks were successful
continuous-integration/drone/push Build is passing

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2024-05-10 12:03:38 +02:00
parent f284171f5a
commit 86310c6764
Signed by: kjuulh
GPG Key ID: 9AA7BC13CE474394
13 changed files with 763 additions and 270 deletions

View File

@ -2,7 +2,7 @@
- [x] Display todos as todos - [x] Display todos as todos
- [x] Create sections - [x] Create sections
- [ ] Edit todos - [x] Edit todos
- [ ] Move items - [ ] Move items
- [ ] Display summaries and limit todos - [ ] Display summaries and limit todos
- [ ] Implement scroll - [ ] Implement scroll

View File

@ -25,6 +25,13 @@ pub enum Command {
description: String, description: String,
state: ItemState, state: ItemState,
}, },
UpdateItem {
root: String,
path: Vec<String>,
title: String,
description: String,
state: ItemState,
},
ToggleItem { ToggleItem {
root: String, root: String,
path: Vec<String>, path: Vec<String>,
@ -88,6 +95,21 @@ impl Commander {
Command::ToggleItem { root, path } => self Command::ToggleItem { root, path } => self
.engine .engine
.toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::<Vec<_>>())?, .toggle_item(&root, &path.iter().map(|p| p.as_str()).collect::<Vec<_>>())?,
Command::UpdateItem {
root,
path,
title,
description,
state,
} => self.engine.update_item(
&root,
&path.iter().map(|p| p.as_str()).collect::<Vec<_>>(),
GraphItem::Item {
title,
description,
state,
},
)?,
} }
self.storage.store(&self.engine)?; self.storage.store(&self.engine)?;

View File

@ -44,7 +44,7 @@ impl Engine {
match current_item { match current_item {
GraphItem::User(u) => match u.get_mut(section.to_owned()) { GraphItem::User(u) => match u.get_mut(section.to_owned()) {
Some(graph_item) => { Some(graph_item) => {
current_item = graph_item.as_mut(); current_item = graph_item;
} }
None => anyhow::bail!("path: {} section was not found", section), None => anyhow::bail!("path: {} section was not found", section),
}, },
@ -60,10 +60,10 @@ impl Engine {
match current_item { match current_item {
GraphItem::User(u) => { GraphItem::User(u) => {
u.insert(last.to_string(), Box::new(item)); u.insert(last.to_string(), item);
} }
GraphItem::Section(s) => { GraphItem::Section(s) => {
s.insert(last.to_string(), Box::new(item)); s.insert(last.to_string(), item);
} }
GraphItem::Item { .. } => anyhow::bail!("cannot insert an item into an item"), GraphItem::Item { .. } => anyhow::bail!("cannot insert an item into an item"),
} }
@ -109,11 +109,11 @@ impl Engine {
match dest { match dest {
GraphItem::User(u) => { GraphItem::User(u) => {
u.try_insert(src_item.to_string(), Box::new(src)) u.try_insert(src_item.to_string(), src)
.map_err(|_e| anyhow!("key was already found, aborting: {}", src_item))?; .map_err(|_e| anyhow!("key was already found, aborting: {}", src_item))?;
} }
GraphItem::Section(s) => { GraphItem::Section(s) => {
s.try_insert(src_item.to_string(), Box::new(src)) s.try_insert(src_item.to_string(), src)
.map_err(|_e| anyhow!("key was already found, aborting: {}", src_item))?; .map_err(|_e| anyhow!("key was already found, aborting: {}", src_item))?;
} }
GraphItem::Item { .. } => { GraphItem::Item { .. } => {
@ -145,6 +145,57 @@ impl Engine {
Ok(()) Ok(())
} }
pub fn update_item(
&mut self,
root: &str,
path: &[&str],
item: &GraphItem,
) -> anyhow::Result<()> {
if let Some((name, dest_last)) = path.split_last() {
if let Some(parent) = self.get_mut(root, dest_last) {
match parent {
GraphItem::User(s) | GraphItem::Section(s) => {
if let Some(mut existing) = s.remove(*name) {
match (&mut existing, item) {
(
GraphItem::Item {
title: ex_title,
description: ex_desc,
state: ex_state,
},
GraphItem::Item {
title,
description,
state,
},
) => {
ex_title.clone_from(title);
ex_desc.clone_from(description);
ex_state.clone_from(state);
let title = title.replace(".", "-");
s.insert(title, existing.clone());
}
_ => {
anyhow::bail!(
"path: {}.{} found is not an item",
root,
path.join(".")
)
}
}
}
}
GraphItem::Item { .. } => {
anyhow::bail!("cannot rename when item is placed in an item")
}
}
}
}
Ok(())
}
} }
impl Display for Engine { impl Display for Engine {

View File

@ -13,13 +13,19 @@ pub enum ItemState {
Done, Done,
} }
impl Default for ItemState {
fn default() -> Self {
Self::NotDone
}
}
#[derive(Deserialize, Serialize, PartialEq, Eq, Clone, Debug)] #[derive(Deserialize, Serialize, PartialEq, Eq, Clone, Debug)]
#[serde(tag = "type")] #[serde(tag = "type")]
pub enum GraphItem { pub enum GraphItem {
#[serde(rename = "user")] #[serde(rename = "user")]
User(BTreeMap<String, Box<GraphItem>>), User(BTreeMap<String, GraphItem>),
#[serde(rename = "section")] #[serde(rename = "section")]
Section(BTreeMap<String, Box<GraphItem>>), Section(BTreeMap<String, GraphItem>),
#[serde(rename = "item")] #[serde(rename = "item")]
Item { Item {
title: String, title: String,
@ -58,8 +64,7 @@ impl GraphItem {
Some((first, rest)) => match self { Some((first, rest)) => match self {
GraphItem::User(section) | GraphItem::Section(section) => { GraphItem::User(section) | GraphItem::Section(section) => {
if rest.is_empty() { if rest.is_empty() {
let val = section.remove(*first); section.remove(*first)
val.map(|v| *v)
} else { } else {
section.get_mut(*first)?.take(rest) section.get_mut(*first)?.take(rest)
} }
@ -131,7 +136,7 @@ mod test {
let mut user = BTreeMap::new(); let mut user = BTreeMap::new();
user.insert( user.insert(
"some-project".into(), "some-project".into(),
Box::new(GraphItem::Section(BTreeMap::default())), GraphItem::Section(BTreeMap::default()),
); );
expected.insert("kjuulh".into(), GraphItem::User(user)); expected.insert("kjuulh".into(), GraphItem::User(user));
@ -160,13 +165,10 @@ mod test {
let mut some_project = BTreeMap::default(); let mut some_project = BTreeMap::default();
some_project.insert( some_project.insert(
"some-nested-project".into(), "some-nested-project".into(),
Box::new(GraphItem::Section(BTreeMap::default())), GraphItem::Section(BTreeMap::default()),
); );
let mut user = BTreeMap::new(); let mut user = BTreeMap::new();
user.insert( user.insert("some-project".into(), GraphItem::Section(some_project));
"some-project".into(),
Box::new(GraphItem::Section(some_project)),
);
expected.insert("kjuulh".into(), GraphItem::User(user)); expected.insert("kjuulh".into(), GraphItem::User(user));
@ -200,23 +202,20 @@ mod test {
let mut nested_project = BTreeMap::default(); let mut nested_project = BTreeMap::default();
nested_project.insert( nested_project.insert(
"some-todo".into(), "some-todo".into(),
Box::new(GraphItem::Item { GraphItem::Item {
title: "some title".into(), title: "some title".into(),
description: "some description".into(), description: "some description".into(),
state: ItemState::NotDone, state: ItemState::NotDone,
}), },
); );
let mut some_project = BTreeMap::default(); let mut some_project = BTreeMap::default();
some_project.insert( some_project.insert(
"some-nested-project".into(), "some-nested-project".into(),
Box::new(GraphItem::Section(nested_project)), GraphItem::Section(nested_project),
); );
let mut user = BTreeMap::new(); let mut user = BTreeMap::new();
user.insert( user.insert("some-project".into(), GraphItem::Section(some_project));
"some-project".into(),
Box::new(GraphItem::Section(some_project)),
);
expected.insert("kjuulh".into(), GraphItem::User(user)); expected.insert("kjuulh".into(), GraphItem::User(user));

View File

@ -49,4 +49,18 @@ impl SharedEngine {
Ok(()) Ok(())
} }
pub(crate) fn update_item(
&self,
root: &str,
path: &[&str],
state: GraphItem,
) -> anyhow::Result<()> {
self.inner
.write()
.unwrap()
.update_item(root, path, &state)?;
Ok(())
}
} }

View File

@ -1,3 +1,4 @@
use hyperlog_core::log::GraphItem;
use ratatui::{ use ratatui::{
prelude::*, prelude::*,
widgets::{Block, Borders, Padding, Paragraph}, widgets::{Block, Borders, Padding, Paragraph},
@ -10,7 +11,10 @@ use crate::{
use self::{ use self::{
command_bar::{CommandBar, CommandBarState}, command_bar::{CommandBar, CommandBarState},
dialog::{CreateItem, CreateItemState}, dialog::{
create_item::{CreateItem, CreateItemState},
edit_item::{EditItem, EditItemState},
},
}; };
mod command_bar; mod command_bar;
@ -18,12 +22,14 @@ pub mod dialog;
pub enum Dialog { pub enum Dialog {
CreateItem { state: CreateItemState }, CreateItem { state: CreateItemState },
EditItem { state: EditItemState },
} }
impl Dialog { impl Dialog {
pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> { pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> {
match self { match self {
Dialog::CreateItem { state } => state.get_command(), Dialog::CreateItem { state } => state.get_command(),
Dialog::EditItem { state } => state.get_command(),
} }
} }
} }
@ -76,12 +82,13 @@ impl<'a> App<'a> {
pub fn update(&mut self, msg: Msg) -> anyhow::Result<impl IntoCommand> { pub fn update(&mut self, msg: Msg) -> anyhow::Result<impl IntoCommand> {
tracing::trace!("handling msg: {:?}", msg); tracing::trace!("handling msg: {:?}", msg);
match msg { match &msg {
Msg::MoveRight => self.graph_explorer.move_right()?, Msg::MoveRight => self.graph_explorer.move_right()?,
Msg::MoveLeft => self.graph_explorer.move_left()?, Msg::MoveLeft => self.graph_explorer.move_left()?,
Msg::MoveDown => self.graph_explorer.move_down()?, Msg::MoveDown => self.graph_explorer.move_down()?,
Msg::MoveUp => self.graph_explorer.move_up()?, Msg::MoveUp => self.graph_explorer.move_up()?,
Msg::OpenCreateItemDialog => self.open_dialog(), Msg::OpenCreateItemDialog => self.open_dialog(),
Msg::OpenEditItemDialog { item } => self.open_edit_item_dialog(item),
Msg::EnterInsertMode => self.mode = Mode::Insert, Msg::EnterInsertMode => self.mode = Mode::Insert,
Msg::EnterViewMode => self.mode = Mode::View, Msg::EnterViewMode => self.mode = Mode::View,
Msg::EnterCommandMode => { Msg::EnterCommandMode => {
@ -95,7 +102,7 @@ impl<'a> App<'a> {
Msg::SubmitCommand { command } => { Msg::SubmitCommand { command } => {
tracing::info!("submitting command"); tracing::info!("submitting command");
if let Some(command) = CommandParser::parse(&command) { if let Some(command) = CommandParser::parse(command) {
match self.focus { match self.focus {
AppFocus::Dialog => { AppFocus::Dialog => {
if command.is_write() { if command.is_write() {
@ -113,7 +120,12 @@ impl<'a> App<'a> {
self.dialog = None; self.dialog = None;
} }
} }
AppFocus::Graph => self.graph_explorer.execute_command(&command)?, AppFocus::Graph => {
if let Some(msg) = self.graph_explorer.execute_command(&command)? {
self.command = None;
return Ok(msg.into_command());
}
}
} }
} }
self.command = None; self.command = None;
@ -128,6 +140,7 @@ impl<'a> App<'a> {
} else if let Some(dialog) = &mut self.dialog { } else if let Some(dialog) = &mut self.dialog {
match dialog { match dialog {
Dialog::CreateItem { state } => state.update(&msg)?, Dialog::CreateItem { state } => state.update(&msg)?,
Dialog::EditItem { state } => state.update(&msg)?,
} }
} }
@ -145,6 +158,20 @@ impl<'a> App<'a> {
}); });
} }
} }
fn open_edit_item_dialog(&mut self, item: &GraphItem) {
if self.dialog.is_none() {
let root = self.root.clone();
let path = self.graph_explorer.get_current_path();
self.dialog = Some(Dialog::EditItem {
state: EditItemState::new(root, path, item),
});
self.command = None;
self.focus = AppFocus::Dialog;
self.mode = Mode::Insert;
}
}
} }
impl<'a> Widget for &mut App<'a> { impl<'a> Widget for &mut App<'a> {
@ -176,6 +203,7 @@ pub fn render_app(frame: &mut Frame, state: &mut App) {
match dialog { match dialog {
Dialog::CreateItem { .. } => heading_parts.push(Span::raw("create item")), Dialog::CreateItem { .. } => heading_parts.push(Span::raw("create item")),
Dialog::EditItem { .. } => heading_parts.push(Span::raw("edit item")),
} }
} }
@ -238,6 +266,9 @@ pub fn render_app(frame: &mut Frame, state: &mut App) {
Dialog::CreateItem { state } => { Dialog::CreateItem { state } => {
frame.render_stateful_widget(&mut CreateItem::default(), chunks[1], state) frame.render_stateful_widget(&mut CreateItem::default(), chunks[1], state)
} }
Dialog::EditItem { state } => {
frame.render_stateful_widget(&mut EditItem::default(), chunks[1], state)
}
} }
return; return;

View File

@ -1,4 +1,3 @@
use itertools::Itertools;
use ratatui::{prelude::*, widgets::*}; use ratatui::{prelude::*, widgets::*};
use crate::models::{EditMsg, Msg}; use crate::models::{EditMsg, Msg};
@ -74,7 +73,16 @@ pub struct InputBuffer {
} }
impl InputBuffer { impl InputBuffer {
fn transform_focused(&mut self) { pub fn new(input: String) -> Self {
Self {
state: BufferState::Static {
content: input,
position: 0,
},
}
}
pub fn transform_focused(&mut self) {
match &mut self.state { match &mut self.state {
BufferState::Focused { .. } => {} BufferState::Focused { .. } => {}
BufferState::Static { content, position } => { BufferState::Static { content, position } => {
@ -136,6 +144,14 @@ impl InputBuffer {
BufferState::Static { content, .. } => content.to_owned(), BufferState::Static { content, .. } => content.to_owned(),
} }
} }
fn set_position(&mut self, title_len: usize) {
match &mut self.state {
BufferState::Focused { position, .. } | BufferState::Static { position, .. } => {
*position = title_len
}
}
}
} }
pub struct InputField<'a> { pub struct InputField<'a> {
@ -189,110 +205,5 @@ fn clamp_x(area: &Rect, x: u16) -> u16 {
} }
} }
enum CreateItemFocused { pub mod create_item;
Title, pub mod edit_item;
Description,
}
impl Default for CreateItemFocused {
fn default() -> Self {
Self::Title
}
}
pub struct CreateItemState {
root: String,
path: Vec<String>,
title: InputBuffer,
description: InputBuffer,
focused: CreateItemFocused,
}
impl CreateItemState {
pub fn new(root: impl Into<String>, path: impl IntoIterator<Item = impl Into<String>>) -> Self {
let root = root.into();
let path = path.into_iter().map(|p| p.into()).collect_vec();
Self {
root,
path,
title: Default::default(),
description: Default::default(),
focused: Default::default(),
}
}
pub fn update(&mut self, msg: &Msg) -> anyhow::Result<()> {
match &msg {
Msg::MoveDown | Msg::MoveUp => match self.focused {
CreateItemFocused::Title => self.focused = CreateItemFocused::Description,
CreateItemFocused::Description => self.focused = CreateItemFocused::Title,
},
_ => {}
}
match self.focused {
CreateItemFocused::Title => {
self.title.update(msg)?;
}
CreateItemFocused::Description => {
self.description.update(msg)?;
}
}
Ok(())
}
pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> {
let title = self.title.string();
let description = self.description.string();
if !title.is_empty() {
let mut path = self.path.clone();
path.push(title.replace([' ', '.'], "-"));
Some(hyperlog_core::commander::Command::CreateItem {
root: self.root.clone(),
path,
title: title.trim().into(),
description: description.trim().into(),
state: hyperlog_core::log::ItemState::NotDone,
})
} else {
None
}
}
}
#[derive(Default)]
pub struct CreateItem {}
impl StatefulWidget for &mut CreateItem {
type State = CreateItemState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let chunks = Layout::vertical(vec![
Constraint::Length(2),
Constraint::Length(3),
Constraint::Length(3),
])
.split(area);
let path = format!("path: {}.{}", state.root, state.path.join("."));
let path_header = Paragraph::new(path).dark_gray();
path_header.render(chunks[0], buf);
let mut title_input = InputField::new("title");
let mut description_input = InputField::new("description");
match state.focused {
CreateItemFocused::Title => title_input.focused = true,
CreateItemFocused::Description => description_input.focused = true,
}
title_input.render(chunks[1], buf, &mut state.title);
description_input.render(chunks[2], buf, &mut state.description);
}
}

View File

@ -0,0 +1,114 @@
use itertools::Itertools;
use ratatui::{prelude::*, widgets::*};
use crate::models::Msg;
use super::{InputBuffer, InputField};
enum CreateItemFocused {
Title,
Description,
}
impl Default for CreateItemFocused {
fn default() -> Self {
Self::Title
}
}
pub struct CreateItemState {
root: String,
path: Vec<String>,
title: InputBuffer,
description: InputBuffer,
focused: CreateItemFocused,
}
impl CreateItemState {
pub fn new(root: impl Into<String>, path: impl IntoIterator<Item = impl Into<String>>) -> Self {
let root = root.into();
let path = path.into_iter().map(|p| p.into()).collect_vec();
Self {
root,
path,
title: Default::default(),
description: Default::default(),
focused: Default::default(),
}
}
pub fn update(&mut self, msg: &Msg) -> anyhow::Result<()> {
match &msg {
Msg::MoveDown | Msg::MoveUp => match self.focused {
CreateItemFocused::Title => self.focused = CreateItemFocused::Description,
CreateItemFocused::Description => self.focused = CreateItemFocused::Title,
},
_ => {}
}
match self.focused {
CreateItemFocused::Title => {
self.title.update(msg)?;
}
CreateItemFocused::Description => {
self.description.update(msg)?;
}
}
Ok(())
}
pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> {
let title = self.title.string();
let description = self.description.string();
if !title.is_empty() {
let mut path = self.path.clone();
path.push(title.replace([' ', '.'], "-"));
Some(hyperlog_core::commander::Command::CreateItem {
root: self.root.clone(),
path,
title: title.trim().into(),
description: description.trim().into(),
state: hyperlog_core::log::ItemState::NotDone,
})
} else {
None
}
}
}
#[derive(Default)]
pub struct CreateItem {}
impl StatefulWidget for &mut CreateItem {
type State = CreateItemState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let chunks = Layout::vertical(vec![
Constraint::Length(2),
Constraint::Length(3),
Constraint::Length(3),
])
.split(area);
let path = format!("path: {}.{}", state.root, state.path.join("."));
let path_header = Paragraph::new(path).dark_gray();
path_header.render(chunks[0], buf);
let mut title_input = InputField::new("title");
let mut description_input = InputField::new("description");
match state.focused {
CreateItemFocused::Title => title_input.focused = true,
CreateItemFocused::Description => description_input.focused = true,
}
title_input.render(chunks[1], buf, &mut state.title);
description_input.render(chunks[2], buf, &mut state.description);
}
}

View File

@ -0,0 +1,138 @@
use hyperlog_core::log::GraphItem;
use itertools::Itertools;
use ratatui::{prelude::*, widgets::*};
use crate::models::Msg;
use super::{InputBuffer, InputField};
enum EditItemFocused {
Title,
Description,
}
impl Default for EditItemFocused {
fn default() -> Self {
Self::Title
}
}
pub struct EditItemState {
root: String,
path: Vec<String>,
title: InputBuffer,
description: InputBuffer,
item: GraphItem,
focused: EditItemFocused,
}
impl EditItemState {
pub fn new(
root: impl Into<String>,
path: impl IntoIterator<Item = impl Into<String>>,
item: &GraphItem,
) -> Self {
let root = root.into();
let path = path.into_iter().map(|p| p.into()).collect_vec();
match item {
GraphItem::Item {
title, description, ..
} => {
let title_len = title.len();
let mut title = InputBuffer::new(title.clone());
title.transform_focused();
title.set_position(title_len);
Self {
root,
path,
item: item.clone(),
title,
description: InputBuffer::new(description.clone()),
focused: Default::default(),
}
}
_ => todo!("cannot edit item from other than GraphItem::Item"),
}
}
pub fn update(&mut self, msg: &Msg) -> anyhow::Result<()> {
match &msg {
Msg::MoveDown | Msg::MoveUp => match self.focused {
EditItemFocused::Title => self.focused = EditItemFocused::Description,
EditItemFocused::Description => self.focused = EditItemFocused::Title,
},
_ => {}
}
match self.focused {
EditItemFocused::Title => {
self.title.update(msg)?;
}
EditItemFocused::Description => {
self.description.update(msg)?;
}
}
Ok(())
}
pub fn get_command(&self) -> Option<hyperlog_core::commander::Command> {
let title = self.title.string();
let description = self.description.string();
if !title.is_empty() {
let path = self.path.clone();
Some(hyperlog_core::commander::Command::UpdateItem {
root: self.root.clone(),
path,
title: title.trim().into(),
description: description.trim().into(),
state: match &self.item {
GraphItem::User(_) => Default::default(),
GraphItem::Section(_) => Default::default(),
GraphItem::Item { state, .. } => state.clone(),
},
})
} else {
None
}
}
}
#[derive(Default)]
pub struct EditItem {}
impl StatefulWidget for &mut EditItem {
type State = EditItemState;
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let chunks = Layout::vertical(vec![
Constraint::Length(2),
Constraint::Length(3),
Constraint::Length(3),
])
.split(area);
let path = format!("path: {}.{}", state.root, state.path.join("."));
let path_header = Paragraph::new(path).dark_gray();
path_header.render(chunks[0], buf);
let mut title_input = InputField::new("title");
let mut description_input = InputField::new("description");
match state.focused {
EditItemFocused::Title => title_input.focused = true,
EditItemFocused::Description => description_input.focused = true,
}
title_input.render(chunks[1], buf, &mut state.title);
description_input.render(chunks[2], buf, &mut state.description);
}
}

View File

@ -6,6 +6,7 @@ pub enum Commands {
WriteQuit, WriteQuit,
Archive, Archive,
CreateSection { name: String }, CreateSection { name: String },
Edit,
} }
impl Commands { impl Commands {
@ -35,6 +36,7 @@ impl CommandParser {
"cs" | "create-section" => rest.first().map(|name| Commands::CreateSection { "cs" | "create-section" => rest.first().map(|name| Commands::CreateSection {
name: name.to_string(), name: name.to_string(),
}), }),
"e" | "edit" => Some(Commands::Edit),
_ => None, _ => None,
}, },
None => None, None => None,

View File

@ -5,7 +5,7 @@ use hyperlog_core::log::{GraphItem, ItemState};
use itertools::Itertools; use itertools::Itertools;
use ratatui::{prelude::*, widgets::*}; use ratatui::{prelude::*, widgets::*};
use crate::{command_parser::Commands, state::SharedState}; use crate::{command_parser::Commands, models::Msg, state::SharedState};
pub struct GraphExplorer<'a> { pub struct GraphExplorer<'a> {
state: SharedState, state: SharedState,
@ -145,7 +145,17 @@ impl<'a> GraphExplorer<'a> {
} }
} }
pub fn execute_command(&mut self, command: &Commands) -> anyhow::Result<()> { fn get_current_item(&self) -> Option<MovementGraphItem> {
let graph = self.linearize_graph();
if let Some(graph) = graph {
graph.get_graph_item(&self.inner.current_position).cloned()
} else {
None
}
}
pub fn execute_command(&mut self, command: &Commands) -> anyhow::Result<Option<Msg>> {
match command { match command {
Commands::Archive => { Commands::Archive => {
if !self.get_current_path().is_empty() { if !self.get_current_path().is_empty() {
@ -165,12 +175,35 @@ impl<'a> GraphExplorer<'a> {
)?; )?;
} }
} }
Commands::Edit => {
if let Some(item) = self.get_current_item() {
let path = self.get_current_path();
tracing::debug!(
"found item to edit: path: {}, item: {}",
path.join("."),
item.name
);
match item.item_type {
GraphItemType::Section => {
todo!("cannot edit section at the moment")
}
GraphItemType::Item { .. } => {
if let Some(item) = self.state.querier.get(&self.inner.root, path) {
if let GraphItem::Item { .. } = item {
return Ok(Some(Msg::OpenEditItemDialog { item }));
}
}
}
}
}
}
_ => (), _ => (),
} }
self.update_graph()?; self.update_graph()?;
Ok(()) Ok(None)
} }
pub(crate) fn interact(&mut self) -> anyhow::Result<()> { pub(crate) fn interact(&mut self) -> anyhow::Result<()> {
@ -240,7 +273,7 @@ impl RenderGraph for MovementGraph {
let embedded_sections = item.values.render_graph_spans(rest); let embedded_sections = item.values.render_graph_spans(rest);
for section in &embedded_sections { for section in &embedded_sections {
let mut line = vec![Span::raw(" ")]; let mut line = vec![Span::raw(" ".repeat(4))];
line.extend_from_slice(section); line.extend_from_slice(section);
lines.push(Line::from(line)); lines.push(Line::from(line));
} }
@ -255,7 +288,7 @@ impl RenderGraph for MovementGraph {
let embedded_sections = item.values.render_graph_spans(&[]); let embedded_sections = item.values.render_graph_spans(&[]);
for section in &embedded_sections { for section in &embedded_sections {
let mut line = vec![Span::raw(" ")]; let mut line = vec![Span::raw(" ".repeat(4))];
line.extend_from_slice(section); line.extend_from_slice(section);
lines.push(Line::from(line)); lines.push(Line::from(line));
} }
@ -306,7 +339,7 @@ impl RenderGraph for MovementGraph {
let embedded_sections = item.values.render_graph_spans(rest); let embedded_sections = item.values.render_graph_spans(rest);
for section in &embedded_sections { for section in &embedded_sections {
let mut line = vec![Span::raw(" ")]; let mut line = vec![Span::raw(" ".repeat(4))];
line.extend_from_slice(section); line.extend_from_slice(section);
lines.push(line); lines.push(line);
} }
@ -319,7 +352,7 @@ impl RenderGraph for MovementGraph {
let embedded_sections = item.values.render_graph_spans(&[]); let embedded_sections = item.values.render_graph_spans(&[]);
for section in &embedded_sections { for section in &embedded_sections {
let mut line = vec![Span::raw(" ")]; let mut line = vec![Span::raw(" ".repeat(4))];
line.extend_from_slice(section); line.extend_from_slice(section);
lines.push(line); lines.push(line);
} }
@ -396,7 +429,7 @@ impl MovementGraph {
fn next_down(&self, items: &[usize]) -> Option<Vec<usize>> { fn next_down(&self, items: &[usize]) -> Option<Vec<usize>> {
match items.split_last() { match items.split_last() {
Some((current_index, rest)) => { Some((current_index, rest)) => {
if let Some(current_item) = self.get_graph_item(rest) { if let Some(current_item) = self.get_graph(rest) {
if *current_index + 1 < current_item.items.len() { if *current_index + 1 < current_item.items.len() {
let mut vec = rest.to_vec(); let mut vec = rest.to_vec();
vec.push(current_index + 1); vec.push(current_index + 1);
@ -415,16 +448,29 @@ impl MovementGraph {
} }
} }
fn get_graph_item(&self, items: &[usize]) -> Option<&MovementGraph> { fn get_graph(&self, items: &[usize]) -> Option<&MovementGraph> {
match items.split_first() { match items.split_first() {
Some((first, rest)) => match self.items.get(*first).map(|s| &s.values) { Some((first, rest)) => match self.items.get(*first).map(|s| &s.values) {
Some(next_graph) => next_graph.get_graph_item(rest), Some(next_graph) => next_graph.get_graph(rest),
None => Some(self), None => Some(self),
}, },
None => Some(self), None => Some(self),
} }
} }
fn get_graph_item(&self, items: &[usize]) -> Option<&MovementGraphItem> {
match items.split_first() {
Some((first, rest)) => match self.items.get(*first) {
Some(next_graph) => match next_graph.values.get_graph_item(rest) {
Some(graph_item) => Some(graph_item),
None => Some(next_graph),
},
None => None,
},
None => None,
}
}
fn to_current_path(&self, position_items: &[usize]) -> Vec<String> { fn to_current_path(&self, position_items: &[usize]) -> Vec<String> {
match position_items.split_first() { match position_items.split_first() {
Some((first, rest)) => match self.items.get(*first) { Some((first, rest)) => match self.items.get(*first) {
@ -462,7 +508,7 @@ impl From<GraphItem> for MovementGraph {
index: i, index: i,
name: key.clone(), name: key.clone(),
values: value.clone().into(), values: value.clone().into(),
item_type: match value.deref() { item_type: match value {
GraphItem::User(_) => GraphItemType::Section, GraphItem::User(_) => GraphItemType::Section,
GraphItem::Section(_) => GraphItemType::Section, GraphItem::Section(_) => GraphItemType::Section,
GraphItem::Item { state, .. } => GraphItemType::Item { GraphItem::Item { state, .. } => GraphItemType::Item {
@ -522,33 +568,30 @@ mod test {
fn test_can_transform_to_movement_graph() { fn test_can_transform_to_movement_graph() {
let graph = GraphItem::User(BTreeMap::from([( let graph = GraphItem::User(BTreeMap::from([(
"0".to_string(), "0".to_string(),
Box::new(GraphItem::Section(BTreeMap::from([ GraphItem::Section(BTreeMap::from([
( ("00".to_string(), GraphItem::Section(BTreeMap::new())),
"00".to_string(),
Box::new(GraphItem::Section(BTreeMap::new())),
),
( (
"01".to_string(), "01".to_string(),
Box::new(GraphItem::Section(BTreeMap::from([ GraphItem::Section(BTreeMap::from([
( (
"010".to_string(), "010".to_string(),
Box::new(GraphItem::Item { GraphItem::Item {
title: "some-title".into(), title: "some-title".into(),
description: "some-desc".into(), description: "some-desc".into(),
state: ItemState::NotDone, state: ItemState::NotDone,
}), },
), ),
( (
"011".to_string(), "011".to_string(),
Box::new(GraphItem::Item { GraphItem::Item {
title: "some-title".into(), title: "some-title".into(),
description: "some-desc".into(), description: "some-desc".into(),
state: ItemState::NotDone, state: ItemState::NotDone,
}), },
), ),
]))), ])),
), ),
]))), ])),
)])); )]));
let actual: MovementGraph = graph.into(); let actual: MovementGraph = graph.into();
@ -672,16 +715,16 @@ mod test {
], ],
}; };
let actual_default = graph.get_graph_item(&[]); let actual_default = graph.get_graph(&[]);
assert_eq!(Some(&graph), actual_default); assert_eq!(Some(&graph), actual_default);
let actual_first = graph.get_graph_item(&[0]); let actual_first = graph.get_graph(&[0]);
assert_eq!(graph.items.first().map(|i| &i.values), actual_first); assert_eq!(graph.items.first().map(|i| &i.values), actual_first);
let actual_second = graph.get_graph_item(&[1]); let actual_second = graph.get_graph(&[1]);
assert_eq!(graph.items.get(1).map(|i| &i.values), actual_second); assert_eq!(graph.items.get(1).map(|i| &i.values), actual_second);
let actual_nested = graph.get_graph_item(&[0, 0]); let actual_nested = graph.get_graph(&[0, 0]);
assert_eq!( assert_eq!(
graph graph
.items .items
@ -691,7 +734,7 @@ mod test {
actual_nested actual_nested
); );
let actual_nested = graph.get_graph_item(&[0, 1]); let actual_nested = graph.get_graph(&[0, 1]);
assert_eq!( assert_eq!(
graph graph
.items .items
@ -701,7 +744,7 @@ mod test {
actual_nested actual_nested
); );
let actual_nested = graph.get_graph_item(&[1, 2]); let actual_nested = graph.get_graph(&[1, 2]);
assert_eq!( assert_eq!(
graph graph
.items .items

View File

@ -1,3 +1,5 @@
use hyperlog_core::log::GraphItem;
use crate::commands::{Command, IntoCommand}; use crate::commands::{Command, IntoCommand};
#[derive(Debug)] #[derive(Debug)]
@ -7,6 +9,7 @@ pub enum Msg {
MoveDown, MoveDown,
MoveUp, MoveUp,
OpenCreateItemDialog, OpenCreateItemDialog,
OpenEditItemDialog { item: GraphItem },
Interact, Interact,
EnterInsertMode, EnterInsertMode,

375
demo.cast
View File

@ -1,105 +1,270 @@
{"version": 2, "width": 106, "height": 35, "timestamp": 1715268076, "env": {"SHELL": "/usr/bin/zsh", "TERM": "alacritty"}} {"version": 2, "width": 209, "height": 37, "timestamp": 1715275908, "env": {"SHELL": "/usr/bin/zsh", "TERM": "alacritty"}}
[0.061956, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] [0.068021, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
[0.108311, "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[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.116188, "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[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.108972, "o", "\u001b[6 q"] [0.116811, "o", "\u001b[6 q"]
[0.109631, "o", "\u001b[6 q"] [0.117407, "o", "\u001b[6 q"]
[0.109701, "o", "\u001b[?2004h"] [0.117474, "o", "\u001b[?2004h"]
[1.076184, "o", "c"] [1.422226, "o", "c"]
[1.077952, "o", "\b\u001b[32mc\u001b[39m"] [1.424015, "o", "\b\u001b[32mc\u001b[39m"]
[1.099899, "o", "\b\u001b[32mc\u001b[39m\u001b[90mlear\u001b[39m\b\b\b\b"] [1.443117, "o", "\b\u001b[32mc\u001b[39m\u001b[90margo run\u001b[39m\u001b[8D"]
[1.16562, "o", "\b\u001b[32mc\u001b[32ma\u001b[39m\u001b[39m \u001b[39m \u001b[39m \b\b\b"] [1.524895, "o", "\b\u001b[32mc\u001b[32ma\u001b[39m"]
[1.170777, "o", "\b\b\u001b[1m\u001b[31mc\u001b[1m\u001b[31ma\u001b[0m\u001b[39m"] [1.530521, "o", "\b\b\u001b[1m\u001b[31mc\u001b[1m\u001b[31ma\u001b[0m\u001b[39m"]
[1.179169, "o", "\u001b[90mrgo clean\u001b[39m\u001b[9D"] [1.584427, "o", "\b\b\u001b[1m\u001b[31mc\u001b[1m\u001b[31ma\u001b[1m\u001b[31mr\u001b[0m\u001b[39m"]
[1.254615, "o", "\b\b\u001b[1m\u001b[31mc\u001b[1m\u001b[31ma\u001b[1m\u001b[31mr\u001b[0m\u001b[39m"] [1.764701, "o", "\b\u001b[1m\u001b[31mr\u001b[1m\u001b[31mg\u001b[0m\u001b[39m"]
[1.404835, "o", "\b\u001b[1m\u001b[31mr\u001b[1m\u001b[31mg\u001b[0m\u001b[39m"] [1.867961, "o", "\b\u001b[1m\u001b[31mg\u001b[1m\u001b[31mo\u001b[0m\u001b[39m"]
[1.511465, "o", "\b\u001b[1m\u001b[31mg\u001b[1m\u001b[31mo\u001b[0m\u001b[39m"] [1.869689, "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"]
[1.512482, "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"] [1.945386, "o", "\b\u001b[32mo\u001b[32m \u001b[39m"]
[1.554502, "o", "\b\u001b[32mo\u001b[32m \u001b[39m"] [1.946701, "o", "\b\b\u001b[32mo\u001b[39m\u001b[39m "]
[1.555456, "o", "\b\b\u001b[32mo\u001b[39m\u001b[39m "] [2.048502, "o", "\u001b[39mr"]
[1.722553, "o", "\u001b[39mr\u001b[39m \u001b[39m \u001b[39m \u001b[39m \b\b\b\b"] [2.050856, "o", "\b\u001b[4mr\u001b[24m"]
[1.724362, "o", "\b\u001b[4mr\u001b[24m"] [2.155029, "o", "\b\u001b[4mr\u001b[39m\u001b[4mu\u001b[24m"]
[1.742164, "o", "\u001b[90mun\u001b[39m\b\b"] [2.156838, "o", "\b\b\u001b[24mr\u001b[24mu"]
[1.811359, "o", "\b\u001b[4mr\u001b[39m\u001b[4mu\u001b[24m"] [2.317861, "o", "\u001b[39mn"]
[1.813462, "o", "\b\b\u001b[24mr\u001b[24mu"] [2.381304, "o", "\u001b[0 q"]
[1.961913, "o", "\u001b[39mn"] [2.381438, "o", "\u001b[?2004l\r\r\n"]
[2.158475, "o", "\u001b[0 q"] [2.553891, "o", "\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused import: `EditMsg`\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/create_item.rs:4:21\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;12m4\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0muse crate::models::{EditMsg, Msg};\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(unused_imports)]` on by default\u001b[0m\r\n\r\n\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused import: `EditMsg`\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/edit_item.rs:5:21\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;12m5\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0muse crate::models::{EditMsg, Msg};\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\r\n\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused import: `itertools::Itertools`\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:1:5\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;12m1\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0muse itertools::Itertools;\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\r\n\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: call to `.deref()` on a reference in this situation does nothing\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0mcrates/hyperlog-tui/src/components.rs:514:47\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;12m514\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m item_type: match value.deref() {\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: the type `GraphItem` does not implement `Deref`, so calling `deref` on `&GraphItem` copies the reference, which does not do anything and can be removed\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(noop_method_call)]` on by default\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;14mhelp\u001b[0m\u001b[0m: remove this redundant call\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;12m514\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;9m- \u001b[0m\u001b[0m item_type: match value\u001b[0m\u001b[0m\u001b[38;5;9m.deref()\u001b[0m\u001b[0m {\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;12m514\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ \u001b[0m\u001b[0m item_type: match value {\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;14mhelp\u001b[0m\u001b[0m: if you meant to clone `GraphItem`, implement `Clone` for it\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0m/home/kjuulh/git/git.front.kjuulh.io/kjuulh/hyperlog/crates/hyperlog-core/src/log.rs:24:1\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;12m24\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[38;5;10m+ #[derive(Clone)]\u001b[0m\r\n\u001b[0m\u001b[1m\u001b[38;5;12m25\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m| \u001b[0m\u001b[0mpub enum GraphItem {\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\r\n\r\n"]
[2.158606, "o", "\u001b[?2004l\r\r\n"] [2.553991, "o", "\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m:\u001b[0m `hyperlog-tui` (lib) generated 4 warnings (run `cargo fix --lib -p hyperlog-tui` to apply 3 suggestions)\r\n\u001b[1m\u001b[32m Finished\u001b[0m \u001b]8;;https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles\u001b\\`dev` profile [unoptimized + debuginfo]\u001b]8;;\u001b\\ target(s) in 0.10s\r\n"]
[2.309291, "o", "\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: unused import: `Commands`\u001b[0m\r\n\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m--> \u001b[0m\u001b[0mcrates/hyperlog-tui/src/app.rs:7:37\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;12m7\u001b[0m\u001b[0m \u001b[0m\u001b[0m\u001b[1m\u001b[38;5;12m|\u001b[0m\u001b[0m \u001b[0m\u001b[0m command_parser::{CommandParser, Commands},\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(unused_imports)]` on by default\u001b[0m\r\n\r\n\u001b[0m\u001b[1m\u001b[33mwarning\u001b[0m\u001b[0m\u001b[1m: method `toggle` is 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:100: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;12m75\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;12mmethod 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;12m100\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[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\u001b[1m\u001b[33mwarning\u001b[0m\u001b[1m:\u001b[0m `hyperlog-tui` (lib) generated 2 warnings (run `cargo fix --lib -p hyperlog-tui` to apply 1 suggestion)\r\n\u001b[1m\u001b[32m Finished\u001b[0m \u001b]8;;https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles\u001b\\`dev` profile [unoptimized + debuginfo]\u001b]8;;\u001b\\ target(s) in 0.09s\r\n"] [2.561394, "o", "\u001b[1m\u001b[32m Running\u001b[0m `target/debug/hyperlog`\r\n"]
[2.315705, "o", "\u001b[1m\u001b[32m Running\u001b[0m `target/debug/hyperlog`\r\n"] [2.571775, "o", "\u001b[?1049h"]
[2.324861, "o", "\u001b[?1049h"] [2.576415, "o", "\u001b[1;1H\u001b[38;5;2mhyperlog\u001b[2;1H\u001b[39m─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[3;1H\u001b[38;5;8m- other\u001b[5;5H- other\u001b[7;9H- other\u001b[9;13H- [x] basdfasdfasdfasdf\u001b[11;13H- [x] sdlfkasldjflsdaslkdjfalkjsdfl\u001b[13;9H- [x] some\u001b[15;9H- something\u001b[17;13H- something-else\u001b[19;17H- [x] another-real-item-man\u001b[21;17H- [x] arealitembaby\u001b[23;9H- [ ] whatever\u001b[25;1H- some\u001b[27;1H- something\u001b[29;5H- else\u001b[31;5H- third\u001b[33;1H- with-something\u001b[37;2H\u001b[39m--\u001b[37;5HVIEW\u001b[37;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[2.327382, "o", "\u001b[1;1H\u001b[38;5;2mhyperlog\u001b[2;1H\u001b[39m──────────────────────────────────────────────────────────────────────────────────────────────────────────\u001b[3;1H\u001b[38;5;8m- other\u001b[5;3H- other\u001b[7;5H- other\u001b[9;7H- [ ] a\u001b[11;5H- [ ] something\u001b[13;1H- some\u001b[15;1H- something\u001b[17;3H- else\u001b[19;3H- third\u001b[35;2H\u001b[39m--\u001b[35;5HVIEW\u001b[35;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [2.830216, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[2.579631, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.083824, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[2.83217, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.312323, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- other\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[3.084795, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.448917, "o", "\u001b[3;1H\u001b[38;5;8m- other\u001b[5;5H\u001b[1m\u001b[38;5;15m- other\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[3.117018, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- other\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.613553, "o", "\u001b[5;5H\u001b[38;5;8m- other\u001b[7;9H\u001b[1m\u001b[38;5;15m- other\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[3.37073, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.870231, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[3.506269, "o", "\u001b[3;1H\u001b[38;5;8m- other\u001b[13;1H\u001b[1m\u001b[38;5;15m- some\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.882483, "o", "\u001b[1;10H~\u001b[1;12Hcreate\u001b[1;19Hitem\u001b[3;1H\u001b[38;5;8mpath: kjuulh.other.other.other \u001b[4;1H \u001b[5;1H\u001b[39m┌title──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[3.759095, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.88257, "o", "────────────────────────┐\u001b[6;1H│\u001b[38;5;0m\u001b[48;5;5m \u001b[6;209H\u001b[39m\u001b[49m│\u001b[7;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[8;1H\u001b[38;5;8m┌description───────────────────────────────────────────────────────────────────────────────"]
[4.011929, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.882597, "o", "─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\u001b[9;1H│ \u001b[9;15H \u001b[9;19H │\u001b[10;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[4.047613, "o", "\u001b[3;1H\u001b[1m\u001b[38;5;15m- other\u001b[13;1H\u001b[22m\u001b[38;5;8m- some\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [3.882674, "o", "────────────────────────────────────────────────────────────────┘\u001b[11;13H\u001b[39m \u001b[13;9H \u001b[15;9H \u001b[17;13H \u001b[19;17H \u001b[21;17H \u001b[23;9H \u001b[25;1H \u001b[27;1H \u001b[29;5H \u001b[31;5H \u001b[33;1H \u001b[37;5HEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[4.300637, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [4.13608, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[4.304359, "o", "\u001b[3;1H\u001b[38;5;8m- other\u001b[5;3H\u001b[1m\u001b[38;5;15m- other\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [4.388789, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[4.557092, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [4.425751, "o", "\u001b[6;2Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[4.737839, "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;106H\u001b[39m\u001b[49m│\u001b[5;1H└────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[6;1H\u001b[38;5;8m┌description────────────────────────────────────────────────────────────────────────────────────────────"] [4.527752, "o", "\u001b[6;3Ho\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[4.737887, "o", "─┐\u001b[7;1H│ \u001b[7;7H │\u001b[8;1H└────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[9;7H\u001b[39m \u001b[11;5H \u001b[13;1H \u001b[15;1H \u001b[17;3H \u001b[19;3H \u001b[35;5HEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [4.678825, "o", "\u001b[6;4Hm\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[4.990266, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [4.756198, "o", "\u001b[6;5He\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[5.242663, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [4.845317, "o", "\u001b[6;6Ht\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[5.263649, "o", "\u001b[4;2Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [4.931464, "o", "\u001b[6;7Hh\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[5.336941, "o", "\u001b[4;3Ho\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.084899, "o", "\u001b[6;8Hi\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[5.473386, "o", "\u001b[4;4Hm\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.188535, "o", "\u001b[6;9Hn\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[5.546165, "o", "\u001b[4;5He\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.339409, "o", "\u001b[6;10Hg\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[5.684402, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.458766, "o", "\u001b[6;11H \u001b[37;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[5.937063, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.711976, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[6.189562, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.787803, "o", "\u001b[37;1H: \u001b[37;5H \u001b[37;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[6.442354, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.909531, "o", "\u001b[37;2Hw\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[6.694082, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [5.985516, "o", "\u001b[37;3Hq\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[6.809652, "o", "\u001b[4;6H \u001b[35;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [6.120986, "o", "\u001b[1;10H \u001b[1;12H \u001b[1;19H \u001b[3;1H\u001b[38;5;8m- other\u001b[39m \u001b[4;1H \u001b[5;1H \u001b[38;5;8m- other\u001b[39m \u001b[6;1H \u001b[6;209H \u001b[7;1H \u001b[1m\u001b[38;5;15m- other\u001b[22m\u001b[39m \u001b[8;1H "]
[7.062032, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [6.121104, "o", " \u001b[9;1H \u001b[38;5;8m-\u001b[9;15H[x]\u001b[9;19Hbasdfasdfasdfasdf\u001b[39m \u001b[10;1H \u001b[11;13H\u001b[38;5;8m- [x] sdlfkasldjflsdaslkdjfalkjsdfl\u001b[13;13H- [ ] something\u001b[15;9H- [x] some\u001b[17;9H- something\u001b[19;13H- something-else\u001b[21;17H- [x] another-real-item-man\u001b[23;17H- [x] arealitembaby\u001b[25;9H- [ ] whatever\u001b[27;1H- some\u001b[29;1H- something\u001b[31;5H- else\u001b[33;5H- third\u001b[35;1H- with-something\u001b[37;1H\u001b[39m --\u001b[37;5HVIEW\u001b[37;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[7.106297, "o", "\u001b[35;1H: \u001b[35;5H \u001b[35;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [6.376468, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[7.196456, "o", "\u001b[35;2Hw\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [6.631583, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[7.255925, "o", "\u001b[35;3Hq\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [6.886855, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[7.467764, "o", "\u001b[1;10H \u001b[1;12H \u001b[1;19H \u001b[3;1H\u001b[38;5;8m- other\u001b[39m \u001b[4;1H \u001b[4;106H \u001b[5;1H \u001b[1m\u001b[38;5;15m- other\u001b[22m\u001b[39m \u001b[6;1H \u001b[7;1H \u001b[38;5;8m-\u001b[7;7Hother\u001b[39m \u001b[8;1H \u001b[9;7H\u001b[38;5;8m- [ ] a\u001b[11;5H- [ ] some\u001b[13;5H- [ ] something\u001b[15;1H- some\u001b[17;1H- something\u001b[19;3H- else\u001b[21;3H- third\u001b[35;1H\u001b[39m --\u001b[35;5HVIEW\u001b[35;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [7.049312, "o", "\u001b[7;9H\u001b[38;5;8m- other\u001b[9;13H\u001b[1m\u001b[38;5;15m- [x] basdfasdfasdfasdf\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[7.720604, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [7.303165, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[7.973639, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [7.42526, "o", "\u001b[9;13H\u001b[38;5;8m- [x] basdfasdfasdfasdf\u001b[11;13H\u001b[1m\u001b[38;5;15m- [x] sdlfkasldjflsdaslkdjfalkjsdfl\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[8.226784, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [7.605653, "o", "\u001b[11;13H\u001b[38;5;8m- [x] sdlfkasldjflsdaslkdjfalkjsdfl\u001b[13;13H\u001b[1m\u001b[38;5;15m- [ ] something\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[8.336689, "o", "\u001b[5;3H\u001b[38;5;8m- other\u001b[7;5H\u001b[1m\u001b[38;5;15m- other\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [7.861055, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[8.590186, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [8.008956, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[8.773505, "o", "\u001b[7;5H\u001b[38;5;8m- other\u001b[9;7H\u001b[1m\u001b[38;5;15m- [ ] a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [8.262789, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[9.026085, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [8.445994, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[9.17675, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [8.699737, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[9.429584, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [8.9533, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[9.643372, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [9.045631, "o", "\u001b[13;16H\u001b[1m\u001b[38;5;15mx\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[9.896858, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [9.299403, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[9.926048, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [9.553163, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[10.178828, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [9.735068, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[10.273339, "o", "\u001b[7;5H\u001b[1m\u001b[38;5;15m- other\u001b[9;7H\u001b[22m\u001b[38;5;8m- [ ] a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [9.988954, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[10.52597, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [10.242337, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[10.5434, "o", "\u001b[7;5H\u001b[38;5;8m- other\u001b[11;5H\u001b[1m\u001b[38;5;15m- [ ] some\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [10.486221, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[10.796065, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [10.741395, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[11.04899, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [10.815189, "o", "\u001b[37;1H: \u001b[37;5H \u001b[37;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[11.302034, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [10.917172, "o", "\u001b[37;2He\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[11.554807, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.085181, "o", "\u001b[37;3Hd\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[11.697704, "o", "\u001b[11;8H\u001b[1m\u001b[38;5;15mx\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.1735, "o", "\u001b[37;4Hi\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[11.951284, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.279168, "o", "\u001b[37;5Ht\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[12.205311, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.369147, "o", "\u001b[1;10H~\u001b[1;12Hedit\u001b[1;17Hitem\u001b[3;1H\u001b[38;5;8mpath: kjuulh.other.other.other.something \u001b[4;1H \u001b[5;1H\u001b[39m┌title──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[12.373535, "o", "\u001b[11;5H\u001b[38;5;8m- [x] some\u001b[13;5H\u001b[1m\u001b[38;5;15m- [ ] something\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.369227, "o", "────────────────────────┐\u001b[6;1H│something\u001b[38;5;0m\u001b[48;5;5m \u001b[6;209H\u001b[39m\u001b[49m│\u001b[7;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[8;1H\u001b[38;5;8m┌description────────────────────────────────────────────────────────────────────────────"]
[12.626159, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.369285, "o", "────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\u001b[9;1H│ \u001b[9;15H \u001b[9;19H │\u001b[10;1H└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[12.823931, "o", "\u001b[13;8H\u001b[1m\u001b[38;5;15mx\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.369321, "o", "───────────────────────────────────────────────────────────────────┘\u001b[11;13H\u001b[39m \u001b[13;13H \u001b[15;9H \u001b[17;9H \u001b[19;13H \u001b[21;17H \u001b[23;17H \u001b[25;9H \u001b[27;1H \u001b[29;1H \u001b[31;5H \u001b[33;5H \u001b[35;1H \u001b[37;1H -- EDIT\u001b[37;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[13.07613, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.622591, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[13.09335, "o", "\u001b[11;5H\u001b[1m\u001b[38;5;15m- [x] some\u001b[13;5H\u001b[22m\u001b[38;5;8m- [x] something\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [11.876231, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[13.287478, "o", "\u001b[7;5H\u001b[1m\u001b[38;5;15m- other\u001b[11;5H\u001b[22m\u001b[38;5;8m- [x] some\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [12.129645, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[13.540166, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [12.382542, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[13.573087, "o", "\u001b[7;5H\u001b[38;5;8m- other\u001b[9;7H\u001b[1m\u001b[38;5;15m- [ ] a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [12.636292, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[13.826053, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [12.705196, "o", "\u001b[6;11Hi\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[13.903827, "o", "\u001b[9;10H\u001b[1m\u001b[38;5;15mx\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [12.958571, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[14.156497, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [13.10767, "o", "\u001b[6;11H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[14.367096, "o", "\u001b[7;5H\u001b[1m\u001b[38;5;15m- other\u001b[9;7H\u001b[22m\u001b[38;5;8m- [x] a\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [13.274155, "o", "\u001b[6;10H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[14.594457, "o", "\u001b[5;3H\u001b[1m\u001b[38;5;15m- other\u001b[7;5H\u001b[22m\u001b[38;5;8m- other\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [13.437362, "o", "\u001b[6;9H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[14.847965, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"] [13.603346, "o", "\u001b[6;8H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.025229, "o", "\u001b[?1049l\u001b[?25h"] [13.797662, "o", "\u001b[6;7H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.026982, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] [13.964183, "o", "\u001b[6;6H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.04886, "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[38;2;255;153;102m≡ \u001b[0m\u001b[1;31mrs \u001b[0m\u001b[33m12s\u001b[0m \r\n\u001b[38;2;255;153;102m\u001b[0m \u001b[K"] [14.128346, "o", "\u001b[6;5H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.049561, "o", "\u001b[6 q"] [14.277769, "o", "\u001b[6;4H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.05028, "o", "\u001b[6 q"] [14.444215, "o", "\u001b[6;3H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.050378, "o", "\u001b[?2004h"] [14.607996, "o", "\u001b[6;2H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[16.301699, "o", "\u001b[?2004l\r\r\n"] [14.817381, "o", "\u001b[6;2HI\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[14.938407, "o", "\u001b[6;3H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.105005, "o", "\u001b[6;4Hc\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.177103, "o", "\u001b[6;5Ha\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.237734, "o", "\u001b[6;6Hn\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.314055, "o", "\u001b[6;7H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.50905, "o", "\u001b[6;8He\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.688487, "o", "\u001b[6;9Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.778225, "o", "\u001b[6;10Hi\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.884484, "o", "\u001b[6;11Ht\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[15.927584, "o", "\u001b[6;12H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[16.064325, "o", "\u001b[6;13Ht\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[16.137399, "o", "\u001b[6;14Hh\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[16.274067, "o", "\u001b[6;15Hi\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[16.334342, "o", "\u001b[6;16Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[16.544224, "o", "\u001b[6;17H \u001b[37;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[16.784735, "o", "\u001b[5;1H\u001b[38;5;8m┌title──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\u001b[6;1H│I can edit this │\u001b[7;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[8;1H\u001b[39m┌description───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[16.784907, "o", "─────────────────┐\u001b[9;1H│ │\u001b[10;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[17.039025, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[17.187426, "o", "\u001b[9;2H\u001b[38;5;0m\u001b[48;5;5m \u001b[37;5H\u001b[39m\u001b[49mEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[17.441615, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[17.696128, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[17.950481, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[17.954099, "o", "\u001b[9;2HA\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.074522, "o", "\u001b[9;3Hn\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.147127, "o", "\u001b[9;4Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.26807, "o", "\u001b[9;5H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.357652, "o", "\u001b[9;6Ht\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.434358, "o", "\u001b[9;7Hh\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.58746, "o", "\u001b[9;8Hi\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.704545, "o", "\u001b[9;9Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[18.884595, "o", "\u001b[9;10H \u001b[37;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[19.137767, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[19.214049, "o", "\u001b[37;1H: \u001b[37;5H \u001b[37;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[19.333851, "o", "\u001b[37;2Hw\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[19.40729, "o", "\u001b[37;3Hq\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[19.545185, "o", "\u001b[1;10H \u001b[1;12H \u001b[1;17H \u001b[3;1H\u001b[38;5;8m- other\u001b[39m \u001b[4;1H \u001b[5;1H \u001b[38;5;8m- other\u001b[39m \u001b[6;1H \u001b[7;1H \u001b[38;5;8m- other\u001b[39m "]
[19.545334, "o", " \u001b[8;1H \u001b[9;1H \u001b[9;6H \u001b[9;13H\u001b[38;5;8m- [x] I can edit this\u001b[9;209H\u001b[39m \u001b[10;1H \u001b[11;13H\u001b[38;5;8m- [x] basdfasdfasdfasdf\u001b[13;13H\u001b[1m\u001b[38;5;15m- [x] sdlfkasldjflsdaslkdjfalkjsdfl\u001b[15;9H\u001b[22m\u001b[38;5;8m- [x] some\u001b[17;9H- something\u001b[19;13H- something-else\u001b[21;17H- [x] another-real-item-man\u001b[23;17H- [x] arealitembaby\u001b[25;9H- [ ] whatever\u001b[27;1H- some\u001b[29;1H- something\u001b[31;5H- else\u001b[33;5H- third\u001b[35;1H- with-something\u001b[37;1H\u001b[39m --\u001b[37;5HVIEW\u001b[37;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[19.799162, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[20.054028, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[20.307998, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[20.561729, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[20.566624, "o", "\u001b[11;13H\u001b[1m\u001b[38;5;15m- [x] basdfasdfasdfasdf\u001b[13;13H\u001b[22m\u001b[38;5;8m- [x] sdlfkasldjflsdaslkdjfalkjsdfl\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[20.702313, "o", "\u001b[9;13H\u001b[1m\u001b[38;5;15m- [x] I can edit this\u001b[11;13H\u001b[22m\u001b[38;5;8m- [x] basdfasdfasdfasdf\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[20.908298, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[21.162091, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[21.37516, "o", "\u001b[9;16H\u001b[1m\u001b[38;5;15m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[21.629428, "o", "\u001b[9;16H\u001b[1m\u001b[38;5;15mx\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[21.88325, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[21.959451, "o", "\u001b[9;16H\u001b[1m\u001b[38;5;15m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[22.155088, "o", "\u001b[9;16H\u001b[1m\u001b[38;5;15mx\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[22.348094, "o", "\u001b[9;16H\u001b[1m\u001b[38;5;15m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[22.528582, "o", "\u001b[9;16H\u001b[1m\u001b[38;5;15mx\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[22.782211, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[23.035832, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[23.248605, "o", "\u001b[9;13H\u001b[38;5;8m- [x] I can edit this\u001b[11;13H\u001b[1m\u001b[38;5;15m- [x] basdfasdfasdfasdf\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[23.445613, "o", "\u001b[9;13H\u001b[1m\u001b[38;5;15m- [x] I can edit this\u001b[11;13H\u001b[22m\u001b[38;5;8m- [x] basdfasdfasdfasdf\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[23.654844, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[23.908641, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[24.162166, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[24.415538, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[24.669106, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[24.915592, "o", "\u001b[37;1H: \u001b[37;5H \u001b[37;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[25.038078, "o", "\u001b[37;2He\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[25.2292, "o", "\u001b[37;3Hd\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[25.318513, "o", "\u001b[37;4Hi\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[25.455016, "o", "\u001b[37;5Ht\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[25.544807, "o", "\u001b[1;10H~\u001b[1;12Hedit\u001b[1;17Hitem\u001b[3;1H\u001b[38;5;8mpath: kjuulh.other.other.other.I can edit this \u001b[4;1H \u001b[5;1H\u001b[39m┌title──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[25.54489, "o", "────────────────────────┐\u001b[6;1H│I\u001b[6;4Hcan\u001b[6;8Hedit\u001b[6;13Hthis\u001b[38;5;0m\u001b[48;5;5m \u001b[6;209H\u001b[39m\u001b[49m│\u001b[7;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[8;1H\u001b[38;5;8m┌description─────────────────────────────────────────────────────────────────────"]
[25.544988, "o", "───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\u001b[9;1H│And this │\u001b[10;1H└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[25.545068, "o", "──────────────────────────────────────────────────────────────────────┘\u001b[11;13H\u001b[39m \u001b[13;13H \u001b[15;9H \u001b[17;9H \u001b[19;13H \u001b[21;17H \u001b[23;17H \u001b[25;9H \u001b[27;1H \u001b[29;1H \u001b[31;5H \u001b[33;5H \u001b[35;1H \u001b[37;1H -- EDIT\u001b[37;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[25.799349, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[26.052485, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[26.23418, "o", "\u001b[6;17Hj\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[26.488909, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[26.742022, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[26.94057, "o", "\u001b[6;17H\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[27.117303, "o", "\u001b[6;17H \u001b[37;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[27.370323, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[27.38653, "o", "\u001b[5;1H\u001b[38;5;8m┌title──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\u001b[6;1H│I can edit this │\u001b[7;1H└──────────────────────────────────────────────────────"]
[27.386567, "o", "─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[8;1H\u001b[39m┌description───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"]
[27.386677, "o", "─────────────────┐\u001b[9;1H│And this │\u001b[10;1H└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[27.639588, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[27.717352, "o", "\u001b[9;2H\u001b[38;5;0m\u001b[48;5;5mA\u001b[37;5H\u001b[39m\u001b[49mEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[27.970564, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[28.223691, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[28.467566, "o", "\u001b[9;2HA\u001b[37;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[28.72076, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[28.874563, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[29.127769, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[29.33782, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[29.534369, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[29.787555, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[29.984355, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[30.134543, "o", "\u001b[9;2H\u001b[38;5;0m\u001b[48;5;5mA\u001b[37;5H\u001b[39m\u001b[49mEDIT\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[30.388285, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[30.478184, "o", "\u001b[9;2HA\u001b[38;5;0m\u001b[48;5;5mn\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[30.658079, "o", "\u001b[9;3Hn\u001b[38;5;0m\u001b[48;5;5md\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[30.795066, "o", "\u001b[9;4Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[30.943548, "o", "\u001b[9;5H \u001b[38;5;0m\u001b[48;5;5mt\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[31.106805, "o", "\u001b[9;6Ht\u001b[38;5;0m\u001b[48;5;5mh\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[31.243172, "o", "\u001b[9;7Hh\u001b[38;5;0m\u001b[48;5;5mi\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[31.394761, "o", "\u001b[9;8Hi\u001b[38;5;0m\u001b[48;5;5ms\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[31.543508, "o", "\u001b[9;9Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[31.797651, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[31.814543, "o", "\u001b[9;10H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[32.067544, "o", "\u001b[9;11HI\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[32.113144, "o", "\u001b[9;12H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[32.365934, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[32.397063, "o", "\u001b[9;13Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[32.650068, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[32.713855, "o", "\u001b[9;14Hh\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[32.877214, "o", "\u001b[9;15Ho\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.026953, "o", "\u001b[9;16Hu\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.193541, "o", "\u001b[9;17Hl\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.270848, "o", "\u001b[9;18Hd\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.327636, "o", "\u001b[9;19H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.433825, "o", "\u001b[9;20Hg\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.567382, "o", "\u001b[9;21He\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.643795, "o", "\u001b[9;22Ht\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.687125, "o", "\u001b[9;23H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[33.940622, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.064137, "o", "\u001b[9;24Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.167239, "o", "\u001b[9;25Ho\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.227022, "o", "\u001b[9;26Hr\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.423997, "o", "\u001b[9;27Ht\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.514008, "o", "\u001b[9;28Hi\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.677124, "o", "\u001b[9;29Hn\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.707248, "o", "\u001b[9;30Hg\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[34.843905, "o", "\u001b[9;31H \u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[35.007343, "o", "\u001b[9;32Hf\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[35.097998, "o", "\u001b[9;33Hi\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[35.234791, "o", "\u001b[9;34Hx\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[35.398271, "o", "\u001b[9;35He\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[35.534597, "o", "\u001b[9;36Hs\u001b[38;5;0m\u001b[48;5;5m \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[35.746795, "o", "\u001b[9;37H \u001b[37;5HVIEW\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[36.000798, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[36.058291, "o", "\u001b[37;1H: \u001b[37;5H \u001b[37;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[36.147303, "o", "\u001b[37;2Hw\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[36.22354, "o", "\u001b[37;3Hq\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[36.37499, "o", "\u001b[1;10H \u001b[1;12H \u001b[1;17H \u001b[3;1H\u001b[38;5;8m- other\u001b[39m \u001b[4;1H \u001b[5;1H \u001b[38;5;8m- other\u001b[39m \u001b[6;1H \u001b[7;1H \u001b[38;5;8m- other\u001b[39m "]
[36.375133, "o", " \u001b[8;1H \u001b[9;1H \u001b[9;6H \u001b[9;11H \u001b[9;13H\u001b[38;5;8m- [x] I can edit this\u001b[39m \u001b[9;209H \u001b[10;1H \u001b[11;13H\u001b[1m\u001b[38;5;15m- [x] basdfasdfasdfasdf\u001b[13;13H\u001b[22m\u001b[38;5;8m- [x] sdlfkasldjflsdaslkdjfalkjsdfl\u001b[15;9H- [x] some\u001b[17;9H- something\u001b[19;13H- something-else\u001b[21;17H- [x] another-real-item-man\u001b[23;17H- [x] arealitembaby\u001b[25;9H- [ ] whatever\u001b[27;1H- some\u001b[29;1H- something\u001b[31;5H- else\u001b[33;5H- third\u001b[35;1H- with-something\u001b[37;1H\u001b[39m --\u001b[37;5HVIEW\u001b[37;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[36.62897, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[36.883979, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[37.048337, "o", "\u001b[9;13H\u001b[1m\u001b[38;5;15m- [x] I can edit this\u001b[11;13H\u001b[22m\u001b[38;5;8m- [x] basdfasdfasdfasdf\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[37.301888, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[37.556956, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[37.810594, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[38.064062, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[38.320665, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[38.574308, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[38.828028, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[39.081369, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[39.298179, "o", "\u001b[37;1H: \u001b[37;5H \u001b[37;10H \u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[39.524441, "o", "\u001b[37;2Hq\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[39.68854, "o", "\u001b[37;1H --\u001b[37;5HVIEW\u001b[37;10H--\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[39.942362, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[40.196662, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[40.450474, "o", "\u001b[39m\u001b[49m\u001b[59m\u001b[0m\u001b[?25l"]
[40.691621, "o", "\u001b[?1049l\u001b[?25h"]
[40.693631, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
[40.718274, "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[38;2;255;153;102m≡ \u001b[0m\u001b[1;31mrs \u001b[0m\u001b[33m38s\u001b[0m \r\n\u001b[38;2;255;153;102m\u001b[0m \u001b[K"]
[40.719012, "o", "\u001b[6 q"]
[40.719517, "o", "\u001b[6 q"]
[40.719593, "o", "\u001b[?2004h"]
[42.251381, "o", "\u001b[?2004l\r\r\n"]