Skip to content

Commit

Permalink
- updated the readme
Browse files Browse the repository at this point in the history
- fixed small issue with expand not working
  • Loading branch information
RealRTTV committed Apr 11, 2024
1 parent 5f767f7 commit 500839b
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 96 deletions.
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nbtworkbench"
version = "1.2.5"
version = "1.2.6"
edition = "2021"
description = "A modern NBT Editor written in Rust designed for performance and efficiency."
license-file = "LICENSE"
Expand All @@ -9,12 +9,12 @@ keywords = ["nbt", "window", "unsafe", "editor", "tree"]
categories = ["graphics", "rendering", "text-editors", "parser-implementations"]

# Wasm Only
[lib]
crate-type = ["cdylib", "rlib"]
path = "src/main.rs"
#[lib]
#crate-type = ["cdylib", "rlib"]
#path = "src/main.rs"

# Windows Only
#[package.metadata.winres]
[package.metadata.winres]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
60 changes: 50 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,81 @@ which is in turn the successor to [NBTExplorer](https://github.com/jaquadro/NBTE
NBT Workbench is written completely from scratch in [Rust](https://www.rust-lang.org/) and designed to be as performant and efficient as possible.

## <img src="icons/features.png" width=16> Features
(Features marked with a star are new and not available in NBT Studio or Explorer):
(Features marked with a are new and not available in NBT Studio or Explorer):

* Java NBT files (`level.dat` / `hotbar.nbt`)
* Java region files (`.mca`)
* ☆ Now supporting the new 1.21 compression format
* ☆ Now supports the new 1.21 LZ4 compression format
* SNBT files (`.snbt`)
*[Web Version](https://rttv.ca/main)
* Save as dialog
* Create new nbt file / new region file
* Tags can be selected, dragged and dropped to move them around.
* ☆ Action wheel
* By holding right-click over an NBT tag: A circular action wheel will appear, which will let you make specific changes to NBT tags, this includes:
* Copying the condensed/raw or formatted/pretty SNBT version of a tag.
* ☆ Opening an array in a preferred hex editor.
* ☆ Opening nbt as SNBT in a preferred text editor.
* ☆ Sorting Compounds alphabetically or by type.
* ☆ Hotkeys to quickly create new elements by their type
* ☆ Editing tag key/values in one click by simply being overtop the text.
* Tags can be selected, dragged and dropped to move them around.
* Undo and redo with Ctrl + Z and Ctrl + Y / Ctrl + Shift + Z respectively.
* ☆ Ctrl + D to duplicate the hovered tag below itself
* ☆ Searching with substrings, regex and snbt matching.
* ☆ Bookmarks
* ☆ Line Numbers
* ☆ Dark Mode
* ☆ Freehand mode to easily dive into NBT files without needing to click precisely
* Alt + Left / Right Arrow to retract and expand respectively
* ☆ Alt + Shift + Right Arrow to expand fully
* ☆ Remastered NBT Explorer Art
* ☆ CLI Mode `nbtworkbench -?`
*`nbtworkbench find` to search across multiple files
*`nbtworkbench reformat` to reformat the extensions of multiple files
* Reload button
* ☆ Tabs
* ☆ The fastest NBT read / write around

## <img src="icons/keybinds.png" width=16> Keybinds (in order of processing)
(Keybinds marked with a ☆ are new and not available in NBT Studio or Explorer):
* (on Selected Text)
* \[\] moves up to previous line.
* \[\] moves down to next line.
*\[Ctrl + ↑\] moves up to first child with the same parent.
*\[Ctrl + ↓\] moves down to last child with the same parent.
*\[Ctrl + Shift + ↑\] moves element up one.
*\[Ctrl + Shift + ↓\] moves element down one.
* \[Alt + ←\] closes currently selected element.
* \[Alt + →\] opens currently selected element.
*\[Alt + Shift + →\] fully expands currently selected element.
* \[Ctrl + F\] Focus find box.
* \[+\] Zoom in.
* \[-\] Zoom out.
*\[1 to 8\] Jump to nth tab.
*\[9\] Jump to last tab.
* \[Ctrl + R\] Reload tab.
*\[Ctrl + Shift + R\] Toggle freehand mode. (Disables selecting text and makes toggle button extend horizontally to make for quick maneuvering)
* \[Ctrl + N\] New tab.
* \[Ctrl + Shift + N\] New region file tab.
* \[Ctrl + O\] Open file.
* \[Ctrl + S\] Save file.
* \[Ctrl + Shift + S\] Save file as.
*\[Ctrl + W\] Close tab.
* \[Ctrl + Z\] Undo.
* \[Ctrl + Y\] / \[Ctrl + Shift + Z\] Redo.
*\[Ctrl + D\] Duplicate hovered element below.
* \[Ctrl + C\] Copy hovered element as SNBT to clipboard.
*\[Ctrl + Shift + C\] Copy hovered element as pretty SNBT to clipboard.
* \[Ctrl + X\] Cut hovered element as SNBT to clipboard.
* ☆ (to create new template elements)
* \[1\] Create byte.
* \[2\] Create short.
* \[3\] Create int.
* \[4\] Create long.
* \[5\] Create float.
* \[6\] Create double.
* \[7\] Create byte array.
* \[8\] Create int array.
* \[9\] Create long array.
* \[0\] Create string.
* \[-\] Create list.
* \[=\] Create compound.
* \[\`\] Create chunk.
* \[V\] Create from clipboard.

# Credits
NBT Workbench was made by myself, Katie;
however, it would not come to be without the lovely projects below inspiring it.
Expand Down
43 changes: 27 additions & 16 deletions src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,22 +147,33 @@ pub const NEW_FILE_UV: Vec2u = Vec2u::new(96, 48);
pub const REFRESH_UV: Vec2u = Vec2u::new(152, 144);
pub const DISABLED_REFRESH_UV: Vec2u = Vec2u::new(168, 144);

pub const BASE_Z: u8 = 5;
pub const JUST_OVERLAPPING_BASE_Z: u8 = BASE_Z + 1;
pub const BASE_TEXT_Z: u8 = 10;
pub const JUST_OVERLAPPING_BASE_TEXT_Z: u8 = BASE_TEXT_Z + 1;
pub const TOGGLE_Z: u8 = 20;
pub const LINE_NUMBER_Z: u8 = 60;
pub const LINE_NUMBER_CONNECTOR_Z: u8 = LINE_NUMBER_Z + 1;
pub const BOOKMARK_Z: u8 = 80;
pub const SELECTED_TEXT_Z: u8 = 130;
pub const ACTION_WHEEL_Z: u8 = 190;
pub const SCROLLBAR_BOOKMARK_Z: u8 = SCROLLBAR_Z - 1;
pub const SCROLLBAR_Z: u8 = 200;
pub const HELD_ENTRY_Z: u8 = 210;
pub const ALERT_Z: u8 = 240;
pub const ALERT_TEXT_Z: u8 = ALERT_Z + 1;
pub const TOOLTIP_Z: u8 = 250;
#[repr(u8)]
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
pub enum ZOffset {
SEARCH_BOX_Z = 50,
SEARCH_BOX_SELECTION_Z = 51,
JUST_UNDERLAPPING_BASE_Z = 79,
BASE_Z = 80,
JUST_OVERLAPPING_BASE_Z = 81,
BASE_TEXT_Z = 90,
JUST_OVERLAPPING_BASE_TEXT_Z = 91,
TOGGLE_Z = 100,
LINE_NUMBER_Z = 130,
LINE_NUMBER_CONNECTOR_Z = 131,
BOOKMARK_Z = 140,
SELECTED_TEXT_Z = 170,
SELECTED_TEXT_SELECTION_Z = 171,
ACTION_WHEEL_Z = 190,
SCROLLBAR_BOOKMARK_Z = 199,
SCROLLBAR_Z = 200,
HELD_ENTRY_Z = 210,
ALERT_Z = 240,
ALERT_TEXT_Z = 241,
TOOLTIP_Z = 250,
}

pub use ZOffset::*;

#[allow(clippy::cast_ptr_alignment)]
pub fn icon() -> Vec<u8> {
Expand Down
4 changes: 2 additions & 2 deletions src/elements/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ macro_rules! array {
ctx.render_errors(ctx.pos(), builder);
let str = Self::transmute(element).to_compact_string();
if ctx.forbid(ctx.pos()) {
builder.settings(ctx.pos() + (20, 0), false, 1);
builder.settings(ctx.pos() + (20, 0), false, JUST_OVERLAPPING_BASE_TEXT_Z);
builder.color = TextColor::TreePrimitive.to_raw();
let _ = write!(builder, "{str}");
}
Expand Down Expand Up @@ -353,7 +353,7 @@ macro_rules! array {
pub const fn max_depth(&self) -> usize { self.max_depth as usize }

#[inline]
pub fn render_icon(pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, $uv, (16, 16)); }
pub fn render_icon(pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, $uv, (16, 16)); }

#[inline]
pub fn render_element_icon(pos: impl Into<(usize, usize)>, builder: &mut VertexBufferBuilder) { builder.draw_texture(pos, $element_uv, (16, 16)); }
Expand Down
10 changes: 5 additions & 5 deletions src/elements/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::thread::Scope;
use compact_str::{format_compact, CompactString, ToCompactString};
use zune_inflate::{DeflateDecoder, DeflateOptions};

use crate::assets::{JUST_OVERLAPPING_BASE_TEXT_Z, BASE_Z, CHUNK_UV, CONNECTION_UV, HEADER_SIZE, LINE_NUMBER_CONNECTOR_Z, LINE_NUMBER_SEPARATOR_UV, REGION_UV};
use crate::assets::{JUST_OVERLAPPING_BASE_TEXT_Z, BASE_Z, CHUNK_UV, CONNECTION_UV, HEADER_SIZE, LINE_NUMBER_CONNECTOR_Z, LINE_NUMBER_SEPARATOR_UV, REGION_UV, ZOffset};
use crate::elements::compound::NbtCompound;
use crate::elements::element::NbtElement;
use crate::elements::list::{ValueIterator, ValueMutIterator};
Expand Down Expand Up @@ -117,7 +117,7 @@ impl NbtRegion {
)?,
),
3 => (FileFormat::Nbt, NbtElement::from_file(data, sort)?),
4 => (FileFormat::ChunkLz4, NbtElement::from_file(&lz4_flex::decompress(data, data.len()).ok()?, sort)?),
4 => (FileFormat::Lz4, NbtElement::from_file(&lz4_flex::decompress(data, data.len()).ok()?, sort)?),
_ => return None,
};
if element.id() != NbtCompound::ID { return None }
Expand Down Expand Up @@ -516,7 +516,7 @@ impl NbtRegion {
}

#[inline]
pub fn render_icon(pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, REGION_UV, (16, 16)); }
pub fn render_icon(pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, REGION_UV, (16, 16)); }

#[inline]
pub fn children(&self) -> ValueIterator {
Expand Down Expand Up @@ -787,7 +787,7 @@ impl NbtChunk {
FileFormat::Gzip => 1_u8,
FileFormat::Zlib => 2_u8,
FileFormat::Nbt => 3_u8,
FileFormat::ChunkLz4 => 4_u8,
FileFormat::Lz4 => 4_u8,
_ => core::hint::unreachable_unchecked(),
}
.to_be_bytes(),
Expand Down Expand Up @@ -921,7 +921,7 @@ impl NbtChunk {
}

#[inline]
pub fn render_icon(pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, CHUNK_UV, (16, 16)); }
pub fn render_icon(pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, CHUNK_UV, (16, 16)); }
}

impl Deref for NbtChunk {
Expand Down
4 changes: 2 additions & 2 deletions src/elements/compound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use compact_str::{format_compact, CompactString, ToCompactString};
use fxhash::FxHasher;
use hashbrown::raw::RawTable;

use crate::assets::{JUST_OVERLAPPING_BASE_TEXT_Z, BASE_Z, COMPOUND_ROOT_UV, COMPOUND_UV, CONNECTION_UV, HEADER_SIZE, LINE_NUMBER_CONNECTOR_Z, LINE_NUMBER_SEPARATOR_UV};
use crate::assets::{JUST_OVERLAPPING_BASE_TEXT_Z, BASE_Z, COMPOUND_ROOT_UV, COMPOUND_UV, CONNECTION_UV, HEADER_SIZE, LINE_NUMBER_CONNECTOR_Z, LINE_NUMBER_SEPARATOR_UV, ZOffset};
use crate::decoder::Decoder;
use crate::elements::chunk::NbtChunk;
use crate::elements::element::NbtElement;
Expand Down Expand Up @@ -717,7 +717,7 @@ impl NbtCompound {
}

#[inline]
pub fn render_icon(pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, COMPOUND_UV, (16, 16)); }
pub fn render_icon(pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, COMPOUND_UV, (16, 16)); }
}

// Based on indexmap, but they didn't let me clone with unchecked mem stuff
Expand Down
4 changes: 2 additions & 2 deletions src/elements/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{fmt, fmt::Write};
use compact_str::{format_compact, CompactString, ToCompactString};
use hashbrown::raw::RawTable;

use crate::assets::{BASE_Z, BYTE_ARRAY_UV, BYTE_UV, CONNECTION_UV, DOUBLE_UV, FLOAT_UV, INT_ARRAY_UV, INT_UV, LONG_ARRAY_UV, LONG_UV, SHORT_UV};
use crate::assets::{BASE_Z, BYTE_ARRAY_UV, BYTE_UV, CONNECTION_UV, DOUBLE_UV, FLOAT_UV, INT_ARRAY_UV, INT_UV, LONG_ARRAY_UV, LONG_UV, SHORT_UV, ZOffset};
use crate::decoder::Decoder;
use crate::elements::chunk::{NbtChunk, NbtRegion};
use crate::elements::compound::{CompoundMap, CompoundMapIter, Entry, NbtCompound};
Expand Down Expand Up @@ -639,7 +639,7 @@ impl NbtElement {
}

#[inline]
pub fn render_icon(id: u8, pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) {
pub fn render_icon(id: u8, pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) {
match id {
0 => {}
NbtByte::ID => NbtByte::render_icon(pos, z, builder),
Expand Down
4 changes: 2 additions & 2 deletions src/elements/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::slice::{Iter, IterMut};
#[cfg(not(target_arch = "wasm32"))]
use std::thread::Scope;

use crate::assets::{JUST_OVERLAPPING_BASE_TEXT_Z, BASE_Z, CONNECTION_UV, LIST_UV};
use crate::assets::{JUST_OVERLAPPING_BASE_TEXT_Z, BASE_Z, CONNECTION_UV, LIST_UV, ZOffset};
use crate::decoder::Decoder;
use crate::elements::chunk::NbtChunk;
use crate::elements::element::{id_to_string_name, NbtElement};
Expand Down Expand Up @@ -466,7 +466,7 @@ impl NbtList {
}

#[inline]
pub fn render_icon(pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, LIST_UV, (16, 16)); }
pub fn render_icon(pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, LIST_UV, (16, 16)); }

#[inline]
pub fn recache_depth(&mut self) {
Expand Down
2 changes: 1 addition & 1 deletion src/elements/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ macro_rules! primitive {
}

#[inline]
pub fn render_icon(pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, $uv, (16, 16)); }
pub fn render_icon(pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, $uv, (16, 16)); }

#[inline]
pub fn value(&self) -> CompactString { $compact_format(self.value) }
Expand Down
4 changes: 2 additions & 2 deletions src/elements/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::ptr::NonNull;

use compact_str::CompactString;

use crate::assets::{BASE_Z, JUST_OVERLAPPING_BASE_TEXT_Z, STRING_UV};
use crate::assets::{BASE_Z, JUST_OVERLAPPING_BASE_TEXT_Z, STRING_UV, ZOffset};
use crate::decoder::Decoder;
use crate::encoder::UncheckedBufWriter;
use crate::{RenderContext, StrExt, VertexBufferBuilder};
Expand Down Expand Up @@ -96,7 +96,7 @@ impl NbtString {
}

#[inline]
pub fn render_icon(pos: impl Into<(usize, usize)>, z: u8, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, STRING_UV, (16, 16)); }
pub fn render_icon(pos: impl Into<(usize, usize)>, z: ZOffset, builder: &mut VertexBufferBuilder) { builder.draw_texture_z(pos, z, STRING_UV, (16, 16)); }
}

#[repr(C)]
Expand Down
10 changes: 5 additions & 5 deletions src/search_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use regex::Regex;
use winit::event::MouseButton;

use winit::keyboard::KeyCode;
use crate::assets::{ADD_SEARCH_BOOKMARKS_UV, BASE_Z, BOOKMARK_UV, DARK_STRIPE_UV, HIDDEN_BOOKMARK_UV, HOVERED_WIDGET_UV, REGEX_SEARCH_MODE_UV, REMOVE_SEARCH_BOOKMARKS_UV, SEARCH_KEYS_UV, SEARCH_KEYS_AND_VALUES_UV, SEARCH_VALUES_UV, SNBT_SEARCH_MODE_UV, STRING_SEARCH_MODE_UV, UNSELECTED_WIDGET_UV};
use crate::assets::{ADD_SEARCH_BOOKMARKS_UV, BASE_Z, BOOKMARK_UV, DARK_STRIPE_UV, HIDDEN_BOOKMARK_UV, HOVERED_WIDGET_UV, REGEX_SEARCH_MODE_UV, REMOVE_SEARCH_BOOKMARKS_UV, SEARCH_KEYS_UV, SEARCH_KEYS_AND_VALUES_UV, SEARCH_VALUES_UV, SNBT_SEARCH_MODE_UV, STRING_SEARCH_MODE_UV, UNSELECTED_WIDGET_UV, SEARCH_BOX_Z, SEARCH_BOX_SELECTION_Z};

use crate::color::TextColor;
use crate::{combined_two_sorted, create_regex, flags, since_epoch, SortAlgorithm, StrExt};
Expand Down Expand Up @@ -172,7 +172,7 @@ impl SearchBox {

builder.draw_texture_region_z(
pos,
0,
SEARCH_BOX_Z,
DARK_STRIPE_UV,
(builder.window_width() - 215 - pos.x, 22),
(16, 16),
Expand All @@ -183,7 +183,7 @@ impl SearchBox {
builder.horizontal_scroll = self.horizontal_scroll;

if self.value.is_empty() {
builder.settings(pos + (0, 3), false, 0);
builder.settings(pos + (0, 3), false, SEARCH_BOX_Z);
builder.color = TextColor::Gray.to_raw();
let _ = write!(builder, "{}", match self.mode {
SearchMode::String => r#"Search..."#,
Expand All @@ -192,9 +192,9 @@ impl SearchBox {
});
}
if self.is_selected() {
self.0.render(builder, TextColor::White, pos + (0, 3), 0);
self.0.render(builder, TextColor::White, pos + (0, 3), SEARCH_BOX_Z, SEARCH_BOX_SELECTION_Z);
} else {
builder.settings(pos + (0, 3), false, 0);
builder.settings(pos + (0, 3), false, SEARCH_BOX_Z);
builder.color = TextColor::White.to_raw();
let _ = write!(builder, "{}", self.value);
}
Expand Down
12 changes: 6 additions & 6 deletions src/selected_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::ops::{Deref, DerefMut};
use winit::keyboard::KeyCode;

use crate::{flags, OptionExt, StrExt};
use crate::assets::{BASE_TEXT_Z, HEADER_SIZE, SELECTED_TEXT_Z, SELECTION_UV};
use crate::assets::{BASE_TEXT_Z, HEADER_SIZE, SELECTED_TEXT_SELECTION_Z, SELECTED_TEXT_Z, SELECTION_UV};
use crate::color::TextColor;
use crate::selected_text::SelectedTextKeyResult::{Down, ForceClose, ForceOpen, Keyfix, ShiftDown, ShiftUp, Up, Valuefix};
use crate::text::{Cachelike, SelectedTextKeyResult, Text};
Expand Down Expand Up @@ -289,13 +289,13 @@ impl SelectedText {
}

if key == KeyCode::ArrowLeft {
if flags & flags!(Shift) == 0 && self.selection.is_none() && self.cursor == 0 && self.keyfix.is_some() { return Keyfix }
if flags == flags!(Alt) || flags == flags!(Shift + Alt) { return ForceClose }
if flags & !flags!(Ctrl) == 0 && self.selection.is_none() && self.cursor == 0 && self.keyfix.is_some() { return Keyfix }
if flags & !flags!(Shift) == flags!(Alt) { return ForceClose }
}

if key == KeyCode::ArrowRight {
if flags & flags!(Shift) == 0 && self.selection.is_none() && self.cursor == self.value.len() && self.valuefix.is_some() { return Valuefix }
if flags == flags!(Alt) || flags == flags!(Shift + Alt) { return ForceOpen }
if flags & !flags!(Ctrl) == 0 && self.selection.is_none() && self.cursor == self.value.len() && self.valuefix.is_some() { return Valuefix }
if (flags) & !flags!(Shift) == flags!(Alt) { return ForceOpen }
}

self.0.on_key_press(key, char, flags).into()
Expand All @@ -313,7 +313,7 @@ impl SelectedText {
if y < HEADER_SIZE { return }

let prefix_width = self.prefix.0.as_str().width() + self.keyfix.as_ref().map_or(0, |x| x.0.width());
self.0.render(builder, self.value_color, (x + prefix_width, y).into(), SELECTED_TEXT_Z);
self.0.render(builder, self.value_color, (x + prefix_width, y).into(), SELECTED_TEXT_Z, SELECTED_TEXT_SELECTION_Z);

builder.draw_texture_z((x - 4 - 16, y), SELECTED_TEXT_Z, SELECTION_UV, (16, 16));
builder.settings((x, y), false, BASE_TEXT_Z);
Expand Down
Loading

0 comments on commit 500839b

Please sign in to comment.