From bce58f166aa056d31d86963da7da6937e7388418 Mon Sep 17 00:00:00 2001 From: ImaginaryDevelopment Date: Sun, 19 Feb 2012 08:58:58 -0800 Subject: [PATCH 1/8] added inventory lookups on player nodes --- Form1.cs | 2844 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 1475 insertions(+), 1369 deletions(-) diff --git a/Form1.cs b/Form1.cs index aee1cdb..4de88f1 100644 --- a/Form1.cs +++ b/Form1.cs @@ -1,1369 +1,1475 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; -using Substrate; -using Substrate.Nbt; -using System.IO; -using Substrate.Core; - -namespace NBTExplorer -{ - public partial class Form1 : Form - { - private static Dictionary _tagIconIndex; - - public Form1 () - { - InitializeComponent(); - - _nodeTree.BeforeExpand += NodeExpand; - _nodeTree.AfterCollapse += NodeCollapse; - _nodeTree.AfterSelect += NodeSelected; - _nodeTree.NodeMouseClick += NodeClicked; - _nodeTree.NodeMouseDoubleClick += NodeDoubleClicked; - - string[] args = Environment.GetCommandLineArgs(); - if (args.Length > 1) { - OpenFile(args[1]); - } - else { - OpenMinecraftDir(); - } - } - - public void LoadNbtStream (TreeNodeCollection parent, Stream stream) - { - LoadNbtStream(parent, stream, null); - } - - public void LoadNbtStream (TreeNodeCollection parent, Stream stream, string name) - { - string text = !String.IsNullOrEmpty(name) ? name : null; - text = text ?? "[root]"; - - TreeNode root = new TreeNode(text, 9, 9); - - LoadNbtStream(root, stream); - - parent.Add(root); - } - - public void LoadNbtStream (TreeNode node, Stream stream) - { - NbtTree tree = new NbtTree(); - tree.ReadFrom(stream); - - if (node.Tag != null && node.Tag is NbtDataNode) { - (node.Tag as NbtDataNode).Tree = tree; - } - - PopulateNodeFromTag(node, tree.Root); - } - - private TreeNode NodeFromTag (TagNode tag) - { - return NodeFromTag(tag, null); - } - - private TreeNode NodeFromTag (TagNode tag, string name) - { - TreeNode node = new TreeNode(); - node.ImageIndex = _tagIconIndex[tag.GetTagType()]; - node.SelectedImageIndex = _tagIconIndex[tag.GetTagType()]; - node.Tag = tag; - node.Text = GetNodeText(name, tag); - - if (tag.GetTagType() == TagType.TAG_LIST) { - PopulateNodeFromTag(node, tag.ToTagList()); - } - else if (tag.GetTagType() == TagType.TAG_COMPOUND) { - PopulateNodeFromTag(node, tag.ToTagCompound()); - } - - return node; - } - - private string GetTagNodeText (TagNode tag) - { - if (tag == null) - return null; - - switch (tag.GetTagType()) { - case TagType.TAG_BYTE: - case TagType.TAG_SHORT: - case TagType.TAG_INT: - case TagType.TAG_LONG: - case TagType.TAG_FLOAT: - case TagType.TAG_DOUBLE: - case TagType.TAG_STRING: - return tag.ToString(); - - case TagType.TAG_BYTE_ARRAY: - return tag.ToTagByteArray().Length + " bytes"; - - case TagType.TAG_LIST: - return tag.ToTagList().Count + " entries"; - - case TagType.TAG_COMPOUND: - return tag.ToTagCompound().Count + " entries"; - } - - return null; - } - - private string GetNodeText (string name, string value) - { - name = String.IsNullOrEmpty(name) ? "" : name + ": "; - value = value ?? ""; - - return name + value; - } - - private string GetNodeText (string name, TagNode tag) - { - return GetNodeText(name, GetTagNodeText(tag)); - } - - private string GetNodeText (TreeNode node) - { - return GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); - } - - private string GetTagNodeText (TreeNode node) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return null; - - return GetTagNodeText(tag); - } - - private void PopulateNodeFromTag (TreeNode node, TagNodeList list) - { - foreach (TagNode tag in list) { - node.Nodes.Add(NodeFromTag(tag)); - } - } - - private void PopulateNodeFromTag (TreeNode node, TagNodeCompound dict) - { - var list = new SortedList(); - foreach (KeyValuePair kv in dict) { - list.Add(new TagKey(kv.Key, kv.Value.GetTagType()), kv.Value); - } - - foreach (KeyValuePair kv in list) { - node.Nodes.Add(NodeFromTag(kv.Value, kv.Key.Name)); - } - } - - public void LoadWorld (string path) - { - NbtWorld world = NbtWorld.Open(path); - - BetaWorld beta = world as BetaWorld; - if (beta != null) { - LoadBetaWorld(beta); - } - } - - private void LoadBetaWorld (BetaWorld world) - { - RegionManager rm = world.GetRegionManager(); - } - - public void LoadRegion (TreeNodeCollection parent, string path) - { - TreeNode root = new TreeNode(Path.GetFileName(path), 11, 11); - LoadRegion(root, path); - parent.Add(root); - } - - public void LoadRegion (TreeNode node, string path) - { - RegionFile rf = new RegionFile(path); - - for (int x = 0; x < 32; x++) { - for (int y = 0; y < 32; y++) { - if (rf.HasChunk(x, y)) { - TreeNode child = CreateLazyChunk(rf, x, y); - node.Nodes.Add(child); - LinkDataNodeParent(child, node); - } - } - } - } - - public TreeNode CreateLazyChunk (RegionFile rf, int x, int z) - { - TreeNode node = new TreeNode(); - node.ImageIndex = 9; - node.SelectedImageIndex = 9; - node.Text = "Chunk [" + x + ", " + z + "]"; - node.Tag = new RegionChunkData(rf, x, z); - node.Nodes.Add(new TreeNode()); - - return node; - } - - public TreeNode CreateLazyRegion (string path) - { - TreeNode node = new TreeNode(); - node.ImageIndex = 11; - node.SelectedImageIndex = 11; - node.Text = Path.GetFileName(path); - node.Tag = new RegionData(path); - node.Nodes.Add(new TreeNode()); - - return node; - } - - public TreeNode CreateLazyNbt (string path, CompressionType cztype) - { - TreeNode node = new TreeNode(); - node.ImageIndex = 12; - node.SelectedImageIndex = 12; - node.Text = Path.GetFileName(path); - node.Tag = new NbtFileData(path, cztype); - node.Nodes.Add(new TreeNode()); - - return node; - } - - public TreeNode CreateLazyDirectory (string path) - { - TreeNode node = new TreeNode(); - node.ImageIndex = 10; - node.SelectedImageIndex = 10; - node.Text = Path.GetFileName(path); - node.Tag = new DirectoryData(path); - node.Nodes.Add(new TreeNode()); - - return node; - } - - public TreeNode CreateLazyDirectory (string path, TreeNode parent) - { - TreeNode node = CreateLazyDirectory(path); - LinkDataNodeParent(node, parent); - - return node; - } - - public TreeNode CreateLazyNbt (string path, CompressionType cztype, TreeNode parent) - { - TreeNode node = CreateLazyNbt(path, cztype); - LinkDataNodeParent(node, parent); - - return node; - } - - private void LinkDataNodeParent (TreeNode node, TreeNode parent) - { - if (node != null && parent != null && node.Tag != null && parent.Tag != null) { - DataNode nodeDn = node.Tag as DataNode; - DataNode parentDn = parent.Tag as DataNode; - - if (nodeDn != null && parentDn != null) { - nodeDn.Parent = parentDn; - } - } - } - - public void LoadLazyChunk (TreeNode node) - { - RegionChunkData data = node.Tag as RegionChunkData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - LoadNbtStream(node, data.Region.GetChunkDataInputStream(data.X, data.Z)); - - data.Expanded = true; - } - - public void LoadLazyNbt (TreeNode node) - { - NbtFileData data = node.Tag as NbtFileData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - - NBTFile file = new NBTFile(data.Path); - LoadNbtStream(node, file.GetDataInputStream(data.CompressionType)); - - data.Expanded = true; - } - - public void LoadLazyDirectory (TreeNode node) - { - DirectoryData data = node.Tag as DirectoryData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - - foreach (string dirpath in Directory.EnumerateDirectories(data.Path)) { - node.Nodes.Add(CreateLazyDirectory(dirpath, node)); - } - - foreach (string filepath in Directory.EnumerateFiles(data.Path)) { - TryLoadFile(node.Nodes, filepath); - } - - data.Expanded = true; - } - - public void LoadLazyRegion (TreeNode node) - { - RegionData data = node.Tag as RegionData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - LoadRegion(node, data.Path); - - data.Expanded = true; - } - - public void UnloadLazyDataNode (TreeNode node) - { - DataNode data = node.Tag as DataNode; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - node.Nodes.Add(new TreeNode()); - - data.Expanded = false; - } - - private void ExpandNode (TreeNode node) - { - if (node.Tag == null) - return; - - if (node.Tag is DataNode) { - if ((node.Tag as DataNode).Expanded) - return; - } - - if (node.Tag is RegionChunkData) { - LoadLazyChunk(node); - } - else if (node.Tag is NbtFileData) { - LoadLazyNbt(node); - } - else if (node.Tag is DirectoryData) { - LoadLazyDirectory(node); - } - else if (node.Tag is RegionData) { - LoadLazyRegion(node); - } - } - - private void CollapseNode (TreeNode node) - { - if (node.Tag == null) - return; - - if (node.Tag is DataNode) { - UnloadLazyDataNode(node); - } - } - - private void NodeExpand (object sender, TreeViewCancelEventArgs e) - { - ExpandNode(e.Node); - } - - private void NodeCollapse (object sender, TreeViewEventArgs e) - { - CollapseNode(e.Node); - } - - private void NodeSelected (object sender, TreeViewEventArgs e) - { - UpdateToolbar(); - } - - private void NodeClicked (object sender, TreeNodeMouseClickEventArgs e) - { - - } - - private void NodeDoubleClicked (object sender, TreeNodeMouseClickEventArgs e) - { - EditNodeValue(_nodeTree.SelectedNode); - } - - private void UpdateToolbar () - { - TreeNode node = _nodeTree.SelectedNode; - TagNode tag = node.Tag as TagNode; - - if (tag == null && node.Tag is NbtDataNode) { - NbtDataNode data = node.Tag as NbtDataNode; - if (data.Tree != null) - tag = data.Tree.Root; - } - - _buttonRename.Enabled = tag != null && node.Tag is TagNode; - _buttonDelete.Enabled = tag != null && node.Tag is TagNode; - _buttonEdit.Enabled = tag != null - && node.Tag is TagNode - && tag.GetTagType() != TagType.TAG_BYTE_ARRAY - && tag.GetTagType() != TagType.TAG_COMPOUND - && tag.GetTagType() != TagType.TAG_LIST; - - if (tag == null || tag.GetTagType() != TagType.TAG_COMPOUND) - SetTagButtons(false); - if (tag != null && tag.GetTagType() == TagType.TAG_COMPOUND) - SetTagButtons(true); - if (tag != null && tag.GetTagType() == TagType.TAG_LIST && tag.ToTagList().Count == 0) - SetTagButtons(true); - - if (tag != null && tag.GetTagType() == TagType.TAG_LIST) { - switch (tag.ToTagList().ValueType) { - case TagType.TAG_BYTE: - _buttonAddTagByte.Enabled = true; - break; - case TagType.TAG_SHORT: - _buttonAddTagShort.Enabled = true; - break; - case TagType.TAG_INT: - _buttonAddTagInt.Enabled = true; - break; - case TagType.TAG_LONG: - _buttonAddTagLong.Enabled = true; - break; - case TagType.TAG_FLOAT: - _buttonAddTagFloat.Enabled = true; - break; - case TagType.TAG_DOUBLE: - _buttonAddTagDouble.Enabled = true; - break; - case TagType.TAG_BYTE_ARRAY: - _buttonAddTagByteArray.Enabled = true; - break; - case TagType.TAG_STRING: - _buttonAddTagString.Enabled = true; - break; - case TagType.TAG_LIST: - _buttonAddTagList.Enabled = true; - break; - case TagType.TAG_COMPOUND: - _buttonAddTagCompound.Enabled = true; - break; - } - } - } - - private void SetTagButtons (bool state) - { - _buttonAddTagByte.Enabled = state; - _buttonAddTagShort.Enabled = state; - _buttonAddTagInt.Enabled = state; - _buttonAddTagLong.Enabled = state; - _buttonAddTagFloat.Enabled = state; - _buttonAddTagDouble.Enabled = state; - _buttonAddTagByteArray.Enabled = state; - _buttonAddTagString.Enabled = state; - _buttonAddTagList.Enabled = state; - _buttonAddTagCompound.Enabled = state; - } - - public void OpenDirectory (string path) - { - _nodeTree.Nodes.Clear(); - - LoadDirectory(path); - - if (_nodeTree.Nodes.Count > 0) { - _nodeTree.Nodes[0].Expand(); - } - } - - public void OpenPaths (string[] paths) - { - _nodeTree.Nodes.Clear(); - - foreach (string path in paths) { - if (Directory.Exists(path)) { - LoadDirectory(path); - } - else if (File.Exists(path)) { - TryLoadFile(_nodeTree.Nodes, path); - } - } - - if (_nodeTree.Nodes.Count > 0) { - _nodeTree.Nodes[0].Expand(); - } - } - - public void OpenMinecraftDir () - { - string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - path = Path.Combine(path, ".minecraft"); - path = Path.Combine(path, "saves"); - - if (!Directory.Exists(path)) { - path = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer); - } - - OpenDirectory(path); - } - - public void LoadDirectory (string path) - { - LoadDirectory(path, _nodeTree.Nodes); - } - - public void LoadDirectory (string path, TreeNodeCollection parent) - { - LoadDirectory(path, parent, path); - } - - public void LoadDirectory (string path, TreeNodeCollection parent, string name) - { - TreeNode root = new TreeNode(name, 10, 10); - - foreach (string dirpath in Directory.EnumerateDirectories(path)) { - root.Nodes.Add(CreateLazyDirectory(dirpath, root)); - } - - foreach (string filepath in Directory.EnumerateFiles(path)) { - TryLoadFile(root.Nodes, filepath); - } - - parent.Add(root); - } - - public void TryLoadFile (TreeNodeCollection parent, string path) - { - if (Path.GetExtension(path) == ".mcr") { - TreeNode node = CreateLazyRegion(path); - parent.Add(node); - LinkDataNodeParent(node, node.Parent); - return; - } - - if (Path.GetExtension(path) == ".dat") { - try { - NBTFile file = new NBTFile(path); - NbtTree tree = new NbtTree(); - tree.ReadFrom(file.GetDataInputStream()); - TreeNode node = CreateLazyNbt(path, CompressionType.GZip); - parent.Add(node); - LinkDataNodeParent(node, node.Parent); - return; - } - catch { } - - try { - NBTFile file = new NBTFile(path); - NbtTree tree = new NbtTree(); - tree.ReadFrom(file.GetDataInputStream(CompressionType.None)); - TreeNode node = CreateLazyNbt(path, CompressionType.None); - parent.Add(node); - LinkDataNodeParent(node, node.Parent); - return; - } - catch { } - } - } - - static Form1 () - { - _tagIconIndex = new Dictionary(); - _tagIconIndex[TagType.TAG_BYTE] = 0; - _tagIconIndex[TagType.TAG_SHORT] = 1; - _tagIconIndex[TagType.TAG_INT] = 2; - _tagIconIndex[TagType.TAG_LONG] = 3; - _tagIconIndex[TagType.TAG_FLOAT] = 4; - _tagIconIndex[TagType.TAG_DOUBLE] = 5; - _tagIconIndex[TagType.TAG_BYTE_ARRAY] = 6; - _tagIconIndex[TagType.TAG_STRING] = 7; - _tagIconIndex[TagType.TAG_LIST] = 8; - _tagIconIndex[TagType.TAG_COMPOUND] = 9; - } - - private void OpenFile () - { - OpenFileDialog ofd = new OpenFileDialog(); - ofd.RestoreDirectory = true; - ofd.Multiselect = true; - - if (ofd.ShowDialog() == DialogResult.OK) { - OpenPaths(ofd.FileNames); - } - } - - private void OpenFile (string file) - { - _nodeTree.Nodes.Clear(); - TryLoadFile(_nodeTree.Nodes, file); - } - - private string _openFolderPath = null; - private void OpenFolder () - { - FolderBrowserDialog ofd = new FolderBrowserDialog(); - if (_openFolderPath != null) - ofd.SelectedPath = _openFolderPath; - - if (ofd.ShowDialog() == DialogResult.OK) { - _openFolderPath = ofd.SelectedPath; - OpenDirectory(ofd.SelectedPath); - } - } - - private void SaveAll () - { - foreach (TreeNode node in _nodeTree.Nodes) { - SaveNode(node); - } - } - - private void SaveNode (TreeNode node) - { - foreach (TreeNode sub in node.Nodes) { - if (sub.Tag != null && sub.Tag is DataNode) { - SaveNode(sub); - } - } - - if (node.Tag is NbtFileData) { - SaveNbtFileNode(node); - } - else if (node.Tag is RegionChunkData) { - SaveRegionChunkNode(node); - } - } - - private void SaveNbtFileNode (TreeNode node) - { - NbtFileData data = node.Tag as NbtFileData; - if (data == null || !data.Modified) - return; - - NBTFile file = new NBTFile(data.Path); - using (Stream str = file.GetDataOutputStream(data.CompressionType)) { - data.Tree.WriteTo(str); - } - data.Modified = false; - } - - private void SaveRegionChunkNode (TreeNode node) - { - RegionChunkData data = node.Tag as RegionChunkData; - if (data == null || !data.Modified) - return; - - using (Stream str = data.Region.GetChunkDataOutputStream(data.X, data.Z)) { - data.Tree.WriteTo(str); - } - data.Modified = false; - } - - private void aboutToolStripMenuItem_Click (object sender, EventArgs e) - { - new About().Show(); - } - - private void openToolStripMenuItem_Click (object sender, EventArgs e) - { - OpenFile(); - } - - private void openFolderToolStripMenuItem_Click (object sender, EventArgs e) - { - OpenFolder(); - } - - private void toolStripButton1_Click (object sender, EventArgs e) - { - OpenFile(); - } - - private TreeNode BaseNode (TreeNode node) - { - if (node == null) - return null; - - TreeNode baseNode = node; - while (baseNode.Tag == null || !(baseNode.Tag is DataNode)) { - baseNode = baseNode.Parent; - } - - return baseNode; - } - - #region Tag Deletion - - private void DeleteNode (TreeNode node) - { - TreeNode baseNode = BaseNode(node); - - // Can only delete internal NBT nodes - if (baseNode == null || baseNode == node) - return; - - (baseNode.Tag as DataNode).Modified = true; - - DeleteNodeNbtTag(node); - - if (node.Parent != null) { - node.Parent.Text = GetNodeText(node.Parent); - } - - node.Remove(); - } - - private void _buttonDelete_Click (object sender, EventArgs e) - { - DeleteNode(_nodeTree.SelectedNode); - } - - private void DeleteNodeNbtTag (TreeNode node) - { - TagNode tag = node.Tag as TagNode; - if (tag == null) - return; - - TagNode parentTag = node.Parent.Tag as TagNode; - if (parentTag == null) { - NbtDataNode parentData = node.Parent.Tag as NbtDataNode; - if (parentData == null) - return; - - parentTag = parentData.Tree.Root; - if (parentTag == null) - return; - } - - switch (parentTag.GetTagType()) { - case TagType.TAG_LIST: - parentTag.ToTagList().Remove(tag); - break; - - case TagType.TAG_COMPOUND: - DeleteTagFromCompound(parentTag.ToTagCompound(), tag); - break; - } - } - - private void DeleteTagFromCompound (TagNodeCompound parent, TagNode target) - { - string match = ""; - foreach (KeyValuePair kv in parent) { - if (kv.Value == target) { - match = kv.Key; - break; - } - } - - if (match != null) { - parent.Remove(match); - } - } - - #endregion - - private void _buttonSave_Click (object sender, EventArgs e) - { - SaveAll(); - } - - private TagNode GetTagNode (TreeNode node) - { - if (node == null) - return null; - - if (node.Tag is TagNode) { - return node.Tag as TagNode; - } - else if (node.Tag is NbtDataNode) { - NbtDataNode data = node.Tag as NbtDataNode; - if (data == null) - return null; - - return data.Tree.Root; - } - - return null; - } - - private TagNode GetParentTagNode (TreeNode node) - { - if (GetTagNode(node) == null) - return null; - - return GetTagNode(node.Parent); - } - - private string GetTagNodeName (TreeNode node) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return null; - - TagNode parentTag = GetTagNode(node.Parent); - if (parentTag == null) - return null; - - if (parentTag.GetTagType() != TagType.TAG_COMPOUND) - return null; - - foreach (KeyValuePair sub in parentTag.ToTagCompound()) { - if (sub.Value == tag) - return sub.Key; - } - - return null; - } - - private bool SetTagNodeName (TreeNode node, string name) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return false; - - TagNode parentTag = GetTagNode(node.Parent); - if (parentTag == null) - return false; - - if (parentTag.GetTagType() != TagType.TAG_COMPOUND) - return false; - - if (parentTag.ToTagCompound().ContainsKey(name)) - return false; - - string oldName = null; - foreach (KeyValuePair sub in parentTag.ToTagCompound()) { - if (sub.Value == tag) { - oldName = sub.Key; - break; - } - } - - parentTag.ToTagCompound().Remove(oldName); - parentTag.ToTagCompound().Add(name, tag); - - return true; - } - - private void EditNodeValue (TreeNode node) - { - if (node == null) - return; - - TagNode tag = GetTagNode(node); - if (tag == null) - return; - - if (tag.GetTagType() == TagType.TAG_BYTE_ARRAY || - tag.GetTagType() == TagType.TAG_LIST || - tag.GetTagType() == TagType.TAG_COMPOUND) - return; - - EditValue form = new EditValue(tag); - if (form.ShowDialog() == DialogResult.OK) { - TreeNode baseNode = BaseNode(node); - if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; - } - - node.Text = GetNodeText(node); - } - } - - private void _buttonEdit_Click (object sender, EventArgs e) - { - EditNodeValue(_nodeTree.SelectedNode); - } - - private void EditNodeName (TreeNode node) - { - if (node == null) - return; - - TagNode tag = GetTagNode(node); - if (tag == null) - return; - - string name = GetTagNodeName(node); - if (name == null) - return; - - EditValue form = new EditValue(name); - - TagNode parentTag = GetParentTagNode(node); - foreach (string key in parentTag.ToTagCompound().Keys) { - form.InvalidNames.Add(key); - } - - if (form.ShowDialog() == DialogResult.OK) { - TreeNode baseNode = BaseNode(node); - if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; - } - - SetTagNodeName(node, form.NodeName); - node.Text = GetNodeText(node); - } - } - - private void _buttonRename_Click (object sender, EventArgs e) - { - EditNodeName(_nodeTree.SelectedNode); - } - - private void AddTagToNode (TreeNode node, TagType type) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return; - - if (tag.GetTagType() != TagType.TAG_COMPOUND && - tag.GetTagType() != TagType.TAG_LIST) - return; - - if (tag.GetTagType() == TagType.TAG_LIST && - tag.ToTagList().ValueType != type && - tag.ToTagList().Count > 0) - return; - - TagNode newNode = null; - switch (type) { - case TagType.TAG_BYTE: - newNode = new TagNodeByte(); - break; - case TagType.TAG_SHORT: - newNode = new TagNodeShort(); - break; - case TagType.TAG_INT: - newNode = new TagNodeInt(); - break; - case TagType.TAG_LONG: - newNode = new TagNodeLong(); - break; - case TagType.TAG_FLOAT: - newNode = new TagNodeFloat(); - break; - case TagType.TAG_DOUBLE: - newNode = new TagNodeDouble(); - break; - case TagType.TAG_BYTE_ARRAY: - newNode = new TagNodeByteArray(); - break; - case TagType.TAG_STRING: - newNode = new TagNodeString(); - break; - case TagType.TAG_LIST: - newNode = new TagNodeList(TagType.TAG_BYTE); - break; - case TagType.TAG_COMPOUND: - newNode = new TagNodeCompound(); - break; - } - - if (tag is TagNodeCompound) { - TagNodeCompound ctag = tag as TagNodeCompound; - - EditValue form = new EditValue(""); - foreach (string key in ctag.Keys) { - form.InvalidNames.Add(key); - } - - if (form.ShowDialog() != DialogResult.OK) - return; - - ctag.Add(form.NodeName, newNode); - - TreeNode tnode = NodeFromTag(newNode, form.NodeName); - node.Nodes.Add(tnode); - - _nodeTree.SelectedNode = tnode; - tnode.Expand(); - } - else if (tag is TagNodeList) { - TagNodeList ltag = tag as TagNodeList; - if (ltag.ValueType != type) - ltag.ChangeValueType(type); - - ltag.Add(newNode); - - TreeNode tnode = NodeFromTag(newNode); - node.Nodes.Add(tnode); - - _nodeTree.SelectedNode = tnode; - tnode.Expand(); - } - - node.Text = GetNodeText(node); - - TreeNode baseNode = BaseNode(node); - if (baseNode != null) { - (baseNode.Tag as DataNode).Modified = true; - } - } - - private void _buttonAddTagByte_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE); - } - - private void _buttonAddTagShort_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_SHORT); - } - - private void _buttonAddTagInt_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_INT); - } - - private void _buttonAddTagLong_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LONG); - } - - private void _buttonAddTagFloat_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_FLOAT); - } - - private void _buttonAddTagDouble_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_DOUBLE); - } - - private void _buttonAddTagByteArray_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE_ARRAY); - } - - private void _buttonAddTagString_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_STRING); - } - - private void _buttonAddTagList_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LIST); - } - - private void _buttonAddTagCompound_Click (object sender, EventArgs e) - { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_COMPOUND); - } - - private void saveToolStripMenuItem_Click (object sender, EventArgs e) - { - SaveAll(); - } - - private void exitToolStripMenuItem_Click (object sender, EventArgs e) - { - Application.Exit(); - } - - private TreeNode _rootSearchNode; - private string _searchName; - private string _searchValue; - private IEnumerator _search; - - private void Find (TreeNode node) - { - if (node == null) - return; - - Find form = new Find(); - if (form.ShowDialog() == DialogResult.OK) { - _rootSearchNode = node; - - _searchName = form.MatchName ? form.NameToken : null; - _searchValue = form.MatchValue ? form.ValueToken : null; - - _search = FindNode(node).GetEnumerator(); - - FindNext(); - } - } - - private void FindNext () - { - if (_search == null) - return; - - statusStrip1.Visible = true; - Application.DoEvents(); - - _nodeTree.SelectedNode = null; - - if (!_search.MoveNext()) { - _nodeTree.SelectedNode = _rootSearchNode; - if (_rootSearchNode != null && _rootSearchNode.Tag is DataNode) { - if (_rootSearchNode.IsExpanded && !(_rootSearchNode.Tag as DataNode).Expanded) { - _rootSearchNode.Collapse(); - } - } - - statusStrip1.Visible = false; - - MessageBox.Show("End of results"); - _search = null; - } - - statusStrip1.Visible = false; - } - - private IEnumerable FindNode (TreeNode node) - { - if (node == null) - yield break; - - bool expand = false; - - if (node.Tag is DataNode) { - DataNode data = node.Tag as DataNode; - if (!data.Expanded) { - ExpandNode(node); - expand = true; - } - } - - TagNode tag = GetTagNode(node); - if (tag != null) { - bool mName = _searchName == null; - bool mValue = _searchValue == null; - - if (_searchName != null) { - string tagName = GetTagNodeName(node); - if (tagName != null) - mName = tagName.Contains(_searchName); - } - if (_searchValue != null) { - string tagValue = GetTagNodeText(node); - if (tagValue != null) - mValue = tagValue.Contains(_searchValue); - } - - if (mName && mValue) { - _nodeTree.SelectedNode = node; - yield return node; - } - } - - foreach (TreeNode sub in node.Nodes) { - foreach (TreeNode s in FindNode(sub)) - yield return s; - } - - if (expand) { - DataNode data = node.Tag as DataNode; - if (!data.Modified) - CollapseNode(node); - } - } - - private void findToolStripMenuItem_Click (object sender, EventArgs e) - { - Find(_nodeTree.SelectedNode); - } - - private void findNextToolStripMenuItem_Click (object sender, EventArgs e) - { - FindNext(); - } - - private void _buttonFindNext_Click (object sender, EventArgs e) - { - if (_search == null) - Find(_nodeTree.SelectedNode); - else - FindNext(); - } - - private void _buttonOpenFolder_Click (object sender, EventArgs e) - { - OpenFolder(); - } - - private void DropFile (DragEventArgs e) - { - string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); - OpenPaths(files); - } - - private void _nodeTree_DragDrop (object sender, DragEventArgs e) - { - DropFile(e); - } - - private void _nodeTree_DragEnter (object sender, DragEventArgs e) - { - if (e.Data.GetDataPresent(DataFormats.FileDrop)) - e.Effect = DragDropEffects.Copy; - } - - private void openMinecraftSaveFolderToolStripMenuItem_Click (object sender, EventArgs e) - { - OpenMinecraftDir(); - } - } - - public class TagKey : IComparable - { - public TagKey (string name, TagType type) - { - Name = name; - TagType = type; - } - - public string Name { get; set; } - public TagType TagType { get; set; } - - #region IComparer Members - - public int Compare(TagKey x, TagKey y) - { - int typeDiff = (int)x.TagType - (int)y.TagType; - if (typeDiff != 0) - return typeDiff; - - return String.Compare(x.Name, y.Name, true); - } - - #endregion - - #region IComparable Members - - public int CompareTo (TagKey other) - { - return Compare(this, other); - } - - #endregion - } - - public class DataNode - { - public DataNode () - { - } - - public DataNode (DataNode parent) - { - Parent = parent; - } - - public DataNode Parent { get; set; } - - private bool _modified; - public bool Modified - { - get { return _modified; } - set - { - if (value && Parent != null) { - Parent.Modified = value; - } - _modified = value; - } - } - - public bool Expanded { get; set; } - } - - public class NbtDataNode : DataNode - { - public NbtDataNode () - { - } - - public NbtDataNode (DataNode parent) - : base(parent) - { - } - - public NbtTree Tree { get; set; } - } - - public class RegionChunkData : NbtDataNode - { - public RegionChunkData (RegionFile file, int x, int z) - : this(null, file, x, z) - { - } - - public RegionChunkData (DataNode parent, RegionFile file, int x, int z) - : base(parent) - { - Region = file; - X = x; - Z = z; - } - - public RegionFile Region { get; private set; } - public int X { get; private set; } - public int Z { get; private set; } - } - - public class RegionData : DataNode - { - public RegionData (string path) - : this(null, path) - { - } - - public RegionData (DataNode parent, string path) - : base(parent) - { - Path = path; - } - - public string Path { get; private set; } - } - - public class NbtFileData : NbtDataNode - { - public NbtFileData (string path, CompressionType cztype) - : this(null, path, cztype) - { - } - - public NbtFileData (DataNode parent, string path, CompressionType cztype) - : base(parent) - { - Path = path; - CompressionType = cztype; - } - - public string Path { get; private set; } - public CompressionType CompressionType { get; private set; } - } - - public class DirectoryData : DataNode - { - public DirectoryData (string path) - : this(null, path) - { - } - - public DirectoryData (DataNode parent, string path) - : base(parent) - { - Path = path; - } - - public string Path { get; private set; } - } -} +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using Substrate; +using Substrate.Nbt; +using System.IO; +using Substrate.Core; +using System.Diagnostics; + +namespace NBTExplorer +{ + public partial class Form1 : Form + { + private static Dictionary _tagIconIndex; + + public Form1() + { + InitializeComponent(); + + _nodeTree.BeforeExpand += NodeExpand; + _nodeTree.AfterCollapse += NodeCollapse; + _nodeTree.AfterSelect += NodeSelected; + _nodeTree.NodeMouseClick += NodeClicked; + _nodeTree.NodeMouseDoubleClick += NodeDoubleClicked; + + string[] args = Environment.GetCommandLineArgs(); + if (args.Length > 1) + { + OpenFile(args[1]); + } + else + { + OpenMinecraftDir(); + } + } + + public void LoadNbtStream(TreeNodeCollection parent, Stream stream) + { + LoadNbtStream(parent, stream, null); + } + + public void LoadNbtStream(TreeNodeCollection parent, Stream stream, string name) + { + string text = !String.IsNullOrEmpty(name) ? name : null; + text = text ?? "[root]"; + + TreeNode root = new TreeNode(text, 9, 9); + + LoadNbtStream(root, stream); + + parent.Add(root); + } + + public void LoadNbtStream(TreeNode node, Stream stream) + { + NbtTree tree = new NbtTree(); + tree.ReadFrom(stream); + + if (node.Tag != null && node.Tag is NbtDataNode) + { + (node.Tag as NbtDataNode).Tree = tree; + } + + PopulateNodeFromTag(node, tree.Root); + } + + private TreeNode NodeFromTag(TagNode tag) + { + return NodeFromTag(tag, null); + } + + private TreeNode NodeFromTag(TagNode tag, string name) + { + TreeNode node = new TreeNode(); + node.ImageIndex = _tagIconIndex[tag.GetTagType()]; + node.SelectedImageIndex = _tagIconIndex[tag.GetTagType()]; + node.Tag = tag; + node.Text = GetNodeText(name, tag); + + if (tag.GetTagType() == TagType.TAG_LIST) + { + PopulateNodeFromTag(node, tag.ToTagList()); + } + else if (tag.GetTagType() == TagType.TAG_COMPOUND) + { + PopulateNodeFromTag(node, tag.ToTagCompound()); + } + + return node; + } + + private string GetTagNodeText(TagNode tag) + { + if (tag == null) + return null; + + switch (tag.GetTagType()) + { + case TagType.TAG_BYTE: + case TagType.TAG_SHORT: + case TagType.TAG_INT: + case TagType.TAG_LONG: + case TagType.TAG_FLOAT: + case TagType.TAG_DOUBLE: + case TagType.TAG_STRING: + return tag.ToString(); + + case TagType.TAG_BYTE_ARRAY: + return tag.ToTagByteArray().Length + " bytes"; + + case TagType.TAG_LIST: + return tag.ToTagList().Count + " entries"; + + case TagType.TAG_COMPOUND: + return tag.ToTagCompound().Count + " entries"; + } + + return null; + } + + private string GetNodeText(string name, string value) + { + name = String.IsNullOrEmpty(name) ? "" : name + ": "; + value = value ?? ""; + + return name + value; + } + + private string GetNodeText(string name, TagNode tag) + { + return GetNodeText(name, GetTagNodeText(tag)); + } + + private string GetNodeText(TreeNode node) + { + return GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); + } + + private string GetTagNodeText(TreeNode node) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return null; + + return GetTagNodeText(tag); + } + + private void PopulateNodeFromTag(TreeNode parentNode, TagNodeList list) + { + foreach (TagNode tag in list) + { + var node = NodeFromTag(tag); + if (parentNode.Text.StartsWith("Inventory")) + { + Debug.Assert(tag.IsCastableTo(TagType.TAG_COMPOUND)); + var tagc = tag as TagNodeCompound; + if (tagc.ContainsKey("id")) + { + int id; + if (int.TryParse(tagc["id"].ToString(), out id)) + { + var item = Substrate.ItemInfo.ItemTable[id]; + if (item != null) + node.Nodes.Insert(0, item.Name); + + } + + } + + } + + + parentNode.Nodes.Add(node); + } + } + + private void PopulateNodeFromTag(TreeNode node, TagNodeCompound dict) + { + if (dict == null) + return; + var list = new SortedList(); + foreach (KeyValuePair kv in dict) + { + list.Add(new TagKey(kv.Key, kv.Value.GetTagType()), kv.Value); + } + + foreach (KeyValuePair kv in list) + { + node.Nodes.Add(NodeFromTag(kv.Value, kv.Key.Name)); + } + } + + public void LoadWorld(string path) + { + NbtWorld world = NbtWorld.Open(path); + + BetaWorld beta = world as BetaWorld; + if (beta != null) + { + LoadBetaWorld(beta); + } + } + + private void LoadBetaWorld(BetaWorld world) + { + RegionManager rm = world.GetRegionManager(); + } + + public void LoadRegion(TreeNodeCollection parent, string path) + { + TreeNode root = new TreeNode(Path.GetFileName(path), 11, 11); + LoadRegion(root, path); + parent.Add(root); + } + + public void LoadRegion(TreeNode node, string path) + { + RegionFile rf = new RegionFile(path); + + for (int x = 0; x < 32; x++) + { + for (int y = 0; y < 32; y++) + { + if (rf.HasChunk(x, y)) + { + TreeNode child = CreateLazyChunk(rf, x, y); + node.Nodes.Add(child); + LinkDataNodeParent(child, node); + } + } + } + } + + public TreeNode CreateLazyChunk(RegionFile rf, int x, int z) + { + TreeNode node = new TreeNode(); + node.ImageIndex = 9; + node.SelectedImageIndex = 9; + node.Text = "Chunk [" + x + ", " + z + "]"; + node.Tag = new RegionChunkData(rf, x, z); + node.Nodes.Add(new TreeNode()); + + return node; + } + + public TreeNode CreateLazyRegion(string path) + { + TreeNode node = new TreeNode(); + node.ImageIndex = 11; + node.SelectedImageIndex = 11; + node.Text = Path.GetFileName(path); + node.Tag = new RegionData(path); + node.Nodes.Add(new TreeNode()); + + return node; + } + + public TreeNode CreateLazyNbt(string path, CompressionType cztype) + { + TreeNode node = new TreeNode(); + node.ImageIndex = 12; + node.SelectedImageIndex = 12; + node.Text = Path.GetFileName(path); + node.Tag = new NbtFileData(path, cztype); + node.Nodes.Add(new TreeNode()); + + return node; + } + + public TreeNode CreateLazyDirectory(string path) + { + TreeNode node = new TreeNode(); + node.ImageIndex = 10; + node.SelectedImageIndex = 10; + node.Text = Path.GetFileName(path); + node.Tag = new DirectoryData(path); + node.Nodes.Add(new TreeNode()); + + return node; + } + + public TreeNode CreateLazyDirectory(string path, TreeNode parent) + { + TreeNode node = CreateLazyDirectory(path); + LinkDataNodeParent(node, parent); + + return node; + } + + public TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode parent) + { + TreeNode node = CreateLazyNbt(path, cztype); + LinkDataNodeParent(node, parent); + + return node; + } + + private void LinkDataNodeParent(TreeNode node, TreeNode parent) + { + if (node != null && parent != null && node.Tag != null && parent.Tag != null) + { + DataNode nodeDn = node.Tag as DataNode; + DataNode parentDn = parent.Tag as DataNode; + + if (nodeDn != null && parentDn != null) + { + nodeDn.Parent = parentDn; + } + } + } + + public void LoadLazyChunk(TreeNode node) + { + RegionChunkData data = node.Tag as RegionChunkData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + LoadNbtStream(node, data.Region.GetChunkDataInputStream(data.X, data.Z)); + + data.Expanded = true; + } + + public void LoadLazyNbt(TreeNode node) + { + NbtFileData data = node.Tag as NbtFileData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + + NBTFile file = new NBTFile(data.Path); + LoadNbtStream(node, file.GetDataInputStream(data.CompressionType)); + + data.Expanded = true; + } + + public void LoadLazyDirectory(TreeNode node) + { + DirectoryData data = node.Tag as DirectoryData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + + foreach (string dirpath in Directory.EnumerateDirectories(data.Path)) + { + node.Nodes.Add(CreateLazyDirectory(dirpath, node)); + } + + foreach (string filepath in Directory.EnumerateFiles(data.Path)) + { + TryLoadFile(node.Nodes, filepath); + } + + data.Expanded = true; + } + + public void LoadLazyRegion(TreeNode node) + { + RegionData data = node.Tag as RegionData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + LoadRegion(node, data.Path); + + data.Expanded = true; + } + + public void UnloadLazyDataNode(TreeNode node) + { + DataNode data = node.Tag as DataNode; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + node.Nodes.Add(new TreeNode()); + + data.Expanded = false; + } + + private void ExpandNode(TreeNode node) + { + if (node.Tag == null) + return; + + if (node.Tag is DataNode) + { + if ((node.Tag as DataNode).Expanded) + return; + } + + if (node.Tag is RegionChunkData) + { + LoadLazyChunk(node); + } + else if (node.Tag is NbtFileData) + { + LoadLazyNbt(node); + } + else if (node.Tag is DirectoryData) + { + LoadLazyDirectory(node); + } + else if (node.Tag is RegionData) + { + LoadLazyRegion(node); + } + } + + private void CollapseNode(TreeNode node) + { + if (node.Tag == null) + return; + + if (node.Tag is DataNode) + { + UnloadLazyDataNode(node); + } + } + + private void NodeExpand(object sender, TreeViewCancelEventArgs e) + { + ExpandNode(e.Node); + } + + private void NodeCollapse(object sender, TreeViewEventArgs e) + { + CollapseNode(e.Node); + } + + private void NodeSelected(object sender, TreeViewEventArgs e) + { + UpdateToolbar(); + } + + private void NodeClicked(object sender, TreeNodeMouseClickEventArgs e) + { + + } + + private void NodeDoubleClicked(object sender, TreeNodeMouseClickEventArgs e) + { + EditNodeValue(_nodeTree.SelectedNode); + } + + private void UpdateToolbar() + { + TreeNode node = _nodeTree.SelectedNode; + TagNode tag = node.Tag as TagNode; + + if (tag == null && node.Tag is NbtDataNode) + { + NbtDataNode data = node.Tag as NbtDataNode; + if (data.Tree != null) + tag = data.Tree.Root; + } + + _buttonRename.Enabled = tag != null && node.Tag is TagNode; + _buttonDelete.Enabled = tag != null && node.Tag is TagNode; + _buttonEdit.Enabled = tag != null + && node.Tag is TagNode + && tag.GetTagType() != TagType.TAG_BYTE_ARRAY + && tag.GetTagType() != TagType.TAG_COMPOUND + && tag.GetTagType() != TagType.TAG_LIST; + + if (tag == null || tag.GetTagType() != TagType.TAG_COMPOUND) + SetTagButtons(false); + if (tag != null && tag.GetTagType() == TagType.TAG_COMPOUND) + SetTagButtons(true); + if (tag != null && tag.GetTagType() == TagType.TAG_LIST && tag.ToTagList().Count == 0) + SetTagButtons(true); + + if (tag != null && tag.GetTagType() == TagType.TAG_LIST) + { + switch (tag.ToTagList().ValueType) + { + case TagType.TAG_BYTE: + _buttonAddTagByte.Enabled = true; + break; + case TagType.TAG_SHORT: + _buttonAddTagShort.Enabled = true; + break; + case TagType.TAG_INT: + _buttonAddTagInt.Enabled = true; + break; + case TagType.TAG_LONG: + _buttonAddTagLong.Enabled = true; + break; + case TagType.TAG_FLOAT: + _buttonAddTagFloat.Enabled = true; + break; + case TagType.TAG_DOUBLE: + _buttonAddTagDouble.Enabled = true; + break; + case TagType.TAG_BYTE_ARRAY: + _buttonAddTagByteArray.Enabled = true; + break; + case TagType.TAG_STRING: + _buttonAddTagString.Enabled = true; + break; + case TagType.TAG_LIST: + _buttonAddTagList.Enabled = true; + break; + case TagType.TAG_COMPOUND: + _buttonAddTagCompound.Enabled = true; + break; + } + } + } + + private void SetTagButtons(bool state) + { + _buttonAddTagByte.Enabled = state; + _buttonAddTagShort.Enabled = state; + _buttonAddTagInt.Enabled = state; + _buttonAddTagLong.Enabled = state; + _buttonAddTagFloat.Enabled = state; + _buttonAddTagDouble.Enabled = state; + _buttonAddTagByteArray.Enabled = state; + _buttonAddTagString.Enabled = state; + _buttonAddTagList.Enabled = state; + _buttonAddTagCompound.Enabled = state; + } + + public void OpenDirectory(string path) + { + _nodeTree.Nodes.Clear(); + + LoadDirectory(path); + + if (_nodeTree.Nodes.Count > 0) + { + _nodeTree.Nodes[0].Expand(); + } + } + + public void OpenPaths(string[] paths) + { + _nodeTree.Nodes.Clear(); + + foreach (string path in paths) + { + if (Directory.Exists(path)) + { + LoadDirectory(path); + } + else if (File.Exists(path)) + { + TryLoadFile(_nodeTree.Nodes, path); + } + } + + if (_nodeTree.Nodes.Count > 0) + { + _nodeTree.Nodes[0].Expand(); + } + } + + public void OpenMinecraftDir() + { + string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + path = Path.Combine(path, ".minecraft"); + path = Path.Combine(path, "saves"); + + if (!Directory.Exists(path)) + { + path = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer); + } + + OpenDirectory(path); + } + + public void LoadDirectory(string path) + { + LoadDirectory(path, _nodeTree.Nodes); + } + + public void LoadDirectory(string path, TreeNodeCollection parent) + { + LoadDirectory(path, parent, path); + } + + public void LoadDirectory(string path, TreeNodeCollection parent, string name) + { + TreeNode root = new TreeNode(name, 10, 10); + + foreach (string dirpath in Directory.EnumerateDirectories(path)) + { + root.Nodes.Add(CreateLazyDirectory(dirpath, root)); + } + + foreach (string filepath in Directory.EnumerateFiles(path)) + { + TryLoadFile(root.Nodes, filepath); + } + + parent.Add(root); + } + + public void TryLoadFile(TreeNodeCollection parent, string path) + { + if (Path.GetExtension(path) == ".mcr") + { + TreeNode node = CreateLazyRegion(path); + parent.Add(node); + LinkDataNodeParent(node, node.Parent); + return; + } + + if (Path.GetExtension(path) == ".dat") + { + try + { + NBTFile file = new NBTFile(path); + NbtTree tree = new NbtTree(); + tree.ReadFrom(file.GetDataInputStream()); + TreeNode node = CreateLazyNbt(path, CompressionType.GZip); + parent.Add(node); + LinkDataNodeParent(node, node.Parent); + return; + } + catch { } + + try + { + NBTFile file = new NBTFile(path); + NbtTree tree = new NbtTree(); + tree.ReadFrom(file.GetDataInputStream(CompressionType.None)); + TreeNode node = CreateLazyNbt(path, CompressionType.None); + parent.Add(node); + LinkDataNodeParent(node, node.Parent); + return; + } + catch { } + } + } + + static Form1() + { + _tagIconIndex = new Dictionary(); + _tagIconIndex[TagType.TAG_BYTE] = 0; + _tagIconIndex[TagType.TAG_SHORT] = 1; + _tagIconIndex[TagType.TAG_INT] = 2; + _tagIconIndex[TagType.TAG_LONG] = 3; + _tagIconIndex[TagType.TAG_FLOAT] = 4; + _tagIconIndex[TagType.TAG_DOUBLE] = 5; + _tagIconIndex[TagType.TAG_BYTE_ARRAY] = 6; + _tagIconIndex[TagType.TAG_STRING] = 7; + _tagIconIndex[TagType.TAG_LIST] = 8; + _tagIconIndex[TagType.TAG_COMPOUND] = 9; + } + + private void OpenFile() + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.RestoreDirectory = true; + ofd.Multiselect = true; + + if (ofd.ShowDialog() == DialogResult.OK) + { + OpenPaths(ofd.FileNames); + } + } + + private void OpenFile(string file) + { + _nodeTree.Nodes.Clear(); + TryLoadFile(_nodeTree.Nodes, file); + } + + private string _openFolderPath = null; + private void OpenFolder() + { + FolderBrowserDialog ofd = new FolderBrowserDialog(); + if (_openFolderPath != null) + ofd.SelectedPath = _openFolderPath; + + if (ofd.ShowDialog() == DialogResult.OK) + { + _openFolderPath = ofd.SelectedPath; + OpenDirectory(ofd.SelectedPath); + } + } + + private void SaveAll() + { + foreach (TreeNode node in _nodeTree.Nodes) + { + SaveNode(node); + } + } + + private void SaveNode(TreeNode node) + { + foreach (TreeNode sub in node.Nodes) + { + if (sub.Tag != null && sub.Tag is DataNode) + { + SaveNode(sub); + } + } + + if (node.Tag is NbtFileData) + { + SaveNbtFileNode(node); + } + else if (node.Tag is RegionChunkData) + { + SaveRegionChunkNode(node); + } + } + + private void SaveNbtFileNode(TreeNode node) + { + NbtFileData data = node.Tag as NbtFileData; + if (data == null || !data.Modified) + return; + + NBTFile file = new NBTFile(data.Path); + using (Stream str = file.GetDataOutputStream(data.CompressionType)) + { + data.Tree.WriteTo(str); + } + data.Modified = false; + } + + private void SaveRegionChunkNode(TreeNode node) + { + RegionChunkData data = node.Tag as RegionChunkData; + if (data == null || !data.Modified) + return; + + using (Stream str = data.Region.GetChunkDataOutputStream(data.X, data.Z)) + { + data.Tree.WriteTo(str); + } + data.Modified = false; + } + + private void aboutToolStripMenuItem_Click(object sender, EventArgs e) + { + new About().Show(); + } + + private void openToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenFile(); + } + + private void openFolderToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenFolder(); + } + + private void toolStripButton1_Click(object sender, EventArgs e) + { + OpenFile(); + } + + private TreeNode BaseNode(TreeNode node) + { + if (node == null) + return null; + + TreeNode baseNode = node; + while (baseNode.Tag == null || !(baseNode.Tag is DataNode)) + { + baseNode = baseNode.Parent; + } + + return baseNode; + } + + #region Tag Deletion + + private void DeleteNode(TreeNode node) + { + TreeNode baseNode = BaseNode(node); + + // Can only delete internal NBT nodes + if (baseNode == null || baseNode == node) + return; + + (baseNode.Tag as DataNode).Modified = true; + + DeleteNodeNbtTag(node); + + if (node.Parent != null) + { + node.Parent.Text = GetNodeText(node.Parent); + } + + node.Remove(); + } + + private void _buttonDelete_Click(object sender, EventArgs e) + { + DeleteNode(_nodeTree.SelectedNode); + } + + private void DeleteNodeNbtTag(TreeNode node) + { + TagNode tag = node.Tag as TagNode; + if (tag == null) + return; + + TagNode parentTag = node.Parent.Tag as TagNode; + if (parentTag == null) + { + NbtDataNode parentData = node.Parent.Tag as NbtDataNode; + if (parentData == null) + return; + + parentTag = parentData.Tree.Root; + if (parentTag == null) + return; + } + + switch (parentTag.GetTagType()) + { + case TagType.TAG_LIST: + parentTag.ToTagList().Remove(tag); + break; + + case TagType.TAG_COMPOUND: + DeleteTagFromCompound(parentTag.ToTagCompound(), tag); + break; + } + } + + private void DeleteTagFromCompound(TagNodeCompound parent, TagNode target) + { + string match = ""; + foreach (KeyValuePair kv in parent) + { + if (kv.Value == target) + { + match = kv.Key; + break; + } + } + + if (match != null) + { + parent.Remove(match); + } + } + + #endregion + + private void _buttonSave_Click(object sender, EventArgs e) + { + SaveAll(); + } + + private TagNode GetTagNode(TreeNode node) + { + if (node == null) + return null; + + if (node.Tag is TagNode) + { + return node.Tag as TagNode; + } + else if (node.Tag is NbtDataNode) + { + NbtDataNode data = node.Tag as NbtDataNode; + if (data == null) + return null; + + return data.Tree.Root; + } + + return null; + } + + private TagNode GetParentTagNode(TreeNode node) + { + if (GetTagNode(node) == null) + return null; + + return GetTagNode(node.Parent); + } + + private string GetTagNodeName(TreeNode node) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return null; + + TagNode parentTag = GetTagNode(node.Parent); + if (parentTag == null) + return null; + + if (parentTag.GetTagType() != TagType.TAG_COMPOUND) + return null; + + foreach (KeyValuePair sub in parentTag.ToTagCompound()) + { + if (sub.Value == tag) + return sub.Key; + } + + return null; + } + + private bool SetTagNodeName(TreeNode node, string name) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return false; + + TagNode parentTag = GetTagNode(node.Parent); + if (parentTag == null) + return false; + + if (parentTag.GetTagType() != TagType.TAG_COMPOUND) + return false; + + if (parentTag.ToTagCompound().ContainsKey(name)) + return false; + + string oldName = null; + foreach (KeyValuePair sub in parentTag.ToTagCompound()) + { + if (sub.Value == tag) + { + oldName = sub.Key; + break; + } + } + + parentTag.ToTagCompound().Remove(oldName); + parentTag.ToTagCompound().Add(name, tag); + + return true; + } + + private void EditNodeValue(TreeNode node) + { + if (node == null) + return; + + TagNode tag = GetTagNode(node); + if (tag == null) + return; + + if (tag.GetTagType() == TagType.TAG_BYTE_ARRAY || + tag.GetTagType() == TagType.TAG_LIST || + tag.GetTagType() == TagType.TAG_COMPOUND) + return; + + EditValue form = new EditValue(tag); + if (form.ShowDialog() == DialogResult.OK) + { + TreeNode baseNode = BaseNode(node); + if (baseNode != null) + { + (baseNode.Tag as DataNode).Modified = true; + } + + node.Text = GetNodeText(node); + } + } + + private void _buttonEdit_Click(object sender, EventArgs e) + { + EditNodeValue(_nodeTree.SelectedNode); + } + + private void EditNodeName(TreeNode node) + { + if (node == null) + return; + + TagNode tag = GetTagNode(node); + if (tag == null) + return; + + string name = GetTagNodeName(node); + if (name == null) + return; + + EditValue form = new EditValue(name); + + TagNode parentTag = GetParentTagNode(node); + foreach (string key in parentTag.ToTagCompound().Keys) + { + form.InvalidNames.Add(key); + } + + if (form.ShowDialog() == DialogResult.OK) + { + TreeNode baseNode = BaseNode(node); + if (baseNode != null) + { + (baseNode.Tag as DataNode).Modified = true; + } + + SetTagNodeName(node, form.NodeName); + node.Text = GetNodeText(node); + } + } + + private void _buttonRename_Click(object sender, EventArgs e) + { + EditNodeName(_nodeTree.SelectedNode); + } + + private void AddTagToNode(TreeNode node, TagType type) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return; + + if (tag.GetTagType() != TagType.TAG_COMPOUND && + tag.GetTagType() != TagType.TAG_LIST) + return; + + if (tag.GetTagType() == TagType.TAG_LIST && + tag.ToTagList().ValueType != type && + tag.ToTagList().Count > 0) + return; + + TagNode newNode = null; + switch (type) + { + case TagType.TAG_BYTE: + newNode = new TagNodeByte(); + break; + case TagType.TAG_SHORT: + newNode = new TagNodeShort(); + break; + case TagType.TAG_INT: + newNode = new TagNodeInt(); + break; + case TagType.TAG_LONG: + newNode = new TagNodeLong(); + break; + case TagType.TAG_FLOAT: + newNode = new TagNodeFloat(); + break; + case TagType.TAG_DOUBLE: + newNode = new TagNodeDouble(); + break; + case TagType.TAG_BYTE_ARRAY: + newNode = new TagNodeByteArray(); + break; + case TagType.TAG_STRING: + newNode = new TagNodeString(); + break; + case TagType.TAG_LIST: + newNode = new TagNodeList(TagType.TAG_BYTE); + break; + case TagType.TAG_COMPOUND: + newNode = new TagNodeCompound(); + break; + } + + if (tag is TagNodeCompound) + { + TagNodeCompound ctag = tag as TagNodeCompound; + + EditValue form = new EditValue(""); + foreach (string key in ctag.Keys) + { + form.InvalidNames.Add(key); + } + + if (form.ShowDialog() != DialogResult.OK) + return; + + ctag.Add(form.NodeName, newNode); + + TreeNode tnode = NodeFromTag(newNode, form.NodeName); + node.Nodes.Add(tnode); + + _nodeTree.SelectedNode = tnode; + tnode.Expand(); + } + else if (tag is TagNodeList) + { + TagNodeList ltag = tag as TagNodeList; + if (ltag.ValueType != type) + ltag.ChangeValueType(type); + + ltag.Add(newNode); + + TreeNode tnode = NodeFromTag(newNode); + node.Nodes.Add(tnode); + + _nodeTree.SelectedNode = tnode; + tnode.Expand(); + } + + node.Text = GetNodeText(node); + + TreeNode baseNode = BaseNode(node); + if (baseNode != null) + { + (baseNode.Tag as DataNode).Modified = true; + } + } + + private void _buttonAddTagByte_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE); + } + + private void _buttonAddTagShort_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_SHORT); + } + + private void _buttonAddTagInt_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_INT); + } + + private void _buttonAddTagLong_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LONG); + } + + private void _buttonAddTagFloat_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_FLOAT); + } + + private void _buttonAddTagDouble_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_DOUBLE); + } + + private void _buttonAddTagByteArray_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE_ARRAY); + } + + private void _buttonAddTagString_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_STRING); + } + + private void _buttonAddTagList_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LIST); + } + + private void _buttonAddTagCompound_Click(object sender, EventArgs e) + { + AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_COMPOUND); + } + + private void saveToolStripMenuItem_Click(object sender, EventArgs e) + { + SaveAll(); + } + + private void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + Application.Exit(); + } + + private TreeNode _rootSearchNode; + private string _searchName; + private string _searchValue; + private IEnumerator _search; + + private void Find(TreeNode node) + { + if (node == null) + return; + + Find form = new Find(); + if (form.ShowDialog() == DialogResult.OK) + { + _rootSearchNode = node; + + _searchName = form.MatchName ? form.NameToken : null; + _searchValue = form.MatchValue ? form.ValueToken : null; + + _search = FindNode(node).GetEnumerator(); + + FindNext(); + } + } + + private void FindNext() + { + if (_search == null) + return; + + statusStrip1.Visible = true; + Application.DoEvents(); + + _nodeTree.SelectedNode = null; + + if (!_search.MoveNext()) + { + _nodeTree.SelectedNode = _rootSearchNode; + if (_rootSearchNode != null && _rootSearchNode.Tag is DataNode) + { + if (_rootSearchNode.IsExpanded && !(_rootSearchNode.Tag as DataNode).Expanded) + { + _rootSearchNode.Collapse(); + } + } + + statusStrip1.Visible = false; + + MessageBox.Show("End of results"); + _search = null; + } + + statusStrip1.Visible = false; + } + + private IEnumerable FindNode(TreeNode node) + { + if (node == null) + yield break; + + bool expand = false; + + if (node.Tag is DataNode) + { + DataNode data = node.Tag as DataNode; + if (!data.Expanded) + { + ExpandNode(node); + expand = true; + } + } + + TagNode tag = GetTagNode(node); + if (tag != null) + { + bool mName = _searchName == null; + bool mValue = _searchValue == null; + + if (_searchName != null) + { + string tagName = GetTagNodeName(node); + if (tagName != null) + mName = tagName.Contains(_searchName); + } + if (_searchValue != null) + { + string tagValue = GetTagNodeText(node); + if (tagValue != null) + mValue = tagValue.Contains(_searchValue); + } + + if (mName && mValue) + { + _nodeTree.SelectedNode = node; + yield return node; + } + } + + foreach (TreeNode sub in node.Nodes) + { + foreach (TreeNode s in FindNode(sub)) + yield return s; + } + + if (expand) + { + DataNode data = node.Tag as DataNode; + if (!data.Modified) + CollapseNode(node); + } + } + + private void findToolStripMenuItem_Click(object sender, EventArgs e) + { + Find(_nodeTree.SelectedNode); + } + + private void findNextToolStripMenuItem_Click(object sender, EventArgs e) + { + FindNext(); + } + + private void _buttonFindNext_Click(object sender, EventArgs e) + { + if (_search == null) + Find(_nodeTree.SelectedNode); + else + FindNext(); + } + + private void _buttonOpenFolder_Click(object sender, EventArgs e) + { + OpenFolder(); + } + + private void DropFile(DragEventArgs e) + { + string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); + OpenPaths(files); + } + + private void _nodeTree_DragDrop(object sender, DragEventArgs e) + { + DropFile(e); + } + + private void _nodeTree_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + e.Effect = DragDropEffects.Copy; + } + + private void openMinecraftSaveFolderToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenMinecraftDir(); + } + } + + public class TagKey : IComparable + { + public TagKey(string name, TagType type) + { + Name = name; + TagType = type; + } + + public string Name { get; set; } + public TagType TagType { get; set; } + + #region IComparer Members + + public int Compare(TagKey x, TagKey y) + { + int typeDiff = (int)x.TagType - (int)y.TagType; + if (typeDiff != 0) + return typeDiff; + + return String.Compare(x.Name, y.Name, true); + } + + #endregion + + #region IComparable Members + + public int CompareTo(TagKey other) + { + return Compare(this, other); + } + + #endregion + } + + public class DataNode + { + public DataNode() + { + } + + public DataNode(DataNode parent) + { + Parent = parent; + } + + public DataNode Parent { get; set; } + + private bool _modified; + public bool Modified + { + get { return _modified; } + set + { + if (value && Parent != null) + { + Parent.Modified = value; + } + _modified = value; + } + } + + public bool Expanded { get; set; } + } + + public class NbtDataNode : DataNode + { + public NbtDataNode() + { + } + + public NbtDataNode(DataNode parent) + : base(parent) + { + } + + public NbtTree Tree { get; set; } + } + + public class RegionChunkData : NbtDataNode + { + public RegionChunkData(RegionFile file, int x, int z) + : this(null, file, x, z) + { + } + + public RegionChunkData(DataNode parent, RegionFile file, int x, int z) + : base(parent) + { + Region = file; + X = x; + Z = z; + } + + public RegionFile Region { get; private set; } + public int X { get; private set; } + public int Z { get; private set; } + } + + public class RegionData : DataNode + { + public RegionData(string path) + : this(null, path) + { + } + + public RegionData(DataNode parent, string path) + : base(parent) + { + Path = path; + } + + public string Path { get; private set; } + } + + public class NbtFileData : NbtDataNode + { + public NbtFileData(string path, CompressionType cztype) + : this(null, path, cztype) + { + } + + public NbtFileData(DataNode parent, string path, CompressionType cztype) + : base(parent) + { + Path = path; + CompressionType = cztype; + } + + public string Path { get; private set; } + public CompressionType CompressionType { get; private set; } + } + + public class DirectoryData : DataNode + { + public DirectoryData(string path) + : this(null, path) + { + } + + public DirectoryData(DataNode parent, string path) + : base(parent) + { + Path = path; + } + + public string Path { get; private set; } + } +} From f4595062caf4cd36f874fd56974db75cd1ac8ede Mon Sep 17 00:00:00 2001 From: ImaginaryDevelopment Date: Sun, 19 Feb 2012 15:11:04 -0800 Subject: [PATCH 2/8] refactoring to split concerns out into other files added a find for locating chunks that have entities in them. --- DataNode.cs | 32 + DirectoryData.cs | 18 + Form1.Designer.cs | 1040 +++++++++++++-------------- Form1.cs | 468 +++++------- Form1.resx | 1652 +++++++++++++++++++++---------------------- NBTExplorer.csproj | 296 ++++---- NbtDataNode.cs | 18 + NbtFileData.cs | 22 + RegionChunkData.cs | 24 + RegionData.cs | 18 + StringExtensions.cs | 15 + SubstrateHelper.cs | 70 ++ TagKey.cs | 39 + UIHelper.cs | 29 + 14 files changed, 1964 insertions(+), 1777 deletions(-) create mode 100644 DataNode.cs create mode 100644 DirectoryData.cs create mode 100644 NbtDataNode.cs create mode 100644 NbtFileData.cs create mode 100644 RegionChunkData.cs create mode 100644 RegionData.cs create mode 100644 StringExtensions.cs create mode 100644 SubstrateHelper.cs create mode 100644 TagKey.cs create mode 100644 UIHelper.cs diff --git a/DataNode.cs b/DataNode.cs new file mode 100644 index 0000000..5b900c9 --- /dev/null +++ b/DataNode.cs @@ -0,0 +1,32 @@ +namespace NBTExplorer +{ + public class DataNode + { + public DataNode() + { + } + + public DataNode(DataNode parent) + { + Parent = parent; + } + + public DataNode Parent { get; set; } + + private bool _modified; + public bool Modified + { + get { return _modified; } + set + { + if (value && Parent != null) + { + Parent.Modified = value; + } + _modified = value; + } + } + + public bool Expanded { get; set; } + } +} \ No newline at end of file diff --git a/DirectoryData.cs b/DirectoryData.cs new file mode 100644 index 0000000..71de574 --- /dev/null +++ b/DirectoryData.cs @@ -0,0 +1,18 @@ +namespace NBTExplorer +{ + public class DirectoryData : DataNode + { + public DirectoryData(string path) + : this(null, path) + { + } + + public DirectoryData(DataNode parent, string path) + : base(parent) + { + Path = path; + } + + public string Path { get; private set; } + } +} \ No newline at end of file diff --git a/Form1.Designer.cs b/Form1.Designer.cs index fe0c6ef..3d844d8 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -27,520 +27,529 @@ protected override void Dispose (bool disposing) /// private void InitializeComponent () { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); - this.menuStrip1 = new System.Windows.Forms.MenuStrip(); - this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); - this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); - this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.findNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); - this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); - this._nodeTree = new System.Windows.Forms.TreeView(); - this.imageList1 = new System.Windows.Forms.ImageList(this.components); - this.toolStrip1 = new System.Windows.Forms.ToolStrip(); - this._buttonOpen = new System.Windows.Forms.ToolStripButton(); - this._buttonOpenFolder = new System.Windows.Forms.ToolStripButton(); - this._buttonSave = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); - this._buttonRename = new System.Windows.Forms.ToolStripButton(); - this._buttonEdit = new System.Windows.Forms.ToolStripButton(); - this._buttonDelete = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this._buttonAddTagByte = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagShort = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagInt = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagLong = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagFloat = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagDouble = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagByteArray = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagString = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagList = new System.Windows.Forms.ToolStripButton(); - this._buttonAddTagCompound = new System.Windows.Forms.ToolStripButton(); - this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); - this._buttonFindNext = new System.Windows.Forms.ToolStripButton(); - this._nodeContainerContext = new System.Windows.Forms.ContextMenuStrip(this.components); - this.openSubTreeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.saveItemToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openMinecraftSaveFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.menuStrip1.SuspendLayout(); - this.toolStripContainer1.ContentPanel.SuspendLayout(); - this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); - this.toolStripContainer1.SuspendLayout(); - this.statusStrip1.SuspendLayout(); - this.toolStrip1.SuspendLayout(); - this._nodeContainerContext.SuspendLayout(); - this.SuspendLayout(); - // - // menuStrip1 - // - this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.fileToolStripMenuItem, - this.searchToolStripMenuItem, - this.helpToolStripMenuItem}); - this.menuStrip1.Location = new System.Drawing.Point(0, 0); - this.menuStrip1.Name = "menuStrip1"; - this.menuStrip1.Size = new System.Drawing.Size(562, 24); - this.menuStrip1.TabIndex = 0; - this.menuStrip1.Text = "menuStrip1"; - // - // fileToolStripMenuItem - // - this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.openToolStripMenuItem, - this.openFolderToolStripMenuItem, - this.openMinecraftSaveFolderToolStripMenuItem, - this.toolStripSeparator3, - this.saveToolStripMenuItem, - this.toolStripSeparator4, - this.exitToolStripMenuItem}); - this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; - this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); - this.fileToolStripMenuItem.Text = "&File"; - // - // openToolStripMenuItem - // - this.openToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.folder_open_document; - this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); - this.openToolStripMenuItem.Size = new System.Drawing.Size(223, 22); - this.openToolStripMenuItem.Text = "&Open..."; - this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); - // - // openFolderToolStripMenuItem - // - this.openFolderToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.folder_open; - this.openFolderToolStripMenuItem.Name = "openFolderToolStripMenuItem"; - this.openFolderToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) - | System.Windows.Forms.Keys.O))); - this.openFolderToolStripMenuItem.Size = new System.Drawing.Size(223, 22); - this.openFolderToolStripMenuItem.Text = "Open &Folder..."; - this.openFolderToolStripMenuItem.Click += new System.EventHandler(this.openFolderToolStripMenuItem_Click); - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(220, 6); - // - // saveToolStripMenuItem - // - this.saveToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.disk; - this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); - this.saveToolStripMenuItem.Size = new System.Drawing.Size(223, 22); - this.saveToolStripMenuItem.Text = "&Save"; - this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); - // - // toolStripSeparator4 - // - this.toolStripSeparator4.Name = "toolStripSeparator4"; - this.toolStripSeparator4.Size = new System.Drawing.Size(220, 6); - // - // exitToolStripMenuItem - // - this.exitToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.door; - this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; - this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4))); - this.exitToolStripMenuItem.Size = new System.Drawing.Size(223, 22); - this.exitToolStripMenuItem.Text = "E&xit"; - this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); - // - // searchToolStripMenuItem - // - this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.findToolStripMenuItem, - this.findNextToolStripMenuItem}); - this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; - this.searchToolStripMenuItem.Size = new System.Drawing.Size(54, 20); - this.searchToolStripMenuItem.Text = "&Search"; - // - // findToolStripMenuItem - // - this.findToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.binocular; - this.findToolStripMenuItem.Name = "findToolStripMenuItem"; - this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); - this.findToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.findToolStripMenuItem.Text = "Find..."; - this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click); - // - // findNextToolStripMenuItem - // - this.findNextToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.binocular__arrow; - this.findNextToolStripMenuItem.Name = "findNextToolStripMenuItem"; - this.findNextToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F3; - this.findNextToolStripMenuItem.Size = new System.Drawing.Size(146, 22); - this.findNextToolStripMenuItem.Text = "Find Next"; - this.findNextToolStripMenuItem.Click += new System.EventHandler(this.findNextToolStripMenuItem_Click); - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.aboutToolStripMenuItem}); - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); - this.helpToolStripMenuItem.Text = "&Help"; - // - // aboutToolStripMenuItem - // - this.aboutToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.information_frame; - this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; - this.aboutToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F1; - this.aboutToolStripMenuItem.Size = new System.Drawing.Size(126, 22); - this.aboutToolStripMenuItem.Text = "&About"; - this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); - // - // toolStripContainer1 - // - // - // toolStripContainer1.ContentPanel - // - this.toolStripContainer1.ContentPanel.Controls.Add(this.statusStrip1); - this.toolStripContainer1.ContentPanel.Controls.Add(this._nodeTree); - this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(562, 351); - this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.toolStripContainer1.Location = new System.Drawing.Point(0, 24); - this.toolStripContainer1.Name = "toolStripContainer1"; - this.toolStripContainer1.Size = new System.Drawing.Size(562, 376); - this.toolStripContainer1.TabIndex = 1; - this.toolStripContainer1.Text = "toolStripContainer1"; - // - // toolStripContainer1.TopToolStripPanel - // - this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1); - // - // statusStrip1 - // - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripStatusLabel1}); - this.statusStrip1.Location = new System.Drawing.Point(0, 329); - this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(562, 22); - this.statusStrip1.SizingGrip = false; - this.statusStrip1.TabIndex = 1; - this.statusStrip1.Text = "statusStrip1"; - this.statusStrip1.Visible = false; - // - // toolStripStatusLabel1 - // - this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.Size = new System.Drawing.Size(547, 17); - this.toolStripStatusLabel1.Spring = true; - this.toolStripStatusLabel1.Text = "Please wait..."; - // - // _nodeTree - // - this._nodeTree.AllowDrop = true; - this._nodeTree.Dock = System.Windows.Forms.DockStyle.Fill; - this._nodeTree.ImageIndex = 0; - this._nodeTree.ImageList = this.imageList1; - this._nodeTree.Location = new System.Drawing.Point(0, 0); - this._nodeTree.Name = "_nodeTree"; - this._nodeTree.SelectedImageIndex = 0; - this._nodeTree.Size = new System.Drawing.Size(562, 351); - this._nodeTree.TabIndex = 0; - this._nodeTree.DragDrop += new System.Windows.Forms.DragEventHandler(this._nodeTree_DragDrop); - this._nodeTree.DragEnter += new System.Windows.Forms.DragEventHandler(this._nodeTree_DragEnter); - // - // imageList1 - // - this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); - this.imageList1.TransparentColor = System.Drawing.Color.Transparent; - this.imageList1.Images.SetKeyName(0, "document-attribute-b.png"); - this.imageList1.Images.SetKeyName(1, "document-attribute-s.png"); - this.imageList1.Images.SetKeyName(2, "document-attribute-i.png"); - this.imageList1.Images.SetKeyName(3, "document-attribute-l.png"); - this.imageList1.Images.SetKeyName(4, "document-attribute-f.png"); - this.imageList1.Images.SetKeyName(5, "document-attribute-d.png"); - this.imageList1.Images.SetKeyName(6, "edit-code.png"); - this.imageList1.Images.SetKeyName(7, "edit-small-caps.png"); - this.imageList1.Images.SetKeyName(8, "edit-list.png"); - this.imageList1.Images.SetKeyName(9, "box.png"); - this.imageList1.Images.SetKeyName(10, "folder.png"); - this.imageList1.Images.SetKeyName(11, "block.png"); - this.imageList1.Images.SetKeyName(12, "wooden-box.png"); - this.imageList1.Images.SetKeyName(13, "map.png"); - // - // toolStrip1 - // - this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None; - this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this._buttonOpen, - this._buttonOpenFolder, - this._buttonSave, - this.toolStripSeparator1, - this._buttonRename, - this._buttonEdit, - this._buttonDelete, - this.toolStripSeparator2, - this._buttonAddTagByte, - this._buttonAddTagShort, - this._buttonAddTagInt, - this._buttonAddTagLong, - this._buttonAddTagFloat, - this._buttonAddTagDouble, - this._buttonAddTagByteArray, - this._buttonAddTagString, - this._buttonAddTagList, - this._buttonAddTagCompound, - this.toolStripSeparator5, - this._buttonFindNext}); - this.toolStrip1.Location = new System.Drawing.Point(0, 0); - this.toolStrip1.Name = "toolStrip1"; - this.toolStrip1.Size = new System.Drawing.Size(562, 25); - this.toolStrip1.Stretch = true; - this.toolStrip1.TabIndex = 0; - // - // _buttonOpen - // - this._buttonOpen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonOpen.Image = ((System.Drawing.Image)(resources.GetObject("_buttonOpen.Image"))); - this._buttonOpen.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonOpen.Name = "_buttonOpen"; - this._buttonOpen.Size = new System.Drawing.Size(23, 22); - this._buttonOpen.Text = "Open NBT Data Source"; - this._buttonOpen.Click += new System.EventHandler(this.toolStripButton1_Click); - // - // _buttonOpenFolder - // - this._buttonOpenFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonOpenFolder.Image = global::NBTExplorer.Properties.Resources.folder_open; - this._buttonOpenFolder.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonOpenFolder.Name = "_buttonOpenFolder"; - this._buttonOpenFolder.Size = new System.Drawing.Size(23, 22); - this._buttonOpenFolder.Text = "Open Folder"; - this._buttonOpenFolder.Click += new System.EventHandler(this._buttonOpenFolder_Click); - // - // _buttonSave - // - this._buttonSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonSave.Image = ((System.Drawing.Image)(resources.GetObject("_buttonSave.Image"))); - this._buttonSave.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonSave.Name = "_buttonSave"; - this._buttonSave.Size = new System.Drawing.Size(23, 22); - this._buttonSave.Text = "Save All Modified Tags"; - this._buttonSave.Click += new System.EventHandler(this._buttonSave_Click); - // - // toolStripSeparator1 - // - this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); - // - // _buttonRename - // - this._buttonRename.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonRename.Image = ((System.Drawing.Image)(resources.GetObject("_buttonRename.Image"))); - this._buttonRename.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonRename.Name = "_buttonRename"; - this._buttonRename.Size = new System.Drawing.Size(23, 22); - this._buttonRename.Text = "Rename Tag"; - this._buttonRename.Click += new System.EventHandler(this._buttonRename_Click); - // - // _buttonEdit - // - this._buttonEdit.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonEdit.Image = ((System.Drawing.Image)(resources.GetObject("_buttonEdit.Image"))); - this._buttonEdit.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonEdit.Name = "_buttonEdit"; - this._buttonEdit.Size = new System.Drawing.Size(23, 22); - this._buttonEdit.Text = "Edit Tag Value"; - this._buttonEdit.Click += new System.EventHandler(this._buttonEdit_Click); - // - // _buttonDelete - // - this._buttonDelete.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonDelete.Image = ((System.Drawing.Image)(resources.GetObject("_buttonDelete.Image"))); - this._buttonDelete.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonDelete.Name = "_buttonDelete"; - this._buttonDelete.Size = new System.Drawing.Size(23, 22); - this._buttonDelete.Text = "Delete Tag"; - this._buttonDelete.Click += new System.EventHandler(this._buttonDelete_Click); - // - // toolStripSeparator2 - // - this.toolStripSeparator2.Name = "toolStripSeparator2"; - this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); - // - // _buttonAddTagByte - // - this._buttonAddTagByte.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagByte.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagByte.Image"))); - this._buttonAddTagByte.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagByte.Name = "_buttonAddTagByte"; - this._buttonAddTagByte.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagByte.Text = "Add Byte Tag"; - this._buttonAddTagByte.Click += new System.EventHandler(this._buttonAddTagByte_Click); - // - // _buttonAddTagShort - // - this._buttonAddTagShort.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagShort.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagShort.Image"))); - this._buttonAddTagShort.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagShort.Name = "_buttonAddTagShort"; - this._buttonAddTagShort.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagShort.Text = "Add Short Tag"; - this._buttonAddTagShort.Click += new System.EventHandler(this._buttonAddTagShort_Click); - // - // _buttonAddTagInt - // - this._buttonAddTagInt.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagInt.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagInt.Image"))); - this._buttonAddTagInt.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagInt.Name = "_buttonAddTagInt"; - this._buttonAddTagInt.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagInt.Text = "Add Int Tag"; - this._buttonAddTagInt.Click += new System.EventHandler(this._buttonAddTagInt_Click); - // - // _buttonAddTagLong - // - this._buttonAddTagLong.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagLong.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagLong.Image"))); - this._buttonAddTagLong.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagLong.Name = "_buttonAddTagLong"; - this._buttonAddTagLong.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagLong.Text = "Add Long Tag"; - this._buttonAddTagLong.Click += new System.EventHandler(this._buttonAddTagLong_Click); - // - // _buttonAddTagFloat - // - this._buttonAddTagFloat.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagFloat.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagFloat.Image"))); - this._buttonAddTagFloat.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagFloat.Name = "_buttonAddTagFloat"; - this._buttonAddTagFloat.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagFloat.Text = "Add Float Tag"; - this._buttonAddTagFloat.Click += new System.EventHandler(this._buttonAddTagFloat_Click); - // - // _buttonAddTagDouble - // - this._buttonAddTagDouble.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagDouble.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagDouble.Image"))); - this._buttonAddTagDouble.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagDouble.Name = "_buttonAddTagDouble"; - this._buttonAddTagDouble.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagDouble.Text = "Add Double Tag"; - this._buttonAddTagDouble.Click += new System.EventHandler(this._buttonAddTagDouble_Click); - // - // _buttonAddTagByteArray - // - this._buttonAddTagByteArray.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagByteArray.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagByteArray.Image"))); - this._buttonAddTagByteArray.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagByteArray.Name = "_buttonAddTagByteArray"; - this._buttonAddTagByteArray.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagByteArray.Text = "Add Byte Array Tag"; - this._buttonAddTagByteArray.Click += new System.EventHandler(this._buttonAddTagByteArray_Click); - // - // _buttonAddTagString - // - this._buttonAddTagString.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagString.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagString.Image"))); - this._buttonAddTagString.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagString.Name = "_buttonAddTagString"; - this._buttonAddTagString.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagString.Text = "Add String Tag"; - this._buttonAddTagString.Click += new System.EventHandler(this._buttonAddTagString_Click); - // - // _buttonAddTagList - // - this._buttonAddTagList.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagList.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagList.Image"))); - this._buttonAddTagList.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagList.Name = "_buttonAddTagList"; - this._buttonAddTagList.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagList.Text = "Add List Tag"; - this._buttonAddTagList.Click += new System.EventHandler(this._buttonAddTagList_Click); - // - // _buttonAddTagCompound - // - this._buttonAddTagCompound.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonAddTagCompound.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagCompound.Image"))); - this._buttonAddTagCompound.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonAddTagCompound.Name = "_buttonAddTagCompound"; - this._buttonAddTagCompound.Size = new System.Drawing.Size(23, 22); - this._buttonAddTagCompound.Text = "Add Compound Tag"; - this._buttonAddTagCompound.Click += new System.EventHandler(this._buttonAddTagCompound_Click); - // - // toolStripSeparator5 - // - this.toolStripSeparator5.Name = "toolStripSeparator5"; - this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); - // - // _buttonFindNext - // - this._buttonFindNext.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; - this._buttonFindNext.Image = global::NBTExplorer.Properties.Resources.binocular__arrow; - this._buttonFindNext.ImageTransparentColor = System.Drawing.Color.Magenta; - this._buttonFindNext.Name = "_buttonFindNext"; - this._buttonFindNext.Size = new System.Drawing.Size(23, 22); - this._buttonFindNext.Text = "Find / Find Next"; - this._buttonFindNext.Click += new System.EventHandler(this._buttonFindNext_Click); - // - // _nodeContainerContext - // - this._nodeContainerContext.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.openSubTreeToolStripMenuItem, - this.saveItemToolStripMenuItem}); - this._nodeContainerContext.Name = "contextMenuStrip1"; - this._nodeContainerContext.Size = new System.Drawing.Size(180, 48); - // - // openSubTreeToolStripMenuItem - // - this.openSubTreeToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.folder_open; - this.openSubTreeToolStripMenuItem.Name = "openSubTreeToolStripMenuItem"; - this.openSubTreeToolStripMenuItem.Size = new System.Drawing.Size(179, 22); - this.openSubTreeToolStripMenuItem.Text = "Open Node As Root"; - // - // saveItemToolStripMenuItem - // - this.saveItemToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.disk; - this.saveItemToolStripMenuItem.Name = "saveItemToolStripMenuItem"; - this.saveItemToolStripMenuItem.Size = new System.Drawing.Size(179, 22); - this.saveItemToolStripMenuItem.Text = "Save Node"; - // - // openMinecraftSaveFolderToolStripMenuItem - // - this.openMinecraftSaveFolderToolStripMenuItem.Name = "openMinecraftSaveFolderToolStripMenuItem"; - this.openMinecraftSaveFolderToolStripMenuItem.Size = new System.Drawing.Size(223, 22); - this.openMinecraftSaveFolderToolStripMenuItem.Text = "Open &Minecraft Save Folder"; - this.openMinecraftSaveFolderToolStripMenuItem.Click += new System.EventHandler(this.openMinecraftSaveFolderToolStripMenuItem_Click); - // - // Form1 - // - this.AllowDrop = true; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(562, 400); - this.Controls.Add(this.toolStripContainer1); - this.Controls.Add(this.menuStrip1); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MainMenuStrip = this.menuStrip1; - this.Name = "Form1"; - this.Text = "NBTExplorer"; - this.menuStrip1.ResumeLayout(false); - this.menuStrip1.PerformLayout(); - this.toolStripContainer1.ContentPanel.ResumeLayout(false); - this.toolStripContainer1.ContentPanel.PerformLayout(); - this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false); - this.toolStripContainer1.TopToolStripPanel.PerformLayout(); - this.toolStripContainer1.ResumeLayout(false); - this.toolStripContainer1.PerformLayout(); - this.statusStrip1.ResumeLayout(false); - this.statusStrip1.PerformLayout(); - this.toolStrip1.ResumeLayout(false); - this.toolStrip1.PerformLayout(); - this._nodeContainerContext.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openMinecraftSaveFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); + this._nodeTree = new System.Windows.Forms.TreeView(); + this.imageList1 = new System.Windows.Forms.ImageList(this.components); + this.toolStrip1 = new System.Windows.Forms.ToolStrip(); + this._buttonOpen = new System.Windows.Forms.ToolStripButton(); + this._buttonOpenFolder = new System.Windows.Forms.ToolStripButton(); + this._buttonSave = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); + this._buttonRename = new System.Windows.Forms.ToolStripButton(); + this._buttonEdit = new System.Windows.Forms.ToolStripButton(); + this._buttonDelete = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this._buttonAddTagByte = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagShort = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagInt = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagLong = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagFloat = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagDouble = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagByteArray = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagString = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagList = new System.Windows.Forms.ToolStripButton(); + this._buttonAddTagCompound = new System.Windows.Forms.ToolStripButton(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); + this._buttonFindNext = new System.Windows.Forms.ToolStripButton(); + this._nodeContainerContext = new System.Windows.Forms.ContextMenuStrip(this.components); + this.openSubTreeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.saveItemToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findEntityChunkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip1.SuspendLayout(); + this.toolStripContainer1.ContentPanel.SuspendLayout(); + this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); + this.toolStripContainer1.SuspendLayout(); + this.statusStrip1.SuspendLayout(); + this.toolStrip1.SuspendLayout(); + this._nodeContainerContext.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.fileToolStripMenuItem, + this.searchToolStripMenuItem, + this.helpToolStripMenuItem}); + this.menuStrip1.Location = new System.Drawing.Point(0, 0); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size(562, 24); + this.menuStrip1.TabIndex = 0; + this.menuStrip1.Text = "menuStrip1"; + // + // fileToolStripMenuItem + // + this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openToolStripMenuItem, + this.openFolderToolStripMenuItem, + this.openMinecraftSaveFolderToolStripMenuItem, + this.toolStripSeparator3, + this.saveToolStripMenuItem, + this.toolStripSeparator4, + this.exitToolStripMenuItem}); + this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); + this.fileToolStripMenuItem.Text = "&File"; + // + // openToolStripMenuItem + // + this.openToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.folder_open_document; + this.openToolStripMenuItem.Name = "openToolStripMenuItem"; + this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.openToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.openToolStripMenuItem.Text = "&Open..."; + this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); + // + // openFolderToolStripMenuItem + // + this.openFolderToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.folder_open; + this.openFolderToolStripMenuItem.Name = "openFolderToolStripMenuItem"; + this.openFolderToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.O))); + this.openFolderToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.openFolderToolStripMenuItem.Text = "Open &Folder..."; + this.openFolderToolStripMenuItem.Click += new System.EventHandler(this.openFolderToolStripMenuItem_Click); + // + // openMinecraftSaveFolderToolStripMenuItem + // + this.openMinecraftSaveFolderToolStripMenuItem.Name = "openMinecraftSaveFolderToolStripMenuItem"; + this.openMinecraftSaveFolderToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.openMinecraftSaveFolderToolStripMenuItem.Text = "Open &Minecraft Save Folder"; + this.openMinecraftSaveFolderToolStripMenuItem.Click += new System.EventHandler(this.openMinecraftSaveFolderToolStripMenuItem_Click); + // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(220, 6); + // + // saveToolStripMenuItem + // + this.saveToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.disk; + this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; + this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.saveToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.saveToolStripMenuItem.Text = "&Save"; + this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(220, 6); + // + // exitToolStripMenuItem + // + this.exitToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.door; + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4))); + this.exitToolStripMenuItem.Size = new System.Drawing.Size(223, 22); + this.exitToolStripMenuItem.Text = "E&xit"; + this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + // + // searchToolStripMenuItem + // + this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.findToolStripMenuItem, + this.findNextToolStripMenuItem, + this.findEntityChunkToolStripMenuItem}); + this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; + this.searchToolStripMenuItem.Size = new System.Drawing.Size(54, 20); + this.searchToolStripMenuItem.Text = "&Search"; + // + // findToolStripMenuItem + // + this.findToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.binocular; + this.findToolStripMenuItem.Name = "findToolStripMenuItem"; + this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); + this.findToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.findToolStripMenuItem.Text = "Find..."; + this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click); + // + // findNextToolStripMenuItem + // + this.findNextToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.binocular__arrow; + this.findNextToolStripMenuItem.Name = "findNextToolStripMenuItem"; + this.findNextToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F3; + this.findNextToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.findNextToolStripMenuItem.Text = "Find Next"; + this.findNextToolStripMenuItem.Click += new System.EventHandler(this.findNextToolStripMenuItem_Click); + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.aboutToolStripMenuItem}); + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20); + this.helpToolStripMenuItem.Text = "&Help"; + // + // aboutToolStripMenuItem + // + this.aboutToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.information_frame; + this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; + this.aboutToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F1; + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(126, 22); + this.aboutToolStripMenuItem.Text = "&About"; + this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + // + // toolStripContainer1 + // + // + // toolStripContainer1.ContentPanel + // + this.toolStripContainer1.ContentPanel.Controls.Add(this.statusStrip1); + this.toolStripContainer1.ContentPanel.Controls.Add(this._nodeTree); + this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(562, 351); + this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.toolStripContainer1.Location = new System.Drawing.Point(0, 24); + this.toolStripContainer1.Name = "toolStripContainer1"; + this.toolStripContainer1.Size = new System.Drawing.Size(562, 376); + this.toolStripContainer1.TabIndex = 1; + this.toolStripContainer1.Text = "toolStripContainer1"; + // + // toolStripContainer1.TopToolStripPanel + // + this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1); + // + // statusStrip1 + // + this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabel1}); + this.statusStrip1.Location = new System.Drawing.Point(0, 329); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size(562, 22); + this.statusStrip1.SizingGrip = false; + this.statusStrip1.TabIndex = 1; + this.statusStrip1.Text = "statusStrip1"; + this.statusStrip1.Visible = false; + // + // toolStripStatusLabel1 + // + this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; + this.toolStripStatusLabel1.Size = new System.Drawing.Size(547, 17); + this.toolStripStatusLabel1.Spring = true; + this.toolStripStatusLabel1.Text = "Please wait..."; + // + // _nodeTree + // + this._nodeTree.AllowDrop = true; + this._nodeTree.Dock = System.Windows.Forms.DockStyle.Fill; + this._nodeTree.ImageIndex = 0; + this._nodeTree.ImageList = this.imageList1; + this._nodeTree.Location = new System.Drawing.Point(0, 0); + this._nodeTree.Name = "_nodeTree"; + this._nodeTree.SelectedImageIndex = 0; + this._nodeTree.Size = new System.Drawing.Size(562, 351); + this._nodeTree.TabIndex = 0; + this._nodeTree.DragDrop += new System.Windows.Forms.DragEventHandler(this._nodeTree_DragDrop); + this._nodeTree.DragEnter += new System.Windows.Forms.DragEventHandler(this._nodeTree_DragEnter); + // + // imageList1 + // + this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); + this.imageList1.TransparentColor = System.Drawing.Color.Transparent; + this.imageList1.Images.SetKeyName(0, "document-attribute-b.png"); + this.imageList1.Images.SetKeyName(1, "document-attribute-s.png"); + this.imageList1.Images.SetKeyName(2, "document-attribute-i.png"); + this.imageList1.Images.SetKeyName(3, "document-attribute-l.png"); + this.imageList1.Images.SetKeyName(4, "document-attribute-f.png"); + this.imageList1.Images.SetKeyName(5, "document-attribute-d.png"); + this.imageList1.Images.SetKeyName(6, "edit-code.png"); + this.imageList1.Images.SetKeyName(7, "edit-small-caps.png"); + this.imageList1.Images.SetKeyName(8, "edit-list.png"); + this.imageList1.Images.SetKeyName(9, "box.png"); + this.imageList1.Images.SetKeyName(10, "folder.png"); + this.imageList1.Images.SetKeyName(11, "block.png"); + this.imageList1.Images.SetKeyName(12, "wooden-box.png"); + this.imageList1.Images.SetKeyName(13, "map.png"); + // + // toolStrip1 + // + this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None; + this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this._buttonOpen, + this._buttonOpenFolder, + this._buttonSave, + this.toolStripSeparator1, + this._buttonRename, + this._buttonEdit, + this._buttonDelete, + this.toolStripSeparator2, + this._buttonAddTagByte, + this._buttonAddTagShort, + this._buttonAddTagInt, + this._buttonAddTagLong, + this._buttonAddTagFloat, + this._buttonAddTagDouble, + this._buttonAddTagByteArray, + this._buttonAddTagString, + this._buttonAddTagList, + this._buttonAddTagCompound, + this.toolStripSeparator5, + this._buttonFindNext}); + this.toolStrip1.Location = new System.Drawing.Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new System.Drawing.Size(562, 25); + this.toolStrip1.Stretch = true; + this.toolStrip1.TabIndex = 0; + // + // _buttonOpen + // + this._buttonOpen.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonOpen.Image = ((System.Drawing.Image)(resources.GetObject("_buttonOpen.Image"))); + this._buttonOpen.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonOpen.Name = "_buttonOpen"; + this._buttonOpen.Size = new System.Drawing.Size(23, 22); + this._buttonOpen.Text = "Open NBT Data Source"; + this._buttonOpen.Click += new System.EventHandler(this.toolStripButton1_Click); + // + // _buttonOpenFolder + // + this._buttonOpenFolder.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonOpenFolder.Image = global::NBTExplorer.Properties.Resources.folder_open; + this._buttonOpenFolder.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonOpenFolder.Name = "_buttonOpenFolder"; + this._buttonOpenFolder.Size = new System.Drawing.Size(23, 22); + this._buttonOpenFolder.Text = "Open Folder"; + this._buttonOpenFolder.Click += new System.EventHandler(this._buttonOpenFolder_Click); + // + // _buttonSave + // + this._buttonSave.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonSave.Image = ((System.Drawing.Image)(resources.GetObject("_buttonSave.Image"))); + this._buttonSave.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonSave.Name = "_buttonSave"; + this._buttonSave.Size = new System.Drawing.Size(23, 22); + this._buttonSave.Text = "Save All Modified Tags"; + this._buttonSave.Click += new System.EventHandler(this._buttonSave_Click); + // + // toolStripSeparator1 + // + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25); + // + // _buttonRename + // + this._buttonRename.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonRename.Image = ((System.Drawing.Image)(resources.GetObject("_buttonRename.Image"))); + this._buttonRename.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonRename.Name = "_buttonRename"; + this._buttonRename.Size = new System.Drawing.Size(23, 22); + this._buttonRename.Text = "Rename Tag"; + this._buttonRename.Click += new System.EventHandler(this._buttonRename_Click); + // + // _buttonEdit + // + this._buttonEdit.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonEdit.Image = ((System.Drawing.Image)(resources.GetObject("_buttonEdit.Image"))); + this._buttonEdit.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonEdit.Name = "_buttonEdit"; + this._buttonEdit.Size = new System.Drawing.Size(23, 22); + this._buttonEdit.Text = "Edit Tag Value"; + this._buttonEdit.Click += new System.EventHandler(this._buttonEdit_Click); + // + // _buttonDelete + // + this._buttonDelete.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonDelete.Image = ((System.Drawing.Image)(resources.GetObject("_buttonDelete.Image"))); + this._buttonDelete.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonDelete.Name = "_buttonDelete"; + this._buttonDelete.Size = new System.Drawing.Size(23, 22); + this._buttonDelete.Text = "Delete Tag"; + this._buttonDelete.Click += new System.EventHandler(this._buttonDelete_Click); + // + // toolStripSeparator2 + // + this.toolStripSeparator2.Name = "toolStripSeparator2"; + this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25); + // + // _buttonAddTagByte + // + this._buttonAddTagByte.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagByte.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagByte.Image"))); + this._buttonAddTagByte.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagByte.Name = "_buttonAddTagByte"; + this._buttonAddTagByte.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagByte.Text = "Add Byte Tag"; + this._buttonAddTagByte.Click += new System.EventHandler(this._buttonAddTagByte_Click); + // + // _buttonAddTagShort + // + this._buttonAddTagShort.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagShort.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagShort.Image"))); + this._buttonAddTagShort.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagShort.Name = "_buttonAddTagShort"; + this._buttonAddTagShort.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagShort.Text = "Add Short Tag"; + this._buttonAddTagShort.Click += new System.EventHandler(this._buttonAddTagShort_Click); + // + // _buttonAddTagInt + // + this._buttonAddTagInt.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagInt.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagInt.Image"))); + this._buttonAddTagInt.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagInt.Name = "_buttonAddTagInt"; + this._buttonAddTagInt.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagInt.Text = "Add Int Tag"; + this._buttonAddTagInt.Click += new System.EventHandler(this._buttonAddTagInt_Click); + // + // _buttonAddTagLong + // + this._buttonAddTagLong.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagLong.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagLong.Image"))); + this._buttonAddTagLong.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagLong.Name = "_buttonAddTagLong"; + this._buttonAddTagLong.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagLong.Text = "Add Long Tag"; + this._buttonAddTagLong.Click += new System.EventHandler(this._buttonAddTagLong_Click); + // + // _buttonAddTagFloat + // + this._buttonAddTagFloat.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagFloat.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagFloat.Image"))); + this._buttonAddTagFloat.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagFloat.Name = "_buttonAddTagFloat"; + this._buttonAddTagFloat.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagFloat.Text = "Add Float Tag"; + this._buttonAddTagFloat.Click += new System.EventHandler(this._buttonAddTagFloat_Click); + // + // _buttonAddTagDouble + // + this._buttonAddTagDouble.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagDouble.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagDouble.Image"))); + this._buttonAddTagDouble.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagDouble.Name = "_buttonAddTagDouble"; + this._buttonAddTagDouble.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagDouble.Text = "Add Double Tag"; + this._buttonAddTagDouble.Click += new System.EventHandler(this._buttonAddTagDouble_Click); + // + // _buttonAddTagByteArray + // + this._buttonAddTagByteArray.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagByteArray.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagByteArray.Image"))); + this._buttonAddTagByteArray.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagByteArray.Name = "_buttonAddTagByteArray"; + this._buttonAddTagByteArray.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagByteArray.Text = "Add Byte Array Tag"; + this._buttonAddTagByteArray.Click += new System.EventHandler(this._buttonAddTagByteArray_Click); + // + // _buttonAddTagString + // + this._buttonAddTagString.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagString.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagString.Image"))); + this._buttonAddTagString.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagString.Name = "_buttonAddTagString"; + this._buttonAddTagString.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagString.Text = "Add String Tag"; + this._buttonAddTagString.Click += new System.EventHandler(this._buttonAddTagString_Click); + // + // _buttonAddTagList + // + this._buttonAddTagList.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagList.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagList.Image"))); + this._buttonAddTagList.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagList.Name = "_buttonAddTagList"; + this._buttonAddTagList.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagList.Text = "Add List Tag"; + this._buttonAddTagList.Click += new System.EventHandler(this._buttonAddTagList_Click); + // + // _buttonAddTagCompound + // + this._buttonAddTagCompound.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonAddTagCompound.Image = ((System.Drawing.Image)(resources.GetObject("_buttonAddTagCompound.Image"))); + this._buttonAddTagCompound.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonAddTagCompound.Name = "_buttonAddTagCompound"; + this._buttonAddTagCompound.Size = new System.Drawing.Size(23, 22); + this._buttonAddTagCompound.Text = "Add Compound Tag"; + this._buttonAddTagCompound.Click += new System.EventHandler(this._buttonAddTagCompound_Click); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(6, 25); + // + // _buttonFindNext + // + this._buttonFindNext.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this._buttonFindNext.Image = global::NBTExplorer.Properties.Resources.binocular__arrow; + this._buttonFindNext.ImageTransparentColor = System.Drawing.Color.Magenta; + this._buttonFindNext.Name = "_buttonFindNext"; + this._buttonFindNext.Size = new System.Drawing.Size(23, 22); + this._buttonFindNext.Text = "Find / Find Next"; + this._buttonFindNext.Click += new System.EventHandler(this._buttonFindNext_Click); + // + // _nodeContainerContext + // + this._nodeContainerContext.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.openSubTreeToolStripMenuItem, + this.saveItemToolStripMenuItem}); + this._nodeContainerContext.Name = "contextMenuStrip1"; + this._nodeContainerContext.Size = new System.Drawing.Size(180, 48); + // + // openSubTreeToolStripMenuItem + // + this.openSubTreeToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.folder_open; + this.openSubTreeToolStripMenuItem.Name = "openSubTreeToolStripMenuItem"; + this.openSubTreeToolStripMenuItem.Size = new System.Drawing.Size(179, 22); + this.openSubTreeToolStripMenuItem.Text = "Open Node As Root"; + // + // saveItemToolStripMenuItem + // + this.saveItemToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.disk; + this.saveItemToolStripMenuItem.Name = "saveItemToolStripMenuItem"; + this.saveItemToolStripMenuItem.Size = new System.Drawing.Size(179, 22); + this.saveItemToolStripMenuItem.Text = "Save Node"; + // + // findEntityChunkToolStripMenuItem + // + this.findEntityChunkToolStripMenuItem.Name = "findEntityChunkToolStripMenuItem"; + this.findEntityChunkToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.findEntityChunkToolStripMenuItem.Text = "Find Entity Chunk"; + this.findEntityChunkToolStripMenuItem.Click += new System.EventHandler(this.findEntityChunkToolStripMenuItem_Click); + // + // Form1 + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(562, 400); + this.Controls.Add(this.toolStripContainer1); + this.Controls.Add(this.menuStrip1); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MainMenuStrip = this.menuStrip1; + this.Name = "Form1"; + this.Text = "NBTExplorer"; + this.menuStrip1.ResumeLayout(false); + this.menuStrip1.PerformLayout(); + this.toolStripContainer1.ContentPanel.ResumeLayout(false); + this.toolStripContainer1.ContentPanel.PerformLayout(); + this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false); + this.toolStripContainer1.TopToolStripPanel.PerformLayout(); + this.toolStripContainer1.ResumeLayout(false); + this.toolStripContainer1.PerformLayout(); + this.statusStrip1.ResumeLayout(false); + this.statusStrip1.PerformLayout(); + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this._nodeContainerContext.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + } #endregion @@ -587,7 +596,8 @@ private void InitializeComponent () private System.Windows.Forms.StatusStrip statusStrip1; private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; private System.Windows.Forms.ToolStripButton _buttonOpenFolder; - private System.Windows.Forms.ToolStripMenuItem openMinecraftSaveFolderToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem openMinecraftSaveFolderToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem findEntityChunkToolStripMenuItem; } } diff --git a/Form1.cs b/Form1.cs index 4de88f1..7579b2a 100644 --- a/Form1.cs +++ b/Form1.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; +using System.Diagnostics; +using System.IO; +using System.Linq; using System.Windows.Forms; using Substrate; -using Substrate.Nbt; -using System.IO; using Substrate.Core; -using System.Diagnostics; +using Substrate.Nbt; namespace NBTExplorer { @@ -79,7 +76,7 @@ private TreeNode NodeFromTag(TagNode tag, string name) node.ImageIndex = _tagIconIndex[tag.GetTagType()]; node.SelectedImageIndex = _tagIconIndex[tag.GetTagType()]; node.Tag = tag; - node.Text = GetNodeText(name, tag); + node.Text =SubstrateHelper. GetNodeText(name, tag); if (tag.GetTagType() == TagType.TAG_LIST) { @@ -93,51 +90,9 @@ private TreeNode NodeFromTag(TagNode tag, string name) return node; } - private string GetTagNodeText(TagNode tag) - { - if (tag == null) - return null; - - switch (tag.GetTagType()) - { - case TagType.TAG_BYTE: - case TagType.TAG_SHORT: - case TagType.TAG_INT: - case TagType.TAG_LONG: - case TagType.TAG_FLOAT: - case TagType.TAG_DOUBLE: - case TagType.TAG_STRING: - return tag.ToString(); - - case TagType.TAG_BYTE_ARRAY: - return tag.ToTagByteArray().Length + " bytes"; - - case TagType.TAG_LIST: - return tag.ToTagList().Count + " entries"; - - case TagType.TAG_COMPOUND: - return tag.ToTagCompound().Count + " entries"; - } - - return null; - } - - private string GetNodeText(string name, string value) - { - name = String.IsNullOrEmpty(name) ? "" : name + ": "; - value = value ?? ""; - - return name + value; - } - - private string GetNodeText(string name, TagNode tag) - { - return GetNodeText(name, GetTagNodeText(tag)); - } - private string GetNodeText(TreeNode node) { - return GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); + return SubstrateHelper.GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); } private string GetTagNodeText(TreeNode node) @@ -146,7 +101,7 @@ private string GetTagNodeText(TreeNode node) if (tag == null) return null; - return GetTagNodeText(tag); + return SubstrateHelper. GetTagNodeText(tag); } private void PopulateNodeFromTag(TreeNode parentNode, TagNodeList list) @@ -154,23 +109,28 @@ private void PopulateNodeFromTag(TreeNode parentNode, TagNodeList list) foreach (TagNode tag in list) { var node = NodeFromTag(tag); - if (parentNode.Text.StartsWith("Inventory")) + if (parentNode.Text.StartsWith("Inventory")|| parentNode.Text.StartsWith("Item")) { + Debug.Assert(tag.IsCastableTo(TagType.TAG_COMPOUND)); - var tagc = tag as TagNodeCompound; - if (tagc.ContainsKey("id")) + var item = UIHelper.TryGetItemName(tag); + + if (item != null) { - int id; - if (int.TryParse(tagc["id"].ToString(), out id)) - { - var item = Substrate.ItemInfo.ItemTable[id]; - if (item != null) - node.Nodes.Insert(0, item.Name); + + TreeNode newNode = new TreeNode(); - } + //node.ImageIndex = _tagIconIndex[0]; + //node.SelectedImageIndex = _tagIconIndex[0]; + newNode.Text = item.Name; + newNode.ToolTipText = "StackSize:" + item.StackSize.ToString(); + node.Nodes.Insert(0, newNode); } + + + } @@ -194,30 +154,14 @@ private void PopulateNodeFromTag(TreeNode node, TagNodeCompound dict) } } - public void LoadWorld(string path) - { - NbtWorld world = NbtWorld.Open(path); - - BetaWorld beta = world as BetaWorld; - if (beta != null) - { - LoadBetaWorld(beta); - } - } - - private void LoadBetaWorld(BetaWorld world) - { - RegionManager rm = world.GetRegionManager(); - } - - public void LoadRegion(TreeNodeCollection parent, string path) + void LoadRegion(TreeNodeCollection parent, string path) { TreeNode root = new TreeNode(Path.GetFileName(path), 11, 11); LoadRegion(root, path); parent.Add(root); } - public void LoadRegion(TreeNode node, string path) + void LoadRegion(TreeNode node, string path) { RegionFile rf = new RegionFile(path); @@ -235,7 +179,7 @@ public void LoadRegion(TreeNode node, string path) } } - public TreeNode CreateLazyChunk(RegionFile rf, int x, int z) + TreeNode CreateLazyChunk(RegionFile rf, int x, int z) { TreeNode node = new TreeNode(); node.ImageIndex = 9; @@ -247,7 +191,7 @@ public TreeNode CreateLazyChunk(RegionFile rf, int x, int z) return node; } - public TreeNode CreateLazyRegion(string path) + TreeNode CreateLazyRegion(string path) { TreeNode node = new TreeNode(); node.ImageIndex = 11; @@ -259,7 +203,7 @@ public TreeNode CreateLazyRegion(string path) return node; } - public TreeNode CreateLazyNbt(string path, CompressionType cztype) + TreeNode CreateLazyNbt(string path, CompressionType cztype) { TreeNode node = new TreeNode(); node.ImageIndex = 12; @@ -271,7 +215,7 @@ public TreeNode CreateLazyNbt(string path, CompressionType cztype) return node; } - public TreeNode CreateLazyDirectory(string path) + TreeNode CreateLazyDirectory(string path) { TreeNode node = new TreeNode(); node.ImageIndex = 10; @@ -283,7 +227,7 @@ public TreeNode CreateLazyDirectory(string path) return node; } - public TreeNode CreateLazyDirectory(string path, TreeNode parent) + TreeNode CreateLazyDirectory(string path, TreeNode parent) { TreeNode node = CreateLazyDirectory(path); LinkDataNodeParent(node, parent); @@ -291,7 +235,7 @@ public TreeNode CreateLazyDirectory(string path, TreeNode parent) return node; } - public TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode parent) + TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode parent) { TreeNode node = CreateLazyNbt(path, cztype); LinkDataNodeParent(node, parent); @@ -299,7 +243,7 @@ public TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode pare return node; } - private void LinkDataNodeParent(TreeNode node, TreeNode parent) + void LinkDataNodeParent(TreeNode node, TreeNode parent) { if (node != null && parent != null && node.Tag != null && parent.Tag != null) { @@ -313,7 +257,7 @@ private void LinkDataNodeParent(TreeNode node, TreeNode parent) } } - public void LoadLazyChunk(TreeNode node) + void LoadLazyChunk(TreeNode node) { RegionChunkData data = node.Tag as RegionChunkData; if (data == null || data.Modified) @@ -325,7 +269,7 @@ public void LoadLazyChunk(TreeNode node) data.Expanded = true; } - public void LoadLazyNbt(TreeNode node) + void LoadLazyNbt(TreeNode node) { NbtFileData data = node.Tag as NbtFileData; if (data == null || data.Modified) @@ -339,7 +283,7 @@ public void LoadLazyNbt(TreeNode node) data.Expanded = true; } - public void LoadLazyDirectory(TreeNode node) + void LoadLazyDirectory(TreeNode node) { DirectoryData data = node.Tag as DirectoryData; if (data == null || data.Modified) @@ -360,7 +304,7 @@ public void LoadLazyDirectory(TreeNode node) data.Expanded = true; } - public void LoadLazyRegion(TreeNode node) + void LoadLazyRegion(TreeNode node) { RegionData data = node.Tag as RegionData; if (data == null || data.Modified) @@ -372,7 +316,7 @@ public void LoadLazyRegion(TreeNode node) data.Expanded = true; } - public void UnloadLazyDataNode(TreeNode node) + void UnloadLazyDataNode(TreeNode node) { DataNode data = node.Tag as DataNode; if (data == null || data.Modified) @@ -384,7 +328,7 @@ public void UnloadLazyDataNode(TreeNode node) data.Expanded = false; } - private void ExpandNode(TreeNode node) + void ExpandNode(TreeNode node) { if (node.Tag == null) return; @@ -413,7 +357,7 @@ private void ExpandNode(TreeNode node) } } - private void CollapseNode(TreeNode node) + void CollapseNode(TreeNode node) { if (node.Tag == null) return; @@ -424,7 +368,7 @@ private void CollapseNode(TreeNode node) } } - private void NodeExpand(object sender, TreeViewCancelEventArgs e) + void NodeExpand(object sender, TreeViewCancelEventArgs e) { ExpandNode(e.Node); } @@ -434,7 +378,7 @@ private void NodeCollapse(object sender, TreeViewEventArgs e) CollapseNode(e.Node); } - private void NodeSelected(object sender, TreeViewEventArgs e) + void NodeSelected(object sender, TreeViewEventArgs e) { UpdateToolbar(); } @@ -444,12 +388,12 @@ private void NodeClicked(object sender, TreeNodeMouseClickEventArgs e) } - private void NodeDoubleClicked(object sender, TreeNodeMouseClickEventArgs e) + void NodeDoubleClicked(object sender, TreeNodeMouseClickEventArgs e) { EditNodeValue(_nodeTree.SelectedNode); } - private void UpdateToolbar() + void UpdateToolbar() { TreeNode node = _nodeTree.SelectedNode; TagNode tag = node.Tag as TagNode; @@ -514,21 +458,21 @@ private void UpdateToolbar() } } - private void SetTagButtons(bool state) + void SetTagButtons(bool state) { - _buttonAddTagByte.Enabled = state; - _buttonAddTagShort.Enabled = state; - _buttonAddTagInt.Enabled = state; - _buttonAddTagLong.Enabled = state; - _buttonAddTagFloat.Enabled = state; - _buttonAddTagDouble.Enabled = state; - _buttonAddTagByteArray.Enabled = state; - _buttonAddTagString.Enabled = state; - _buttonAddTagList.Enabled = state; - _buttonAddTagCompound.Enabled = state; + var toEnable = new[] + { + _buttonAddTagByte, _buttonAddTagShort, _buttonAddTagInt, + _buttonAddTagLong,_buttonAddTagFloat, _buttonAddTagDouble, + _buttonAddTagByteArray, _buttonAddTagString, _buttonAddTagList, + _buttonAddTagCompound + }; + foreach (var button in toEnable) + button.Enabled = state; + } - public void OpenDirectory(string path) + void OpenDirectory(string path) { _nodeTree.Nodes.Clear(); @@ -540,7 +484,7 @@ public void OpenDirectory(string path) } } - public void OpenPaths(string[] paths) + void OpenPaths(string[] paths) { _nodeTree.Nodes.Clear(); @@ -562,7 +506,7 @@ public void OpenPaths(string[] paths) } } - public void OpenMinecraftDir() + void OpenMinecraftDir() { string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); path = Path.Combine(path, ".minecraft"); @@ -576,17 +520,17 @@ public void OpenMinecraftDir() OpenDirectory(path); } - public void LoadDirectory(string path) + void LoadDirectory(string path) { LoadDirectory(path, _nodeTree.Nodes); } - public void LoadDirectory(string path, TreeNodeCollection parent) + void LoadDirectory(string path, TreeNodeCollection parent) { LoadDirectory(path, parent, path); } - public void LoadDirectory(string path, TreeNodeCollection parent, string name) + void LoadDirectory(string path, TreeNodeCollection parent, string name) { TreeNode root = new TreeNode(name, 10, 10); @@ -603,7 +547,7 @@ public void LoadDirectory(string path, TreeNodeCollection parent, string name) parent.Add(root); } - public void TryLoadFile(TreeNodeCollection parent, string path) + void TryLoadFile(TreeNodeCollection parent, string path) { if (Path.GetExtension(path) == ".mcr") { @@ -656,7 +600,7 @@ static Form1() _tagIconIndex[TagType.TAG_COMPOUND] = 9; } - private void OpenFile() + void OpenFile() { OpenFileDialog ofd = new OpenFileDialog(); ofd.RestoreDirectory = true; @@ -668,14 +612,14 @@ private void OpenFile() } } - private void OpenFile(string file) + void OpenFile(string file) { _nodeTree.Nodes.Clear(); TryLoadFile(_nodeTree.Nodes, file); } - private string _openFolderPath = null; - private void OpenFolder() + string _openFolderPath = null; + void OpenFolder() { FolderBrowserDialog ofd = new FolderBrowserDialog(); if (_openFolderPath != null) @@ -688,7 +632,7 @@ private void OpenFolder() } } - private void SaveAll() + void SaveAll() { foreach (TreeNode node in _nodeTree.Nodes) { @@ -696,7 +640,7 @@ private void SaveAll() } } - private void SaveNode(TreeNode node) + void SaveNode(TreeNode node) { foreach (TreeNode sub in node.Nodes) { @@ -716,7 +660,7 @@ private void SaveNode(TreeNode node) } } - private void SaveNbtFileNode(TreeNode node) + void SaveNbtFileNode(TreeNode node) { NbtFileData data = node.Tag as NbtFileData; if (data == null || !data.Modified) @@ -730,7 +674,7 @@ private void SaveNbtFileNode(TreeNode node) data.Modified = false; } - private void SaveRegionChunkNode(TreeNode node) + void SaveRegionChunkNode(TreeNode node) { RegionChunkData data = node.Tag as RegionChunkData; if (data == null || !data.Modified) @@ -743,12 +687,12 @@ private void SaveRegionChunkNode(TreeNode node) data.Modified = false; } - private void aboutToolStripMenuItem_Click(object sender, EventArgs e) + void aboutToolStripMenuItem_Click(object sender, EventArgs e) { new About().Show(); } - private void openToolStripMenuItem_Click(object sender, EventArgs e) + void openToolStripMenuItem_Click(object sender, EventArgs e) { OpenFile(); } @@ -758,12 +702,12 @@ private void openFolderToolStripMenuItem_Click(object sender, EventArgs e) OpenFolder(); } - private void toolStripButton1_Click(object sender, EventArgs e) + void toolStripButton1_Click(object sender, EventArgs e) { OpenFile(); } - private TreeNode BaseNode(TreeNode node) + TreeNode BaseNode(TreeNode node) { if (node == null) return null; @@ -779,7 +723,7 @@ private TreeNode BaseNode(TreeNode node) #region Tag Deletion - private void DeleteNode(TreeNode node) + void DeleteNode(TreeNode node) { TreeNode baseNode = BaseNode(node); @@ -799,12 +743,12 @@ private void DeleteNode(TreeNode node) node.Remove(); } - private void _buttonDelete_Click(object sender, EventArgs e) + void _buttonDelete_Click(object sender, EventArgs e) { DeleteNode(_nodeTree.SelectedNode); } - private void DeleteNodeNbtTag(TreeNode node) + void DeleteNodeNbtTag(TreeNode node) { TagNode tag = node.Tag as TagNode; if (tag == null) @@ -834,7 +778,7 @@ private void DeleteNodeNbtTag(TreeNode node) } } - private void DeleteTagFromCompound(TagNodeCompound parent, TagNode target) + void DeleteTagFromCompound(TagNodeCompound parent, TagNode target) { string match = ""; foreach (KeyValuePair kv in parent) @@ -854,12 +798,12 @@ private void DeleteTagFromCompound(TagNodeCompound parent, TagNode target) #endregion - private void _buttonSave_Click(object sender, EventArgs e) + void _buttonSave_Click(object sender, EventArgs e) { SaveAll(); } - private TagNode GetTagNode(TreeNode node) + TagNode GetTagNode(TreeNode node) { if (node == null) return null; @@ -880,7 +824,7 @@ private TagNode GetTagNode(TreeNode node) return null; } - private TagNode GetParentTagNode(TreeNode node) + TagNode GetParentTagNode(TreeNode node) { if (GetTagNode(node) == null) return null; @@ -888,7 +832,7 @@ private TagNode GetParentTagNode(TreeNode node) return GetTagNode(node.Parent); } - private string GetTagNodeName(TreeNode node) + string GetTagNodeName(TreeNode node) { TagNode tag = GetTagNode(node); if (tag == null) @@ -910,7 +854,7 @@ private string GetTagNodeName(TreeNode node) return null; } - private bool SetTagNodeName(TreeNode node, string name) + bool SetTagNodeName(TreeNode node, string name) { TagNode tag = GetTagNode(node); if (tag == null) @@ -942,7 +886,7 @@ private bool SetTagNodeName(TreeNode node, string name) return true; } - private void EditNodeValue(TreeNode node) + void EditNodeValue(TreeNode node) { if (node == null) return; @@ -969,12 +913,12 @@ private void EditNodeValue(TreeNode node) } } - private void _buttonEdit_Click(object sender, EventArgs e) + void _buttonEdit_Click(object sender, EventArgs e) { EditNodeValue(_nodeTree.SelectedNode); } - private void EditNodeName(TreeNode node) + void EditNodeName(TreeNode node) { if (node == null) return; @@ -1008,12 +952,12 @@ private void EditNodeName(TreeNode node) } } - private void _buttonRename_Click(object sender, EventArgs e) + void _buttonRename_Click(object sender, EventArgs e) { EditNodeName(_nodeTree.SelectedNode); } - private void AddTagToNode(TreeNode node, TagType type) + void AddTagToNode(TreeNode node, TagType type) { TagNode tag = GetTagNode(node); if (tag == null) @@ -1108,17 +1052,17 @@ private void AddTagToNode(TreeNode node, TagType type) } } - private void _buttonAddTagByte_Click(object sender, EventArgs e) + void _buttonAddTagByte_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE); } - private void _buttonAddTagShort_Click(object sender, EventArgs e) + void _buttonAddTagShort_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_SHORT); } - private void _buttonAddTagInt_Click(object sender, EventArgs e) + void _buttonAddTagInt_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_INT); } @@ -1128,52 +1072,52 @@ private void _buttonAddTagLong_Click(object sender, EventArgs e) AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LONG); } - private void _buttonAddTagFloat_Click(object sender, EventArgs e) + void _buttonAddTagFloat_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_FLOAT); } - private void _buttonAddTagDouble_Click(object sender, EventArgs e) + void _buttonAddTagDouble_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_DOUBLE); } - private void _buttonAddTagByteArray_Click(object sender, EventArgs e) + void _buttonAddTagByteArray_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE_ARRAY); } - private void _buttonAddTagString_Click(object sender, EventArgs e) + void _buttonAddTagString_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_STRING); } - private void _buttonAddTagList_Click(object sender, EventArgs e) + void _buttonAddTagList_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LIST); } - private void _buttonAddTagCompound_Click(object sender, EventArgs e) + void _buttonAddTagCompound_Click(object sender, EventArgs e) { AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_COMPOUND); } - private void saveToolStripMenuItem_Click(object sender, EventArgs e) + void saveToolStripMenuItem_Click(object sender, EventArgs e) { SaveAll(); } - private void exitToolStripMenuItem_Click(object sender, EventArgs e) + void exitToolStripMenuItem_Click(object sender, EventArgs e) { Application.Exit(); } - private TreeNode _rootSearchNode; - private string _searchName; - private string _searchValue; - private IEnumerator _search; + TreeNode _rootSearchNode; + string _searchName; + string _searchValue; + IEnumerator _search; - private void Find(TreeNode node) + void Find(TreeNode node) { if (node == null) return; @@ -1192,12 +1136,13 @@ private void Find(TreeNode node) } } - private void FindNext() + void FindNext() { if (_search == null) return; statusStrip1.Visible = true; + statusStrip1.Text = "Please wait..."; Application.DoEvents(); _nodeTree.SelectedNode = null; @@ -1222,7 +1167,7 @@ private void FindNext() statusStrip1.Visible = false; } - private IEnumerable FindNode(TreeNode node) + IEnumerable FindNode(TreeNode node) { if (node == null) yield break; @@ -1279,17 +1224,17 @@ private IEnumerable FindNode(TreeNode node) } } - private void findToolStripMenuItem_Click(object sender, EventArgs e) + void findToolStripMenuItem_Click(object sender, EventArgs e) { Find(_nodeTree.SelectedNode); } - private void findNextToolStripMenuItem_Click(object sender, EventArgs e) + void findNextToolStripMenuItem_Click(object sender, EventArgs e) { FindNext(); } - private void _buttonFindNext_Click(object sender, EventArgs e) + void _buttonFindNext_Click(object sender, EventArgs e) { if (_search == null) Find(_nodeTree.SelectedNode); @@ -1297,179 +1242,114 @@ private void _buttonFindNext_Click(object sender, EventArgs e) FindNext(); } - private void _buttonOpenFolder_Click(object sender, EventArgs e) + void _buttonOpenFolder_Click(object sender, EventArgs e) { OpenFolder(); } - private void DropFile(DragEventArgs e) + void DropFile(DragEventArgs e) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); OpenPaths(files); } - private void _nodeTree_DragDrop(object sender, DragEventArgs e) + void _nodeTree_DragDrop(object sender, DragEventArgs e) { DropFile(e); } - private void _nodeTree_DragEnter(object sender, DragEventArgs e) + void _nodeTree_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy; } - private void openMinecraftSaveFolderToolStripMenuItem_Click(object sender, EventArgs e) + void openMinecraftSaveFolderToolStripMenuItem_Click(object sender, EventArgs e) { OpenMinecraftDir(); } - } - public class TagKey : IComparable - { - public TagKey(string name, TagType type) + IEnumerable FindChunks(IEnumerable nodes) { - Name = name; - TagType = type; + foreach (var region in nodes) + foreach (var chunk in region.Nodes.Cast().Where(c => c.Text.StartsWith("Chunk"))) + { + yield return chunk; + } } - public string Name { get; set; } - public TagType TagType { get; set; } - - #region IComparer Members - - public int Compare(TagKey x, TagKey y) + int _nodesSearched = 0; + bool NeedsExpand(TreeNode node) { - int typeDiff = (int)x.TagType - (int)y.TagType; - if (typeDiff != 0) - return typeDiff; + return node.Tag is DataNode && (node.Tag as DataNode).Expanded == false; - return String.Compare(x.Name, y.Name, true); } - - #endregion - - #region IComparable Members - - public int CompareTo(TagKey other) + IEnumerable FindRegions(IEnumerable nodes, Func predicate) { - return Compare(this, other); - } - #endregion - } - public class DataNode - { - public DataNode() - { - } + foreach (var node in nodes) + { + _nodesSearched++; + if (NeedsExpand(node)) + ExpandNode(node); + if (predicate(node)) + yield return node; + else + foreach (var region in FindRegions(node.Nodes.Cast(),predicate)) + { + yield return region; + } + } - public DataNode(DataNode parent) - { - Parent = parent; - } - public DataNode Parent { get; set; } + } - private bool _modified; - public bool Modified + void findEntityChunkToolStripMenuItem_Click(object sender, EventArgs e) { - get { return _modified; } - set + _nodesSearched = 0; + var entityNodes = FindRegions(_nodeTree.Nodes.Cast(),tn=>tn.Text.EndsWith(".mcr")); + var entityRegions = entityNodes.ToArray(); + try { - if (value && Parent != null) + if (entityRegions == null || entityRegions.Any() == false) { - Parent.Modified = value; + return; } - _modified = value; + var chunks = FindChunks(entityRegions); + if (chunks == null || chunks.Any() == false) + return; + var populatedChunks = FindChunksWithEntities(chunks); + if (populatedChunks == null || populatedChunks.Any() == false) + return; + _nodeTree.SelectedNode = populatedChunks.First(); } + finally + { + toolStrip1.Text = "Searched " + _nodesSearched + " nodes"; + toolStrip1.Visible = true; + } + } - public bool Expanded { get; set; } - } - - public class NbtDataNode : DataNode - { - public NbtDataNode() - { - } - - public NbtDataNode(DataNode parent) - : base(parent) - { - } - - public NbtTree Tree { get; set; } - } - - public class RegionChunkData : NbtDataNode - { - public RegionChunkData(RegionFile file, int x, int z) - : this(null, file, x, z) - { - } - - public RegionChunkData(DataNode parent, RegionFile file, int x, int z) - : base(parent) - { - Region = file; - X = x; - Z = z; - } - - public RegionFile Region { get; private set; } - public int X { get; private set; } - public int Z { get; private set; } - } - - public class RegionData : DataNode - { - public RegionData(string path) - : this(null, path) - { - } - - public RegionData(DataNode parent, string path) - : base(parent) - { - Path = path; - } - - public string Path { get; private set; } - } - - public class NbtFileData : NbtDataNode - { - public NbtFileData(string path, CompressionType cztype) - : this(null, path, cztype) - { - } - - public NbtFileData(DataNode parent, string path, CompressionType cztype) - : base(parent) - { - Path = path; - CompressionType = cztype; - } - - public string Path { get; private set; } - public CompressionType CompressionType { get; private set; } - } - - public class DirectoryData : DataNode - { - public DirectoryData(string path) - : this(null, path) - { - } - - public DirectoryData(DataNode parent, string path) - : base(parent) + IEnumerable FindChunksWithEntities(IEnumerable chunks) { - Path = path; + foreach (var chunk in chunks) + { + if (NeedsExpand(chunk)) + ExpandNode(chunk); + var level = chunk.Nodes.Cast().FirstOrDefault(n => n.Text.StartsWith("Level")); + if (level == null) + continue; + var entityNode = level.Nodes.Cast().FirstOrDefault(n => n.Text.StartsWith("Entities")); + if (entityNode == null) + continue; + var text = entityNode.Text.Where(c => char.IsNumber(c)).Select(c=>c.ToString()).Aggregate((c1,c2)=>c1+c2); + + var entityCount = int.Parse(text); + if (entityCount > 0) + yield return chunk; + } } - - public string Path { get; private set; } } } diff --git a/Form1.resx b/Form1.resx index 80c9a63..e12af37 100644 --- a/Form1.resx +++ b/Form1.resx @@ -1,827 +1,827 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 527, 17 - - - 237, 17 - - - - AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w - LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADW - LgAAAk1TRnQBSQFMAgEBDgEAAaABAAGgAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA - AwABQAMAAQEBAAEYBgABMBIAA/wD+SH4A/kD/AMAA/0D+SH4A/kD/WMAAZYBqQG8AVwBhAGuAVwBhAGu - AVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGu - AVwBhAGuAZYBqQG8AwACzwHLArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5 - AbACuQGwArkBsALPActjAAFsAZMBugFVAYgBuwFwAaMB1gFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFn - AZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFwAaMB1gFVAYgBuwFsAZMBugMAAsEBuQL5AekC8wHi - AvMB4gLzAeIC8wHiAvMB4gLzAeIC8wHiAvMB4gLzAeIC8wHiAvMB4gL5AekCwQG5YwABfgGiAccBcQGk - AdcBVQGIAbsBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGk - AdcBVQGIAbsBcQGkAdcBfgGiAccDAALLAcMC9AHkAXoBpwGbAYcBtwGnAYcBtQGjAYkBswGiAWgBoAGG - AVcBlwF4AVgBkwF5AWgBkAF+AZIBpAGTAYYBlwGAAqgBjgL0AeQCywHDYwABhgGqAc0BcwGmAdkBagGd - AdABSAF7Aa4BXwGSAcUBTAF/AbIBXwGSAcUBTAF/AbIBXwGSAcUBTAF/AbIBXwGSAcUBSAF7Aa4BagGd - AdABcwGmAdkBhgGqAc0DAALPAccC9QHmAYQBtQGrAZgB1wHHAZAB0QG+AXMBsAGZAZcBywG2AacBzgG9 - AZcBvQGsAZQBugGoAakBvwGvAY4BrQGhAbcBrQGLAvUB5gLPAcdjAAGLAa0BzwF1AagB2wFsAZ8B0gFK - AX0BsAFsAZ8B0gFSAYUBuAFsAZ8B0gFSAYUBuAFsAZ8B0gFSAYUBuAFsAZ8B0gFKAX0BsAFsAZ8B0gF1 - AagB2wGLAa0BzwMAAtEByQL2AekBkAG8AbUBuQHlAdsBpgHdAdABiAHAAbIBhwHJAbUBfgG+AaQBiAG5 - AaMBrgHQAb8BqQHHAbUBlAG6AagBtgG1AZEC9gHpAtEByWMAAY8BsQHSAXcBqgHdAW4BoQHUAUcBegGt - AW4BoQHUAU8BggG1AW4BoQHUAU8BggG1AW4BoQHUAU8BggG1AW4BoQHUAUcBegGtAW4BoQHUAXcBqgHd - AY8BsQHSAwAC0wHMAvcB6wHFAbgBhwH/Ad4BjAH4AecBrQHVAdEBsAHKAesB4gG9AeUB2QGgAcoBuwGq - Ac4BrwGCAcEBpAF+AbYCmAGsAYQC9wHrAtMBzGMAAZMBtAHUAXgBqwHeAW8BogHVAUQBdwGqAW8BogHV - AUwBfwGyAW8BogHVAUwBfwGyAW8BogHVAUwBfwGyAW8BogHVAUQBdwGqAW8BogHVAXgBqwHeAZMBtAHU - AwAC1QHNAvgB7gHRAa4BaQHbAboBcQHeAb4BdAHpAckBfAG/Ac0BqAGVAcwBwgGhAc8BvgGRAcQBrwF/ - Ab0BpgF3AbcBnQGoAaoBdwL4Ae4C1QHNYwABmAG4AdcBegGtAeABcQGkAdcBQQF0AacBcQGkAdcBSQF8 - Aa8BcQGkAdcBSQF8Aa8BcQGkAdcBSQF8Aa8BcQGkAdcBQQF0AacBcQGkAdcBegGtAeABmAG4AdcDAALX - Ac8C+QHxAdMBrAFmAf8B0wF+Af8B1gGCAeABvgF0AfYB4QGZAbAB7QHkAa8B0QG/AaIB4AHTAZgB2AHG - AY4B0AG6AbgBsgGAAvkB8QLXAc9jAAGbAboB2QF8Aa8B4gFzAaYB2QE/AXIBpQFzAaYB2QFHAXoBrQFz - AaYB2QFHAXoBrQFzAaYB2QFHAXoBrQFzAaYB2QE/AXIBpQFzAaYB2QF8Aa8B4gGbAboB2QMAAtkB0QL7 - AfQB1QGpAWIB/wHOAXkB/wHSAX0B3wG6AW8B/wHYAYMB5gHqAb0BpgHYAc0BswHsAeIBuQHkAdABtgHc - AcQBqwG+AZcC+wH0AtkB0WMAAZ0BvQHbAX4BsQHkAXUBqAHbATgBawGeAVEBhAG3ATgBawGeAVEBhAG3 - ATgBawGeAVEBhAG3ATgBawGeAVEBhAG3ATgBawGeAXUBqAHbAX4BsQHkAZ0BvQHbAwAC2gHTAvwB9wHX - AacBXwHaAawBZAHcAbABZwHnAbwBcAHgAboBbwHjAb4BcwHfAdEBmAHbAc8BlgHVAdEBnAHEAc0BpAGd - AdEBwwL8AfcC2gHTYwABoAG+AdwBfwGyAeUBZgGZAcwBdgGpAdwBdgGpAdwBdgGpAdwBdgGpAdwBdgGp - AdwBdgGpAdwBdgGpAdwBdgGpAdwBdgGpAdwBZgGZAcwBfwGyAeUBoAG+AdwDAALbAdQC/QH5AdkBpAFc - Af8BxAFvAf8ByAFzAd4BsAFnAf8BzgF5Af8B0gF9AeQBvgFyAf8B2AGDAe0B5AGoAeIB5gG2AdAB1wGt - Av0B+QLbAdRjAAGjAcAB3gFrAZ4B0QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3 - AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QFrAZ4B0QGjAcAB3gMAAt0B1QL+AfwB2gGjAVoB/wG/ - AWsB/wHCAW4B3gGsAWIB/wHJAXQB/wHNAXgB4wG5AW4B/wHTAX4B/wHXAYMB/AHeAZUB7AHKAXwC/gH8 - At0B1WMAAaYBwwHgAaAB0wH6AZgBywH1AZMBxgHzAZMBxgHzAZMBxgHzAZMBxgHzAZMBxgHzAZMBxgHz - AZMBxgHzAZMBxgHzAZMBxgHzAZgBywH1AaAB0wH6AaYBwwHgAwAC3gHXAv8B/gHbAaEBWAHbAaIBWQHb - AaQBWwHbAaUBXQHbAakBYAHbAawBYwHbAa8BZgHbAbEBaAHbAbQBawHbAbcBbgHbAbkBcQL/Af4C3gHX - YwAB6AHtAfMBqAHEAeEBlwHKAfUBkgHFAfMBkgHFAfMBkgHFAfMBkgHFAfMBkgHFAfMBkgHFAfMBkgHF - AfMBkgHFAfMBkgHFAfMBlwHKAfUBqAHEAeEB6AHtAfMDAALfAdkn/wLfAdlmAAHoAe0B8wGpAcUB4gGp - AcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gHo - Ae0B8wYAAuoB5gLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLg - AdkC6gHmwwAD+wPxAZUBrwG8AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2 - AWgBmwG2AWgBmwG2AWgBmwG2AZUBrwG8A/ED+xUAEvgD+QP9MwAD/AP5JPgD+QP8A/0D+gF3AagBwQGG - Ac8B8AGBAcsB7QGBAcsB7QGBAcsB7QGBAcsB7QGBAcsB7QGBAcsB7QGGAc8B8AFLAY8BsQGGAc8B8AF3 - AagBwQHcAeIB5Qb9A/kM+APzAYkBpQGPAVUBiwFfAVUBiwFfAVUBiwFfAVUBiwFfAVUBiwFfAVUBiwFf - AZQBrQGZBgADwAMsA8ADAAP7G/gD+wP3AZMBpgG6AWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGv - AWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGvAZMBpgG6A/cGAAGGAbUBzQGE - Ac4B7gF8AccB6AF8AccB6AF8AccB6AF8AccB6AF8AccB6AF8AccB6AGEAc4B7gFXAZsBvQGEAc4B7gH0 - AbYBLgGGAbUBzQMAApQBuAJVAaMCVQGjAlUBowJVAaMCVQGjAlUBowFVAXoBiQE1Ab0BeQFDAcsBhwE+ - AcYBggE+AcYBggE+AcYBggFDAcsBhwFVAaABcAYAA0ABZwJWA0ADAAP7A2EDXgNcA1kDVANJAzwDLwNs - A/sDAAFyAZgBvwF7Aa4B4AF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6 - Aa0B3wF6Aa0B3wF6Aa0B3wF7Aa4B4AFyAZgBvwkAAZEBvgHUAYcB0AHvAX8BygHpAX8BygHpAX8BygHp - AX8BygHpAX8BygHpAX8BygHpAYcB0AHvAV8BowHFAYcB0AHvAf4ByQFBAZEBvgHUAwACVQG0AS8BHgHc - ASUBEwHYASUBEwHYASUBEwHYASUBEwHYASUBEwHYAVUBfgGVATcBvwF7AUIBygGGATcBvwF7ATcBvwF7 - ATcBvwF7AUIBygGGAVUBpwF2BgADywNVA8snAAGEAacBywGBAbQB5AF9AbAB4QF9AbAB4QF9AbAB4QF9 - AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QGBAbQB5AGEAacBywkAAZQBwAHW - AYoB0wHwAYIBzQHrAYIBzQHrAYIBzQHrAYIBzQHrAYIBzQHrAYIBzQHrAYoB0wHwAWIBpgHIAYoB0wHw - AukB2wGUAcAB1gMAAlUBuQEtARwB3gEVAQAB1QEVAQAB1QEVAQAB1QEVAQAB1QEVAQAB1QFVAYEBmgE7 - AcMBfwFIAc8BjAE7AcMBfwE7AcMBfwE7AcMBfwFIAc8BjAFVAa0BezYAAYoBrQHPAYgBuwHqAYIBtQHl - AYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYgBuwHq - AYoBrQHPCQABmAHDAdgBjgHWAfIBhwHQAe0BhwHQAe0BhwHQAe0BhwHQAe0BhwHQAe0BhwHQAe0BjgHW - AfIBZgGqAcwBjgHWAfIC8AHmAZgBwwHYAwACVQG/ATYBJQHkARkBAAHbARkBAAHbARkBAAHbARkBAAHb - ARkBAAHbAVUBhAGgAT4BxgGCAU0B1QGRAT4BxgGCAT4BxgGCAT4BxgGCAU0B1QGRAVUBswGANgABjgGw - AdEBjwHCAe4BhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6 - AekBhwG6AekBjwHCAe4BjgGwAdEJAAGbAcYB2gGSAdoB9AGLAdQB8AGLAdQB8AGLAdQB8AGLAdQB8AGL - AdQB8AGLAdQB8AGSAdoB9AFpAa0BzwGSAdoB9AL4AfMBmwHGAdoDAAJVAcQBPgEtAewBHAEAAeMBHAEA - AeMBHAEAAeMBHAEAAeMBHAEAAeMBVQGGAaQBQgHKAYYBUQHZAZUBQgHKAYYBQgHKAYYBQgHKAYYBUQHZ - AZUBVQG5AYQGAAPQA2cD0CcAAZMBtAHUAZYByQHyAYwBvwHsAYwBvwHsAYwBvwHsAUQBdwGqAYwBvwHs - AUQBdwGqAYwBvwHsAYwBvwHsAYwBvwHsAYwBvwHsAZYByQHyAZMBtAHUCQABnwHIAd0BlwHeAfYBkAHY - AfIBkAHYAfIBkAHYAfIBkAHYAfIBkAHYAfIBkAHYAfIBlwHeAfYBeQG9AdwBeAG9AdwC/gH9AZ8ByAHd - AwACVQHIAUYBNQHyASABAAHpASABAAHpASABAAHpASABAAHpASABAAHpAVUBiQGoAUQBzAGIAWUB7QGp - AWUB7QGpAWUB7QGpAWUB7QGpAVgB1gGWAX8BywGkBgADbAFvAmkDbAYAA3UDdANxA24DbANoA2UDYwNg - BgABmAG4AdcBmwHOAfYBkQHEAfABkQHEAfABkQHEAfABVQGIAbsBRAF3AaoBVQGIAbsBQAFzAaYBkQHE - AfABkQHEAfABkQHEAfABmwHOAfYBmAG4AdcJAAGiAcoB3gGbAeEB9wGUAdsB9AGUAdsB9AGUAdsB9AGU - AdsB9AGUAdsB9AGUAdsB9AGUAdsB9AGeAeQB+QF8AcAB3gGiAcoB3gHuAfMB9QMAAn8B1QFiAWEB5wF2 - AXUB/gF2AXUB/gF5AWIBowF7AVABVQF7AVABVQFqAVkBPwFqAW4BMgFqAW4BMgFhAYsBUQFVAcEBigFV - AcEBigFVAcEBigHiAe8B6AYAA9MDcQPTJwABmwG6AdkBnwHSAfkBlQHIAfMBlQHIAfMBlQHIAfMBVQGI - AbsBVQGIAbsBVQGIAbsBTQGAAbMBlQHIAfMBlQHIAfMBlQHIAfMBnwHSAfkBmwG6AdkJAAGlAc0B4AGe - AeUB+QGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGhAegB+gGl - Ac0B4AYAAuIB8QJVAc4CVQHOAlUBzgFtAVMBdQHcAakBMgHXAaQBLQHXAaQBLQHXAaQBLQHcAakBMgGw - AYYBSEIAAZ8BvQHbAakB2wH+AaoB3QH/AaoB3QH/AaoB3QH/AXcBqgHdAXcBqgHdAXcBqgHdAWYBmQHM - AaoB3QH/AaoB3QH/AaoB3QH/AakB2wH+AZ8BvQHbCQABqAHOAeIBowHoAfsBnQHjAfkBnQHjAfkBnQHj - AfkBnQHjAfkBnQHjAfkBnQHjAfkBnQHjAfkBnQHjAfkBowHoAfsBqAHOAeISAAG2AYsBRQHcAakBMgHR - AZ4BJwHRAZ4BJwHRAZ4BJwHcAakBMgG2AYsBRUIAAccB1wHnAYgBtgHiAYABswHmAYABswHmAYABswHm - AU4BgQG0AU4BgQG0AU4BgQG0AUgBewGuAYABswHmAYABswHmAYABswHmAYgBtgHiAccB1wHnCQABqwHQ - AeMBpgHrAfwBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBpgHr - AfwBqwHQAeMSAAG7AZABQQHhAa4BOAHWAaMBLAHWAaMBLAHWAaMBLAHhAa4BOAG7AZABQRIAA9cDfQPX - JwAB4wHqAfEBjgG4AeEBiQG8Ae8BiAG7Ae4BiAG7Ae4BQQF0AacBQQF0AacBQQF0AacBPgFxAaQBiAG7 - Ae4BiAG7Ae4BiQG8Ae8BjgG4AeEB4wHqAfEJAAGuAdIB5AGpAe4B/QGkAekB/AGkAekB/AGkAekB/AGk - AekB/AGkAekB/AGkAekB/AGkAekB/AGkAekB/AGpAe4B/QGuAdIB5BIAAcABlQE/AecBtAE9AdoBpwEw - AdoBpwEwAdoBpwEwAecBtAE9AcABlQE/EgADfwN3A38GAAOCA4EDfwN+A3wDegN5A3YDqwYAAfUB9wH5 - AZsBvgHfAYkBvAHvAYgBuwHuAYgBuwHuATUBaAGbATUBaAGbATUBaAGbATUBaAGbAYgBuwHuAYgBuwHu - AYkBvAHvAZsBvgHfAfUB9wH5CQABsAHUAeYBrAHxAf8BpwHsAf4BpwHsAf4BpwHsAf4BpwHsAf4BpwHs - Af4BpwHsAf4BpwHsAf4BpwHsAf4BrAHxAf8BsAHUAeYSAAHGAZoBPQHrAbgBQQHdAaoBMwHdAaoBMwHd - AaoBMwHrAbgBQQHGAZoBPRIAA9gDggPYJwAD/gHLAdoB6gGpAcUB4gGpAcUB4gGpAcUB4gFVAX0BpgFV - AX0BpgFVAX0BpgFVAX0BpgGpAcUB4gGpAcUB4gGpAcUB4gHLAdoB6gP+CQABsgHVAeYBsQH1Af8BrgHy - Af8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BsQH1Af8BsgHVAeYSAAHU - AbMBbAHnAbgBRgH+AcsBVAH+AcsBVAH+AcsBVAHnAbgBRgHUAbMBbHUAAdAB5AHuAbMB1gHnAbMB1gHn - AbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAdAB5AHuEgAB8AHr - Ad4BzQGgATkBzQGgATkBzQGgATkBzQGgATkBzQGgATkB8AHrAd4PAAP7A/ECyAHDArgBsAK4AbACuAGw - ArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4 - AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8QP7YAAD/QP6AsABuAv/A/4B/QL+AfwC/QH7Av0B+gL8 - AfgC/gH5AsABuAP6Bv0D+gLAAbgL/wP+Af0C/gH8Av0B+wL9AfoC/AH4Av4B+QLAAbgD+gP9ZgACyQHB - Bv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7AvwB+QL7 - AfgC+gH2AvgB9AL7AfYCyQHBbAACzwHHA/8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL3AfIC+wH1 - As8BxwwAAs8BxwP/A/4C/QH8Av0B+wL8AfkC+wH4AvoB9gL4AfQC9wHyAvsB9QLPAccMAAP+A/wG+QP6 - BvwD+wb5A/wD/gYAA/0D/AP6HvgD+gP8A/0GAALQAcgC/wH+Av0B/AL9AfsBvwFIAa4B7AHOAeUC+gH2 - AvgB9AL3AfIC9gHwAvoB8wLQAcgMAALQAcgC/wH+Av0B/AHpAc8B6wGuAUgBvwGuAUgBvwGuAUgBvwHT - AaEB2gL3AfIC9gHwAvoB8wLQAcgMAAP+A/wD+QOzA1wG/ANcA7QD+QP8A/4GAAP9A4QDNAOEA/gD4gY0 - A4QD4gN1A6QD+AOEAzQD6QYAAtIBywL+A/0B+wL8AfkBxgFPAbUB7AHPAeUC+AH0AvcB8gL2AfAC9QHu - AvoB8gLSAcsMAALSAcsC/gP9AfsB6gHRAe0BtQFPAcYC+gH2AecBzgHoAbUBTwHGAe4B4QHrAvUB7gL6 - AfIC0gHLEgADywN1A/gGAAP4A3UDyxIAA3kD9QYAA6oDeQYAA8sDvgPuA6oDwgkAAtUBzQL+A/wB+QL7 - AfgBzgFXAb0BzgFXAb0BzgFXAb0B4gGmAdYC9QHuAvQB7AL5Ae8C1QHNDAAC1QHNAv4D/AH5AesB0gHt - Ab0BVwHOAvgB9AL3AfIBvQFXAc4B5wHNAeUC9AHsAvkB7wLVAc0PAAPOA38D+QwAA/kDfwPODwADxgxg - A8YGAAP1CWAD6QkAAtYBzgL9A/sB+AL6AfYB1gFfAcUB7wHRAeYC9gHwAvUB7gL0AewC8QHnAvcB6gLW - Ac4MAALWAc4C/QP7AfgB7AHTAe4BxQFfAdYC9wHyAeoB0QHqAcUBXwHWAe0B4QHpAvEB5wL3AeoC1gHO - DAAD0AOGA/kSAAP5A4YD0AwAA/UDlAPvA9EDaAP1CQADkwPvA2gMAALYAdAC/QP6AfYC+AH0AdwBZQHL - AdwBZQHLAdwBZQHLAeIBiQHTAvEB5wLsAd8C9AHlAtgB0AwAAtgB0AL9A/oB9gHtAdMB7gHLAWUB3AHL - AWUB3AHLAWUB3AHfAawB4wLxAecC7AHfAvQB5QLYAdAJAAPvA2wD7xgAA+8DbAPvDAADjwP2A7cDjwwA - A8wDfQPMDAAC2gHSAvwD+AH0AvcB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLzAeIC2gHSDAAC2gHS - AvwD+AH0AvcB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLzAeIC2gHSDAAD1AORA/kSAAP5A5ED1A8A - A84D1QN3A84MAAPsA3cD7AwAAtsB0wL8A/cB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC8gHh - AtsB0wwAAtsB0wL8A/cB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC8gHhAtsB0w8AA9UDlgP5 - DAAD+QOWA9USAAP2A6IDfgP2IQAC3AHVAvsD9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1ALy - AeEC3AHVDAAC3AHVAvsD9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1ALyAeEC3AHVEgAD1wOZ - A/oGAAP6A5kD1xgABpwkAALdAdYC+gH0AvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAqQBkwKkAZMCpAGT - AskBwAwAAt0B1gL6AfQC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUCpAGTAqQBkwKkAZMCyQHAFQAD2AOd - BgADnQPYRQAC3gHXAvoB8wL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1AK2AaUD/wLeAdcC9wH2DAAC3gHX - AvoB8wL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1AK2AaUD/wLeAdcC9wH2bAAC3wHZAvwB9QL5Ae8C9gHq - AvQB5QLzAeIC8gHhAvIB4QLCAbEC3wHZAvcB9g8AAt8B2QL8AfUC+QHvAvYB6gL0AeUC8wHiAvIB4QLy - AeECwgGxAt8B2QL3AfZvAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfYSAALq - AeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfZsAAP7A/ECyAHDArgBsAK4AbACuAGw - ArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4 - AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4AbACuAGw - ArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4 - AbACuAGwArgBsALIAcMD8QP7A/0D+gLAAbgL/wP+Af0C/gH8Av0B+wL9AfoC/AH4Av4B+QLAAbgD+gb9 - A/oCwAG4C/8D/gH9Av4B/AL9AfsC/QH6AvwB+AL+AfkCwAG4A/oG/QP6AsABuAv/A/4B/QL+AfwC/QH7 - Av0B+gL8AfgC/gH5AsABuAP6Bv0D+gLAAbgL/wP+Af0C/gH8Av0B+wL9AfoC/AH4Av4B+QLAAbgD+gP9 - BgACyQHBBv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7 - AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7 - AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACzwHHA/8D/gL9 - AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL3AfIC+wH1As8BxwwAAs8BxwP/A/4C/QH8Av0B+wL8AfkC+wH4 - AvoB9gL4AfQC9wHyAvsB9QLPAccMAALPAccD/wP+Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0AvcB8gL7 - AfUCzwHHDAACzwHHA/8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL3AfIC+wH1As8BxwwAAtAByAL/ - Af4C/QH8AdwBzwHrAXsBSAG/AXsBSAG/AXsBSAG/AYsBXgHGAegB4QHrAvYB8AL6AfMC0AHIDAAC0AHI - Av8B/gL9AfwC/QH7AYIBwgG0AVkBrgGdAVkBrgGdAakB0wHIAvcB8gL2AfAC+gHzAtAByAwAAtAByAL/ - Af4C/QH8Av0B+wHeAaIBqQG/AUgBWQG/AUgBWQHcAaABpgL3AfIC9gHwAvoB8wLQAcgMAALQAcgC/wH+ - Av0B/AL9AfsBvwF7AUgBvwF7AUgBvwF7AUgB3AG6AZ4C9wHyAvYB8AL6AfMC0AHIDAAC0gHLAv4D/QH7 - Ad0B0QHtAYIBTwHGAvoB9gL4AfQBggFPAcYB2QHMAeUC9QHuAvoB8gLSAcsMAALSAcsC/gP9AfsC/AH5 - AvsB+AL6AfYB0gHoAeABYAG1AaQC9gHwAvUB7gL6AfIC0gHLDAAC0gHLAv4D/QH7AvwB+QL7AfgB4AGl - AasB0wF6AYUC9wHyAvYB8AL1Ae4C+gHyAtIBywwAAtIBywL+A/0B+wL8AfkBxgGCAU8B7AHbAcwC+AH0 - AvcB8gL2AfAC9QHuAvoB8gLSAcsMAALVAc0C/gP8AfkB3wHSAe0BigFXAc4BmAFsAdMBigFXAc4BpQF/ - AdcB5wHhAekC9AHsAvkB7wLVAc0MAALVAc0C/gP8AfkC+wH4AbIB3AHSAWgBvQGsAWgBvQGsAa4B2QHN - AvUB7gL0AewC+QHvAtUBzQwAAtUBzQL+A/wB+QL7AfgC+gH2AeMBqAGuAdkBfwGLAvYB8AL1Ae4C9AHs - AvkB7wLVAc0MAALVAc0C/gP8AfkC+wH4Ac4BigFXAe4B3QHMAvcB8gL2AfAC9QHuAvQB7AL5Ae8C1QHN - DAAC1gHOAv0D+wH4AeAB0wHuAZIBXwHWAvcB8gHdAdAB6QGSAV8B1gL0AewC8QHnAvcB6gLWAc4MAALW - Ac4C/QP7AfgC+gH2AXABxQG0AdUB6wHiAvYB8AL1Ae4C9AHsAvEB5wL3AeoC1gHODAAC1gHOAv0D+wH4 - AvoB9gL4AfQB5wGrAbEB3gGFAZAC9QHuAvQB7ALxAecC9wHqAtYBzgwAAtYBzgL9A/sB+AL6AfYB1gGS - AV8B7wHeAc0C9gHwAvUB7gL0AewC8QHnAvcB6gLWAc4MAALYAdAC/QP6AfYB4AHTAe4BmAFlAdwBmAFl - AdwBmAFlAdwBxQGsAeMC8QHnAuwB3wL0AeUC2AHQDAAC2AHQAv0D+gH2AvgB9AG3AeEB1QF2AcsBugF2 - AcsBugGVAdUBxgLxAecC7AHfAvQB5QLYAdAMAALYAdAC/QP6AfYC+AH0AeoBrwG0AdwBZQF2AdwBZQF2 - AegBrAGxAvEB5wLsAd8C9AHlAtgB0AwAAtgB0AL9A/oB9gL4AfQB3AGYAWUB7wHeAc0C9QHuAvQB7ALx - AecC7AHfAvQB5QLYAdAMAALaAdIC/AP4AfQC9wHyAvYB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLa - AdIMAALaAdIC/AP4AfQC9wHyAvYB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLaAdIMAALaAdIC/AP4 - AfQC9wHyAvYB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLaAdIMAALaAdIC/AP4AfQC9wHyAvYB8AL1 - Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLaAdIMAALbAdMC/AP3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLo - AdkC5gHVAvIB4QLbAdMMAALbAdMC/AP3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAvIB4QLb - AdMMAALbAdMC/AP3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAvIB4QLbAdMMAALbAdMC/AP3 - AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAvIB4QLbAdMMAALcAdUC+wP2AfAC9QHuAvQB7ALx - AecC7AHfAugB2QLmAdUC5QHUAvIB4QLcAdUMAALcAdUC+wP2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLm - AdUC5QHUAvIB4QLcAdUMAALcAdUC+wP2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC5QHUAvIB4QLc - AdUMAALcAdUC+wP2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC5QHUAvIB4QLcAdUMAALdAdYC+gH0 - AvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAqQBkwKkAZMCpAGTAskBwAwAAt0B1gL6AfQC9QHuAvQB7ALx - AecC7AHfAugB2QLmAdUCpAGTAqQBkwKkAZMCyQHADAAC3QHWAvoB9AL1Ae4C9AHsAvEB5wLsAd8C6AHZ - AuYB1QKkAZMCpAGTAqQBkwLJAcAMAALdAdYC+gH0AvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAqQBkwKk - AZMCpAGTAskBwAwAAt4B1wL6AfMC9AHsAvEB5wLsAd8C6AHZAuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwA - At4B1wL6AfMC9AHsAvEB5wLsAd8C6AHZAuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwAAt4B1wL6AfMC9AHs - AvEB5wLsAd8C6AHZAuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwAAt4B1wL6AfMC9AHsAvEB5wLsAd8C6AHZ - AuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwAAt8B2QL8AfUC+QHvAvYB6gL0AeUC8wHiAvIB4QLyAeECwgGx - At8B2QL3AfYPAALfAdkC/AH1AvkB7wL2AeoC9AHlAvMB4gLyAeEC8gHhAsIBsQLfAdkC9wH2DwAC3wHZ - AvwB9QL5Ae8C9gHqAvQB5QLzAeIC8gHhAvIB4QLCAbEC3wHZAvcB9g8AAt8B2QL8AfUC+QHvAvYB6gL0 - AeUC8wHiAvIB4QLyAeECwgGxAt8B2QL3AfYPAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZ - AuAB2QL3AfYSAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfYSAALqAeYC4AHZ - AuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfYSAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLg - AdkC4AHZAuAB2QL3AfYMAAFCAU0BPgcAAT4DAAEoAwABQAMAAUADAAEBAQABAQYAAQIWAAP/AgABAQEA - AQEFAAEBAQABAQUAAQEBAAEBBQABAQEAAQEFAAEBAQABAQUAAQEBAAEBBQABAQEAAQEFAAEBAQABAQUA - AQEBAAEBBQABAQEAAQEFAAEBAQABAQUAAQEBAAEBBQABAQEAAQEFAAEBAQABAQUAAQEBAAEBBAABgAED - AQABAQQABP8CAAH+AQEC/wUAAQEBiAMAAcABAQEAAQEBiAEAAYABAQHAAQEBAAEBAY8B/wGAAQEBwAEB - AQABAQL/AYABAQHAAQEBAAEBAv8BgAEBAcABAQEAAQEBjwH/AYABAQHAAQEBAAEBAYwBAQGAAQEBwAEB - AQABAQGPAf8BgAEBAcABAwEAAR8C/wGAAQEBwAEDAfABHwL/AYABAQHAAQMB8AEfAY8B/wGAAQEBwAED - AfABHwGMAQEBgAEBAcABAwHwAR8BjwH/AYABAQHAAQMB8AEfBP8BwAEDAfABHwQABP8EAAT/AcABAwHA - AQME/wHAAQMBwAEDAcABAwIAAcABAwHAAQMBwAEDAgABwAEDAcABAwHxAY8BzAHBAcABAwHAAQMB4wHH - AcABwQHAAQMBwAEDAccB4wHAAeMBwAEDAcABAwGPAfEB4QHjAcABAwHAAQMBxwHjAeEB4wHAAQMBwAED - AeMBxwHhAf8BwAEDAcABAwHxAY8B8wH/AcABAwHAAQMB+QGfAv8BwAEDAcABAwT/AcABBwHAAQcE/wHA - AQ8BwAEPBP8QAAHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHA - AQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHA - AQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHA - AQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQcBwAEHAcABBwHAAQcBwAEPAcABDwHAAQ8BwAEPCw== - - - - 132, 17 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ5SURBVDhPjdNdSFNhHMfx56Kb3i7scl10M28kIW+6kCDC - mF1EikF5IViDBMMkJQbKzHyZLiUVXc6hGdU0K0OTMFPBGkGpWIJiqznX3nybc3Oezb3663ke8sBJgg58 - Of/ncM6H58A5hPw5ZrTk+rSWVP1P7N6958TzVB2pESxarH28hvWJfAhz95BwdgHLT6Wt94Lduw/4XEs0 - 2HqNXd8rhB06eL8U470+A6PvmiSNjbdhsPZ4+z7gUy2pT2y+QHzNyEv4XmJm4BZcXi9WBAFOmj0QwBuT - CZpKxUiOWp0sQUxVpCHu6UVs+QmPzZN9SsxbLPhmNsPq8WBhZQU9w8NgR3ZZWaEEmbhLHsRWnyHifMRj - s+lxLr4vLnJk2e/nSJvRKJacmakWdzFWQVoi7m6EbB08Nk90XcGPpSWObNBX2EPYTtjrKEpKikRgpJzo - duydECw6HpvHDTmw2Gwc8QWDEsS5vY2MoqJiEXirIvrQkh4BcwuPzSPtWbDa7RzZ2tmRIKuhEM4WFNwW - gUEV6RR+tsI/38hj83DrRdgowBAhHJYgm3R9RqksFYH+UtIdWGiCd7aex+ah5guwOxwcCUWjEiRA16fz - 8u6IQG8xMfrnGuCZqeaxeaBRAYfTyZFwLCZBBAqk5eaqGHCQdsxwgwz5ZumnPFXJ89Fd9N8/D5fLxZFY - PC5BghQ8mZVVwYAkmrxQQTpGW9IC1qHC6MZ0NTa/atBXdw5utxsuWmJ3F3FaNJFAhGIROsvS07WSr9FQ - QLL1SmJ4Xi77MNlz6Zfq8gHHIbm87XBKSsPR1NT6vzsil9/c90+wC8355FRjHlHXXCUP6fIETfaPkn4D - qvVdCMceSq0AAAAASUVORK5CYII= - - - - - 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 - RpkLgwRoAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG9SURBVDhPjZLNSwJRFMVdFu1a1DrIhRC0CCKiVUG5KIi0 - KGjRxkpKwpAJ1BgIpEWboH8gwqIoCiHaBv4L1UIQ+8ISkcpxZvz2ds/QRPLMenB4PDj3x73nXYvl68xs - bk5My/JiMzlludv0C7czEFjSKhV6LxYpreuUVFV6yuXoUVEMRaJRgmcqGLQ2hEz6/cu5UokyXPiazdJ9 - JkOxVIruXl7oNpmkw6srwoGvIWRCktwqA940rSFkLxwmU9axsaDQxbjPt6KXy/TB7f8GQScYB14BMOr1 - ruY5AyWfbwoBAF4BMOLxeAoMUAuFphAEC68AGHa710rVKumcAyCXF2mSXHFDkbPUd7D4HXgFwJDL5S0z - oMA5mJDI6SvthhJ1maR5RHgFwODCwnqlVqMij2FCzo+faUeO1WWCPYFXAPTPz/uqDEAXJuT08IFC/pu6 - TBQeEV4B0Dc7K9V4USoMAOTkIEFz9mtDR/vxbwiWDV4B0OtwbGDTatyFCfk5jvk7GmcErwCw2u0BY1f/ - gGDZ4P0JaOVHR+fAwJYJMCAsZIJgMRK+GHtS5De8qGGh1tLO6mnp6lpvs9m2/yN4UYPaT6iBRnEAJMyK - AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGzSURBVDhPjZK9S4JRFMYdi7aGmoUchKAhCImmgnRIiuzD - QcjFSkpCEQM/EFyCxlqamuwPaHFoCRyarKmCyIoCTUQ0X/X1+z2dR3olumZdeLhceM6Pc557NJqvsxYK - mVfD4c1+WgmHx1S/cK8EAluVVosK9TplZZlS5TK9lUr0KkkdncfjBM9yMKjrCVny+7dLjQbluPC9WKSX - XI4eMhm6S6fpNpWis1iMcODrCTH7fM4yA/KVSk/IcTRKqnRGY1DoYsHr3ZGbTfrg9n+DoBOMA68AmHe7 - d6ucgVSt9oUAAK8AmHO5XDUGlGu1vhAEC68AmHU69xrtNsmcAyCOkyRdPxeEcfA78AqAGYfD3WRAjXMA - ZOPovgP4mUmWR4RXAEzb7Z6WolCdxwBk/fCGEk95YRzsCbwCYMpm87YZgC4AWYxcUeIxJ2QicXfwCoBJ - q9Wn8KK0GACIKXDZ1elFstsJlg1eATBhsexj0xTuQoWo46jB4osrPB68AkBnMgU6u/oHBMsG73fAID9G - Rg2GiAroQFjIBMFiJHwx9qTOb3hRw0KtZpg1PqDVeob0+oP/CF7UoPYTXb5IoCRPHYoAAAAASUVORK5C - YII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG1SURBVDhPjZK9S4JRFMYdi7aGmoUchKAhCImmgnRIirRy - EHKxkpJQxMAPhJZo7l+oxqAhtwiEWgIjKiEIIuE1kZfM1+/P03mk9yW4Zl14uFx4zo9znnt0uu+zGo1a - V2KxjX6yx2Jjql+47eHwZrnVony9TrlKhaRSidLFIr0pSlfniQTBsxyJGHpClkKhrWKjQTIXvhcK9CrL - 9JzN0lMmQ4+SRCfxOOHA1xNiDQY9JQZ8lMs9IUfHx6TKYDZHhC4WAoHtSrNJn9z+bxB0gnHgFQDzPt9O - lTNQqtW+EADgFQBzXq+3xoBSrdYXgmDhFQCzHs9uo92mCucAyK37RdPDYVoLFr8DrwCYcbt9TQbUOAdA - rtdTlLnPC+PkeER4BcC0y+VvdTpU5zEAuVxLakqdprVgsSfwCoAppzPQZgC6AORi8YakO1nIROHu4BUA - kw5HsMOL0mIAIGeWK5KSspaJ+jtYNngFwITNtodN63AXKkQdRw0WkDKPB68AMFgs4e6u/gHBssH7EzDI - j5FRk2lfBXQhLGSCYDESvhh7Uuc3vKhhoVY3zBof0Ov9Q0bjwX8EL2pQ+wUVkUjMVKxfkgAAAABJRU5E - rkJggg== - - - - - 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 - - - - 347, 17 - - - - AAABAAQAMDAAAAEAIACoJQAARgAAACAgAAABACAAqBAAAO4lAAAYGAAAAQAgAIgJAACWNgAAEBAAAAEA - IABoBAAAHkAAACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAABjRbAAY0WwsGNFvIBTNa/wo5Yf8jXo3/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAABTNaAAUzWgsFM1rIBDJZ/wk4YP8iXYz/KGSU/yZhkf8NPmf/BTNa/wY0 - W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzVdAAc1XQsHNV3IBjRc/ws6Yv8jXo3/KGSU/yZh - kf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIFiGACBYhgsgWIbIH1iG/yFa - iP8mYpL/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk - lAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0 - W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChk - lAAoZJQAKGSUAChklAAoZJQAKGSUAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZh - kf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAChklAAoZJQGKGSUCihklAkoZJQCKGSUAAAAAAAAAAAAJmKRACZikQsmYpHIJmKR/yZi - kv8nY5P/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - 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 - lAAoZJQAKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAgoZJSuKGSU4CNejeAjXo30I16N/yRejf8nYpL/KGSU/yNe - jf8KOWH/BTNa/wY0W/QGNFtOBjRbHgY0WxoGNFsDBjRbAAY0WwoGNFuxBjRb4AY0W8QGNFsYBjRbAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAEoZJQXKGSUHgo5YR4KOWGxCThg/wo7 - Y/8gWoj/KGSU/yNejf8KOWH/BTNa/wY0W/0GNFvmBjRb4AY0W8UGNFsYBjRbAAY0WwEGNFsYBjRbHgY0 - WxoGNFsDBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEURuABFEbgARRG4AEURuAAUz - WgAFM1mkBDFY/wY0W/8gWYf/KGWV/yNejf8JOGD/BDJZ/wUzWv8FM1r/BjRb/wY0W+EGNFsYBjRbAAY0 - WwAGNFsABjRbAAY0WwAGNFsABjRbAAY0WwAGNFsABjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjRbAAY0 - WwIGNFsqBjRbNgY0WzYKOmK5DD1m/w0/aP8bU4D/IFqI/x1Wg/8PQGr/DD1m/ww9Zv8HNl3/BTNa/wY0 - W+YGNFtMBjRbNgY0WzMGNFsLBjRbAAY0WwYGNFswBjRbNgY0WyoGNFsCBjRbAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAABjRbAAY0WwkGNFu9BjRb9AY0W/QbUX77JmKS/yRfjv8NP2j/BjRb/ws6Yv8hXIv/JmGR/yRf - jv8MPWb/BTNa/wY0W/0GNFv1BjRb9AY0W+cGNFsxBjRbAAY0Wx0GNFvYBjRb9AY0W7sGNFsJBjRbAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAY0WwAGNFsABjRbAAUzWgUFM1rFBTNZ/wUzWf8bUn//KGWV/yZhkf8MPWb/BDBX/wk4 - X/8jXo3/KGSU/yZhkf8MPWb/BDJY/wUzWf8FM1n/BTNZ/wUzWfIFM1owBjRbAAY0WxoGNFviBjRb/wUz - WsMFM1kFBTNZAChklAAoZJQAKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0WwAGNFs4BTNaVwY0W14OQGrZEURu/xFEbv4gWIbFKGSUpyZh - kacNPmenEUNtpxRHcrEkYI/0KGSU/yZikv8WS3b/EUNt/xFEbv8RRG7/EURu/xFDbfYIN155BTNaVwY0 - W2wGNFvrBTNa/wg3X9gRQ21eEURuVyhklEsoZJQJKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY0WwAGNFukBTNa/gY1XP4fWIb+J2OT/ydj - k/4nY5NXKGSUACZhkQANPmcAJ2OTACdjkx4nY5PgKGSU/ydjk/8nY5P/J2OT/ydjk/8nY5P/J2OT/yVg - kP4MPGX+BTNa/gY0W/4GNFv+BTNa/ww9Z/4lYZD+J2OT/ihklNwoZJQaKGSUAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChklAAoZJQAKGSUAAUzWgAFM1qjBDJZ/wY1 - XP8fWIb/KGSU/yhklP8oZJRYKGSUAChklAAoZJQAKGSUAChklBooZJTfKGSU/yhklP8oZJT/KGSU/yhk - lP8oZJT/KGSU/yZhkf8MPGX/BDJZ/wUzWv8FM1r/BDJZ/ww9Z/8lYZD/KGSU/yhklOAoZJQbKGSUAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChklAAoZJQcKGSUOA0+ - ZzgNPme5DD1m/w5AafwhW4nSKGSUxihklMUoZJRDKGSUAChklAIoZJQsKGSUOChklFAoZJTmKGSU/ydj - k/8hW4n/IFmH/yBZh/8gWYf/IFmH/x9Xhf8RQ23/DD1m/w0+Z/8NPmf/DD1m/xNGcfEmYpHIKGSUxihk - lKsoZJQUKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChk - lAAoZJR7KGSU9CZhkfQmYZH7JmGR/yZikfQnY5NAKGSUCihklAooZJQDKGSUAChklAooZJS/KGSU9Chk - lPUoZJT9KGSU/yZhkf8OP2j/BjVc/wc2Xf8HNl3/BjVc/wg3X/8fWIb/JmGR/yZhkf8mYZH/JmGR/yZi - ksYnY5MUKGSUCihklAkoZJQBKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAChklAAoZJSEKGSU/yhklP8oZJT/KGSU/yhklPgoZJQ4KGSUAChklAAoZJQAKGSUAChk - lAsoZJTIKGSU/yhklP8oZJX/KGSV/yZhkv8NPmf/BDJZ/wUzWv8FM1r/BDJZ/wY1XP8gWoj/KGSU/yhk - lP8oZJT/KGSU/yhklMIoZJUEKGSVAAs8ZAALPGQACzxkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAChklAAoZJRTKGSUpShklKUoZJSlKGSUpShklJ4oZJQkKGSUAAAA - AAAAAAAAKGSUAChklAsoZJTIKGSU/yZhkf8dVIL/G1J//xpRfvoKOmK4BTNapQY0W6UGNFulBTNapQc2 - XaUgWoilKGSUpShklLAoZJT0KGSU/yVgj9gcU4BfG1J/WQY0W00GNFsJBjRbAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChklAAoZJQAKGSUAChklAAoZJQAKGSUAChk - lAAoZJQAKGSUAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yNejf8KOWH/BTNa/wY0W/MGNFs2BTNaAAY0 - WwAGNFsABTNaAAc2XQAgWogAKGSUAChklB8oZJTiKGSU/yBZhv4HNV3+BTNa/gY0W9wGNFsaBjRbAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yNejf8KOWH/BTNa/wY0 - W/MGNFs2BjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklB8oZJTiKGSU/x9Yhf8GNFv/BDJY/wY0 - W+EGNFsbBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yNe - jf8KOWH/BTNa/wY0W/MGNFs2BjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklB8oZJTiKGSU/yNe - jOEXTHiGFkt2gQY0W3AGNFsNBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk - lAsoZJTIKGSU/yNejf8KOWH/BTNa/wY0W/MGNFs2BjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk - lB8oZJTiKGSU/yhklMMoZJQGKGSUAAY0WwAGNFsABjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAKGSUAChklAsoZJTLKGSU/yJdjP8JOGD/BDJY/wUzWfMFM1k2BTNZAAAAAAAAAAAAAAAAAAAA - AAAAAAAAKGSUAChklB8oZJTmKGSU/yhklMcoZJQKKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAcoZJSAKGSUpCRgj64USHPzEURu/xJFb/MSRW82EkVvAAAA - AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklBMoZJSRKGSUpChklH4oZJQGKGSUAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZJQAKGSUACdjkx4nY5PgJ2OT/ydj - k/MnY5M2J2OTAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZJQAKGSUAChklAAoZJQAKGSUAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk - lB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAKGSUAChklB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklB4oZJTgKGSU/yhk - lPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///gD//8AAP//+AP//wAA///4A///AAD///gD//8AAP// - +AP//wAA///4A///AAD///gD//8AAP//+AP//wAA///4A///AAD/8fgD//8AAP/x+AP//wAA//H4A/// - AAD/8f8Af8cAAP/x/wB/xwAA//D/AH/HAAD/gBgAcAcAAP+AGABwBwAA/4AYAHAHAADgAAAAAD8AAOAA - AAAAPwAA4AAAAAA/AAD//gAfj/8AAP/+AB+P/wAA//4AH4//AAD//8AD//8AAP//wAP//wAA///AA/// - AAD//gAAcf8AAP/+AABx/wAA//gAAAB/AAD/8B8AAD8AAP/wHwAAPwAA//A+AAA/AAD/gfgAAf8AAP+B - +AAB/wAA/4H4AAB/AAD///gf8D8AAP//+B/wPwAA///4H/A/AAD///gf8f8AAP//+B/x/wAA///4H/H/ - AAD///8f//8AAP///x///wAA////H///AAD///8f//8AAP///x///wAA////H///AAAoAAAAIAAAAEAA - AAABACAAAAAAAIAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkEMlnPCDdf/yNfjv0mYZH9Cjpi/wQyWd0JOF8SAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQIwV88GNV3/I16N/SZikv0KOmH/BDJZ3Qk4 - XxIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJHVSCzx5Wg/8mYpL9JmGR/Qo6 - Yv8EMlndCThfEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkpZZbPKGSV/yhk - lP0mYJD9Cjpj/wQyWd0JOF8SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoZJQAKGSUAChklAAoZJQAKGSUAChklAAAAAAAAAAACSdj - k88mYpL/KGST/SZhkf0KOmL/BDJZ3Ak4XxEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChklAAoZJQAKGSUAChklAAoZJQAKGSUAAAA - AAAAAAAIKGSTziZjk/4nY5T8JmCQ/Qo6Y/8EMlndCThfEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZJR+KGSUwChk - lCcoZJQAAChMAP///wkMPWbRD0Fq/yRgj/0lYZH8Cjpi/gQyWdwJOWAPBTNaAAY0WwAAAAAAAAAAAAAA - AAAoZJQAKGSUAChklAAoZJQAKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOLgAoZJQBKGSUACdj - k7EnY5P/J2OTOShklAAAKEwAuLi4BwEuVcQHN1/3I16O+yZikf0KOmH/BDJZ3Qc1XB4FM1oKBjRbAQY0 - WwAGNFsALmyeAShklAAmYpICJ2OTDChklAgoZJQAKGSUAAAAAAAAAAAAAAAAAAAAAAACMFcAAA4uAChk - lAAnY5MAKGSUpihklfwoZJQxKGSUAAEpTAD///8CHVWDGh9YhjonYpPmJWCQ/go6Yv0EMVj4BjRb2gUz - WsIGNFsZBTNaAAUzWgAoZJQAKGSUAChklCIoZJTWKGSUlyhjkwAoZJQCAAAAAAAAAAAAAAAAAAAAAAEv - VgAACikAIFiGEidjkx4jXo2zIl2M/yRfjU0jXowbACtRCgAAAAAqZ5cSKGSVLihklOUkX4//Cjlj/AQy - Wf4GNFv/BTNa7wY0Wx8GNFsCBjVcHh9XhSAkXo4bJWCQRydikv8oZJS5J2SUAChklAMAAAAAKGSUAChk - lAAmYpIABTNZAAQxWAAAK1GAAS9V7wc2XvQGNV3+BjVc7AMwVukEMVg/AgICACZjk74nY5PwJ2OU+iVg - kP4JOmP+AzFY/QUzWv0EMlnoBzVcFQUzWhwFMlncAi5U6gAtUucLPWXqJWGR/yhklLUqZ5gAKGSUAyhk - lAAoZJQAKGSUCCZikhMMPGUSBDJaDAc2XpcHN1//BjVd/AY1XfwHNl3/BzZe/wY0XFUBAgMRJ2KS2CZi - kv8nY5P9JF+P/go6Yv4EMVj8BzVd/QY2XekEMVgnBjRcNAU0XPUHN17/BTVc/ww8ZfsmYZHxJ2OTpSpo - mAAoZJQCKGSUBChklAAoZJR2J2OT6CtpmuApZpfgIl2M9CNejf8jXo3/Il2M/yJdjP8iXYz9DD1m5gU4 - Y9whW4r3KGSV/ihllf4mYpH/CTlh/wc2Xf8gWYj/I1+O/yNfjuAlYJDiI1+N/yNejf8iXIv/I16M1ylk - lCgnY5MVJ2aVAChklAAoZJQEKGSUAChklHMoZJThJ2KS2SdjktwoZZXZKGWV1illldYnZJTXKGSU9Cdk - lf0RRG//CDde/yFbif8nY5P+IlyL/yBZh/wIN1/eCTdg1iVgkNUjX47ZIl2L/iNdi/wjXo3YJ2OT1Cll - ldooZJSrKGOTACdjkwAoZ5YAKGSUAChklAAoZJQAKGSUBidjkw0oZJQLJ2KSDCZikQ0kXo0OJ2OTDSNe - jRAnYpLMJmKS/yZhkf0lYZH9J2SU/iNejf0IOGD+BTNb7wY0XC8HNVwHBjRbCwQyWSAGNVzpBjVc3hgA - ABghWogLI2CPDiRgjwsAAAABAAAAACpomAAAAAAAKGSUAChklAAoZJQAKGSUAChklAAoZJQAKGSUAChk - lAAnY5MADSExAC1rnLEqaJjqI16N9SRejv8nY5P+I16N/Qc2Xv8EMVjwBjVcOwQzWREFM1oABTNZDwUz - Ws0FM1rCAAAACCNcigAAAAAARY/IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAGrC/ABT0f8ACjlkDgEoUxIGNFy4BzZd/yJci/slYZD+BzVd/wMwV/sFM1rrBTNaxAY0 - WwgEMlkABzVcFgc1XBUAAAAABjRbAAUzWgAGNFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAQyWQADMVgAACJTAQAAAAIBLFUhAShSKgg3YL0KOmP8HVaD+h9YhvwMPWb+CTpi/QU0 - W/8FM1rmCDZePgY0WykEM1oCBTNaBApany0GNFsjBjRbAgg3XwEAAAAAEURuAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAABTNaAAQyWQAFM1kAAAAAAAUyWLwDMVb7HFSC/yZikv8JOWL/BjVc/yJd - jP8kX47+Bzhf/gIvVvsEMVf4AzBX3wc4Xw0GNFsXBTNZ8QUzWrQFM1oABTJZAAAAAAARRG4AAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAChllQAFM1oABDJZAQUzVzEBFSZMDD1m1A5Aaf4fV4bIJ2OTsg0/ - aLUNP2e9JGCQ9yZhkv8RRG/+DT5n/g5Aaf8NPmjwBjZdWQUzWmAFM1r9BjVd0A4/aUkSRnE5AAAAARFE - bgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoZJQALGucAAIwVwABLlUAAzBYqAM2YP8fWIb/KWWV/ydi - kkknY5MAKGaYACxqnA0nY5PhJ2OT/ihklfwoZJX+KWWX/iVgkP4HNl7/AzBX/wIvVf4LPGX/KGWV/ylm - l9UAAAAGEURuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChklAAxcaMAEkVwHgk6YzUKO2S5Czxk+yBa - iM8oZJTEJmKSOChklAEnYpMtJmKRTidjk+gnYpL+IFqI+x9Yhv0gWYf8HlaE/A0/afwLPGX7Cjtk/xFE - b+4mYpHLJmGSnwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAShklAAraJmSKWaW/yZi - kv8nYpL/J2STPCdjkwAoX48AJWGRCCdjk8snY5P/KWWW/CZhkv8KOmL/BDFY/wQzWf8GNl7/IlyL/ydj - k/8mYZL/J2OTuSpnlwApZpYAAAAAABtSfwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoZJQAJ2OTACZi - kl8nY5KuKGSUqChklKgoY5MlKGSUACdhkQAAAAAJKGSTzyZhkf4cVIL9GlF++Qg4YbcEMlipBDFYqgY2 - XaojXoyoJ2OTtSdjk/0lYI/QH1eEUhpQfEAAAAABG1J/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChk - lAAoY5MAKGSUAClllQApZpYAKWWVAClklQAoZJQAAAAAAAAAAAgoZZXOI16N/gc1Xf8DMFfvBjVcIgY0 - WwAGNFsAAzNZAChklAAlYZAiKWWW8B1Wg/8AK1H/AC1T2wAAAAYbUn8AAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAKGSUAChklAAoZJQAKGSUAChklAEoZJQBKGSUAChklAAAAAAAAAAACChllMwkX478CDdf/gUy - WfAHNl0oBjRbAQY0WwIFNVwCJ2OTASZikicoZJTyIlyL4BJFb48NP2hyAAAAAxtSfwAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChklAAAAAAJKGWV2SNe - jf8GNFz/Ai9V7wU0WigEMVcABDJYAQAAAAEoZJQAKGSUKCdjk/8oZJTEKWaWAClllQAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAAAA - AAUnZJSCJF+OrBJFcPUQQ23xEURuJxFEbgARRG0BAAAAAChklAAnY5MXKGSUnydjk3knY5MBJ2OTAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAoZJQAAAAAACdjkwAoZZUQKGWV5ihllfQpZZYlKGWVAChklAEAAAAAKGSUAChklAAoZJQAKGSUAChk - lAAoZJQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAABKGSUASdjkxonY5PnJ2OT8yhklCYoZJQAKGSUAQAAAAAoZJQAKGSUAChk - lAEoZJQBKGSUAChklAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEnY5MAKGSUGSdjk+cnY5P0J2OTJidjkwAnY5MBAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAShklAAoZJQZKGSU5yhklPQoZJQmKGSUAChk - lAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/8D////A////wP///8 - D////A////wP//88D///PA///z8D8/8/A/P8DAMD/AwDA8AAAA/AAAAP/8A8///APP//8A////AP///A - Az//wAI//w8AD/8PAA/8PAA//jwAP//8Pw///D8P//w/P//8Pz///z////8/////P////z//KAAAABgA - AAAwAAAAAQAgAAAAAABgCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAi9WAwArUQABLlRkBDNa/yZikvsYTXn/AzBV3AAAAA0AAAAAAAAAAQAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACzxmAwk5YQALO2RkDT9o/ydj - k/sXTHj/AzBW3AAAAA0AAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAoZJQAKGSUAChklAIoZJQCKGSUAidikgAmYpJkJmKS/ylml/sWS3f/AzBX3AAAAA0AAAAAAAAAAQAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoZJQAKGSUAChklAAoZJQAJWCQAypn - lwAoZZZjKGWV/ipnmPoWS3f/AzBX3AAAAA0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAoZJQAKGSUAChklDMoZJQwMnKkARtSfwAcVIFkHVWC/yhllfsXTHj/AzBW2wk4 - YAsAAAAAAAAAASNbiQAoZJQAKGSUAChklAAoZJQAKGSUAAAAAAAAAAAABjRbAAUzWgAoZJQBJ2OTAidj - k8AnY5O5N3mtAgApTwABLlRiBjVd/yZikvoYTXn+AzBV3Ao6YxIGNFsBBjRbAStmlgIYTnoCHFSBAylk - lAQnZJMAKGWVAAAAAAAAAAAABTNaAQQyWQEoZJQAKmeXACpnl7cqZ5ewKWaWADd6rgAVS3YLF015NClm - lugXTXn/AzBW8wY0W9kGNFtkBjRbABZLdQAraZoAK2iZJCdklM8oY5QsJ2OTAAAAAAAAAAAABDFXAAQy - WQANPmcRDj9ocBVKddwVSnbWDkBpeAo0WxcubZ4jKGSUgypml/AYTXn+Ai9X+wUzWv8FM1p4BTNaCQo5 - YXsNPmd1GE57mSdjk/8nZJM6KGSUAChklAAoZJQACTlhCgQyWQcDMVgyBDNa/wUzWv8EM1n+BTRb/wAk - ST0qZ5dnJmKS/ylmlv0XTHj8Ay9V9wY0W/kGNFx0AzJZKwU0W/8DMFf/Czxl/ydjk+4nY5IzKGWWAChk - lAAoZJQcKWaW2CllluolYZDtI12M/yJdjP8iXYz/I16N+Qg4YOIRRG7nKGWV+ytomf0XTHj/Bzli/yRh - kv8lYZDwJGGQ4CJdi/8jXYz/I16N0ShklCAnY5IGKGSTAChklAAoZJQOJ2OTcSdjk3wpZZV4KmaXdilm - lm4nY5SkKGOU/xlRfv8cVIH/JmKR/BZMd/8NPme7Ax0zbBEvVW4VS3bHFUp19ihnmnMqZ5h4KWWWVydj - kwAoZJQAKWSUAChklAAoZJQAKGSUAChklAAoZJQAJ2OTAChklAAsaZpCKWia7SVhkPYoZJT9JF6N+gUz - W/8CL1WMAB86AAInSwACL1V4Ai9VxgAAAAAua5wAKmeYACpomAEoZJQAAAAAAAAAAAAAAAAAKGSUAyhk - lAMZUHwDAAAAA5D4/wUNPmkHAwAbCQIuVL0TR3H9J2SU+gY0W/0DMVf4BzhhyCuw8wEdUn8IDT1mFQAA - AAAAEzUCAClPBAAJKQAkX44AAAAAAAAAAAAAAAAAAAAAAAAAAAADMVgABTNaAQQyWQACL1YpACNGlxVJ - dekVS3f/EERt/xpQff4PQWv/Ai5U8wMwVqUDMVg6BjRcBAY7Z5sDMFchAzBXAAAmSQEbU4EAAAAAAAAA - AAAAAAAAKGSUAAAAAAACMFcABDFYAwQxWCgIOGCEDD9o/yRejdAcVIG8CDdexihllfgdVIL+Cztk/A0+ - Z/8JOWGbBTNaWAQyWf8JOmJ4DkBqKyFbjQEWTHgAAAAAAAAAAAAAAAAAKGSUAChllQAEMlkAABs+AAAq - T6kOQGn/KWaX/yVhkT8oZJUALWudDCZikuUnY5P9KGWW+Sxpm/cVSnX7AC5T/gIvVvcdVYP/LWuczIPn - /wAlYZEAAAAAAAAAAAAAAAAAKGSUAChklAAnZJQdJV+PqBtTgPIeVoTQKGWVUidikhQmYpI9JmKStytn - mfQdVIL/D0Bq/w9Ba/8VSXX/HFOA/xpRfv4kX496J2SUMUyZzAEta50AAAAAAAAAAAAAAAAAKGSUAShk - lAAoZJQeKGSUsypnmLcqZ5duJ2OTAChllQAnZJRqJmKR/x9Xhf8RRG/ZACxTrQIvVbAYT3usK2mbvClm - l/0fV4V2GE56LwATNAEFNFwAAAAAAAAAAAAAAAAAKGSUAChklAAnY5MAJ2OTAC5tnwAubZ4AKGSUBSto - mQAqZpdhJF+O+QY1W/4DMFeEAjBWAA9AawApZ5cAJmKSJChkk/MNP2f/ACdLwTcyLgAFNFsAAAAAAAAA - AAAAAAAAKGSUAChklAAAAAAAKGSUAShklAEoZJQAKGSUAytomQAqZpdpJF+O/wY0W/8BLVSJACtQAQw8 - ZgYoY5MBJ2OTLydjk/8kX45nI12LG3+kwgIXTXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAKGSUASlmlgApZZU+JGCPqRJFcP0QQ22KEEJrABZMdwQnY5MAKGSUGyhklJ8pZZUlKWWVAAdL - ggEYTXgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUACtpmgEnY5MAKWWVCClm - lvYpZZaOKWaWAChllQIoZJQAKGSUAChklAAqZ5gAKmeYAQAWXgAWS3YAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAKGSUACxqmwAoZJQBJ2OTFSdjk/cnY5ONJ2OTACdjkwMoZJQAKGSUAChk - lAIoZJQAKGSUAChklAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAEnY5MAKGSUEydjk/cnY5OOJ2OTACdjkwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/B - /wD/wf8A/8H/AP/B/wD/wf8A/MH/APzwewD4YEMA+EBDAMAABwDAAA8A/wM/AP+B/wD/AN8A/gBPAPxw - BwD44A8A+MAPAP/DxwD/w88A/+PfAP/z/wD/8/8A//P/ACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAzBW2B9Yhv8JOWHcAAAABwAU - NAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAoZJQAKGSUAAAAAAApZZYAQ4XMBR1UgtciXIv/CDdf3AAA - AAcAEzMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZZUAKmaXAD6EzwYsaZvYJF6O/gc2 - XtsEMlYGABY5ACFbiQEtbJ0AKGSUAChklAAAAAAABzZdAChklQEoZJQAKGSVgypmlypaq+sCEENt2SFa - if8IOGDbBDJbBQALIwAwcaMAAAALAClllQAoZJYAKGSUAAAOLAAmYZEAKGSUACZikcMmYZFLUZvFAB1V - gkEjXo3vCDhg+AMxV64AAAwHIluKAidikkkoY5SMJ2OTAChklAAJOWEIBDJZCgUzWo4KO2P6BzZe4y5o - gjcsaZqvJWGR/Ac3X/8FNFviCjxnOgUzWdsTRnHyKWaWpSpmlwAoZJQAKGSUbidklMshW4ndIluK6iFb - iv8JOWXoIl2L/yJci/0LO2TmH1iF5R9Zh+IhXo70Il2MtilklRAlYZACKGSUAChklQ4oZJQcKmiYEyNf - jxIpZZa2I16M/iNejfwIOF/vBjJZKgs7Yy0JOWG+ChMaDSBahwoqZpcAK2eYAChklAApZpYAHleEABxS - fQAYTXsAE0VxIww+Zt0cU4D/Cjtj/gIvVs4AIEMeBDFYDAAOHRAAKE0AL3CiASdjkwAAAAAAJmGRAFuq - 6AEMPmYABDBVHwk6YtUdVYPVDkBpviFbifkQQmz/DD1m0QIvVmYGNl7EDD1lMA5AaQAlYJABAAAAACZh - kQASRXAADkFqJg0/aNQfWYfdM3SmISxqmy4oZZbxIVqJ/xxTgP8KOmP/E0dy8C1rnYQtbJ0AKWaWBAAA - AAAnY5MBKGSVACxpm3EnY5O6KGSUHhtQfgAmYpLdHFSC/QUyWbkLPGSvKWaXwyRfj8wZT3s7GlB9AAEu - VQEAAAAAJWCQAClllwA2eKwAIFmHACRfjgBRp9wGIl2M6wUzWvUAHkELH1iGAC9tnzIgWojzDj9peA5B - agAIOGADAAAAACZhkQAkXo4AAAAAAP///wEva50AKmiZAiRfjpQTR3LpEUJsGB9YhQEmYpIrKWWWbito - mQAsapsAAClQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASdjkwAoZJQKKmaX1ylmlxooZJUAJmKRAChl - lQAqaJgBMnKkAAAmSwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoZJQAJ2OTHCdjk9koZJQZJ2OTAChk - lAIoZJQFKGSUAChklAAAAAAA/j8AAP4/AAD+PwAA9j8AAPcdAADiEQAAgAMAAPhvAAD8PwAA+AcAAPMD - AADmBwAA/nMAAP53AAD/fwAA/38AAA== - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 527, 17 + + + 237, 17 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADW + LgAAAk1TRnQBSQFMAgEBDgEAAagBAAGoAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA + AwABQAMAAQEBAAEYBgABMBIAA/wD+SH4A/kD/AMAA/0D+SH4A/kD/WMAAZYBqQG8AVwBhAGuAVwBhAGu + AVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGu + AVwBhAGuAZYBqQG8AwACzwHLArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5 + AbACuQGwArkBsALPActjAAFsAZMBugFVAYgBuwFwAaMB1gFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFn + AZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFnAZoBzQFwAaMB1gFVAYgBuwFsAZMBugMAAsEBuQL5AekC8wHi + AvMB4gLzAeIC8wHiAvMB4gLzAeIC8wHiAvMB4gLzAeIC8wHiAvMB4gL5AekCwQG5YwABfgGiAccBcQGk + AdcBVQGIAbsBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGkAdcBcQGk + AdcBVQGIAbsBcQGkAdcBfgGiAccDAALLAcMC9AHkAXoBpwGbAYcBtwGnAYcBtQGjAYkBswGiAWgBoAGG + AVcBlwF4AVgBkwF5AWgBkAF+AZIBpAGTAYYBlwGAAqgBjgL0AeQCywHDYwABhgGqAc0BcwGmAdkBagGd + AdABSAF7Aa4BXwGSAcUBTAF/AbIBXwGSAcUBTAF/AbIBXwGSAcUBTAF/AbIBXwGSAcUBSAF7Aa4BagGd + AdABcwGmAdkBhgGqAc0DAALPAccC9QHmAYQBtQGrAZgB1wHHAZAB0QG+AXMBsAGZAZcBywG2AacBzgG9 + AZcBvQGsAZQBugGoAakBvwGvAY4BrQGhAbcBrQGLAvUB5gLPAcdjAAGLAa0BzwF1AagB2wFsAZ8B0gFK + AX0BsAFsAZ8B0gFSAYUBuAFsAZ8B0gFSAYUBuAFsAZ8B0gFSAYUBuAFsAZ8B0gFKAX0BsAFsAZ8B0gF1 + AagB2wGLAa0BzwMAAtEByQL2AekBkAG8AbUBuQHlAdsBpgHdAdABiAHAAbIBhwHJAbUBfgG+AaQBiAG5 + AaMBrgHQAb8BqQHHAbUBlAG6AagBtgG1AZEC9gHpAtEByWMAAY8BsQHSAXcBqgHdAW4BoQHUAUcBegGt + AW4BoQHUAU8BggG1AW4BoQHUAU8BggG1AW4BoQHUAU8BggG1AW4BoQHUAUcBegGtAW4BoQHUAXcBqgHd + AY8BsQHSAwAC0wHMAvcB6wHFAbgBhwH/Ad4BjAH4AecBrQHVAdEBsAHKAesB4gG9AeUB2QGgAcoBuwGq + Ac4BrwGCAcEBpAF+AbYCmAGsAYQC9wHrAtMBzGMAAZMBtAHUAXgBqwHeAW8BogHVAUQBdwGqAW8BogHV + AUwBfwGyAW8BogHVAUwBfwGyAW8BogHVAUwBfwGyAW8BogHVAUQBdwGqAW8BogHVAXgBqwHeAZMBtAHU + AwAC1QHNAvgB7gHRAa4BaQHbAboBcQHeAb4BdAHpAckBfAG/Ac0BqAGVAcwBwgGhAc8BvgGRAcQBrwF/ + Ab0BpgF3AbcBnQGoAaoBdwL4Ae4C1QHNYwABmAG4AdcBegGtAeABcQGkAdcBQQF0AacBcQGkAdcBSQF8 + Aa8BcQGkAdcBSQF8Aa8BcQGkAdcBSQF8Aa8BcQGkAdcBQQF0AacBcQGkAdcBegGtAeABmAG4AdcDAALX + Ac8C+QHxAdMBrAFmAf8B0wF+Af8B1gGCAeABvgF0AfYB4QGZAbAB7QHkAa8B0QG/AaIB4AHTAZgB2AHG + AY4B0AG6AbgBsgGAAvkB8QLXAc9jAAGbAboB2QF8Aa8B4gFzAaYB2QE/AXIBpQFzAaYB2QFHAXoBrQFz + AaYB2QFHAXoBrQFzAaYB2QFHAXoBrQFzAaYB2QE/AXIBpQFzAaYB2QF8Aa8B4gGbAboB2QMAAtkB0QL7 + AfQB1QGpAWIB/wHOAXkB/wHSAX0B3wG6AW8B/wHYAYMB5gHqAb0BpgHYAc0BswHsAeIBuQHkAdABtgHc + AcQBqwG+AZcC+wH0AtkB0WMAAZ0BvQHbAX4BsQHkAXUBqAHbATgBawGeAVEBhAG3ATgBawGeAVEBhAG3 + ATgBawGeAVEBhAG3ATgBawGeAVEBhAG3ATgBawGeAXUBqAHbAX4BsQHkAZ0BvQHbAwAC2gHTAvwB9wHX + AacBXwHaAawBZAHcAbABZwHnAbwBcAHgAboBbwHjAb4BcwHfAdEBmAHbAc8BlgHVAdEBnAHEAc0BpAGd + AdEBwwL8AfcC2gHTYwABoAG+AdwBfwGyAeUBZgGZAcwBdgGpAdwBdgGpAdwBdgGpAdwBdgGpAdwBdgGp + AdwBdgGpAdwBdgGpAdwBdgGpAdwBdgGpAdwBZgGZAcwBfwGyAeUBoAG+AdwDAALbAdQC/QH5AdkBpAFc + Af8BxAFvAf8ByAFzAd4BsAFnAf8BzgF5Af8B0gF9AeQBvgFyAf8B2AGDAe0B5AGoAeIB5gG2AdAB1wGt + Av0B+QLbAdRjAAGjAcAB3gFrAZ4B0QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3 + AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QF3AaoB3QFrAZ4B0QGjAcAB3gMAAt0B1QL+AfwB2gGjAVoB/wG/ + AWsB/wHCAW4B3gGsAWIB/wHJAXQB/wHNAXgB4wG5AW4B/wHTAX4B/wHXAYMB/AHeAZUB7AHKAXwC/gH8 + At0B1WMAAaYBwwHgAaAB0wH6AZgBywH1AZMBxgHzAZMBxgHzAZMBxgHzAZMBxgHzAZMBxgHzAZMBxgHz + AZMBxgHzAZMBxgHzAZMBxgHzAZgBywH1AaAB0wH6AaYBwwHgAwAC3gHXAv8B/gHbAaEBWAHbAaIBWQHb + AaQBWwHbAaUBXQHbAakBYAHbAawBYwHbAa8BZgHbAbEBaAHbAbQBawHbAbcBbgHbAbkBcQL/Af4C3gHX + YwAB6AHtAfMBqAHEAeEBlwHKAfUBkgHFAfMBkgHFAfMBkgHFAfMBkgHFAfMBkgHFAfMBkgHFAfMBkgHF + AfMBkgHFAfMBkgHFAfMBlwHKAfUBqAHEAeEB6AHtAfMDAALfAdkn/wLfAdlmAAHoAe0B8wGpAcUB4gGp + AcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gGpAcUB4gHo + Ae0B8wYAAuoB5gLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QLg + AdkC6gHmwwAD+wPxAZUBrwG8AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2AWgBmwG2 + AWgBmwG2AWgBmwG2AWgBmwG2AZUBrwG8A/ED+xUAEvgD+QP9MwAD/AP5JPgD+QP8A/0D+gF3AagBwQGG + Ac8B8AGBAcsB7QGBAcsB7QGBAcsB7QGBAcsB7QGBAcsB7QGBAcsB7QGGAc8B8AFLAY8BsQGGAc8B8AF3 + AagBwQHcAeIB5Qb9A/kM+APzAYkBpQGPAVUBiwFfAVUBiwFfAVUBiwFfAVUBiwFfAVUBiwFfAVUBiwFf + AZQBrQGZBgADwAMsA8ADAAP7G/gD+wP3AZMBpgG6AWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGv + AWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGvAWABiAGvAZMBpgG6A/cGAAGGAbUBzQGE + Ac4B7gF8AccB6AF8AccB6AF8AccB6AF8AccB6AF8AccB6AF8AccB6AGEAc4B7gFXAZsBvQGEAc4B7gH0 + AbYBLgGGAbUBzQMAApQBuAJVAaMCVQGjAlUBowJVAaMCVQGjAlUBowFVAXoBiQE1Ab0BeQFDAcsBhwE+ + AcYBggE+AcYBggE+AcYBggFDAcsBhwFVAaABcAYAA0ABZwJWA0ADAAP7A2EDXgNcA1kDVANJAzwDLwNs + A/sDAAFyAZgBvwF7Aa4B4AF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6Aa0B3wF6 + Aa0B3wF6Aa0B3wF6Aa0B3wF7Aa4B4AFyAZgBvwkAAZEBvgHUAYcB0AHvAX8BygHpAX8BygHpAX8BygHp + AX8BygHpAX8BygHpAX8BygHpAYcB0AHvAV8BowHFAYcB0AHvAf4ByQFBAZEBvgHUAwACVQG0AS8BHgHc + ASUBEwHYASUBEwHYASUBEwHYASUBEwHYASUBEwHYAVUBfgGVATcBvwF7AUIBygGGATcBvwF7ATcBvwF7 + ATcBvwF7AUIBygGGAVUBpwF2BgADywNVA8snAAGEAacBywGBAbQB5AF9AbAB4QF9AbAB4QF9AbAB4QF9 + AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QF9AbAB4QGBAbQB5AGEAacBywkAAZQBwAHW + AYoB0wHwAYIBzQHrAYIBzQHrAYIBzQHrAYIBzQHrAYIBzQHrAYIBzQHrAYoB0wHwAWIBpgHIAYoB0wHw + AukB2wGUAcAB1gMAAlUBuQEtARwB3gEVAQAB1QEVAQAB1QEVAQAB1QEVAQAB1QEVAQAB1QFVAYEBmgE7 + AcMBfwFIAc8BjAE7AcMBfwE7AcMBfwE7AcMBfwFIAc8BjAFVAa0BezYAAYoBrQHPAYgBuwHqAYIBtQHl + AYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYIBtQHlAYgBuwHq + AYoBrQHPCQABmAHDAdgBjgHWAfIBhwHQAe0BhwHQAe0BhwHQAe0BhwHQAe0BhwHQAe0BhwHQAe0BjgHW + AfIBZgGqAcwBjgHWAfIC8AHmAZgBwwHYAwACVQG/ATYBJQHkARkBAAHbARkBAAHbARkBAAHbARkBAAHb + ARkBAAHbAVUBhAGgAT4BxgGCAU0B1QGRAT4BxgGCAT4BxgGCAT4BxgGCAU0B1QGRAVUBswGANgABjgGw + AdEBjwHCAe4BhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6AekBhwG6 + AekBhwG6AekBjwHCAe4BjgGwAdEJAAGbAcYB2gGSAdoB9AGLAdQB8AGLAdQB8AGLAdQB8AGLAdQB8AGL + AdQB8AGLAdQB8AGSAdoB9AFpAa0BzwGSAdoB9AL4AfMBmwHGAdoDAAJVAcQBPgEtAewBHAEAAeMBHAEA + AeMBHAEAAeMBHAEAAeMBHAEAAeMBVQGGAaQBQgHKAYYBUQHZAZUBQgHKAYYBQgHKAYYBQgHKAYYBUQHZ + AZUBVQG5AYQGAAPQA2cD0CcAAZMBtAHUAZYByQHyAYwBvwHsAYwBvwHsAYwBvwHsAUQBdwGqAYwBvwHs + AUQBdwGqAYwBvwHsAYwBvwHsAYwBvwHsAYwBvwHsAZYByQHyAZMBtAHUCQABnwHIAd0BlwHeAfYBkAHY + AfIBkAHYAfIBkAHYAfIBkAHYAfIBkAHYAfIBkAHYAfIBlwHeAfYBeQG9AdwBeAG9AdwC/gH9AZ8ByAHd + AwACVQHIAUYBNQHyASABAAHpASABAAHpASABAAHpASABAAHpASABAAHpAVUBiQGoAUQBzAGIAWUB7QGp + AWUB7QGpAWUB7QGpAWUB7QGpAVgB1gGWAX8BywGkBgADbAFvAmkDbAYAA3UDdANxA24DbANoA2UDYwNg + BgABmAG4AdcBmwHOAfYBkQHEAfABkQHEAfABkQHEAfABVQGIAbsBRAF3AaoBVQGIAbsBQAFzAaYBkQHE + AfABkQHEAfABkQHEAfABmwHOAfYBmAG4AdcJAAGiAcoB3gGbAeEB9wGUAdsB9AGUAdsB9AGUAdsB9AGU + AdsB9AGUAdsB9AGUAdsB9AGUAdsB9AGeAeQB+QF8AcAB3gGiAcoB3gHuAfMB9QMAAn8B1QFiAWEB5wF2 + AXUB/gF2AXUB/gF5AWIBowF7AVABVQF7AVABVQFqAVkBPwFqAW4BMgFqAW4BMgFhAYsBUQFVAcEBigFV + AcEBigFVAcEBigHiAe8B6AYAA9MDcQPTJwABmwG6AdkBnwHSAfkBlQHIAfMBlQHIAfMBlQHIAfMBVQGI + AbsBVQGIAbsBVQGIAbsBTQGAAbMBlQHIAfMBlQHIAfMBlQHIAfMBnwHSAfkBmwG6AdkJAAGlAc0B4AGe + AeUB+QGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGYAd8B9gGhAegB+gGl + Ac0B4AYAAuIB8QJVAc4CVQHOAlUBzgFtAVMBdQHcAakBMgHXAaQBLQHXAaQBLQHXAaQBLQHcAakBMgGw + AYYBSEIAAZ8BvQHbAakB2wH+AaoB3QH/AaoB3QH/AaoB3QH/AXcBqgHdAXcBqgHdAXcBqgHdAWYBmQHM + AaoB3QH/AaoB3QH/AaoB3QH/AakB2wH+AZ8BvQHbCQABqAHOAeIBowHoAfsBnQHjAfkBnQHjAfkBnQHj + AfkBnQHjAfkBnQHjAfkBnQHjAfkBnQHjAfkBnQHjAfkBowHoAfsBqAHOAeISAAG2AYsBRQHcAakBMgHR + AZ4BJwHRAZ4BJwHRAZ4BJwHcAakBMgG2AYsBRUIAAccB1wHnAYgBtgHiAYABswHmAYABswHmAYABswHm + AU4BgQG0AU4BgQG0AU4BgQG0AUgBewGuAYABswHmAYABswHmAYABswHmAYgBtgHiAccB1wHnCQABqwHQ + AeMBpgHrAfwBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBoQHmAfsBpgHr + AfwBqwHQAeMSAAG7AZABQQHhAa4BOAHWAaMBLAHWAaMBLAHWAaMBLAHhAa4BOAG7AZABQRIAA9cDfQPX + JwAB4wHqAfEBjgG4AeEBiQG8Ae8BiAG7Ae4BiAG7Ae4BQQF0AacBQQF0AacBQQF0AacBPgFxAaQBiAG7 + Ae4BiAG7Ae4BiQG8Ae8BjgG4AeEB4wHqAfEJAAGuAdIB5AGpAe4B/QGkAekB/AGkAekB/AGkAekB/AGk + AekB/AGkAekB/AGkAekB/AGkAekB/AGkAekB/AGpAe4B/QGuAdIB5BIAAcABlQE/AecBtAE9AdoBpwEw + AdoBpwEwAdoBpwEwAecBtAE9AcABlQE/EgADfwN3A38GAAOCA4EDfwN+A3wDegN5A3YDqwYAAfUB9wH5 + AZsBvgHfAYkBvAHvAYgBuwHuAYgBuwHuATUBaAGbATUBaAGbATUBaAGbATUBaAGbAYgBuwHuAYgBuwHu + AYkBvAHvAZsBvgHfAfUB9wH5CQABsAHUAeYBrAHxAf8BpwHsAf4BpwHsAf4BpwHsAf4BpwHsAf4BpwHs + Af4BpwHsAf4BpwHsAf4BpwHsAf4BrAHxAf8BsAHUAeYSAAHGAZoBPQHrAbgBQQHdAaoBMwHdAaoBMwHd + AaoBMwHrAbgBQQHGAZoBPRIAA9gDggPYJwAD/gHLAdoB6gGpAcUB4gGpAcUB4gGpAcUB4gFVAX0BpgFV + AX0BpgFVAX0BpgFVAX0BpgGpAcUB4gGpAcUB4gGpAcUB4gHLAdoB6gP+CQABsgHVAeYBsQH1Af8BrgHy + Af8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BrgHyAf8BsQH1Af8BsgHVAeYSAAHU + AbMBbAHnAbgBRgH+AcsBVAH+AcsBVAH+AcsBVAHnAbgBRgHUAbMBbHUAAdAB5AHuAbMB1gHnAbMB1gHn + AbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAbMB1gHnAdAB5AHuEgAB8AHr + Ad4BzQGgATkBzQGgATkBzQGgATkBzQGgATkBzQGgATkB8AHrAd4PAAP7A/ECyAHDArgBsAK4AbACuAGw + ArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4 + AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8QP7YAAD/QP6AsABuAv/A/4B/QL+AfwC/QH7Av0B+gL8 + AfgC/gH5AsABuAP6Bv0D+gLAAbgL/wP+Af0C/gH8Av0B+wL9AfoC/AH4Av4B+QLAAbgD+gP9ZgACyQHB + Bv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7AvwB+QL7 + AfgC+gH2AvgB9AL7AfYCyQHBbAACzwHHA/8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL3AfIC+wH1 + As8BxwwAAs8BxwP/A/4C/QH8Av0B+wL8AfkC+wH4AvoB9gL4AfQC9wHyAvsB9QLPAccMAAP+A/wG+QP6 + BvwD+wb5A/wD/gYAA/0D/AP6HvgD+gP8A/0GAALQAcgC/wH+Av0B/AL9AfsBvwFIAa4B7AHOAeUC+gH2 + AvgB9AL3AfIC9gHwAvoB8wLQAcgMAALQAcgC/wH+Av0B/AHpAc8B6wGuAUgBvwGuAUgBvwGuAUgBvwHT + AaEB2gL3AfIC9gHwAvoB8wLQAcgMAAP+A/wD+QOzA1wG/ANcA7QD+QP8A/4GAAP9A4QDNAOEA/gD4gY0 + A4QD4gN1A6QD+AOEAzQD6QYAAtIBywL+A/0B+wL8AfkBxgFPAbUB7AHPAeUC+AH0AvcB8gL2AfAC9QHu + AvoB8gLSAcsMAALSAcsC/gP9AfsB6gHRAe0BtQFPAcYC+gH2AecBzgHoAbUBTwHGAe4B4QHrAvUB7gL6 + AfIC0gHLEgADywN1A/gGAAP4A3UDyxIAA3kD9QYAA6oDeQYAA8sDvgPuA6oDwgkAAtUBzQL+A/wB+QL7 + AfgBzgFXAb0BzgFXAb0BzgFXAb0B4gGmAdYC9QHuAvQB7AL5Ae8C1QHNDAAC1QHNAv4D/AH5AesB0gHt + Ab0BVwHOAvgB9AL3AfIBvQFXAc4B5wHNAeUC9AHsAvkB7wLVAc0PAAPOA38D+QwAA/kDfwPODwADxgxg + A8YGAAP1CWAD6QkAAtYBzgL9A/sB+AL6AfYB1gFfAcUB7wHRAeYC9gHwAvUB7gL0AewC8QHnAvcB6gLW + Ac4MAALWAc4C/QP7AfgB7AHTAe4BxQFfAdYC9wHyAeoB0QHqAcUBXwHWAe0B4QHpAvEB5wL3AeoC1gHO + DAAD0AOGA/kSAAP5A4YD0AwAA/UDlAPvA9EDaAP1CQADkwPvA2gMAALYAdAC/QP6AfYC+AH0AdwBZQHL + AdwBZQHLAdwBZQHLAeIBiQHTAvEB5wLsAd8C9AHlAtgB0AwAAtgB0AL9A/oB9gHtAdMB7gHLAWUB3AHL + AWUB3AHLAWUB3AHfAawB4wLxAecC7AHfAvQB5QLYAdAJAAPvA2wD7xgAA+8DbAPvDAADjwP2A7cDjwwA + A8wDfQPMDAAC2gHSAvwD+AH0AvcB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLzAeIC2gHSDAAC2gHS + AvwD+AH0AvcB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLzAeIC2gHSDAAD1AORA/kSAAP5A5ED1A8A + A84D1QN3A84MAAPsA3cD7AwAAtsB0wL8A/cB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC8gHh + AtsB0wwAAtsB0wL8A/cB8gL2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC8gHhAtsB0w8AA9UDlgP5 + DAAD+QOWA9USAAP2A6IDfgP2IQAC3AHVAvsD9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1ALy + AeEC3AHVDAAC3AHVAvsD9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1ALyAeEC3AHVEgAD1wOZ + A/oGAAP6A5kD1xgABpwkAALdAdYC+gH0AvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAqQBkwKkAZMCpAGT + AskBwAwAAt0B1gL6AfQC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUCpAGTAqQBkwKkAZMCyQHAFQAD2AOd + BgADnQPYRQAC3gHXAvoB8wL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1AK2AaUD/wLeAdcC9wH2DAAC3gHX + AvoB8wL0AewC8QHnAuwB3wLoAdkC5gHVAuUB1AK2AaUD/wLeAdcC9wH2bAAC3wHZAvwB9QL5Ae8C9gHq + AvQB5QLzAeIC8gHhAvIB4QLCAbEC3wHZAvcB9g8AAt8B2QL8AfUC+QHvAvYB6gL0AeUC8wHiAvIB4QLy + AeECwgGxAt8B2QL3AfZvAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfYSAALq + AeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfZsAAP7A/ECyAHDArgBsAK4AbACuAGw + ArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4 + AbACuAGwArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4AbACuAGw + ArgBsAK4AbACuAGwArgBsALIAcMD8Qb7A/ECyAHDArgBsAK4AbACuAGwArgBsAK4AbACuAGwArgBsAK4 + AbACuAGwArgBsALIAcMD8QP7A/0D+gLAAbgL/wP+Af0C/gH8Av0B+wL9AfoC/AH4Av4B+QLAAbgD+gb9 + A/oCwAG4C/8D/gH9Av4B/AL9AfsC/QH6AvwB+AL+AfkCwAG4A/oG/QP6AsABuAv/A/4B/QL+AfwC/QH7 + Av0B+gL8AfgC/gH5AsABuAP6Bv0D+gLAAbgL/wP+Af0C/gH8Av0B+wL9AfoC/AH4Av4B+QLAAbgD+gP9 + BgACyQHBBv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7 + AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7 + AfYCyQHBDAACyQHBBv8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL7AfYCyQHBDAACzwHHA/8D/gL9 + AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL3AfIC+wH1As8BxwwAAs8BxwP/A/4C/QH8Av0B+wL8AfkC+wH4 + AvoB9gL4AfQC9wHyAvsB9QLPAccMAALPAccD/wP+Av0B/AL9AfsC/AH5AvsB+AL6AfYC+AH0AvcB8gL7 + AfUCzwHHDAACzwHHA/8D/gL9AfwC/QH7AvwB+QL7AfgC+gH2AvgB9AL3AfIC+wH1As8BxwwAAtAByAL/ + Af4C/QH8AdwBzwHrAXsBSAG/AXsBSAG/AXsBSAG/AYsBXgHGAegB4QHrAvYB8AL6AfMC0AHIDAAC0AHI + Av8B/gL9AfwC/QH7AYIBwgG0AVkBrgGdAVkBrgGdAakB0wHIAvcB8gL2AfAC+gHzAtAByAwAAtAByAL/ + Af4C/QH8Av0B+wHeAaIBqQG/AUgBWQG/AUgBWQHcAaABpgL3AfIC9gHwAvoB8wLQAcgMAALQAcgC/wH+ + Av0B/AL9AfsBvwF7AUgBvwF7AUgBvwF7AUgB3AG6AZ4C9wHyAvYB8AL6AfMC0AHIDAAC0gHLAv4D/QH7 + Ad0B0QHtAYIBTwHGAvoB9gL4AfQBggFPAcYB2QHMAeUC9QHuAvoB8gLSAcsMAALSAcsC/gP9AfsC/AH5 + AvsB+AL6AfYB0gHoAeABYAG1AaQC9gHwAvUB7gL6AfIC0gHLDAAC0gHLAv4D/QH7AvwB+QL7AfgB4AGl + AasB0wF6AYUC9wHyAvYB8AL1Ae4C+gHyAtIBywwAAtIBywL+A/0B+wL8AfkBxgGCAU8B7AHbAcwC+AH0 + AvcB8gL2AfAC9QHuAvoB8gLSAcsMAALVAc0C/gP8AfkB3wHSAe0BigFXAc4BmAFsAdMBigFXAc4BpQF/ + AdcB5wHhAekC9AHsAvkB7wLVAc0MAALVAc0C/gP8AfkC+wH4AbIB3AHSAWgBvQGsAWgBvQGsAa4B2QHN + AvUB7gL0AewC+QHvAtUBzQwAAtUBzQL+A/wB+QL7AfgC+gH2AeMBqAGuAdkBfwGLAvYB8AL1Ae4C9AHs + AvkB7wLVAc0MAALVAc0C/gP8AfkC+wH4Ac4BigFXAe4B3QHMAvcB8gL2AfAC9QHuAvQB7AL5Ae8C1QHN + DAAC1gHOAv0D+wH4AeAB0wHuAZIBXwHWAvcB8gHdAdAB6QGSAV8B1gL0AewC8QHnAvcB6gLWAc4MAALW + Ac4C/QP7AfgC+gH2AXABxQG0AdUB6wHiAvYB8AL1Ae4C9AHsAvEB5wL3AeoC1gHODAAC1gHOAv0D+wH4 + AvoB9gL4AfQB5wGrAbEB3gGFAZAC9QHuAvQB7ALxAecC9wHqAtYBzgwAAtYBzgL9A/sB+AL6AfYB1gGS + AV8B7wHeAc0C9gHwAvUB7gL0AewC8QHnAvcB6gLWAc4MAALYAdAC/QP6AfYB4AHTAe4BmAFlAdwBmAFl + AdwBmAFlAdwBxQGsAeMC8QHnAuwB3wL0AeUC2AHQDAAC2AHQAv0D+gH2AvgB9AG3AeEB1QF2AcsBugF2 + AcsBugGVAdUBxgLxAecC7AHfAvQB5QLYAdAMAALYAdAC/QP6AfYC+AH0AeoBrwG0AdwBZQF2AdwBZQF2 + AegBrAGxAvEB5wLsAd8C9AHlAtgB0AwAAtgB0AL9A/oB9gL4AfQB3AGYAWUB7wHeAc0C9QHuAvQB7ALx + AecC7AHfAvQB5QLYAdAMAALaAdIC/AP4AfQC9wHyAvYB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLa + AdIMAALaAdIC/AP4AfQC9wHyAvYB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLaAdIMAALaAdIC/AP4 + AfQC9wHyAvYB8AL1Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLaAdIMAALaAdIC/AP4AfQC9wHyAvYB8AL1 + Ae4C9AHsAvEB5wLsAd8C6AHZAvMB4gLaAdIMAALbAdMC/AP3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLo + AdkC5gHVAvIB4QLbAdMMAALbAdMC/AP3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAvIB4QLb + AdMMAALbAdMC/AP3AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAvIB4QLbAdMMAALbAdMC/AP3 + AfIC9gHwAvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAvIB4QLbAdMMAALcAdUC+wP2AfAC9QHuAvQB7ALx + AecC7AHfAugB2QLmAdUC5QHUAvIB4QLcAdUMAALcAdUC+wP2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLm + AdUC5QHUAvIB4QLcAdUMAALcAdUC+wP2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC5QHUAvIB4QLc + AdUMAALcAdUC+wP2AfAC9QHuAvQB7ALxAecC7AHfAugB2QLmAdUC5QHUAvIB4QLcAdUMAALdAdYC+gH0 + AvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAqQBkwKkAZMCpAGTAskBwAwAAt0B1gL6AfQC9QHuAvQB7ALx + AecC7AHfAugB2QLmAdUCpAGTAqQBkwKkAZMCyQHADAAC3QHWAvoB9AL1Ae4C9AHsAvEB5wLsAd8C6AHZ + AuYB1QKkAZMCpAGTAqQBkwLJAcAMAALdAdYC+gH0AvUB7gL0AewC8QHnAuwB3wLoAdkC5gHVAqQBkwKk + AZMCpAGTAskBwAwAAt4B1wL6AfMC9AHsAvEB5wLsAd8C6AHZAuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwA + At4B1wL6AfMC9AHsAvEB5wLsAd8C6AHZAuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwAAt4B1wL6AfMC9AHs + AvEB5wLsAd8C6AHZAuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwAAt4B1wL6AfMC9AHsAvEB5wLsAd8C6AHZ + AuYB1QLlAdQCtgGlA/8C3gHXAvcB9gwAAt8B2QL8AfUC+QHvAvYB6gL0AeUC8wHiAvIB4QLyAeECwgGx + At8B2QL3AfYPAALfAdkC/AH1AvkB7wL2AeoC9AHlAvMB4gLyAeEC8gHhAsIBsQLfAdkC9wH2DwAC3wHZ + AvwB9QL5Ae8C9gHqAvQB5QLzAeIC8gHhAvIB4QLCAbEC3wHZAvcB9g8AAt8B2QL8AfUC+QHvAvYB6gL0 + AeUC8wHiAvIB4QLyAeECwgGxAt8B2QL3AfYPAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZ + AuAB2QL3AfYSAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfYSAALqAeYC4AHZ + AuAB2QLgAdkC4AHZAuAB2QLgAdkC4AHZAuAB2QL3AfYSAALqAeYC4AHZAuAB2QLgAdkC4AHZAuAB2QLg + AdkC4AHZAuAB2QL3AfYMAAFCAU0BPgcAAT4DAAEoAwABQAMAAUADAAEBAQABAQYAAQIWAAP/AgABAQEA + AQEFAAEBAQABAQUAAQEBAAEBBQABAQEAAQEFAAEBAQABAQUAAQEBAAEBBQABAQEAAQEFAAEBAQABAQUA + AQEBAAEBBQABAQEAAQEFAAEBAQABAQUAAQEBAAEBBQABAQEAAQEFAAEBAQABAQUAAQEBAAEBBAABgAED + AQABAQQABP8CAAH+AQEC/wUAAQEBiAMAAcABAQEAAQEBiAEAAYABAQHAAQEBAAEBAY8B/wGAAQEBwAEB + AQABAQL/AYABAQHAAQEBAAEBAv8BgAEBAcABAQEAAQEBjwH/AYABAQHAAQEBAAEBAYwBAQGAAQEBwAEB + AQABAQGPAf8BgAEBAcABAwEAAR8C/wGAAQEBwAEDAfABHwL/AYABAQHAAQMB8AEfAY8B/wGAAQEBwAED + AfABHwGMAQEBgAEBAcABAwHwAR8BjwH/AYABAQHAAQMB8AEfBP8BwAEDAfABHwQABP8EAAT/AcABAwHA + AQME/wHAAQMBwAEDAcABAwIAAcABAwHAAQMBwAEDAgABwAEDAcABAwHxAY8BzAHBAcABAwHAAQMB4wHH + AcABwQHAAQMBwAEDAccB4wHAAeMBwAEDAcABAwGPAfEB4QHjAcABAwHAAQMBxwHjAeEB4wHAAQMBwAED + AeMBxwHhAf8BwAEDAcABAwHxAY8B8wH/AcABAwHAAQMB+QGfAv8BwAEDAcABAwT/AcABBwHAAQcE/wHA + AQ8BwAEPBP8QAAHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHA + AQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHA + AQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHA + AQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQcBwAEHAcABBwHAAQcBwAEPAcABDwHAAQ8BwAEPCw== + + + + 132, 17 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ5SURBVDhPjdNdSFNhHMfx56Kb3i7scl10M28kIW+6kCDC + mF1EikF5IViDBMMkJQbKzHyZLiUVXc6hGdU0K0OTMFPBGkGpWIJiqznX3nybc3Oezb3663ke8sBJgg58 + Of/ncM6H58A5hPw5ZrTk+rSWVP1P7N6958TzVB2pESxarH28hvWJfAhz95BwdgHLT6Wt94Lduw/4XEs0 + 2HqNXd8rhB06eL8U470+A6PvmiSNjbdhsPZ4+z7gUy2pT2y+QHzNyEv4XmJm4BZcXi9WBAFOmj0QwBuT + CZpKxUiOWp0sQUxVpCHu6UVs+QmPzZN9SsxbLPhmNsPq8WBhZQU9w8NgR3ZZWaEEmbhLHsRWnyHifMRj + s+lxLr4vLnJk2e/nSJvRKJacmakWdzFWQVoi7m6EbB08Nk90XcGPpSWObNBX2EPYTtjrKEpKikRgpJzo + duydECw6HpvHDTmw2Gwc8QWDEsS5vY2MoqJiEXirIvrQkh4BcwuPzSPtWbDa7RzZ2tmRIKuhEM4WFNwW + gUEV6RR+tsI/38hj83DrRdgowBAhHJYgm3R9RqksFYH+UtIdWGiCd7aex+ah5guwOxwcCUWjEiRA16fz + 8u6IQG8xMfrnGuCZqeaxeaBRAYfTyZFwLCZBBAqk5eaqGHCQdsxwgwz5ZumnPFXJ89Fd9N8/D5fLxZFY + PC5BghQ8mZVVwYAkmrxQQTpGW9IC1qHC6MZ0NTa/atBXdw5utxsuWmJ3F3FaNJFAhGIROsvS07WSr9FQ + QLL1SmJ4Xi77MNlz6Zfq8gHHIbm87XBKSsPR1NT6vzsil9/c90+wC8355FRjHlHXXCUP6fIETfaPkn4D + qvVdCMceSq0AAAAASUVORK5CYII= + + + + + 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 + RpkLgwRoAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG9SURBVDhPjZLNSwJRFMVdFu1a1DrIhRC0CCKiVUG5KIi0 + KGjRxkpKwpAJ1BgIpEWboH8gwqIoCiHaBv4L1UIQ+8ISkcpxZvz2ds/QRPLMenB4PDj3x73nXYvl68xs + bk5My/JiMzlludv0C7czEFjSKhV6LxYpreuUVFV6yuXoUVEMRaJRgmcqGLQ2hEz6/cu5UokyXPiazdJ9 + JkOxVIruXl7oNpmkw6srwoGvIWRCktwqA940rSFkLxwmU9axsaDQxbjPt6KXy/TB7f8GQScYB14BMOr1 + ruY5AyWfbwoBAF4BMOLxeAoMUAuFphAEC68AGHa710rVKumcAyCXF2mSXHFDkbPUd7D4HXgFwJDL5S0z + oMA5mJDI6SvthhJ1maR5RHgFwODCwnqlVqMij2FCzo+faUeO1WWCPYFXAPTPz/uqDEAXJuT08IFC/pu6 + TBQeEV4B0Dc7K9V4USoMAOTkIEFz9mtDR/vxbwiWDV4B0OtwbGDTatyFCfk5jvk7GmcErwCw2u0BY1f/ + gGDZ4P0JaOVHR+fAwJYJMCAsZIJgMRK+GHtS5De8qGGh1tLO6mnp6lpvs9m2/yN4UYPaT6iBRnEAJMyK + AAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGzSURBVDhPjZK9S4JRFMYdi7aGmoUchKAhCImmgnRIiuzD + QcjFSkpCEQM/EFyCxlqamuwPaHFoCRyarKmCyIoCTUQ0X/X1+z2dR3olumZdeLhceM6Pc557NJqvsxYK + mVfD4c1+WgmHx1S/cK8EAluVVosK9TplZZlS5TK9lUr0KkkdncfjBM9yMKjrCVny+7dLjQbluPC9WKSX + XI4eMhm6S6fpNpWis1iMcODrCTH7fM4yA/KVSk/IcTRKqnRGY1DoYsHr3ZGbTfrg9n+DoBOMA68AmHe7 + d6ucgVSt9oUAAK8AmHO5XDUGlGu1vhAEC68AmHU69xrtNsmcAyCOkyRdPxeEcfA78AqAGYfD3WRAjXMA + ZOPovgP4mUmWR4RXAEzb7Z6WolCdxwBk/fCGEk95YRzsCbwCYMpm87YZgC4AWYxcUeIxJ2QicXfwCoBJ + q9Wn8KK0GACIKXDZ1elFstsJlg1eATBhsexj0xTuQoWo46jB4osrPB68AkBnMgU6u/oHBMsG73fAID9G + Rg2GiAroQFjIBMFiJHwx9qTOb3hRw0KtZpg1PqDVeob0+oP/CF7UoPYTXb5IoCRPHYoAAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG1SURBVDhPjZK9S4JRFMYdi7aGmoUchKAhCImmgnRIirRy + EHKxkpJQxMAPhJZo7l+oxqAhtwiEWgIjKiEIIuE1kZfM1+/P03mk9yW4Zl14uFx4zo9znnt0uu+zGo1a + V2KxjX6yx2Jjql+47eHwZrnVony9TrlKhaRSidLFIr0pSlfniQTBsxyJGHpClkKhrWKjQTIXvhcK9CrL + 9JzN0lMmQ4+SRCfxOOHA1xNiDQY9JQZ8lMs9IUfHx6TKYDZHhC4WAoHtSrNJn9z+bxB0gnHgFQDzPt9O + lTNQqtW+EADgFQBzXq+3xoBSrdYXgmDhFQCzHs9uo92mCucAyK37RdPDYVoLFr8DrwCYcbt9TQbUOAdA + rtdTlLnPC+PkeER4BcC0y+VvdTpU5zEAuVxLakqdprVgsSfwCoAppzPQZgC6AORi8YakO1nIROHu4BUA + kw5HsMOL0mIAIGeWK5KSspaJ+jtYNngFwITNtodN63AXKkQdRw0WkDKPB68AMFgs4e6u/gHBssH7EzDI + j5FRk2lfBXQhLGSCYDESvhh7Uuc3vKhhoVY3zBof0Ov9Q0bjwX8EL2pQ+wUVkUjMVKxfkgAAAABJRU5E + rkJggg== + + + + + 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 + + + + 347, 17 + + + + AAABAAQAMDAAAAEAIACoJQAARgAAACAgAAABACAAqBAAAO4lAAAYGAAAAQAgAIgJAACWNgAAEBAAAAEA + IABoBAAAHkAAACgAAAAwAAAAYAAAAAEAIAAAAAAAgCUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAABjRbAAY0WwsGNFvIBTNa/wo5Yf8jXo3/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAABTNaAAUzWgsFM1rIBDJZ/wk4YP8iXYz/KGSU/yZhkf8NPmf/BTNa/wY0 + W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzVdAAc1XQsHNV3IBjRc/ws6Yv8jXo3/KGSU/yZh + kf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIFiGACBYhgsgWIbIH1iG/yFa + iP8mYpL/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk + lAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZhkf8NPmf/BTNa/wY0 + W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAChk + lAAoZJQAKGSUAChklAAoZJQAKGSUAAAAAAAAAAAAKGSUAChklAsoZJTIKGSU/yhklP8oZJT/KGSU/yZh + kf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAChklAAoZJQGKGSUCihklAkoZJQCKGSUAAAAAAAAAAAAJmKRACZikQsmYpHIJmKR/yZi + kv8nY5P/KGSU/yZhkf8NPmf/BTNa/wY0W+AGNFscBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + lAAoZJQAKGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAgoZJSuKGSU4CNejeAjXo30I16N/yRejf8nYpL/KGSU/yNe + jf8KOWH/BTNa/wY0W/QGNFtOBjRbHgY0WxoGNFsDBjRbAAY0WwoGNFuxBjRb4AY0W8QGNFsYBjRbAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAEoZJQXKGSUHgo5YR4KOWGxCThg/wo7 + Y/8gWoj/KGSU/yNejf8KOWH/BTNa/wY0W/0GNFvmBjRb4AY0W8UGNFsYBjRbAAY0WwEGNFsYBjRbHgY0 + WxoGNFsDBjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEURuABFEbgARRG4AEURuAAUz + WgAFM1mkBDFY/wY0W/8gWYf/KGWV/yNejf8JOGD/BDJZ/wUzWv8FM1r/BjRb/wY0W+EGNFsYBjRbAAY0 + WwAGNFsABjRbAAY0WwAGNFsABjRbAAY0WwAGNFsABjRbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjRbAAY0 + WwIGNFsqBjRbNgY0WzYKOmK5DD1m/w0/aP8bU4D/IFqI/x1Wg/8PQGr/DD1m/ww9Zv8HNl3/BTNa/wY0 + W+YGNFtMBjRbNgY0WzMGNFsLBjRbAAY0WwYGNFswBjRbNgY0WyoGNFsCBjRbAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAABjRbAAY0WwkGNFu9BjRb9AY0W/QbUX77JmKS/yRfjv8NP2j/BjRb/ws6Yv8hXIv/JmGR/yRf + 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 + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklBMoZJSRKGSUpChklH4oZJQGKGSUAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZJQAKGSUACdjkx4nY5PgJ2OT/ydj + k/MnY5M2J2OTAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklAAoZJQAKGSUAChklAAoZJQAKGSUAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKGSUAChk + lB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKGSUAChklB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAKGSUAChklB4oZJTgKGSU/yhklPMoZJQ2KGSUAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + 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 + AADmBwAA/nMAAP53AAD/fwAA/38AAA== + + \ No newline at end of file diff --git a/NBTExplorer.csproj b/NBTExplorer.csproj index c1b0390..c6874f6 100644 --- a/NBTExplorer.csproj +++ b/NBTExplorer.csproj @@ -1,149 +1,161 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {8A458245-8176-4599-95CD-3CA39F2435CE} - WinExe - Properties - NBTExplorer - NBTExplorer - v4.0 - Client - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - dead_bush.ico - - - - ..\Substrate\SubstrateCS\bin\Release\NET4\Substrate.dll - - - - - - - - - - - Form - - - About.cs - - - Form - - - EditValue.cs - - - Form - - - Find.cs - - - Form - - - Form1.cs - - - - - About.cs - - - EditValue.cs - - - Find.cs - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + Debug + x86 + 8.0.30703 + 2.0 + {8A458245-8176-4599-95CD-3CA39F2435CE} + WinExe + Properties + NBTExplorer + NBTExplorer + v4.0 + Client + 512 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + dead_bush.ico + + + + + + + + + + + + Form + + + About.cs + + + + + Form + + + EditValue.cs + + + Form + + + Find.cs + + + Form + + + Form1.cs + + + + + + + + + + + + + About.cs + + + EditValue.cs + + + Find.cs + + + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {7264A1C4-AB4A-4437-B252-7379B98B5509} + Substrate %28NET4%29 + + + + --> \ No newline at end of file diff --git a/NbtDataNode.cs b/NbtDataNode.cs new file mode 100644 index 0000000..06bcda4 --- /dev/null +++ b/NbtDataNode.cs @@ -0,0 +1,18 @@ +using Substrate.Nbt; + +namespace NBTExplorer +{ + public class NbtDataNode : DataNode + { + public NbtDataNode() + { + } + + public NbtDataNode(DataNode parent) + : base(parent) + { + } + + public NbtTree Tree { get; set; } + } +} \ No newline at end of file diff --git a/NbtFileData.cs b/NbtFileData.cs new file mode 100644 index 0000000..35ad680 --- /dev/null +++ b/NbtFileData.cs @@ -0,0 +1,22 @@ +using Substrate.Core; + +namespace NBTExplorer +{ + public class NbtFileData : NbtDataNode + { + public NbtFileData(string path, CompressionType cztype) + : this(null, path, cztype) + { + } + + public NbtFileData(DataNode parent, string path, CompressionType cztype) + : base(parent) + { + Path = path; + CompressionType = cztype; + } + + public string Path { get; private set; } + public CompressionType CompressionType { get; private set; } + } +} \ No newline at end of file diff --git a/RegionChunkData.cs b/RegionChunkData.cs new file mode 100644 index 0000000..7dfe1b5 --- /dev/null +++ b/RegionChunkData.cs @@ -0,0 +1,24 @@ +using Substrate.Core; + +namespace NBTExplorer +{ + public class RegionChunkData : NbtDataNode + { + public RegionChunkData(RegionFile file, int x, int z) + : this(null, file, x, z) + { + } + + public RegionChunkData(DataNode parent, RegionFile file, int x, int z) + : base(parent) + { + Region = file; + X = x; + Z = z; + } + + public RegionFile Region { get; private set; } + public int X { get; private set; } + public int Z { get; private set; } + } +} \ No newline at end of file diff --git a/RegionData.cs b/RegionData.cs new file mode 100644 index 0000000..5a5155f --- /dev/null +++ b/RegionData.cs @@ -0,0 +1,18 @@ +namespace NBTExplorer +{ + public class RegionData : DataNode + { + public RegionData(string path) + : this(null, path) + { + } + + public RegionData(DataNode parent, string path) + : base(parent) + { + Path = path; + } + + public string Path { get; private set; } + } +} \ No newline at end of file diff --git a/StringExtensions.cs b/StringExtensions.cs new file mode 100644 index 0000000..5f9ca18 --- /dev/null +++ b/StringExtensions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NBTExplorer +{ + public static class StringExtensions + { + public static bool IsNullOrEmpty(this string s) + { + return string.IsNullOrEmpty(s); + } + } +} diff --git a/SubstrateHelper.cs b/SubstrateHelper.cs new file mode 100644 index 0000000..5128d73 --- /dev/null +++ b/SubstrateHelper.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Substrate.Nbt; +using Substrate; + +namespace NBTExplorer +{ + public class SubstrateHelper + { + + public static void LoadWorld(string path) + { + NbtWorld world = NbtWorld.Open(path); + + BetaWorld beta = world as BetaWorld; + if (beta != null) + { + LoadBetaWorld(beta); + } + } + + private static void LoadBetaWorld(BetaWorld world) + { + RegionManager rm = world.GetRegionManager(); + } + + public static string GetNodeText(string name, string value) + { + name = String.IsNullOrEmpty(name) ? "" : name + ": "; + value = value ?? ""; + + return name + value; + } + + public static string GetNodeText(string name, TagNode tag) + { + return GetNodeText(name,SubstrateHelper. GetTagNodeText(tag)); + } + public static string GetTagNodeText(TagNode tag) + { + if (tag == null) + return null; + + switch (tag.GetTagType()) + { + case TagType.TAG_BYTE: + case TagType.TAG_SHORT: + case TagType.TAG_INT: + case TagType.TAG_LONG: + case TagType.TAG_FLOAT: + case TagType.TAG_DOUBLE: + case TagType.TAG_STRING: + return tag.ToString(); + + case TagType.TAG_BYTE_ARRAY: + return tag.ToTagByteArray().Length + " bytes"; + + case TagType.TAG_LIST: + return tag.ToTagList().Count + " entries"; + + case TagType.TAG_COMPOUND: + return tag.ToTagCompound().Count + " entries"; + } + + return null; + } + } +} diff --git a/TagKey.cs b/TagKey.cs new file mode 100644 index 0000000..d18b778 --- /dev/null +++ b/TagKey.cs @@ -0,0 +1,39 @@ +using System; +using Substrate.Nbt; + +namespace NBTExplorer +{ + public class TagKey : IComparable + { + public TagKey(string name, TagType type) + { + Name = name; + TagType = type; + } + + public string Name { get; set; } + public TagType TagType { get; set; } + + #region IComparer Members + + public int Compare(TagKey x, TagKey y) + { + int typeDiff = (int)x.TagType - (int)y.TagType; + if (typeDiff != 0) + return typeDiff; + + return String.Compare(x.Name, y.Name, true); + } + + #endregion + + #region IComparable Members + + public int CompareTo(TagKey other) + { + return Compare(this, other); + } + + #endregion + } +} \ No newline at end of file diff --git a/UIHelper.cs b/UIHelper.cs new file mode 100644 index 0000000..e275fd2 --- /dev/null +++ b/UIHelper.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Substrate; +using Substrate.Nbt; + +namespace NBTExplorer +{ + public class UIHelper + { + + internal static ItemInfo TryGetItemName(TagNode tag) + { + + var tagc = tag as TagNodeCompound; + if (tagc.ContainsKey("id") == false) + return null; + int id; + if (int.TryParse(tagc["id"].ToString(), out id)) + { + return Substrate.ItemInfo.ItemTable[id]; + } + return null; + + + } + } +} From 59fa7006da53ac0833853d8edab5c3b08b679c43 Mon Sep 17 00:00:00 2001 From: ImaginaryDevelopment Date: Sun, 19 Feb 2012 18:06:14 -0800 Subject: [PATCH 3/8] added feature to allow find populated chunks to find next on next click --- About.cs | 8 +- EditValue.cs | 14 +- Find.cs | 7 +- Form1.Designer.cs | 6 +- Form1.cs | 479 +++++++++++++++++++++++++------------------- Program.cs | 3 +- StringExtensions.cs | 6 +- SubstrateHelper.cs | 5 +- UIHelper.cs | 6 +- 9 files changed, 287 insertions(+), 247 deletions(-) diff --git a/About.cs b/About.cs index 279e5cf..e172265 100644 --- a/About.cs +++ b/About.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; +using System.Windows.Forms; namespace NBTExplorer { diff --git a/EditValue.cs b/EditValue.cs index 29fead5..432df99 100644 --- a/EditValue.cs +++ b/EditValue.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; +using System.Collections.Generic; using System.Windows.Forms; using Substrate.Nbt; @@ -17,11 +13,11 @@ public enum EditValueType public partial class EditValue : Form { - private string _name; - private TagNode _tag; - private EditValueType _type; + string _name; + readonly TagNode _tag; + readonly EditValueType _type; - private List _invalidNames = new List(); + readonly List _invalidNames = new List(); public EditValue (TagNode tag) { diff --git a/Find.cs b/Find.cs index 0f45d2a..6271904 100644 --- a/Find.cs +++ b/Find.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; +using System; using System.Windows.Forms; namespace NBTExplorer diff --git a/Form1.Designer.cs b/Form1.Designer.cs index 3d844d8..3fba7df 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -160,7 +160,7 @@ private void InitializeComponent () this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4))); this.exitToolStripMenuItem.Size = new System.Drawing.Size(223, 22); this.exitToolStripMenuItem.Text = "E&xit"; - this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click); + this.exitToolStripMenuItem.Click += new System.EventHandler(exitToolStripMenuItem_Click); // // searchToolStripMenuItem // @@ -205,7 +205,7 @@ private void InitializeComponent () this.aboutToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F1; this.aboutToolStripMenuItem.Size = new System.Drawing.Size(126, 22); this.aboutToolStripMenuItem.Text = "&About"; - this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click); + this.aboutToolStripMenuItem.Click += new System.EventHandler(aboutToolStripMenuItem_Click); // // toolStripContainer1 // @@ -257,7 +257,7 @@ private void InitializeComponent () this._nodeTree.Size = new System.Drawing.Size(562, 351); this._nodeTree.TabIndex = 0; this._nodeTree.DragDrop += new System.Windows.Forms.DragEventHandler(this._nodeTree_DragDrop); - this._nodeTree.DragEnter += new System.Windows.Forms.DragEventHandler(this._nodeTree_DragEnter); + this._nodeTree.DragEnter += new System.Windows.Forms.DragEventHandler(_nodeTree_DragEnter); // // imageList1 // diff --git a/Form1.cs b/Form1.cs index 7579b2a..ffceb5d 100644 --- a/Form1.cs +++ b/Form1.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Windows.Forms; -using Substrate; using Substrate.Core; using Substrate.Nbt; @@ -12,7 +11,7 @@ namespace NBTExplorer { public partial class Form1 : Form { - private static Dictionary _tagIconIndex; + readonly static Dictionary _tagIconIndex; public Form1() { @@ -24,7 +23,7 @@ public Form1() _nodeTree.NodeMouseClick += NodeClicked; _nodeTree.NodeMouseDoubleClick += NodeDoubleClicked; - string[] args = Environment.GetCommandLineArgs(); + var args = Environment.GetCommandLineArgs(); if (args.Length > 1) { OpenFile(args[1]); @@ -35,14 +34,14 @@ public Form1() } } - public void LoadNbtStream(TreeNodeCollection parent, Stream stream) + void LoadNbtStream(TreeNodeCollection parent, Stream stream) { - LoadNbtStream(parent, stream, null); + LoadNbtStream(parent, stream); } - public void LoadNbtStream(TreeNodeCollection parent, Stream stream, string name) + void LoadNbtStream(TreeNodeCollection parent, Stream stream, string name = null) { - string text = !String.IsNullOrEmpty(name) ? name : null; + var text = !String.IsNullOrEmpty(name) ? name : null; text = text ?? "[root]"; TreeNode root = new TreeNode(text, 9, 9); @@ -52,7 +51,7 @@ public void LoadNbtStream(TreeNodeCollection parent, Stream stream, string name) parent.Add(root); } - public void LoadNbtStream(TreeNode node, Stream stream) + void LoadNbtStream(TreeNode node, Stream stream) { NbtTree tree = new NbtTree(); tree.ReadFrom(stream); @@ -65,18 +64,16 @@ public void LoadNbtStream(TreeNode node, Stream stream) PopulateNodeFromTag(node, tree.Root); } - private TreeNode NodeFromTag(TagNode tag) + TreeNode NodeFromTag(TagNode tag) { return NodeFromTag(tag, null); } - private TreeNode NodeFromTag(TagNode tag, string name) + TreeNode NodeFromTag(TagNode tag, string name) { - TreeNode node = new TreeNode(); - node.ImageIndex = _tagIconIndex[tag.GetTagType()]; - node.SelectedImageIndex = _tagIconIndex[tag.GetTagType()]; - node.Tag = tag; - node.Text =SubstrateHelper. GetNodeText(name, tag); + var text = SubstrateHelper.GetNodeText(name, tag); + var node=InitializeTreeNode(_tagIconIndex[tag.GetTagType()], text, tag); + if (tag.GetTagType() == TagType.TAG_LIST) { @@ -90,26 +87,26 @@ private TreeNode NodeFromTag(TagNode tag, string name) return node; } - private string GetNodeText(TreeNode node) + static string GetNodeText(TreeNode node) { - return SubstrateHelper.GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); + return SubstrateHelper.GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); } - private string GetTagNodeText(TreeNode node) + static string GetTagNodeText(TreeNode node) { TagNode tag = GetTagNode(node); if (tag == null) return null; - return SubstrateHelper. GetTagNodeText(tag); + return SubstrateHelper.GetTagNodeText(tag); } - private void PopulateNodeFromTag(TreeNode parentNode, TagNodeList list) + void PopulateNodeFromTag(TreeNode parentNode, IEnumerable list) { foreach (TagNode tag in list) { var node = NodeFromTag(tag); - if (parentNode.Text.StartsWith("Inventory")|| parentNode.Text.StartsWith("Item")) + if (parentNode.Text.StartsWith("Inventory") || parentNode.Text.StartsWith("Item")) { Debug.Assert(tag.IsCastableTo(TagType.TAG_COMPOUND)); @@ -117,12 +114,14 @@ private void PopulateNodeFromTag(TreeNode parentNode, TagNodeList list) if (item != null) { - - TreeNode newNode = new TreeNode(); + + var newNode = new TreeNode(); //node.ImageIndex = _tagIconIndex[0]; //node.SelectedImageIndex = _tagIconIndex[0]; newNode.Text = item.Name; + node.ImageIndex = this.imageList1.Images.Count; + node.SelectedImageIndex = this.imageList1.Images.Count; newNode.ToolTipText = "StackSize:" + item.StackSize.ToString(); node.Nodes.Insert(0, newNode); @@ -138,7 +137,7 @@ private void PopulateNodeFromTag(TreeNode parentNode, TagNodeList list) } } - private void PopulateNodeFromTag(TreeNode node, TagNodeCompound dict) + void PopulateNodeFromTag(TreeNode node, IEnumerable> dict) { if (dict == null) return; @@ -154,14 +153,14 @@ private void PopulateNodeFromTag(TreeNode node, TagNodeCompound dict) } } - void LoadRegion(TreeNodeCollection parent, string path) + void LoadRegion(TreeNodeCollection parent, string path) { TreeNode root = new TreeNode(Path.GetFileName(path), 11, 11); LoadRegion(root, path); parent.Add(root); } - void LoadRegion(TreeNode node, string path) + static void LoadRegion(TreeNode node, string path) { RegionFile rf = new RegionFile(path); @@ -179,55 +178,56 @@ void LoadRegion(TreeNode node, string path) } } - TreeNode CreateLazyChunk(RegionFile rf, int x, int z) + static TreeNode CreateLazyChunk(RegionFile rf, int x, int z) { - TreeNode node = new TreeNode(); - node.ImageIndex = 9; - node.SelectedImageIndex = 9; - node.Text = "Chunk [" + x + ", " + z + "]"; - node.Tag = new RegionChunkData(rf, x, z); - node.Nodes.Add(new TreeNode()); + return InitializeParentNode(9, "Chunk [" + x + ", " + z + "]", new RegionChunkData(rf, x, z)); + } + static TreeNode InitializeTreeNode(Int32 imageIndex, string text, object tag) + { + var node = new TreeNode + { + ImageIndex = imageIndex, + SelectedImageIndex = imageIndex, + Text = text, + Tag = tag + }; return node; } - TreeNode CreateLazyRegion(string path) + static TreeNode InitializeParentNode(Int32 imageIndex, string text, object tag) + { + + var node = InitializeTreeNode(imageIndex, text, tag); + node.Nodes.Add(new TreeNode()); //add stub so that it shows as expandable + return node; + } + + static TreeNode CreateLazyRegion(string path) { - TreeNode node = new TreeNode(); - node.ImageIndex = 11; - node.SelectedImageIndex = 11; - node.Text = Path.GetFileName(path); - node.Tag = new RegionData(path); - node.Nodes.Add(new TreeNode()); + var fileName = Path.GetFileName(path); + var node = InitializeParentNode(11, fileName, new RegionData(path)); return node; } - TreeNode CreateLazyNbt(string path, CompressionType cztype) + static TreeNode CreateLazyNbt(string path, CompressionType cztype) { - TreeNode node = new TreeNode(); - node.ImageIndex = 12; - node.SelectedImageIndex = 12; - node.Text = Path.GetFileName(path); - node.Tag = new NbtFileData(path, cztype); - node.Nodes.Add(new TreeNode()); + var fileName = Path.GetFileName(path); + var node = InitializeParentNode(12, fileName,new NbtFileData(path, cztype)); return node; } - TreeNode CreateLazyDirectory(string path) + static TreeNode CreateLazyDirectory(string path) { - TreeNode node = new TreeNode(); - node.ImageIndex = 10; - node.SelectedImageIndex = 10; - node.Text = Path.GetFileName(path); - node.Tag = new DirectoryData(path); - node.Nodes.Add(new TreeNode()); + var filename = Path.GetFileName(path); + var node = InitializeParentNode(10, filename, new DirectoryData(path)); return node; } - TreeNode CreateLazyDirectory(string path, TreeNode parent) + static TreeNode CreateLazyDirectory(string path, TreeNode parent) { TreeNode node = CreateLazyDirectory(path); LinkDataNodeParent(node, parent); @@ -235,15 +235,15 @@ TreeNode CreateLazyDirectory(string path, TreeNode parent) return node; } - TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode parent) + TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode parent) { - TreeNode node = CreateLazyNbt(path, cztype); + var node = CreateLazyNbt(path, cztype); LinkDataNodeParent(node, parent); return node; } - void LinkDataNodeParent(TreeNode node, TreeNode parent) + static void LinkDataNodeParent(TreeNode node, TreeNode parent) { if (node != null && parent != null && node.Tag != null && parent.Tag != null) { @@ -257,7 +257,7 @@ void LinkDataNodeParent(TreeNode node, TreeNode parent) } } - void LoadLazyChunk(TreeNode node) + void LoadLazyChunk(TreeNode node) { RegionChunkData data = node.Tag as RegionChunkData; if (data == null || data.Modified) @@ -269,7 +269,7 @@ void LoadLazyChunk(TreeNode node) data.Expanded = true; } - void LoadLazyNbt(TreeNode node) + void LoadLazyNbt(TreeNode node) { NbtFileData data = node.Tag as NbtFileData; if (data == null || data.Modified) @@ -283,9 +283,9 @@ void LoadLazyNbt(TreeNode node) data.Expanded = true; } - void LoadLazyDirectory(TreeNode node) + static void LoadLazyDirectory(TreeNode node) { - DirectoryData data = node.Tag as DirectoryData; + var data = node.Tag as DirectoryData; if (data == null || data.Modified) return; @@ -304,7 +304,7 @@ void LoadLazyDirectory(TreeNode node) data.Expanded = true; } - void LoadLazyRegion(TreeNode node) + static void LoadLazyRegion(TreeNode node) { RegionData data = node.Tag as RegionData; if (data == null || data.Modified) @@ -316,7 +316,7 @@ void LoadLazyRegion(TreeNode node) data.Expanded = true; } - void UnloadLazyDataNode(TreeNode node) + static void UnloadLazyDataNode(TreeNode node) { DataNode data = node.Tag as DataNode; if (data == null || data.Modified) @@ -328,7 +328,7 @@ void UnloadLazyDataNode(TreeNode node) data.Expanded = false; } - void ExpandNode(TreeNode node) + void ExpandNode(TreeNode node) { if (node.Tag == null) return; @@ -357,7 +357,7 @@ void ExpandNode(TreeNode node) } } - void CollapseNode(TreeNode node) + static void CollapseNode(TreeNode node) { if (node.Tag == null) return; @@ -368,32 +368,7 @@ void CollapseNode(TreeNode node) } } - void NodeExpand(object sender, TreeViewCancelEventArgs e) - { - ExpandNode(e.Node); - } - - private void NodeCollapse(object sender, TreeViewEventArgs e) - { - CollapseNode(e.Node); - } - - void NodeSelected(object sender, TreeViewEventArgs e) - { - UpdateToolbar(); - } - - private void NodeClicked(object sender, TreeNodeMouseClickEventArgs e) - { - - } - - void NodeDoubleClicked(object sender, TreeNodeMouseClickEventArgs e) - { - EditNodeValue(_nodeTree.SelectedNode); - } - - void UpdateToolbar() + void UpdateToolbar() { TreeNode node = _nodeTree.SelectedNode; TagNode tag = node.Tag as TagNode; @@ -458,7 +433,7 @@ void UpdateToolbar() } } - void SetTagButtons(bool state) + void SetTagButtons(bool state) { var toEnable = new[] { @@ -472,10 +447,10 @@ void SetTagButtons(bool state) } - void OpenDirectory(string path) + void OpenDirectory(string path) { _nodeTree.Nodes.Clear(); - + findEntityChunkToolStripMenuItem.DropDownItems.Clear(); LoadDirectory(path); if (_nodeTree.Nodes.Count > 0) @@ -484,10 +459,10 @@ void OpenDirectory(string path) } } - void OpenPaths(string[] paths) + void OpenPaths(IEnumerable paths) { _nodeTree.Nodes.Clear(); - + findEntityChunkToolStripMenuItem.DropDownItems.Clear(); foreach (string path in paths) { if (Directory.Exists(path)) @@ -506,7 +481,7 @@ void OpenPaths(string[] paths) } } - void OpenMinecraftDir() + void OpenMinecraftDir() { string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); path = Path.Combine(path, ".minecraft"); @@ -520,17 +495,17 @@ void OpenMinecraftDir() OpenDirectory(path); } - void LoadDirectory(string path) + void LoadDirectory(string path) { LoadDirectory(path, _nodeTree.Nodes); } - void LoadDirectory(string path, TreeNodeCollection parent) + void LoadDirectory(string path, TreeNodeCollection parent) { LoadDirectory(path, parent, path); } - void LoadDirectory(string path, TreeNodeCollection parent, string name) + static void LoadDirectory(string path, TreeNodeCollection parent, string name) { TreeNode root = new TreeNode(name, 10, 10); @@ -547,7 +522,7 @@ void LoadDirectory(string path, TreeNodeCollection parent, string name) parent.Add(root); } - void TryLoadFile(TreeNodeCollection parent, string path) + static void TryLoadFile(TreeNodeCollection parent, string path) { if (Path.GetExtension(path) == ".mcr") { @@ -609,12 +584,14 @@ void OpenFile() if (ofd.ShowDialog() == DialogResult.OK) { OpenPaths(ofd.FileNames); + findEntityChunkToolStripMenuItem.DropDownItems.Clear(); } } void OpenFile(string file) { _nodeTree.Nodes.Clear(); + findEntityChunkToolStripMenuItem.DropDownItems.Clear(); TryLoadFile(_nodeTree.Nodes, file); } @@ -629,6 +606,7 @@ void OpenFolder() { _openFolderPath = ofd.SelectedPath; OpenDirectory(ofd.SelectedPath); + } } @@ -640,7 +618,7 @@ void SaveAll() } } - void SaveNode(TreeNode node) + static void SaveNode(TreeNode node) { foreach (TreeNode sub in node.Nodes) { @@ -660,7 +638,7 @@ void SaveNode(TreeNode node) } } - void SaveNbtFileNode(TreeNode node) + static void SaveNbtFileNode(TreeNode node) { NbtFileData data = node.Tag as NbtFileData; if (data == null || !data.Modified) @@ -674,7 +652,7 @@ void SaveNbtFileNode(TreeNode node) data.Modified = false; } - void SaveRegionChunkNode(TreeNode node) + static void SaveRegionChunkNode(TreeNode node) { RegionChunkData data = node.Tag as RegionChunkData; if (data == null || !data.Modified) @@ -687,27 +665,8 @@ void SaveRegionChunkNode(TreeNode node) data.Modified = false; } - void aboutToolStripMenuItem_Click(object sender, EventArgs e) - { - new About().Show(); - } - void openToolStripMenuItem_Click(object sender, EventArgs e) - { - OpenFile(); - } - - private void openFolderToolStripMenuItem_Click(object sender, EventArgs e) - { - OpenFolder(); - } - - void toolStripButton1_Click(object sender, EventArgs e) - { - OpenFile(); - } - - TreeNode BaseNode(TreeNode node) + static TreeNode BaseNode(TreeNode node) { if (node == null) return null; @@ -723,7 +682,7 @@ TreeNode BaseNode(TreeNode node) #region Tag Deletion - void DeleteNode(TreeNode node) + static void DeleteNode(TreeNode node) { TreeNode baseNode = BaseNode(node); @@ -743,12 +702,9 @@ void DeleteNode(TreeNode node) node.Remove(); } - void _buttonDelete_Click(object sender, EventArgs e) - { - DeleteNode(_nodeTree.SelectedNode); - } - void DeleteNodeNbtTag(TreeNode node) + + static void DeleteNodeNbtTag(TreeNode node) { TagNode tag = node.Tag as TagNode; if (tag == null) @@ -778,7 +734,7 @@ void DeleteNodeNbtTag(TreeNode node) } } - void DeleteTagFromCompound(TagNodeCompound parent, TagNode target) + static void DeleteTagFromCompound(IDictionary parent, TagNode target) { string match = ""; foreach (KeyValuePair kv in parent) @@ -798,12 +754,8 @@ void DeleteTagFromCompound(TagNodeCompound parent, TagNode target) #endregion - void _buttonSave_Click(object sender, EventArgs e) - { - SaveAll(); - } - TagNode GetTagNode(TreeNode node) + static TagNode GetTagNode(TreeNode node) { if (node == null) return null; @@ -824,7 +776,7 @@ TagNode GetTagNode(TreeNode node) return null; } - TagNode GetParentTagNode(TreeNode node) + static TagNode GetParentTagNode(TreeNode node) { if (GetTagNode(node) == null) return null; @@ -832,7 +784,7 @@ TagNode GetParentTagNode(TreeNode node) return GetTagNode(node.Parent); } - string GetTagNodeName(TreeNode node) + static string GetTagNodeName(TreeNode node) { TagNode tag = GetTagNode(node); if (tag == null) @@ -854,7 +806,7 @@ string GetTagNodeName(TreeNode node) return null; } - bool SetTagNodeName(TreeNode node, string name) + static bool SetTagNodeName(TreeNode node, string name) { TagNode tag = GetTagNode(node); if (tag == null) @@ -886,7 +838,7 @@ bool SetTagNodeName(TreeNode node, string name) return true; } - void EditNodeValue(TreeNode node) + static void EditNodeValue(TreeNode node) { if (node == null) return; @@ -913,12 +865,9 @@ void EditNodeValue(TreeNode node) } } - void _buttonEdit_Click(object sender, EventArgs e) - { - EditNodeValue(_nodeTree.SelectedNode); - } - void EditNodeName(TreeNode node) + + static void EditNodeName(TreeNode node) { if (node == null) return; @@ -931,9 +880,9 @@ void EditNodeName(TreeNode node) if (name == null) return; - EditValue form = new EditValue(name); + var form = new EditValue(name); - TagNode parentTag = GetParentTagNode(node); + var parentTag = GetParentTagNode(node); foreach (string key in parentTag.ToTagCompound().Keys) { form.InvalidNames.Add(key); @@ -952,10 +901,6 @@ void EditNodeName(TreeNode node) } } - void _buttonRename_Click(object sender, EventArgs e) - { - EditNodeName(_nodeTree.SelectedNode); - } void AddTagToNode(TreeNode node, TagType type) { @@ -1030,7 +975,7 @@ void AddTagToNode(TreeNode node, TagType type) } else if (tag is TagNodeList) { - TagNodeList ltag = tag as TagNodeList; + var ltag = tag as TagNodeList; if (ltag.ValueType != type) ltag.ChangeValueType(type); @@ -1051,6 +996,95 @@ void AddTagToNode(TreeNode node, TagType type) (baseNode.Tag as DataNode).Modified = true; } } + #region Events + + static void aboutToolStripMenuItem_Click(object sender, EventArgs e) + { + new About().Show(); + } + + void NodeExpand(object sender, TreeViewCancelEventArgs e) + { + ExpandNode(e.Node); + } + + static void NodeCollapse(object sender, TreeViewEventArgs e) + { + CollapseNode(e.Node); + } + + void NodeSelected(object sender, TreeViewEventArgs e) + { + UpdateToolbar(); + } + + static void NodeClicked(object sender, TreeNodeMouseClickEventArgs e) + { + + } + + void NodeDoubleClicked(object sender, TreeNodeMouseClickEventArgs e) + { + EditNodeValue(_nodeTree.SelectedNode); + } + + void _buttonEdit_Click(object sender, EventArgs e) + { + EditNodeValue(_nodeTree.SelectedNode); + } + + void _buttonSave_Click(object sender, EventArgs e) + { + SaveAll(); + } + + void openToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenFile(); + } + + private void openFolderToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenFolder(); + } + + void toolStripButton1_Click(object sender, EventArgs e) + { + OpenFile(); + } + + void _buttonDelete_Click(object sender, EventArgs e) + { + DeleteNode(_nodeTree.SelectedNode); + } + + void _buttonRename_Click(object sender, EventArgs e) + { + EditNodeName(_nodeTree.SelectedNode); + } + + void _buttonOpenFolder_Click(object sender, EventArgs e) + { + OpenFolder(); + } + + void findToolStripMenuItem_Click(object sender, EventArgs e) + { + Find(_nodeTree.SelectedNode); + } + + void findNextToolStripMenuItem_Click(object sender, EventArgs e) + { + FindNext(); + } + + void _buttonFindNext_Click(object sender, EventArgs e) + { + if (_search == null) + Find(_nodeTree.SelectedNode); + else + FindNext(); + } void _buttonAddTagByte_Click(object sender, EventArgs e) { @@ -1107,11 +1141,29 @@ void saveToolStripMenuItem_Click(object sender, EventArgs e) SaveAll(); } - void exitToolStripMenuItem_Click(object sender, EventArgs e) + static void exitToolStripMenuItem_Click(object sender, EventArgs e) { Application.Exit(); } + void _nodeTree_DragDrop(object sender, DragEventArgs e) + { + DropFile(e); + } + + static void _nodeTree_DragEnter(object sender, DragEventArgs e) + { + if (e.Data.GetDataPresent(DataFormats.FileDrop)) + e.Effect = DragDropEffects.Copy; + } + + void openMinecraftSaveFolderToolStripMenuItem_Click(object sender, EventArgs e) + { + OpenMinecraftDir(); + } + + #endregion + TreeNode _rootSearchNode; string _searchName; string _searchValue; @@ -1224,70 +1276,34 @@ IEnumerable FindNode(TreeNode node) } } - void findToolStripMenuItem_Click(object sender, EventArgs e) - { - Find(_nodeTree.SelectedNode); - } - - void findNextToolStripMenuItem_Click(object sender, EventArgs e) - { - FindNext(); - } - - void _buttonFindNext_Click(object sender, EventArgs e) - { - if (_search == null) - Find(_nodeTree.SelectedNode); - else - FindNext(); - } - - void _buttonOpenFolder_Click(object sender, EventArgs e) - { - OpenFolder(); - } - void DropFile(DragEventArgs e) { string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); OpenPaths(files); } - void _nodeTree_DragDrop(object sender, DragEventArgs e) - { - DropFile(e); - } - - void _nodeTree_DragEnter(object sender, DragEventArgs e) - { - if (e.Data.GetDataPresent(DataFormats.FileDrop)) - e.Effect = DragDropEffects.Copy; - } - void openMinecraftSaveFolderToolStripMenuItem_Click(object sender, EventArgs e) - { - OpenMinecraftDir(); - } - - IEnumerable FindChunks(IEnumerable nodes) + static IEnumerable FindChunks(IEnumerable nodes,Func predicate) { foreach (var region in nodes) foreach (var chunk in region.Nodes.Cast().Where(c => c.Text.StartsWith("Chunk"))) { + if(predicate==null || predicate(chunk)) yield return chunk; } } int _nodesSearched = 0; - bool NeedsExpand(TreeNode node) + + static bool NeedsExpand(TreeNode node) { return node.Tag is DataNode && (node.Tag as DataNode).Expanded == false; } + IEnumerable FindRegions(IEnumerable nodes, Func predicate) { - foreach (var node in nodes) { _nodesSearched++; @@ -1296,40 +1312,91 @@ IEnumerable FindRegions(IEnumerable nodes, Func(),predicate)) + foreach (var region in FindRegions(node.Nodes.Cast(), predicate)) { yield return region; } } + } + + /// + /// Find next chunk that has entities + /// + /// + IEnumerable FindNextChunk() + { + var lastFound = + findEntityChunkToolStripMenuItem.DropDownItems.Cast().LastOrDefault( + t => t.Text.StartsWith("Chunk")); + if (lastFound != null) + { + + lastFound.PerformClick(); + Application.DoEvents(); + return FindFrom(_nodeTree.SelectedNode); + } + else return FindFrom(_nodeTree.Nodes[0]); } - void findEntityChunkToolStripMenuItem_Click(object sender, EventArgs e) + /// + /// Find the next chunk that has entities starting from start + /// + /// + /// + IEnumerable FindFrom(TreeNode start) { - _nodesSearched = 0; - var entityNodes = FindRegions(_nodeTree.Nodes.Cast(),tn=>tn.Text.EndsWith(".mcr")); + if (this._nodeTree.Nodes.Count==0) + return Enumerable.Empty(); + + var entityNodes = + FindRegions( + _nodeTree.Nodes.Cast(),tn => tn.Text.EndsWith(".mcr")); + var entityRegions = entityNodes.ToArray(); try { if (entityRegions == null || entityRegions.Any() == false) { - return; + return Enumerable.Empty(); } - var chunks = FindChunks(entityRegions); + var chunks = FindChunks(entityRegions,tn=> tn.Index > start.Index); if (chunks == null || chunks.Any() == false) - return; + return Enumerable.Empty(); var populatedChunks = FindChunksWithEntities(chunks); if (populatedChunks == null || populatedChunks.Any() == false) - return; - _nodeTree.SelectedNode = populatedChunks.First(); + return Enumerable.Empty(); + return populatedChunks; } finally { toolStrip1.Text = "Searched " + _nodesSearched + " nodes"; toolStrip1.Visible = true; } - + } + void findEntityChunkToolStripMenuItem_Click(object sender, EventArgs e) + { + _nodesSearched = 0; + var populatedChunks=FindNextChunk(); + var first = populatedChunks.FirstOrDefault(); + if (first == null) + return; + first.EnsureVisible(); + _nodeTree.SelectedNode = first; + var ddl = new ToolStripButton(); + ddl.Text = first.Text; + ddl.Width = Text.Length*5; + ddl.ToolTipText = first.Parent.Text; + + ddl.Click += (sender2, e2) => + { + first.EnsureVisible(); + _nodeTree.SelectedNode = first; + }; + findEntityChunkToolStripMenuItem.DropDownItems.Add(ddl); + + } IEnumerable FindChunksWithEntities(IEnumerable chunks) @@ -1344,7 +1411,7 @@ IEnumerable FindChunksWithEntities(IEnumerable chunks) var entityNode = level.Nodes.Cast().FirstOrDefault(n => n.Text.StartsWith("Entities")); if (entityNode == null) continue; - var text = entityNode.Text.Where(c => char.IsNumber(c)).Select(c=>c.ToString()).Aggregate((c1,c2)=>c1+c2); + var text = entityNode.Text.Where(c => char.IsNumber(c)).Select(c => c.ToString()).Aggregate((c1, c2) => c1 + c2); var entityCount = int.Parse(text); if (entityCount > 0) diff --git a/Program.cs b/Program.cs index c9908a1..3d3633d 100644 --- a/Program.cs +++ b/Program.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System; using System.Windows.Forms; namespace NBTExplorer diff --git a/StringExtensions.cs b/StringExtensions.cs index 5f9ca18..3c59163 100644 --- a/StringExtensions.cs +++ b/StringExtensions.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - + namespace NBTExplorer { public static class StringExtensions diff --git a/SubstrateHelper.cs b/SubstrateHelper.cs index 5128d73..a7258d4 100644 --- a/SubstrateHelper.cs +++ b/SubstrateHelper.cs @@ -1,9 +1,6 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Substrate.Nbt; using Substrate; +using Substrate.Nbt; namespace NBTExplorer { diff --git a/UIHelper.cs b/UIHelper.cs index e275fd2..439509b 100644 --- a/UIHelper.cs +++ b/UIHelper.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Substrate; +using Substrate; using Substrate.Nbt; namespace NBTExplorer From e8b6316b82a2f1fd03b368f22a790af74f6bf227 Mon Sep 17 00:00:00 2001 From: ImaginaryDevelopment Date: Tue, 21 Feb 2012 05:06:17 -0800 Subject: [PATCH 4/8] added another situation where the tree does a lookup to show the name of the item --- Form1.cs | 59 +++++++++++++++++++++++++++++++---------------------- UIHelper.cs | 7 +++++-- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/Form1.cs b/Form1.cs index ffceb5d..1c5cc6e 100644 --- a/Form1.cs +++ b/Form1.cs @@ -72,8 +72,8 @@ TreeNode NodeFromTag(TagNode tag) TreeNode NodeFromTag(TagNode tag, string name) { var text = SubstrateHelper.GetNodeText(name, tag); - var node=InitializeTreeNode(_tagIconIndex[tag.GetTagType()], text, tag); - + var node = InitializeTreeNode(_tagIconIndex[tag.GetTagType()], text, tag); + if (tag.GetTagType() == TagType.TAG_LIST) { @@ -115,13 +115,7 @@ void PopulateNodeFromTag(TreeNode parentNode, IEnumerable list) if (item != null) { - var newNode = new TreeNode(); - - //node.ImageIndex = _tagIconIndex[0]; - //node.SelectedImageIndex = _tagIconIndex[0]; - newNode.Text = item.Name; - node.ImageIndex = this.imageList1.Images.Count; - node.SelectedImageIndex = this.imageList1.Images.Count; + var newNode = CreateDescriptionNode(item.Name); newNode.ToolTipText = "StackSize:" + item.StackSize.ToString(); node.Nodes.Insert(0, newNode); @@ -137,6 +131,15 @@ void PopulateNodeFromTag(TreeNode parentNode, IEnumerable list) } } + TreeNode CreateDescriptionNode(string text) + { + var newNode = new TreeNode(); + newNode.Text = text; + newNode.ImageIndex = this.imageList1.Images.Count; + newNode.SelectedImageIndex = this.imageList1.Images.Count; + return newNode; + } + void PopulateNodeFromTag(TreeNode node, IEnumerable> dict) { if (dict == null) @@ -151,6 +154,14 @@ void PopulateNodeFromTag(TreeNode node, IEnumerable FindChunks(IEnumerable nodes,Func predicate) + static IEnumerable FindChunks(IEnumerable nodes, Func predicate) { foreach (var region in nodes) foreach (var chunk in region.Nodes.Cast().Where(c => c.Text.StartsWith("Chunk"))) { - if(predicate==null || predicate(chunk)) - yield return chunk; + if (predicate == null || predicate(chunk)) + yield return chunk; } } @@ -1319,7 +1330,7 @@ IEnumerable FindRegions(IEnumerable nodes, Func /// Find next chunk that has entities /// @@ -1347,12 +1358,12 @@ IEnumerable FindNextChunk() /// IEnumerable FindFrom(TreeNode start) { - if (this._nodeTree.Nodes.Count==0) + if (this._nodeTree.Nodes.Count == 0) return Enumerable.Empty(); - + var entityNodes = FindRegions( - _nodeTree.Nodes.Cast(),tn => tn.Text.EndsWith(".mcr")); + _nodeTree.Nodes.Cast(), tn => tn.Text.EndsWith(".mcr")); var entityRegions = entityNodes.ToArray(); try @@ -1361,7 +1372,7 @@ IEnumerable FindFrom(TreeNode start) { return Enumerable.Empty(); } - var chunks = FindChunks(entityRegions,tn=> tn.Index > start.Index); + var chunks = FindChunks(entityRegions, tn => tn.Index > start.Index); if (chunks == null || chunks.Any() == false) return Enumerable.Empty(); var populatedChunks = FindChunksWithEntities(chunks); @@ -1378,7 +1389,7 @@ IEnumerable FindFrom(TreeNode start) void findEntityChunkToolStripMenuItem_Click(object sender, EventArgs e) { _nodesSearched = 0; - var populatedChunks=FindNextChunk(); + var populatedChunks = FindNextChunk(); var first = populatedChunks.FirstOrDefault(); if (first == null) return; @@ -1386,7 +1397,7 @@ void findEntityChunkToolStripMenuItem_Click(object sender, EventArgs e) _nodeTree.SelectedNode = first; var ddl = new ToolStripButton(); ddl.Text = first.Text; - ddl.Width = Text.Length*5; + ddl.Width = Text.Length * 5; ddl.ToolTipText = first.Parent.Text; ddl.Click += (sender2, e2) => diff --git a/UIHelper.cs b/UIHelper.cs index 439509b..600f7dd 100644 --- a/UIHelper.cs +++ b/UIHelper.cs @@ -5,7 +5,10 @@ namespace NBTExplorer { public class UIHelper { - + internal static ItemInfo TryGetItemName(int id) + { + return Substrate.ItemInfo.ItemTable[id]; + } internal static ItemInfo TryGetItemName(TagNode tag) { @@ -15,7 +18,7 @@ internal static ItemInfo TryGetItemName(TagNode tag) int id; if (int.TryParse(tagc["id"].ToString(), out id)) { - return Substrate.ItemInfo.ItemTable[id]; + return TryGetItemName(id); } return null; From 82d1c2ad1670158276f12ccfc54a457b2bfe63db Mon Sep 17 00:00:00 2001 From: ImaginaryDevelopment Date: Wed, 29 Feb 2012 19:28:47 -0800 Subject: [PATCH 5/8] splitting out features into individual files --- ViewModel/ChunkNode.cs | 73 ++++ ViewModel/RegionNode.cs | 34 ++ ViewModel/ServerNode.cs | 811 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 918 insertions(+) create mode 100644 ViewModel/ChunkNode.cs create mode 100644 ViewModel/RegionNode.cs create mode 100644 ViewModel/ServerNode.cs diff --git a/ViewModel/ChunkNode.cs b/ViewModel/ChunkNode.cs new file mode 100644 index 0000000..7f3c6db --- /dev/null +++ b/ViewModel/ChunkNode.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Substrate.Nbt; + +namespace NBTExplorer.ViewModel +{ + public class ChunkNode + { + readonly TreeNode _node; + readonly int _descriptionImageIndex; + public int Index { get { return _node.Index; } } + public string Text { get { return _node.Text; } } + + public TreeNode GetLevelNode() + { + if (ServerNode.NeedsExpand(_node)) + ServerNode.ExpandNode(_node, _descriptionImageIndex); + var level = _node.Nodes.Cast().FirstOrDefault(n => n.Text.StartsWith("Level")); + return level; + } + public bool HasEntities() + { + var count = GetEntityCount(); + return count.HasValue && count.Value > 0; + } + public void EnsureEntitiesVisible() + { + var entityNode = GetEntityNode(); + if (entityNode != null) + entityNode.EnsureVisible(); + } + TreeNode GetEntityNode() + { + var level = GetLevelNode(); + if (level == null) + return null; + var entityNode = level.Nodes.Cast().FirstOrDefault(n => n.Text.StartsWith("Entities")); + return entityNode; + } + + public int? GetEntityCount() + { + var entityNode = GetEntityNode(); + if (entityNode == null) + return null; + var text = entityNode.Text.Where(c => char.IsNumber(c)).Select(c => c.ToString()).Aggregate((c1, c2) => c1 + c2); + + var entityCount = int.Parse(text); + return entityCount; + } + public TreeNode Node { get { return _node; } } + public ChunkNode(TreeNode node,int descriptionImageIndex) + { + _node = node; + _descriptionImageIndex = descriptionImageIndex; + } + public TreeNode Parent { get { return _node.Parent; } } + internal void EnsureVisible() + { + _node.EnsureVisible(); + } + + internal void SelectEntityNode() + { + var entityNode = GetEntityNode(); + if(entityNode!=null) + entityNode.TreeView.SelectedNode = entityNode; + } + } +} diff --git a/ViewModel/RegionNode.cs b/ViewModel/RegionNode.cs new file mode 100644 index 0000000..3a47b1e --- /dev/null +++ b/ViewModel/RegionNode.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.Diagnostics; + +namespace NBTExplorer.ViewModel +{ + public class RegionNode + { + readonly TreeNode _node; + readonly int _descriptionImageIndex; + public int Index { get { return _node.Index; } } + public string Text { get { return _node.Text; } } + + public RegionNode(TreeNode node,int descriptionImageIndex) + { + Debug.Assert(node.Text.EndsWith(".mcr")); + + _node = node; + _descriptionImageIndex = descriptionImageIndex; + } + + public IEnumerable FindChunks(Func predicate) + { + foreach (var chunk in _node.Nodes.Cast().Where(c => c.Text.StartsWith("Chunk")).Select(tn=> new ChunkNode(tn,_descriptionImageIndex))) + { + if (predicate == null || predicate(chunk)) + yield return chunk; + } + } + } +} diff --git a/ViewModel/ServerNode.cs b/ViewModel/ServerNode.cs new file mode 100644 index 0000000..2f69906 --- /dev/null +++ b/ViewModel/ServerNode.cs @@ -0,0 +1,811 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.IO; +using Substrate.Core; +using Substrate.Nbt; +using System.Diagnostics; + +namespace NBTExplorer.ViewModel +{ + internal class ServerNode + { + private static IDictionary _tagIconIndex; + static ServerNode() + { + _tagIconIndex = new Dictionary(); + _tagIconIndex[TagType.TAG_BYTE] = 0; + _tagIconIndex[TagType.TAG_SHORT] = 1; + _tagIconIndex[TagType.TAG_INT] = 2; + _tagIconIndex[TagType.TAG_LONG] = 3; + _tagIconIndex[TagType.TAG_FLOAT] = 4; + _tagIconIndex[TagType.TAG_DOUBLE] = 5; + _tagIconIndex[TagType.TAG_BYTE_ARRAY] = 6; + _tagIconIndex[TagType.TAG_STRING] = 7; + _tagIconIndex[TagType.TAG_LIST] = 8; + _tagIconIndex[TagType.TAG_COMPOUND] = 9; + } + + static TagNode GetTagNode(TreeNode node) + { + if (node == null) + return null; + + if (node.Tag is TagNode) + { + return node.Tag as TagNode; + } + else if (node.Tag is NbtDataNode) + { + NbtDataNode data = node.Tag as NbtDataNode; + if (data == null) + return null; + + return data.Tree.Root; + } + + return null; + } + + static TagNode GetParentTagNode(TreeNode node) + { + if (GetTagNode(node) == null) + return null; + + return GetTagNode(node.Parent); + } + + static string GetTagNodeName(TreeNode node) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return null; + + TagNode parentTag = GetTagNode(node.Parent); + if (parentTag == null) + return null; + + if (parentTag.GetTagType() != TagType.TAG_COMPOUND) + return null; + + foreach (KeyValuePair sub in parentTag.ToTagCompound()) + { + if (sub.Value == tag) + return sub.Key; + } + + return null; + } + + static bool SetTagNodeName(TreeNode node, string name) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return false; + + TagNode parentTag = GetTagNode(node.Parent); + if (parentTag == null) + return false; + + if (parentTag.GetTagType() != TagType.TAG_COMPOUND) + return false; + + if (parentTag.ToTagCompound().ContainsKey(name)) + return false; + + string oldName = null; + foreach (KeyValuePair sub in parentTag.ToTagCompound()) + { + if (sub.Value == tag) + { + oldName = sub.Key; + break; + } + } + + parentTag.ToTagCompound().Remove(oldName); + parentTag.ToTagCompound().Add(name, tag); + + return true; + } + #region Tag Deletion + + internal static void DeleteNode(TreeNode node) + { + TreeNode baseNode = BaseNode(node); + + // Can only delete internal NBT nodes + if (baseNode == null || baseNode == node) + return; + + (baseNode.Tag as DataNode).Modified = true; + + DeleteNodeNbtTag(node); + + if (node.Parent != null) + { + node.Parent.Text = GetNodeText(node.Parent); + } + + node.Remove(); + } + + + + static void DeleteNodeNbtTag(TreeNode node) + { + TagNode tag = node.Tag as TagNode; + if (tag == null) + return; + + TagNode parentTag = node.Parent.Tag as TagNode; + if (parentTag == null) + { + NbtDataNode parentData = node.Parent.Tag as NbtDataNode; + if (parentData == null) + return; + + parentTag = parentData.Tree.Root; + if (parentTag == null) + return; + } + + switch (parentTag.GetTagType()) + { + case TagType.TAG_LIST: + parentTag.ToTagList().Remove(tag); + break; + + case TagType.TAG_COMPOUND: + DeleteTagFromCompound(parentTag.ToTagCompound(), tag); + break; + } + } + + static void DeleteTagFromCompound(IDictionary parent, TagNode target) + { + string match = ""; + foreach (KeyValuePair kv in parent) + { + if (kv.Value == target) + { + match = kv.Key; + break; + } + } + + if (match != null) + { + parent.Remove(match); + } + } + + #endregion + + internal static IEnumerable FindNode(TreeNode node,int descriptionImageIndex,string searchName,string searchValue) + { + if (node == null) + yield break; + + bool expand = false; + + if (node.Tag is DataNode) + { + DataNode data = node.Tag as DataNode; + if (!data.Expanded) + { + ServerNode.ExpandNode(node,descriptionImageIndex); + expand = true; + } + } + + TagNode tag = ServerNode.GetTagNode(node); + if (tag != null) + { + bool mName = searchName == null; + bool mValue = searchValue == null; + + if (searchName != null) + { + string tagName = GetTagNodeName(node); + if (tagName != null) + mName = tagName.Contains(searchName); + } + if (searchValue != null) + { + string tagValue = GetTagNodeText(node); + if (tagValue != null) + mValue = tagValue.Contains(searchValue); + } + + if (mName && mValue) + { + node.TreeView.SelectedNode = node; + yield return node; + } + } + + foreach (TreeNode sub in node.Nodes) + { + foreach (TreeNode s in FindNode(sub,descriptionImageIndex,searchName,searchValue)) + yield return s; + } + + if (expand) + { + DataNode data = node.Tag as DataNode; + if (!data.Modified) + ServerNode.CollapseNode(node); + } + } + internal static void EditNodeValue(TreeNode node) + { + if (node == null) + return; + + TagNode tag = GetTagNode(node); + if (tag == null) + return; + + if (tag.GetTagType() == TagType.TAG_BYTE_ARRAY || + tag.GetTagType() == TagType.TAG_LIST || + tag.GetTagType() == TagType.TAG_COMPOUND) + return; + + EditValue form = new EditValue(tag); + if (form.ShowDialog() == DialogResult.OK) + { + TreeNode baseNode = BaseNode(node); + if (baseNode != null) + { + (baseNode.Tag as DataNode).Modified = true; + } + + node.Text = GetNodeText(node); + } + } + static TreeNode BaseNode(TreeNode node) + { + if (node == null) + return null; + + TreeNode baseNode = node; + while (baseNode.Tag == null || !(baseNode.Tag is DataNode)) + { + baseNode = baseNode.Parent; + } + + return baseNode; + } + + + internal static void EditNodeName(TreeNode node) + { + if (node == null) + return; + + TagNode tag = GetTagNode(node); + if (tag == null) + return; + + string name = GetTagNodeName(node); + if (name == null) + return; + + var form = new EditValue(name); + + var parentTag = GetParentTagNode(node); + foreach (string key in parentTag.ToTagCompound().Keys) + { + form.InvalidNames.Add(key); + } + + if (form.ShowDialog() == DialogResult.OK) + { + TreeNode baseNode = BaseNode(node); + if (baseNode != null) + { + (baseNode.Tag as DataNode).Modified = true; + } + + SetTagNodeName(node, form.NodeName); + node.Text = GetNodeText(node); + } + } + static void LoadNbtStream(TreeNodeCollection parent, Stream stream) + { + LoadNbtStream(parent, stream); + } + + static void LoadNbtStream(TreeNodeCollection parent,int descriptionImageIndex, Stream stream, string name = null) + { + var text = !String.IsNullOrEmpty(name) ? name : null; + text = text ?? "[root]"; + + TreeNode root = new TreeNode(text, 9, 9); + + LoadNbtStream(root, descriptionImageIndex, stream); + + parent.Add(root); + } + internal static bool NeedsExpand(TreeNode node) + { + return node.Tag is DataNode && (node.Tag as DataNode).Expanded == false; + + } + + static string GetNodeText(TreeNode node) + { + return SubstrateHelper.GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); + } + + static string GetTagNodeText(TreeNode node) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return null; + + return SubstrateHelper.GetTagNodeText(tag); + } + + static TreeNode CreateDescriptionNode(string text,int imageIndex) + { + var newNode = new TreeNode(); + newNode.Text = text; + newNode.ImageIndex =imageIndex; + newNode.SelectedImageIndex = imageIndex; + return newNode; + } + + static void PopulateNodeFromTag(TreeNode parentNode,int descriptionIndex, IEnumerable list) + { + foreach (TagNode tag in list) + { + var node = NodeFromTag(tag,descriptionIndex); + if (parentNode.Text.StartsWith("Inventory") || parentNode.Text.StartsWith("Item")) + { + + Debug.Assert(tag.IsCastableTo(TagType.TAG_COMPOUND)); + var item = UIHelper.TryGetItemName(tag); + + if (item != null) + { + + var newNode = CreateDescriptionNode(item.Name,descriptionIndex); + newNode.ToolTipText = "StackSize:" + item.StackSize.ToString(); + + node.Nodes.Insert(0, newNode); + } + + + + + } + + + parentNode.Nodes.Add(node); + } + } + internal static void AddTagToNode( TreeNode node, int descriptionIndex, TagType type) + { + TagNode tag = GetTagNode(node); + if (tag == null) + return; + + if (tag.GetTagType() != TagType.TAG_COMPOUND && + tag.GetTagType() != TagType.TAG_LIST) + return; + + if (tag.GetTagType() == TagType.TAG_LIST && + tag.ToTagList().ValueType != type && + tag.ToTagList().Count > 0) + return; + + TagNode newNode = null; + switch (type) + { + case TagType.TAG_BYTE: + newNode = new TagNodeByte(); + break; + case TagType.TAG_SHORT: + newNode = new TagNodeShort(); + break; + case TagType.TAG_INT: + newNode = new TagNodeInt(); + break; + case TagType.TAG_LONG: + newNode = new TagNodeLong(); + break; + case TagType.TAG_FLOAT: + newNode = new TagNodeFloat(); + break; + case TagType.TAG_DOUBLE: + newNode = new TagNodeDouble(); + break; + case TagType.TAG_BYTE_ARRAY: + newNode = new TagNodeByteArray(); + break; + case TagType.TAG_STRING: + newNode = new TagNodeString(); + break; + case TagType.TAG_LIST: + newNode = new TagNodeList(TagType.TAG_BYTE); + break; + case TagType.TAG_COMPOUND: + newNode = new TagNodeCompound(); + break; + } + + if (tag is TagNodeCompound) + { + TagNodeCompound ctag = tag as TagNodeCompound; + + EditValue form = new EditValue(""); + foreach (string key in ctag.Keys) + { + form.InvalidNames.Add(key); + } + + if (form.ShowDialog() != DialogResult.OK) + return; + + ctag.Add(form.NodeName, newNode); + + TreeNode tnode = NodeFromTag(newNode, descriptionIndex, form.NodeName); + node.Nodes.Add(tnode); + + tnode.TreeView.SelectedNode = tnode; + tnode.Expand(); + } + else if (tag is TagNodeList) + { + var ltag = tag as TagNodeList; + if (ltag.ValueType != type) + ltag.ChangeValueType(type); + + ltag.Add(newNode); + + TreeNode tnode = NodeFromTag(newNode, descriptionIndex); + node.Nodes.Add(tnode); + tnode.TreeView.SelectedNode = tnode; + + tnode.Expand(); + } + + node.Text = GetNodeText(node); + + TreeNode baseNode = BaseNode(node); + if (baseNode != null) + { + (baseNode.Tag as DataNode).Modified = true; + } + } + internal static void CollapseNode(TreeNode node) + { + if (node.Tag == null) + return; + + if (node.Tag is DataNode) + { + UnloadLazyDataNode(node); + } + } + + + static TreeNode NodeFromTag(TagNode tag, int descriptionImageIndex) + { + return NodeFromTag(tag, descriptionImageIndex, null); + } + + static TreeNode NodeFromTag(TagNode tag, int descriptionIndex ,string name) + { + var text = SubstrateHelper.GetNodeText(name, tag); + var node = ServerNode.InitializeTreeNode(_tagIconIndex[tag.GetTagType()], text, tag); + + + if (tag.GetTagType() == TagType.TAG_LIST) + { + PopulateNodeFromTag(node,descriptionIndex, tag.ToTagList()); + } + else if (tag.GetTagType() == TagType.TAG_COMPOUND) + { + PopulateNodeFromTag(node,descriptionIndex, tag.ToTagCompound()); + } + + return node; + } + static void PopulateNodeFromTag(TreeNode node,int descriptionIndex, IEnumerable> dict) + { + if (dict == null) + return; + var list = new SortedList(); + foreach (KeyValuePair kv in dict) + { + list.Add(new TagKey(kv.Key, kv.Value.GetTagType()), kv.Value); + } + + foreach (KeyValuePair kv in list) + { + node.Nodes.Add(NodeFromTag(kv.Value,descriptionIndex, kv.Key.Name)); + } + if (node.Text.StartsWith("Item")) + { + var item = UIHelper.TryGetItemName((TagNode)node.Tag); + if (item == null) + return; + var newNode = CreateDescriptionNode(item.Name,descriptionIndex); + node.Nodes.Insert(0, newNode); + } + } + + static void LoadNbtStream(TreeNode node,int descriptionIndex, Stream stream) + { + NbtTree tree = new NbtTree(); + tree.ReadFrom(stream); + + if (node.Tag != null && node.Tag is NbtDataNode) + { + (node.Tag as NbtDataNode).Tree = tree; + } + + PopulateNodeFromTag(node,descriptionIndex, tree.Root); + } + internal static void LoadLazyNbt(TreeNode node, int descriptionImageIndex) + { + NbtFileData data = node.Tag as NbtFileData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + + NBTFile file = new NBTFile(data.Path); + LoadNbtStream(node,descriptionImageIndex, file.GetDataInputStream(data.CompressionType)); + + data.Expanded = true; + } + + internal static void LoadRegion(TreeNodeCollection parent, string path) + { + TreeNode root = new TreeNode(Path.GetFileName(path), 11, 11); + LoadRegion(root, path); + parent.Add(root); + } + + internal static void TryLoadFile(TreeNodeCollection parent, string path) + { + if (Path.GetExtension(path) == ".mcr") + { + TreeNode node = ServerNode.CreateLazyRegion(path); + parent.Add(node); + LinkDataNodeParent(node, node.Parent); + return; + } + + if (Path.GetExtension(path) == ".dat") + { + try + { + NBTFile file = new NBTFile(path); + NbtTree tree = new NbtTree(); + tree.ReadFrom(file.GetDataInputStream()); + TreeNode node = ServerNode.CreateLazyNbt(path, CompressionType.GZip); + parent.Add(node); + LinkDataNodeParent(node, node.Parent); + return; + } + catch { } + + try + { + NBTFile file = new NBTFile(path); + NbtTree tree = new NbtTree(); + tree.ReadFrom(file.GetDataInputStream(CompressionType.None)); + TreeNode node = ServerNode.CreateLazyNbt(path, CompressionType.None); + parent.Add(node); + LinkDataNodeParent(node, node.Parent); + return; + } + catch { } + } + } + + internal static void LoadRegion(TreeNode node, string path) + { + RegionFile rf = new RegionFile(path); + + for (int x = 0; x < 32; x++) + { + for (int y = 0; y < 32; y++) + { + if (rf.HasChunk(x, y)) + { + TreeNode child = CreateLazyChunk(rf, x, y); + node.Nodes.Add(child); + LinkDataNodeParent(child, node); + } + } + } + } + + static void LinkDataNodeParent(TreeNode node, TreeNode parent) + { + if (node != null && parent != null && node.Tag != null && parent.Tag != null) + { + DataNode nodeDn = node.Tag as DataNode; + DataNode parentDn = parent.Tag as DataNode; + + if (nodeDn != null && parentDn != null) + { + nodeDn.Parent = parentDn; + } + } + } + + internal static TreeNode InitializeParentNode(Int32 imageIndex, string text, object tag) + { + + var node = InitializeTreeNode(imageIndex, text, tag); + node.Nodes.Add(new TreeNode()); //add stub so that it shows as expandable + return node; + } + internal static TreeNode InitializeTreeNode(Int32 imageIndex, string text, object tag) + { + var node = new TreeNode + { + ImageIndex = imageIndex, + SelectedImageIndex = imageIndex, + Text = text, + Tag = tag + + }; + return node; + } + + internal static void LoadDirectory(string path, TreeNodeCollection parent, string name) + { + TreeNode root = new TreeNode(name, 10, 10); + + foreach (string dirpath in Directory.EnumerateDirectories(path)) + { + root.Nodes.Add(CreateLazyDirectory(dirpath, root)); + } + + foreach (string filepath in Directory.EnumerateFiles(path)) + { + TryLoadFile(root.Nodes, filepath); + } + + parent.Add(root); + } + internal static TreeNode CreateLazyChunk(RegionFile rf, int x, int z) + { + return InitializeParentNode(9, "Chunk [" + x + ", " + z + "]", new RegionChunkData(rf, x, z)); + } + internal static TreeNode CreateLazyRegion(string path) + { + var fileName = Path.GetFileName(path); + var node = InitializeParentNode(11, fileName, new RegionData(path)); + + return node; + } + + internal static TreeNode CreateLazyNbt(string path, CompressionType cztype) + { + var fileName = Path.GetFileName(path); + var node = InitializeParentNode(12, fileName, new NbtFileData(path, cztype)); + + return node; + } + + internal static TreeNode CreateLazyDirectory(string path) + { + var filename = Path.GetFileName(path); + var node = InitializeParentNode(10, filename, new DirectoryData(path)); + + return node; + } + + internal static TreeNode CreateLazyDirectory(string path, TreeNode parent) + { + TreeNode node = CreateLazyDirectory(path); + LinkDataNodeParent(node, parent); + + return node; + } + + internal TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode parent) + { + var node = CreateLazyNbt(path, cztype); + LinkDataNodeParent(node, parent); + + return node; + } + + internal static void LoadLazyDirectory(TreeNode node) + { + var data = node.Tag as DirectoryData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + + foreach (string dirpath in Directory.EnumerateDirectories(data.Path)) + { + node.Nodes.Add(CreateLazyDirectory(dirpath, node)); + } + + foreach (string filepath in Directory.EnumerateFiles(data.Path)) + { + TryLoadFile(node.Nodes, filepath); + } + + data.Expanded = true; + } + + internal static void LoadLazyRegion(TreeNode node) + { + RegionData data = node.Tag as RegionData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + LoadRegion(node, data.Path); + + data.Expanded = true; + } + + internal static void UnloadLazyDataNode(TreeNode node) + { + DataNode data = node.Tag as DataNode; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + node.Nodes.Add(new TreeNode()); + + data.Expanded = false; + } + + internal static void LoadLazyChunk(TreeNode node,int descriptionImageIndex) + { + RegionChunkData data = node.Tag as RegionChunkData; + if (data == null || data.Modified) + return; + + node.Nodes.Clear(); + LoadNbtStream(node, descriptionImageIndex,data.Region.GetChunkDataInputStream(data.X, data.Z)); + + data.Expanded = true; + } + internal static void ExpandNode(TreeNode node,int descriptionImageIndex) + { + if (node.Tag == null) + return; + + if (node.Tag is DataNode) + { + if ((node.Tag as DataNode).Expanded) + return; + } + + if (node.Tag is RegionChunkData) + { + LoadLazyChunk(node,descriptionImageIndex); + } + else if (node.Tag is NbtFileData) + { + LoadLazyNbt(node, descriptionImageIndex); + } + else if (node.Tag is DirectoryData) + { + LoadLazyDirectory(node); + } + else if (node.Tag is RegionData) + { + LoadLazyRegion(node); + } + } + } +} From 7edd8e0d2e28485f1054c38187e19a92f9c8079f Mon Sep 17 00:00:00 2001 From: ImaginaryDevelopment Date: Wed, 29 Feb 2012 19:29:19 -0800 Subject: [PATCH 6/8] added findBloatedChunk feature --- Form1.Designer.cs | 34 +- Form1.cs | 946 ++++--------------------------------- Form1.resx | 6 +- NBTExplorer.csproj | 58 +++ Properties/AssemblyInfo.cs | 6 +- 5 files changed, 170 insertions(+), 880 deletions(-) diff --git a/Form1.Designer.cs b/Form1.Designer.cs index 3fba7df..8c9c8df 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -41,6 +41,7 @@ private void InitializeComponent () this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.findToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.findNextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findEntityChunkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); @@ -72,7 +73,7 @@ private void InitializeComponent () this._nodeContainerContext = new System.Windows.Forms.ContextMenuStrip(this.components); this.openSubTreeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.saveItemToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.findEntityChunkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.findBloatedChunkToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip1.SuspendLayout(); this.toolStripContainer1.ContentPanel.SuspendLayout(); this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); @@ -167,7 +168,8 @@ private void InitializeComponent () this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.findToolStripMenuItem, this.findNextToolStripMenuItem, - this.findEntityChunkToolStripMenuItem}); + this.findEntityChunkToolStripMenuItem, + this.findBloatedChunkToolStripMenuItem}); this.searchToolStripMenuItem.Name = "searchToolStripMenuItem"; this.searchToolStripMenuItem.Size = new System.Drawing.Size(54, 20); this.searchToolStripMenuItem.Text = "&Search"; @@ -177,7 +179,7 @@ private void InitializeComponent () this.findToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.binocular; this.findToolStripMenuItem.Name = "findToolStripMenuItem"; this.findToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F))); - this.findToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.findToolStripMenuItem.Size = new System.Drawing.Size(178, 22); this.findToolStripMenuItem.Text = "Find..."; this.findToolStripMenuItem.Click += new System.EventHandler(this.findToolStripMenuItem_Click); // @@ -186,10 +188,17 @@ private void InitializeComponent () this.findNextToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.binocular__arrow; this.findNextToolStripMenuItem.Name = "findNextToolStripMenuItem"; this.findNextToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F3; - this.findNextToolStripMenuItem.Size = new System.Drawing.Size(168, 22); + this.findNextToolStripMenuItem.Size = new System.Drawing.Size(178, 22); this.findNextToolStripMenuItem.Text = "Find Next"; this.findNextToolStripMenuItem.Click += new System.EventHandler(this.findNextToolStripMenuItem_Click); // + // findEntityChunkToolStripMenuItem + // + this.findEntityChunkToolStripMenuItem.Name = "findEntityChunkToolStripMenuItem"; + this.findEntityChunkToolStripMenuItem.Size = new System.Drawing.Size(178, 22); + this.findEntityChunkToolStripMenuItem.Text = "Find Entity Chunk"; + this.findEntityChunkToolStripMenuItem.Click += new System.EventHandler(this.findEntityChunkToolStripMenuItem_Click); + // // helpToolStripMenuItem // this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -203,7 +212,7 @@ private void InitializeComponent () this.aboutToolStripMenuItem.Image = global::NBTExplorer.Properties.Resources.information_frame; this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem"; this.aboutToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F1; - this.aboutToolStripMenuItem.Size = new System.Drawing.Size(126, 22); + this.aboutToolStripMenuItem.Size = new System.Drawing.Size(152, 22); this.aboutToolStripMenuItem.Text = "&About"; this.aboutToolStripMenuItem.Click += new System.EventHandler(aboutToolStripMenuItem_Click); // @@ -256,7 +265,7 @@ private void InitializeComponent () this._nodeTree.SelectedImageIndex = 0; this._nodeTree.Size = new System.Drawing.Size(562, 351); this._nodeTree.TabIndex = 0; - this._nodeTree.DragDrop += new System.Windows.Forms.DragEventHandler(this._nodeTree_DragDrop); + this._nodeTree.DragDrop += new System.Windows.Forms.DragEventHandler(_nodeTree_DragDrop); this._nodeTree.DragEnter += new System.Windows.Forms.DragEventHandler(_nodeTree_DragEnter); // // imageList1 @@ -515,12 +524,12 @@ private void InitializeComponent () this.saveItemToolStripMenuItem.Size = new System.Drawing.Size(179, 22); this.saveItemToolStripMenuItem.Text = "Save Node"; // - // findEntityChunkToolStripMenuItem + // findBloatedChunkToolStripMenuItem // - this.findEntityChunkToolStripMenuItem.Name = "findEntityChunkToolStripMenuItem"; - this.findEntityChunkToolStripMenuItem.Size = new System.Drawing.Size(168, 22); - this.findEntityChunkToolStripMenuItem.Text = "Find Entity Chunk"; - this.findEntityChunkToolStripMenuItem.Click += new System.EventHandler(this.findEntityChunkToolStripMenuItem_Click); + this.findBloatedChunkToolStripMenuItem.Name = "findBloatedChunkToolStripMenuItem"; + this.findBloatedChunkToolStripMenuItem.Size = new System.Drawing.Size(178, 22); + this.findBloatedChunkToolStripMenuItem.Text = "Find Bloated Chunk"; + this.findBloatedChunkToolStripMenuItem.Click += new System.EventHandler(this.findBloatedChunkToolStripMenuItem_Click); // // Form1 // @@ -597,7 +606,8 @@ private void InitializeComponent () private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; private System.Windows.Forms.ToolStripButton _buttonOpenFolder; private System.Windows.Forms.ToolStripMenuItem openMinecraftSaveFolderToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem findEntityChunkToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem findEntityChunkToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem findBloatedChunkToolStripMenuItem; } } diff --git a/Form1.cs b/Form1.cs index 1c5cc6e..b0aa38e 100644 --- a/Form1.cs +++ b/Form1.cs @@ -6,6 +6,7 @@ using System.Windows.Forms; using Substrate.Core; using Substrate.Nbt; +using NBTExplorer.ViewModel; namespace NBTExplorer { @@ -16,7 +17,7 @@ public partial class Form1 : Form public Form1() { InitializeComponent(); - + findBloatedChunkToolStripMenuItem.ToolTipText = "Chunks with " + BloatedAt.ToString() + " or more entities"; _nodeTree.BeforeExpand += NodeExpand; _nodeTree.AfterCollapse += NodeCollapse; _nodeTree.AfterSelect += NodeSelected; @@ -34,350 +35,6 @@ public Form1() } } - void LoadNbtStream(TreeNodeCollection parent, Stream stream) - { - LoadNbtStream(parent, stream); - } - - void LoadNbtStream(TreeNodeCollection parent, Stream stream, string name = null) - { - var text = !String.IsNullOrEmpty(name) ? name : null; - text = text ?? "[root]"; - - TreeNode root = new TreeNode(text, 9, 9); - - LoadNbtStream(root, stream); - - parent.Add(root); - } - - void LoadNbtStream(TreeNode node, Stream stream) - { - NbtTree tree = new NbtTree(); - tree.ReadFrom(stream); - - if (node.Tag != null && node.Tag is NbtDataNode) - { - (node.Tag as NbtDataNode).Tree = tree; - } - - PopulateNodeFromTag(node, tree.Root); - } - - TreeNode NodeFromTag(TagNode tag) - { - return NodeFromTag(tag, null); - } - - TreeNode NodeFromTag(TagNode tag, string name) - { - var text = SubstrateHelper.GetNodeText(name, tag); - var node = InitializeTreeNode(_tagIconIndex[tag.GetTagType()], text, tag); - - - if (tag.GetTagType() == TagType.TAG_LIST) - { - PopulateNodeFromTag(node, tag.ToTagList()); - } - else if (tag.GetTagType() == TagType.TAG_COMPOUND) - { - PopulateNodeFromTag(node, tag.ToTagCompound()); - } - - return node; - } - - static string GetNodeText(TreeNode node) - { - return SubstrateHelper.GetNodeText(GetTagNodeName(node), GetTagNodeText(node)); - } - - static string GetTagNodeText(TreeNode node) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return null; - - return SubstrateHelper.GetTagNodeText(tag); - } - - void PopulateNodeFromTag(TreeNode parentNode, IEnumerable list) - { - foreach (TagNode tag in list) - { - var node = NodeFromTag(tag); - if (parentNode.Text.StartsWith("Inventory") || parentNode.Text.StartsWith("Item")) - { - - Debug.Assert(tag.IsCastableTo(TagType.TAG_COMPOUND)); - var item = UIHelper.TryGetItemName(tag); - - if (item != null) - { - - var newNode = CreateDescriptionNode(item.Name); - newNode.ToolTipText = "StackSize:" + item.StackSize.ToString(); - - node.Nodes.Insert(0, newNode); - } - - - - - } - - - parentNode.Nodes.Add(node); - } - } - - TreeNode CreateDescriptionNode(string text) - { - var newNode = new TreeNode(); - newNode.Text = text; - newNode.ImageIndex = this.imageList1.Images.Count; - newNode.SelectedImageIndex = this.imageList1.Images.Count; - return newNode; - } - - void PopulateNodeFromTag(TreeNode node, IEnumerable> dict) - { - if (dict == null) - return; - var list = new SortedList(); - foreach (KeyValuePair kv in dict) - { - list.Add(new TagKey(kv.Key, kv.Value.GetTagType()), kv.Value); - } - - foreach (KeyValuePair kv in list) - { - node.Nodes.Add(NodeFromTag(kv.Value, kv.Key.Name)); - } - if(node.Text.StartsWith("Item")) - { - var item = UIHelper.TryGetItemName((TagNode) node.Tag); - if (item == null) - return; - var newNode = CreateDescriptionNode(item.Name); - node.Nodes.Insert(0,newNode); - } - } - - void LoadRegion(TreeNodeCollection parent, string path) - { - TreeNode root = new TreeNode(Path.GetFileName(path), 11, 11); - LoadRegion(root, path); - parent.Add(root); - } - - static void LoadRegion(TreeNode node, string path) - { - RegionFile rf = new RegionFile(path); - - for (int x = 0; x < 32; x++) - { - for (int y = 0; y < 32; y++) - { - if (rf.HasChunk(x, y)) - { - TreeNode child = CreateLazyChunk(rf, x, y); - node.Nodes.Add(child); - LinkDataNodeParent(child, node); - } - } - } - } - - static TreeNode CreateLazyChunk(RegionFile rf, int x, int z) - { - return InitializeParentNode(9, "Chunk [" + x + ", " + z + "]", new RegionChunkData(rf, x, z)); - } - static TreeNode InitializeTreeNode(Int32 imageIndex, string text, object tag) - { - var node = new TreeNode - { - ImageIndex = imageIndex, - SelectedImageIndex = imageIndex, - Text = text, - Tag = tag - - }; - return node; - } - - static TreeNode InitializeParentNode(Int32 imageIndex, string text, object tag) - { - - var node = InitializeTreeNode(imageIndex, text, tag); - node.Nodes.Add(new TreeNode()); //add stub so that it shows as expandable - return node; - } - - static TreeNode CreateLazyRegion(string path) - { - var fileName = Path.GetFileName(path); - var node = InitializeParentNode(11, fileName, new RegionData(path)); - - return node; - } - - static TreeNode CreateLazyNbt(string path, CompressionType cztype) - { - var fileName = Path.GetFileName(path); - var node = InitializeParentNode(12, fileName, new NbtFileData(path, cztype)); - - return node; - } - - static TreeNode CreateLazyDirectory(string path) - { - var filename = Path.GetFileName(path); - var node = InitializeParentNode(10, filename, new DirectoryData(path)); - - return node; - } - - static TreeNode CreateLazyDirectory(string path, TreeNode parent) - { - TreeNode node = CreateLazyDirectory(path); - LinkDataNodeParent(node, parent); - - return node; - } - - TreeNode CreateLazyNbt(string path, CompressionType cztype, TreeNode parent) - { - var node = CreateLazyNbt(path, cztype); - LinkDataNodeParent(node, parent); - - return node; - } - - static void LinkDataNodeParent(TreeNode node, TreeNode parent) - { - if (node != null && parent != null && node.Tag != null && parent.Tag != null) - { - DataNode nodeDn = node.Tag as DataNode; - DataNode parentDn = parent.Tag as DataNode; - - if (nodeDn != null && parentDn != null) - { - nodeDn.Parent = parentDn; - } - } - } - - void LoadLazyChunk(TreeNode node) - { - RegionChunkData data = node.Tag as RegionChunkData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - LoadNbtStream(node, data.Region.GetChunkDataInputStream(data.X, data.Z)); - - data.Expanded = true; - } - - void LoadLazyNbt(TreeNode node) - { - NbtFileData data = node.Tag as NbtFileData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - - NBTFile file = new NBTFile(data.Path); - LoadNbtStream(node, file.GetDataInputStream(data.CompressionType)); - - data.Expanded = true; - } - - static void LoadLazyDirectory(TreeNode node) - { - var data = node.Tag as DirectoryData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - - foreach (string dirpath in Directory.EnumerateDirectories(data.Path)) - { - node.Nodes.Add(CreateLazyDirectory(dirpath, node)); - } - - foreach (string filepath in Directory.EnumerateFiles(data.Path)) - { - TryLoadFile(node.Nodes, filepath); - } - - data.Expanded = true; - } - - static void LoadLazyRegion(TreeNode node) - { - RegionData data = node.Tag as RegionData; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - LoadRegion(node, data.Path); - - data.Expanded = true; - } - - static void UnloadLazyDataNode(TreeNode node) - { - DataNode data = node.Tag as DataNode; - if (data == null || data.Modified) - return; - - node.Nodes.Clear(); - node.Nodes.Add(new TreeNode()); - - data.Expanded = false; - } - - void ExpandNode(TreeNode node) - { - if (node.Tag == null) - return; - - if (node.Tag is DataNode) - { - if ((node.Tag as DataNode).Expanded) - return; - } - - if (node.Tag is RegionChunkData) - { - LoadLazyChunk(node); - } - else if (node.Tag is NbtFileData) - { - LoadLazyNbt(node); - } - else if (node.Tag is DirectoryData) - { - LoadLazyDirectory(node); - } - else if (node.Tag is RegionData) - { - LoadLazyRegion(node); - } - } - - static void CollapseNode(TreeNode node) - { - if (node.Tag == null) - return; - - if (node.Tag is DataNode) - { - UnloadLazyDataNode(node); - } - } void UpdateToolbar() { @@ -482,7 +139,7 @@ void OpenPaths(IEnumerable paths) } else if (File.Exists(path)) { - TryLoadFile(_nodeTree.Nodes, path); + ServerNode.TryLoadFile(_nodeTree.Nodes, path); } } @@ -513,78 +170,12 @@ void LoadDirectory(string path) void LoadDirectory(string path, TreeNodeCollection parent) { - LoadDirectory(path, parent, path); - } - - static void LoadDirectory(string path, TreeNodeCollection parent, string name) - { - TreeNode root = new TreeNode(name, 10, 10); - - foreach (string dirpath in Directory.EnumerateDirectories(path)) - { - root.Nodes.Add(CreateLazyDirectory(dirpath, root)); - } - - foreach (string filepath in Directory.EnumerateFiles(path)) - { - TryLoadFile(root.Nodes, filepath); - } - - parent.Add(root); + ServerNode.LoadDirectory(path, parent, path); } - static void TryLoadFile(TreeNodeCollection parent, string path) - { - if (Path.GetExtension(path) == ".mcr") - { - TreeNode node = CreateLazyRegion(path); - parent.Add(node); - LinkDataNodeParent(node, node.Parent); - return; - } + - if (Path.GetExtension(path) == ".dat") - { - try - { - NBTFile file = new NBTFile(path); - NbtTree tree = new NbtTree(); - tree.ReadFrom(file.GetDataInputStream()); - TreeNode node = CreateLazyNbt(path, CompressionType.GZip); - parent.Add(node); - LinkDataNodeParent(node, node.Parent); - return; - } - catch { } - - try - { - NBTFile file = new NBTFile(path); - NbtTree tree = new NbtTree(); - tree.ReadFrom(file.GetDataInputStream(CompressionType.None)); - TreeNode node = CreateLazyNbt(path, CompressionType.None); - parent.Add(node); - LinkDataNodeParent(node, node.Parent); - return; - } - catch { } - } - } - - static Form1() - { - _tagIconIndex = new Dictionary(); - _tagIconIndex[TagType.TAG_BYTE] = 0; - _tagIconIndex[TagType.TAG_SHORT] = 1; - _tagIconIndex[TagType.TAG_INT] = 2; - _tagIconIndex[TagType.TAG_LONG] = 3; - _tagIconIndex[TagType.TAG_FLOAT] = 4; - _tagIconIndex[TagType.TAG_DOUBLE] = 5; - _tagIconIndex[TagType.TAG_BYTE_ARRAY] = 6; - _tagIconIndex[TagType.TAG_STRING] = 7; - _tagIconIndex[TagType.TAG_LIST] = 8; - _tagIconIndex[TagType.TAG_COMPOUND] = 9; - } + void OpenFile() { @@ -603,7 +194,7 @@ void OpenFile(string file) { _nodeTree.Nodes.Clear(); findEntityChunkToolStripMenuItem.DropDownItems.Clear(); - TryLoadFile(_nodeTree.Nodes, file); + ServerNode.TryLoadFile(_nodeTree.Nodes, file); } string _openFolderPath = null; @@ -675,338 +266,7 @@ static void SaveRegionChunkNode(TreeNode node) } data.Modified = false; } - - - static TreeNode BaseNode(TreeNode node) - { - if (node == null) - return null; - - TreeNode baseNode = node; - while (baseNode.Tag == null || !(baseNode.Tag is DataNode)) - { - baseNode = baseNode.Parent; - } - - return baseNode; - } - - #region Tag Deletion - - static void DeleteNode(TreeNode node) - { - TreeNode baseNode = BaseNode(node); - - // Can only delete internal NBT nodes - if (baseNode == null || baseNode == node) - return; - - (baseNode.Tag as DataNode).Modified = true; - - DeleteNodeNbtTag(node); - - if (node.Parent != null) - { - node.Parent.Text = GetNodeText(node.Parent); - } - - node.Remove(); - } - - - - static void DeleteNodeNbtTag(TreeNode node) - { - TagNode tag = node.Tag as TagNode; - if (tag == null) - return; - - TagNode parentTag = node.Parent.Tag as TagNode; - if (parentTag == null) - { - NbtDataNode parentData = node.Parent.Tag as NbtDataNode; - if (parentData == null) - return; - - parentTag = parentData.Tree.Root; - if (parentTag == null) - return; - } - - switch (parentTag.GetTagType()) - { - case TagType.TAG_LIST: - parentTag.ToTagList().Remove(tag); - break; - - case TagType.TAG_COMPOUND: - DeleteTagFromCompound(parentTag.ToTagCompound(), tag); - break; - } - } - - static void DeleteTagFromCompound(IDictionary parent, TagNode target) - { - string match = ""; - foreach (KeyValuePair kv in parent) - { - if (kv.Value == target) - { - match = kv.Key; - break; - } - } - - if (match != null) - { - parent.Remove(match); - } - } - - #endregion - - - static TagNode GetTagNode(TreeNode node) - { - if (node == null) - return null; - - if (node.Tag is TagNode) - { - return node.Tag as TagNode; - } - else if (node.Tag is NbtDataNode) - { - NbtDataNode data = node.Tag as NbtDataNode; - if (data == null) - return null; - - return data.Tree.Root; - } - - return null; - } - - static TagNode GetParentTagNode(TreeNode node) - { - if (GetTagNode(node) == null) - return null; - - return GetTagNode(node.Parent); - } - - static string GetTagNodeName(TreeNode node) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return null; - - TagNode parentTag = GetTagNode(node.Parent); - if (parentTag == null) - return null; - - if (parentTag.GetTagType() != TagType.TAG_COMPOUND) - return null; - - foreach (KeyValuePair sub in parentTag.ToTagCompound()) - { - if (sub.Value == tag) - return sub.Key; - } - - return null; - } - - static bool SetTagNodeName(TreeNode node, string name) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return false; - - TagNode parentTag = GetTagNode(node.Parent); - if (parentTag == null) - return false; - - if (parentTag.GetTagType() != TagType.TAG_COMPOUND) - return false; - - if (parentTag.ToTagCompound().ContainsKey(name)) - return false; - - string oldName = null; - foreach (KeyValuePair sub in parentTag.ToTagCompound()) - { - if (sub.Value == tag) - { - oldName = sub.Key; - break; - } - } - - parentTag.ToTagCompound().Remove(oldName); - parentTag.ToTagCompound().Add(name, tag); - - return true; - } - - static void EditNodeValue(TreeNode node) - { - if (node == null) - return; - - TagNode tag = GetTagNode(node); - if (tag == null) - return; - - if (tag.GetTagType() == TagType.TAG_BYTE_ARRAY || - tag.GetTagType() == TagType.TAG_LIST || - tag.GetTagType() == TagType.TAG_COMPOUND) - return; - - EditValue form = new EditValue(tag); - if (form.ShowDialog() == DialogResult.OK) - { - TreeNode baseNode = BaseNode(node); - if (baseNode != null) - { - (baseNode.Tag as DataNode).Modified = true; - } - - node.Text = GetNodeText(node); - } - } - - - - static void EditNodeName(TreeNode node) - { - if (node == null) - return; - - TagNode tag = GetTagNode(node); - if (tag == null) - return; - - string name = GetTagNodeName(node); - if (name == null) - return; - - var form = new EditValue(name); - - var parentTag = GetParentTagNode(node); - foreach (string key in parentTag.ToTagCompound().Keys) - { - form.InvalidNames.Add(key); - } - - if (form.ShowDialog() == DialogResult.OK) - { - TreeNode baseNode = BaseNode(node); - if (baseNode != null) - { - (baseNode.Tag as DataNode).Modified = true; - } - - SetTagNodeName(node, form.NodeName); - node.Text = GetNodeText(node); - } - } - - - void AddTagToNode(TreeNode node, TagType type) - { - TagNode tag = GetTagNode(node); - if (tag == null) - return; - - if (tag.GetTagType() != TagType.TAG_COMPOUND && - tag.GetTagType() != TagType.TAG_LIST) - return; - - if (tag.GetTagType() == TagType.TAG_LIST && - tag.ToTagList().ValueType != type && - tag.ToTagList().Count > 0) - return; - - TagNode newNode = null; - switch (type) - { - case TagType.TAG_BYTE: - newNode = new TagNodeByte(); - break; - case TagType.TAG_SHORT: - newNode = new TagNodeShort(); - break; - case TagType.TAG_INT: - newNode = new TagNodeInt(); - break; - case TagType.TAG_LONG: - newNode = new TagNodeLong(); - break; - case TagType.TAG_FLOAT: - newNode = new TagNodeFloat(); - break; - case TagType.TAG_DOUBLE: - newNode = new TagNodeDouble(); - break; - case TagType.TAG_BYTE_ARRAY: - newNode = new TagNodeByteArray(); - break; - case TagType.TAG_STRING: - newNode = new TagNodeString(); - break; - case TagType.TAG_LIST: - newNode = new TagNodeList(TagType.TAG_BYTE); - break; - case TagType.TAG_COMPOUND: - newNode = new TagNodeCompound(); - break; - } - - if (tag is TagNodeCompound) - { - TagNodeCompound ctag = tag as TagNodeCompound; - - EditValue form = new EditValue(""); - foreach (string key in ctag.Keys) - { - form.InvalidNames.Add(key); - } - - if (form.ShowDialog() != DialogResult.OK) - return; - - ctag.Add(form.NodeName, newNode); - - TreeNode tnode = NodeFromTag(newNode, form.NodeName); - node.Nodes.Add(tnode); - - _nodeTree.SelectedNode = tnode; - tnode.Expand(); - } - else if (tag is TagNodeList) - { - var ltag = tag as TagNodeList; - if (ltag.ValueType != type) - ltag.ChangeValueType(type); - - ltag.Add(newNode); - - TreeNode tnode = NodeFromTag(newNode); - node.Nodes.Add(tnode); - - _nodeTree.SelectedNode = tnode; - tnode.Expand(); - } - - node.Text = GetNodeText(node); - - TreeNode baseNode = BaseNode(node); - if (baseNode != null) - { - (baseNode.Tag as DataNode).Modified = true; - } - } + #region Events static void aboutToolStripMenuItem_Click(object sender, EventArgs e) @@ -1016,12 +276,12 @@ static void aboutToolStripMenuItem_Click(object sender, EventArgs e) void NodeExpand(object sender, TreeViewCancelEventArgs e) { - ExpandNode(e.Node); + ServerNode.ExpandNode(e.Node, this.imageList1.Images.Count); } static void NodeCollapse(object sender, TreeViewEventArgs e) { - CollapseNode(e.Node); + ServerNode.CollapseNode(e.Node); } void NodeSelected(object sender, TreeViewEventArgs e) @@ -1036,12 +296,12 @@ static void NodeClicked(object sender, TreeNodeMouseClickEventArgs e) void NodeDoubleClicked(object sender, TreeNodeMouseClickEventArgs e) { - EditNodeValue(_nodeTree.SelectedNode); + ServerNode.EditNodeValue(_nodeTree.SelectedNode); } void _buttonEdit_Click(object sender, EventArgs e) { - EditNodeValue(_nodeTree.SelectedNode); + ServerNode.EditNodeValue(_nodeTree.SelectedNode); } void _buttonSave_Click(object sender, EventArgs e) @@ -1066,12 +326,12 @@ void toolStripButton1_Click(object sender, EventArgs e) void _buttonDelete_Click(object sender, EventArgs e) { - DeleteNode(_nodeTree.SelectedNode); + ServerNode.DeleteNode(_nodeTree.SelectedNode); } void _buttonRename_Click(object sender, EventArgs e) { - EditNodeName(_nodeTree.SelectedNode); + ServerNode.EditNodeName(_nodeTree.SelectedNode); } void _buttonOpenFolder_Click(object sender, EventArgs e) @@ -1096,55 +356,58 @@ void _buttonFindNext_Click(object sender, EventArgs e) else FindNext(); } - + void AddTagToNode(TagType type) + { + ServerNode.AddTagToNode(_nodeTree.SelectedNode, this.imageList1.Images.Count, type); + } void _buttonAddTagByte_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE); + AddTagToNode(TagType.TAG_BYTE); } void _buttonAddTagShort_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_SHORT); + AddTagToNode(TagType.TAG_SHORT); } void _buttonAddTagInt_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_INT); + AddTagToNode(TagType.TAG_INT); } private void _buttonAddTagLong_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LONG); + AddTagToNode(TagType.TAG_LONG); } void _buttonAddTagFloat_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_FLOAT); + AddTagToNode(TagType.TAG_FLOAT); } void _buttonAddTagDouble_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_DOUBLE); + AddTagToNode(TagType.TAG_DOUBLE); } void _buttonAddTagByteArray_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_BYTE_ARRAY); + AddTagToNode(TagType.TAG_BYTE_ARRAY); } void _buttonAddTagString_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_STRING); + AddTagToNode(TagType.TAG_STRING); } void _buttonAddTagList_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_LIST); + AddTagToNode(TagType.TAG_LIST); } void _buttonAddTagCompound_Click(object sender, EventArgs e) { - AddTagToNode(_nodeTree.SelectedNode, TagType.TAG_COMPOUND); + AddTagToNode(TagType.TAG_COMPOUND); } void saveToolStripMenuItem_Click(object sender, EventArgs e) @@ -1193,7 +456,7 @@ void Find(TreeNode node) _searchName = form.MatchName ? form.NameToken : null; _searchValue = form.MatchValue ? form.ValueToken : null; - _search = FindNode(node).GetEnumerator(); + _search = ServerNode.FindNode(node,this.imageList1.Images.Count,_searchName, _searchValue).GetEnumerator(); FindNext(); } @@ -1230,62 +493,7 @@ void FindNext() statusStrip1.Visible = false; } - IEnumerable FindNode(TreeNode node) - { - if (node == null) - yield break; - - bool expand = false; - - if (node.Tag is DataNode) - { - DataNode data = node.Tag as DataNode; - if (!data.Expanded) - { - ExpandNode(node); - expand = true; - } - } - - TagNode tag = GetTagNode(node); - if (tag != null) - { - bool mName = _searchName == null; - bool mValue = _searchValue == null; - - if (_searchName != null) - { - string tagName = GetTagNodeName(node); - if (tagName != null) - mName = tagName.Contains(_searchName); - } - if (_searchValue != null) - { - string tagValue = GetTagNodeText(node); - if (tagValue != null) - mValue = tagValue.Contains(_searchValue); - } - - if (mName && mValue) - { - _nodeTree.SelectedNode = node; - yield return node; - } - } - - foreach (TreeNode sub in node.Nodes) - { - foreach (TreeNode s in FindNode(sub)) - yield return s; - } - - if (expand) - { - DataNode data = node.Tag as DataNode; - if (!data.Modified) - CollapseNode(node); - } - } + void DropFile(DragEventArgs e) { @@ -1294,32 +502,27 @@ void DropFile(DragEventArgs e) } - static IEnumerable FindChunks(IEnumerable nodes, Func predicate) + static IEnumerable FindChunks(IEnumerable nodes, Func predicate) { foreach (var region in nodes) - foreach (var chunk in region.Nodes.Cast().Where(c => c.Text.StartsWith("Chunk"))) + foreach (var chunk in region.FindChunks(predicate)) { - if (predicate == null || predicate(chunk)) yield return chunk; } } - int _nodesSearched = 0; + int _nodesSearchedForEntity = 0; - static bool NeedsExpand(TreeNode node) - { - return node.Tag is DataNode && (node.Tag as DataNode).Expanded == false; - - } + IEnumerable FindRegions(IEnumerable nodes, Func predicate) { foreach (var node in nodes) { - _nodesSearched++; - if (NeedsExpand(node)) - ExpandNode(node); + _nodesSearchedForEntity++; + if (ServerNode.NeedsExpand(node)) + ServerNode.ExpandNode(node,this.imageList1.Images.Count); if (predicate(node)) yield return node; else @@ -1335,19 +538,20 @@ IEnumerable FindRegions(IEnumerable nodes, Func /// - IEnumerable FindNextChunk() + IEnumerable FindNextPopulatedChunk(IEnumerable previouslyFound) { + var lastFound = - findEntityChunkToolStripMenuItem.DropDownItems.Cast().LastOrDefault( + previouslyFound.LastOrDefault( t => t.Text.StartsWith("Chunk")); if (lastFound != null) { lastFound.PerformClick(); Application.DoEvents(); - return FindFrom(_nodeTree.SelectedNode); + return FindNextPopulatedFrom(_nodeTree.SelectedNode); } - else return FindFrom(_nodeTree.Nodes[0]); + else return FindNextPopulatedFrom(_nodeTree.Nodes[0]); } @@ -1356,45 +560,45 @@ IEnumerable FindNextChunk() /// /// /// - IEnumerable FindFrom(TreeNode start) + IEnumerable FindNextPopulatedFrom(TreeNode start) { if (this._nodeTree.Nodes.Count == 0) - return Enumerable.Empty(); + return Enumerable.Empty(); var entityNodes = FindRegions( - _nodeTree.Nodes.Cast(), tn => tn.Text.EndsWith(".mcr")); + _nodeTree.Nodes.Cast(), tn => tn.Text.EndsWith(".mcr")).Select(tn=>new ViewModel.RegionNode(tn,this.imageList1.Images.Count)); var entityRegions = entityNodes.ToArray(); try { if (entityRegions == null || entityRegions.Any() == false) { - return Enumerable.Empty(); + return Enumerable.Empty(); } var chunks = FindChunks(entityRegions, tn => tn.Index > start.Index); if (chunks == null || chunks.Any() == false) - return Enumerable.Empty(); + return Enumerable.Empty(); var populatedChunks = FindChunksWithEntities(chunks); if (populatedChunks == null || populatedChunks.Any() == false) - return Enumerable.Empty(); + return Enumerable.Empty(); return populatedChunks; } finally { - toolStrip1.Text = "Searched " + _nodesSearched + " nodes"; + toolStrip1.Text = "Searched " + _nodesSearchedForEntity + " nodes"; toolStrip1.Visible = true; } } void findEntityChunkToolStripMenuItem_Click(object sender, EventArgs e) { - _nodesSearched = 0; - var populatedChunks = FindNextChunk(); + _nodesSearchedForEntity = 0; + var populatedChunks = FindNextPopulatedChunk(findEntityChunkToolStripMenuItem.DropDownItems.Cast()); var first = populatedChunks.FirstOrDefault(); if (first == null) return; first.EnsureVisible(); - _nodeTree.SelectedNode = first; + _nodeTree.SelectedNode = first.Node; var ddl = new ToolStripButton(); ddl.Text = first.Text; ddl.Width = Text.Length * 5; @@ -1403,31 +607,49 @@ void findEntityChunkToolStripMenuItem_Click(object sender, EventArgs e) ddl.Click += (sender2, e2) => { first.EnsureVisible(); - _nodeTree.SelectedNode = first; + _nodeTree.SelectedNode = first.Node; }; findEntityChunkToolStripMenuItem.DropDownItems.Add(ddl); } - IEnumerable FindChunksWithEntities(IEnumerable chunks) + IEnumerable FindChunksWithEntities(IEnumerable chunks) { foreach (var chunk in chunks) { - if (NeedsExpand(chunk)) - ExpandNode(chunk); - var level = chunk.Nodes.Cast().FirstOrDefault(n => n.Text.StartsWith("Level")); - if (level == null) - continue; - var entityNode = level.Nodes.Cast().FirstOrDefault(n => n.Text.StartsWith("Entities")); - if (entityNode == null) - continue; - var text = entityNode.Text.Where(c => char.IsNumber(c)).Select(c => c.ToString()).Aggregate((c1, c2) => c1 + c2); - - var entityCount = int.Parse(text); - if (entityCount > 0) + + if (chunk.GetEntityCount()>0) yield return chunk; } } + + int _nodesSearchedForBloat = 0; + public const int BloatedAt = 300; + private void findBloatedChunkToolStripMenuItem_Click(object sender, EventArgs e) + { + _nodesSearchedForBloat = 0; // findEntityChunkToolStripMenuItem.DropDownItems.Cast() + var populatedChunks = FindNextPopulatedChunk(findBloatedChunkToolStripMenuItem.DropDownItems.Cast()); + var first = populatedChunks.FirstOrDefault(c => c.GetEntityCount() >= BloatedAt); + + if (first == null) + return; + first.EnsureVisible(); + first.EnsureEntitiesVisible(); + first.SelectEntityNode(); + + var ddl = new ToolStripButton(); + ddl.Text = first.Text; + ddl.Width = Text.Length * 5; + ddl.ToolTipText = first.Parent.Text; + + ddl.Click += (sender2, e2) => + { + + first.EnsureVisible(); + _nodeTree.SelectedNode = first.Node; + }; + findBloatedChunkToolStripMenuItem.DropDownItems.Add(ddl); + } } } diff --git a/Form1.resx b/Form1.resx index e12af37..3755788 100644 --- a/Form1.resx +++ b/Form1.resx @@ -131,7 +131,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADW - LgAAAk1TRnQBSQFMAgEBDgEAAagBAAGoAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA + LgAAAk1TRnQBSQFMAgEBDgEAAbABAAGwAQABEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA AwABQAMAAQEBAAEYBgABMBIAA/wD+SH4A/kD/AMAA/0D+SH4A/kD/WMAAZYBqQG8AVwBhAGuAVwBhAGu AVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGuAVwBhAGu AVwBhAGuAZYBqQG8AwACzwHLArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5AbACuQGwArkBsAK5 @@ -517,11 +517,11 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFySURBVDhPY2CgBthfz8CyP4kl40AiczcM19sxnEHGyHIg tSA9cLv3xrErn6rWXPp+T+f/d7s7wHh2hikKhomD1IDUgvTADdiVwOx+c4r3EWQDlpc4/ofhJYV2cINB - akBqQXrgBuyIZ8m9vyz7wbPNDf9heEuj338YXlftARcHyYPUgvTADdgawzz15bHlf//fXfUfhu+uKgcy + akBqQXrgBuyIZ8m9vyz7wbPNDf9heEuj338YXlftARcHyYPUgvTADdgawzz1xdHlf//fXfUfhu+uKgcy IfjMzDS4OEgepBakB27A5ijmGT8vzf//+cRUON7dEfofhjc3+KLIgdSC9MAN2BDFPPvbudn/PxyZCMcg zavKXcCGLCt2QJEDqQXpgRuwOoJ5/qeT0/6/2d8DxyDNID6MRpYDqQXpgRuwPIx58btD/f9f7monCoPU gvTADVgSwrjsFTDun25tIgqD1IL0wA2YH8C4+smWxv8PN9QShUFqQXrgBkzxZNzxYF31//trq4jCILUg - PTAD5FKNGee1uTAeJQWD9AANkAMZwg/E4kAsRSIG6QHppQwAANmG3WiWwmadAAAAAElFTkSuQmCC + PTAD5FKNGee1uTAeJQWD9AANkAMZwg/E4kAsRSIG6QHppQwAAM7Y3WS4HD+dAAAAAElFTkSuQmCC diff --git a/NBTExplorer.csproj b/NBTExplorer.csproj index c6874f6..62947ad 100644 --- a/NBTExplorer.csproj +++ b/NBTExplorer.csproj @@ -13,6 +13,25 @@ v4.0 Client 512 + true + ftp://ftp.imaginarydevelopment.com/imaginarydevelopment.com/clickonce/NbtExplorer/ + true + Web + true + Foreground + 7 + Days + false + false + true + http://imaginarydevelopment.com/clickonce/NbtExplorer/ + true + publish.htm + 3 + 1.0.0.%2a + false + true + true x86 @@ -36,6 +55,18 @@ dead_bush.ico + + 64396E069743F7BE392C01230CDA47C1469B8D85 + + + NBTExplorer_TemporaryKey.pfx + + + true + + + true + @@ -51,6 +82,7 @@ About.cs + @@ -81,6 +113,8 @@ + + About.cs @@ -103,6 +137,7 @@ Resources.resx True + SettingsSingleFileGenerator Settings.Designer.cs @@ -150,6 +185,29 @@ Substrate %28NET4%29 + + + False + Microsoft .NET Framework 4 Client Profile %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + +