Added icons and API for indeterminate checkmarks for the Tree class.

This commit is contained in:
Kevin Fischer 2021-07-22 13:34:54 -07:00
parent cfdac0973c
commit 75866c81e7
9 changed files with 60 additions and 2 deletions

View file

@ -552,6 +552,9 @@
<theme_item name="hseparation" data_type="constant" type="int" default="4"> <theme_item name="hseparation" data_type="constant" type="int" default="4">
The horizontal space between item cells. This is also used as the margin at the start of an item when folding is disabled. The horizontal space between item cells. This is also used as the margin at the start of an item when folding is disabled.
</theme_item> </theme_item>
<theme_item name="indeterminate" data_type="icon" type="Texture2D">
The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is indeterminate.
</theme_item>
<theme_item name="item_margin" data_type="constant" type="int" default="12"> <theme_item name="item_margin" data_type="constant" type="int" default="12">
The horizontal margin at the start of an item. This is used when folding is enabled for the item. The horizontal margin at the start of an item. This is used when folding is enabled for the item.
</theme_item> </theme_item>

View file

@ -340,6 +340,13 @@
Returns [code]true[/code] if column [code]column[/code] is editable. Returns [code]true[/code] if column [code]column[/code] is editable.
</description> </description>
</method> </method>
<method name="is_indeterminate" qualifiers="const">
<return type="bool" />
<argument index="0" name="column" type="int" />
<description>
Returns [code]true[/code] if the given column is indeterminate.
</description>
</method>
<method name="is_selectable" qualifiers="const"> <method name="is_selectable" qualifiers="const">
<return type="bool" /> <return type="bool" />
<argument index="0" name="column" type="int" /> <argument index="0" name="column" type="int" />
@ -415,7 +422,7 @@
<argument index="0" name="column" type="int" /> <argument index="0" name="column" type="int" />
<argument index="1" name="checked" type="bool" /> <argument index="1" name="checked" type="bool" />
<description> <description>
If [code]true[/code], the column [code]column[/code] is checked. If [code]true[/code], the column [code]column[/code] is checked. Clears column's indeterminate status.
</description> </description>
</method> </method>
<method name="set_custom_as_button"> <method name="set_custom_as_button">
@ -507,6 +514,15 @@
Sets the given column's icon's texture region. Sets the given column's icon's texture region.
</description> </description>
</method> </method>
<method name="set_indeterminate">
<return type="void" />
<argument index="0" name="column" type="int" />
<argument index="1" name="indeterminate" type="bool" />
<description>
If [code]true[/code], the column [code]column[/code] is marked indeterminate.
[b]Note:[/b] If set [code]true[/code] from [code]false[/code], then column is cleared of checked status.
</description>
</method>
<method name="set_language"> <method name="set_language">
<return type="void" /> <return type="void" />
<argument index="0" name="column" type="int" /> <argument index="0" name="column" type="int" />

View file

@ -219,6 +219,7 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
exceptions.insert("DefaultProjectIcon"); exceptions.insert("DefaultProjectIcon");
exceptions.insert("GuiChecked"); exceptions.insert("GuiChecked");
exceptions.insert("GuiRadioChecked"); exceptions.insert("GuiRadioChecked");
exceptions.insert("GuiIndeterminate");
exceptions.insert("GuiCloseCustomizable"); exceptions.insert("GuiCloseCustomizable");
exceptions.insert("GuiGraphNodePort"); exceptions.insert("GuiGraphNodePort");
exceptions.insert("GuiResizer"); exceptions.insert("GuiResizer");
@ -812,6 +813,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// Tree // Tree
theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons"));
theme->set_icon("indeterminate", "Tree", theme->get_icon("GuiIndeterminate", "EditorIcons"));
theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons")); theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons"));
theme->set_icon("arrow", "Tree", theme->get_icon("GuiTreeArrowDown", "EditorIcons")); theme->set_icon("arrow", "Tree", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons")); theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m3.333 1c-1.288 0-2.333 1.045-2.333 2.333v9.334c0 1.288 1.045 2.333 2.333 2.333h9.334c1.288 0 2.333-1.045 2.333-2.333v-9.334c0-1.288-1.045-2.333-2.333-2.333z" fill="#699ce8" fill-rule="nonzero"/><path d="m3 7h10.058v2.12h-10.058z" fill="#fff" transform="matrix(.99428 0 0 .943295 .017161 .396936)"/></svg>

After

Width:  |  Height:  |  Size: 461 B

View file

@ -167,6 +167,18 @@ TreeItem::TreeCellMode TreeItem::get_cell_mode(int p_column) const {
void TreeItem::set_checked(int p_column, bool p_checked) { void TreeItem::set_checked(int p_column, bool p_checked) {
ERR_FAIL_INDEX(p_column, cells.size()); ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].checked = p_checked; cells.write[p_column].checked = p_checked;
cells.write[p_column].indeterminate = false;
_changed_notify(p_column);
}
void TreeItem::set_indeterminate(int p_column, bool p_indeterminate) {
ERR_FAIL_INDEX(p_column, cells.size());
// Prevent uncheck if indeterminate set to false twice
if (p_indeterminate == cells[p_column].indeterminate) {
return;
}
cells.write[p_column].indeterminate = p_indeterminate;
cells.write[p_column].checked = false;
_changed_notify(p_column); _changed_notify(p_column);
} }
@ -175,6 +187,11 @@ bool TreeItem::is_checked(int p_column) const {
return cells[p_column].checked; return cells[p_column].checked;
} }
bool TreeItem::is_indeterminate(int p_column) const {
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].indeterminate;
}
void TreeItem::set_text(int p_column, String p_text) { void TreeItem::set_text(int p_column, String p_text) {
ERR_FAIL_INDEX(p_column, cells.size()); ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].text = p_text; cells.write[p_column].text = p_text;
@ -1042,7 +1059,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_cell_mode", "column"), &TreeItem::get_cell_mode); ClassDB::bind_method(D_METHOD("get_cell_mode", "column"), &TreeItem::get_cell_mode);
ClassDB::bind_method(D_METHOD("set_checked", "column", "checked"), &TreeItem::set_checked); ClassDB::bind_method(D_METHOD("set_checked", "column", "checked"), &TreeItem::set_checked);
ClassDB::bind_method(D_METHOD("set_indeterminate", "column", "indeterminate"), &TreeItem::set_indeterminate);
ClassDB::bind_method(D_METHOD("is_checked", "column"), &TreeItem::is_checked); ClassDB::bind_method(D_METHOD("is_checked", "column"), &TreeItem::is_checked);
ClassDB::bind_method(D_METHOD("is_indeterminate", "column"), &TreeItem::is_indeterminate);
ClassDB::bind_method(D_METHOD("set_text", "column", "text"), &TreeItem::set_text); ClassDB::bind_method(D_METHOD("set_text", "column", "text"), &TreeItem::set_text);
ClassDB::bind_method(D_METHOD("get_text", "column"), &TreeItem::get_text); ClassDB::bind_method(D_METHOD("get_text", "column"), &TreeItem::get_text);
@ -1228,6 +1247,7 @@ void Tree::update_cache() {
cache.checked = get_theme_icon(SNAME("checked")); cache.checked = get_theme_icon(SNAME("checked"));
cache.unchecked = get_theme_icon(SNAME("unchecked")); cache.unchecked = get_theme_icon(SNAME("unchecked"));
cache.indeterminate = get_theme_icon(SNAME("indeterminate"));
if (is_layout_rtl()) { if (is_layout_rtl()) {
cache.arrow_collapsed = get_theme_icon(SNAME("arrow_collapsed_mirrored")); cache.arrow_collapsed = get_theme_icon(SNAME("arrow_collapsed_mirrored"));
} else { } else {
@ -1721,10 +1741,13 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
case TreeItem::CELL_MODE_CHECK: { case TreeItem::CELL_MODE_CHECK: {
Ref<Texture2D> checked = cache.checked; Ref<Texture2D> checked = cache.checked;
Ref<Texture2D> unchecked = cache.unchecked; Ref<Texture2D> unchecked = cache.unchecked;
Ref<Texture2D> indeterminate = cache.indeterminate;
Point2i check_ofs = item_rect.position; Point2i check_ofs = item_rect.position;
check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2); check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2);
if (p_item->cells[i].checked) { if (p_item->cells[i].indeterminate) {
indeterminate->draw(ci, check_ofs);
} else if (p_item->cells[i].checked) {
checked->draw(ci, check_ofs); checked->draw(ci, check_ofs);
} else { } else {
unchecked->draw(ci, check_ofs); unchecked->draw(ci, check_ofs);

View file

@ -82,6 +82,7 @@ private:
int icon_max_w = 0; int icon_max_w = 0;
bool expr = false; bool expr = false;
bool checked = false; bool checked = false;
bool indeterminate = false;
bool editable = false; bool editable = false;
bool selected = false; bool selected = false;
bool selectable = true; bool selectable = true;
@ -209,7 +210,9 @@ public:
/* check mode */ /* check mode */
void set_checked(int p_column, bool p_checked); void set_checked(int p_column, bool p_checked);
void set_indeterminate(int p_column, bool p_indeterminate);
bool is_checked(int p_column) const; bool is_checked(int p_column) const;
bool is_indeterminate(int p_column) const;
void set_text(int p_column, String p_text); void set_text(int p_column, String p_text);
String get_text(int p_column) const; String get_text(int p_column) const;
@ -491,6 +494,7 @@ private:
Ref<Texture2D> checked; Ref<Texture2D> checked;
Ref<Texture2D> unchecked; Ref<Texture2D> unchecked;
Ref<Texture2D> indeterminate;
Ref<Texture2D> arrow_collapsed; Ref<Texture2D> arrow_collapsed;
Ref<Texture2D> arrow; Ref<Texture2D> arrow;
Ref<Texture2D> select_arrow; Ref<Texture2D> select_arrow;

View file

@ -704,6 +704,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("checked", "Tree", make_icon(checked_png)); theme->set_icon("checked", "Tree", make_icon(checked_png));
theme->set_icon("unchecked", "Tree", make_icon(unchecked_png)); theme->set_icon("unchecked", "Tree", make_icon(unchecked_png));
theme->set_icon("indeterminate", "Tree", make_icon(indeterminate_png));
theme->set_icon("updown", "Tree", make_icon(updown_png)); theme->set_icon("updown", "Tree", make_icon(updown_png));
theme->set_icon("select_arrow", "Tree", make_icon(dropdown_png)); theme->set_icon("select_arrow", "Tree", make_icon(dropdown_png));
theme->set_icon("arrow", "Tree", make_icon(arrow_down_png)); theme->set_icon("arrow", "Tree", make_icon(arrow_down_png));

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

View file

@ -214,6 +214,14 @@ static const unsigned char icon_zoom_reset_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0xa, 0x3c, 0xc, 0x7b, 0xf0, 0xff, 0xc1, 0x7f, 0x9c, 0x22, 0xcf, 0x44, 0x1e, 0xbc, 0x84, 0x72, 0xb1, 0x8b, 0x3c, 0x58, 0x5, 0xe4, 0x40, 0xb8, 0x38, 0x45, 0x18, 0x60, 0x5c, 0x84, 0x30, 0x59, 0xa, 0xa0, 0x80, 0x6e, 0xa, 0x86, 0x92, 0x2f, 0x8, 0x3, 0x0, 0x69, 0xc8, 0x86, 0x87, 0x72, 0xca, 0x85, 0x23, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0xa, 0x3c, 0xc, 0x7b, 0xf0, 0xff, 0xc1, 0x7f, 0x9c, 0x22, 0xcf, 0x44, 0x1e, 0xbc, 0x84, 0x72, 0xb1, 0x8b, 0x3c, 0x58, 0x5, 0xe4, 0x40, 0xb8, 0x38, 0x45, 0x18, 0x60, 0x5c, 0x84, 0x30, 0x59, 0xa, 0xa0, 0x80, 0x6e, 0xa, 0x86, 0x92, 0x2f, 0x8, 0x3, 0x0, 0x69, 0xc8, 0x86, 0x87, 0x72, 0xca, 0x85, 0x23, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
}; };
static const unsigned char indeterminate_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x36, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0xfe, 0xfe, 0xfe, 0x98, 0x4d, 0x2d, 0x9a, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0xb4, 0xfa, 0xfb, 0xb4, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x77, 0x5e, 0x7f, 0x0, 0x0, 0x0, 0x59, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x85, 0xcf, 0xc1, 0x12, 0x80, 0x20, 0x8, 0x45, 0xd1, 0x4, 0x14, 0xd, 0xc5, 0xfa, 0xff, 0x9f, 0x8d, 0x9c, 0x6c, 0x9a, 0xb4, 0xe9, 0x2e, 0xcf, 0x42, 0x9e, 0xcb, 0x32, 0xe4, 0x0, 0xc9, 0xb7, 0x8, 0xc1, 0x19, 0x40, 0x60, 0xc9, 0x2d, 0xe1, 0x0, 0x6, 0xc8, 0x45, 0x6b, 0x4b, 0xb, 0xa3, 0x1, 0x89, 0x6e, 0x57, 0x2a, 0x64, 0xe0, 0x73, 0xed, 0x50, 0xb3, 0x9f, 0xc3, 0x7e, 0xf7, 0x5, 0x7f, 0x6f, 0xc, 0x67, 0x9f, 0xc3, 0xe2, 0x39, 0xc, 0x52, 0xec, 0xd3, 0xd7, 0x4, 0xb3, 0xcf, 0xbd, 0x3a, 0x0, 0xa0, 0xa2, 0x8, 0xbc, 0xf6, 0x84, 0x3a, 0x9d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char indeterminate_disabled_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x3c, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x7a, 0x78, 0x83, 0x6a, 0x69, 0x70, 0x6a, 0x68, 0x70, 0x58, 0x58, 0x5c, 0x58, 0x58, 0x5b, 0x58, 0x58, 0x5b, 0x5c, 0x5c, 0x5f, 0x5a, 0x5a, 0x5e, 0x59, 0x59, 0x5d, 0x58, 0x58, 0x5b, 0x57, 0x57, 0x5a, 0x56, 0x56, 0x59, 0xff, 0x0, 0x0, 0xff, 0xff, 0xff, 0x9e, 0x9e, 0x9e, 0x8c, 0x93, 0x80, 0x95, 0x0, 0x0, 0x0, 0x14, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0xb4, 0xb4, 0xfa, 0xfa, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6c, 0xb9, 0x8d, 0x1e, 0x0, 0x0, 0x0, 0x59, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x85, 0xcf, 0xd1, 0xe, 0x80, 0x20, 0x8, 0x85, 0xe1, 0x4, 0xd4, 0x30, 0x51, 0xb6, 0xde, 0xff, 0x5d, 0x23, 0x97, 0xad, 0xa5, 0xad, 0xff, 0xf2, 0xbb, 0x90, 0xe3, 0xb2, 0xc, 0x39, 0x40, 0xf2, 0x2d, 0x42, 0x70, 0x6, 0x10, 0x58, 0x6b, 0x4b, 0x39, 0x80, 0x1, 0x72, 0x91, 0xdc, 0x92, 0xc2, 0x68, 0x40, 0x2a, 0xdb, 0x95, 0x28, 0x19, 0xf8, 0x9a, 0x3b, 0xe4, 0xea, 0xe7, 0xb0, 0xdf, 0x7d, 0xc1, 0xdf, 0x1b, 0xc3, 0xd9, 0xe7, 0xb0, 0x74, 0xe, 0x83, 0x98, 0xfa, 0xf4, 0x35, 0xc2, 0xec, 0x73, 0xaf, 0xe, 0x57, 0x20, 0x8, 0x2c, 0x1a, 0x56, 0xe5, 0x32, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char line_edit_png[] = { static const unsigned char line_edit_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
}; };