Browse Source

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

Kevin Fischer 4 years ago
parent
commit
75866c81e7

+ 3 - 0
doc/classes/Tree.xml

@@ -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>

+ 17 - 1
doc/classes/TreeItem.xml

@@ -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" />

+ 2 - 0
editor/editor_themes.cpp

@@ -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"));

+ 1 - 0
editor/icons/GuiIndeterminate.svg

@@ -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>

+ 24 - 1
scene/gui/tree.cpp

@@ -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);

+ 4 - 0
scene/gui/tree.h

@@ -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;

+ 1 - 0
scene/resources/default_theme/default_theme.cpp

@@ -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));

BIN
scene/resources/default_theme/indeterminate.png


+ 8 - 0
scene/resources/default_theme/theme_data.h

@@ -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
 };
 };