diff options
Diffstat (limited to 'gfx/angle/src/tests/gl_tests')
71 files changed, 44631 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/BindGeneratesResourceTest.cpp b/gfx/angle/src/tests/gl_tests/BindGeneratesResourceTest.cpp new file mode 100644 index 000000000..e8ae739f8 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/BindGeneratesResourceTest.cpp @@ -0,0 +1,123 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BindGeneratesResourceTest.cpp : Tests of the GL_CHROMIUM_bind_generates_resource extension. + +#include "test_utils/ANGLETest.h" + +namespace angle +{ + +class BindGeneratesResourceTest : public ANGLETest +{ + protected: + BindGeneratesResourceTest() { setBindGeneratesResource(false); } +}; + +// Context creation would fail if EGL_CHROMIUM_create_context_bind_generates_resource was not +// available so the GL extension should always be present +TEST_P(BindGeneratesResourceTest, ExtensionStringExposed) +{ + EXPECT_TRUE(extensionEnabled("GL_CHROMIUM_bind_generates_resource")); +} + +// Verify that GL_BIND_GENERATES_RESOURCE_CHROMIUM can be queried but not changed +TEST_P(BindGeneratesResourceTest, QueryValidation) +{ + GLint intValue = 2; + glGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &intValue); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(intValue, GL_FALSE); + + float floatValue = 2.0f; + glGetFloatv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &floatValue); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(floatValue, 0.0f); + + GLboolean boolValue = GL_TRUE; + glGetBooleanv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &boolValue); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(boolValue, GL_FALSE); + + boolValue = glIsEnabled(GL_BIND_GENERATES_RESOURCE_CHROMIUM); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(boolValue, GL_FALSE); + + glEnable(GL_BIND_GENERATES_RESOURCE_CHROMIUM); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glDisable(GL_BIND_GENERATES_RESOURCE_CHROMIUM); + EXPECT_GL_ERROR(GL_INVALID_ENUM); +} + +// Test that buffers cannot be generated on bind +TEST_P(BindGeneratesResourceTest, Buffers) +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 2); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + EXPECT_GL_NO_ERROR(); + + if (getClientMajorVersion() >= 3) + { + glBindBufferBase(GL_UNIFORM_BUFFER, 0, 3); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0); + EXPECT_GL_NO_ERROR(); + + glBindBufferRange(GL_UNIFORM_BUFFER, 0, 4, 1, 2); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBindBufferRange(GL_UNIFORM_BUFFER, 0, 0, 1, 2); + EXPECT_GL_NO_ERROR(); + } +} + +// Test that textures cannot be generated on bind +TEST_P(BindGeneratesResourceTest, Textures) +{ + glBindTexture(GL_TEXTURE_2D, 2); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBindTexture(GL_TEXTURE_2D, 0); + EXPECT_GL_NO_ERROR(); +} + +// Test that framebuffers cannot be generated on bind +TEST_P(BindGeneratesResourceTest, Framebuffers) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 2); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + EXPECT_GL_NO_ERROR(); +} + +// Test that renderbuffer cannot be generated on bind +TEST_P(BindGeneratesResourceTest, Renderbuffers) +{ + glBindRenderbuffer(GL_RENDERBUFFER, 2); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(BindGeneratesResourceTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/BindUniformLocationTest.cpp b/gfx/angle/src/tests/gl_tests/BindUniformLocationTest.cpp new file mode 100755 index 000000000..732a11068 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/BindUniformLocationTest.cpp @@ -0,0 +1,484 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BindUniformLocationTest.cpp : Tests of the GL_CHROMIUM_bind_uniform_location extension. + +#include "test_utils/ANGLETest.h" + +#include <cmath> + +using namespace angle; + +namespace +{ + +class BindUniformLocationTest : public ANGLETest +{ + protected: + BindUniformLocationTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + mBindUniformLocation = reinterpret_cast<PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC>( + eglGetProcAddress("glBindUniformLocationCHROMIUM")); + } + + void TearDown() override + { + if (mProgram != 0) + { + glDeleteProgram(mProgram); + } + ANGLETest::TearDown(); + } + + typedef void(GL_APIENTRYP PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC)(GLuint mProgram, + GLint location, + const GLchar *name); + PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC mBindUniformLocation = nullptr; + + GLuint mProgram = 0; +}; + +// Test basic functionality of GL_CHROMIUM_bind_uniform_location +TEST_P(BindUniformLocationTest, Basic) +{ + if (!extensionEnabled("GL_CHROMIUM_bind_uniform_location")) + { + std::cout << "Test skipped because GL_CHROMIUM_bind_uniform_location is not available." + << std::endl; + return; + } + + ASSERT_NE(mBindUniformLocation, nullptr); + + // clang-format off + const std::string vsSource = SHADER_SOURCE + ( + attribute vec4 a_position; + void main() + { + gl_Position = a_position; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + precision mediump float; + uniform vec4 u_colorC; + uniform vec4 u_colorB[2]; + uniform vec4 u_colorA; + void main() + { + gl_FragColor = u_colorA + u_colorB[0] + u_colorB[1] + u_colorC; + } + ); + // clang-format on + + GLint colorALocation = 3; + GLint colorBLocation = 10; + GLint colorCLocation = 5; + + GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); + + mProgram = glCreateProgram(); + + mBindUniformLocation(mProgram, colorALocation, "u_colorA"); + mBindUniformLocation(mProgram, colorBLocation, "u_colorB[0]"); + mBindUniformLocation(mProgram, colorCLocation, "u_colorC"); + + glAttachShader(mProgram, vs); + glDeleteShader(vs); + + glAttachShader(mProgram, fs); + glDeleteShader(fs); + + // Link the mProgram + glLinkProgram(mProgram); + // Check the link status + GLint linked = 0; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); + ASSERT_EQ(1, linked); + + glUseProgram(mProgram); + + static const float colorB[] = { + 0.0f, 0.50f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f, 0.0f, + }; + + glUniform4f(colorALocation, 0.25f, 0.0f, 0.0f, 0.0f); + glUniform4fv(colorBLocation, 2, colorB); + glUniform4f(colorCLocation, 0.0f, 0.0f, 0.0f, 1.0f); + + drawQuad(mProgram, "a_position", 0.5f); + + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(0, 0, 64, 128, 192, 255, 1.0); +} + +// Test that conflicts are detected when two uniforms are bound to the same location +TEST_P(BindUniformLocationTest, ConflictsDetection) +{ + if (!extensionEnabled("GL_CHROMIUM_bind_uniform_location")) + { + std::cout << "Test skipped because GL_CHROMIUM_bind_uniform_location is not available." + << std::endl; + return; + } + + ASSERT_NE(nullptr, mBindUniformLocation); + + // clang-format off + const std::string vsSource = SHADER_SOURCE + ( + attribute vec4 a_position; + void main() + { + gl_Position = a_position; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + precision mediump float; + uniform vec4 u_colorA; + uniform vec4 u_colorB; + void main() + { + gl_FragColor = u_colorA + u_colorB; + } + ); + // clang-format on + + GLint colorALocation = 3; + GLint colorBLocation = 4; + + GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); + + mProgram = glCreateProgram(); + glAttachShader(mProgram, vs); + glDeleteShader(vs); + glAttachShader(mProgram, fs); + glDeleteShader(fs); + + mBindUniformLocation(mProgram, colorALocation, "u_colorA"); + // Bind u_colorB to location a, causing conflicts, link should fail. + mBindUniformLocation(mProgram, colorALocation, "u_colorB"); + glLinkProgram(mProgram); + GLint linked = 0; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); + ASSERT_EQ(0, linked); + + // Bind u_colorB to location b, no conflicts, link should succeed. + mBindUniformLocation(mProgram, colorBLocation, "u_colorB"); + glLinkProgram(mProgram); + linked = 0; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); + EXPECT_EQ(1, linked); +} + +// Test a use case of the chromium compositor +TEST_P(BindUniformLocationTest, Compositor) +{ + if (!extensionEnabled("GL_CHROMIUM_bind_uniform_location")) + { + std::cout << "Test skipped because GL_CHROMIUM_bind_uniform_location is not available." + << std::endl; + return; + } + + ASSERT_NE(nullptr, mBindUniformLocation); + + // clang-format off + const std::string vsSource = SHADER_SOURCE + ( + attribute vec4 a_position; + attribute vec2 a_texCoord; + uniform mat4 matrix; + uniform vec2 color_a[4]; + uniform vec4 color_b; + varying vec4 v_color; + void main() + { + v_color.xy = color_a[0] + color_a[1]; + v_color.zw = color_a[2] + color_a[3]; + v_color += color_b; + gl_Position = matrix * a_position; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + precision mediump float; + varying vec4 v_color; + uniform float alpha; + uniform vec4 multiplier; + uniform vec3 color_c[8]; + void main() + { + vec4 color_c_sum = vec4(0.0); + color_c_sum.xyz += color_c[0]; + color_c_sum.xyz += color_c[1]; + color_c_sum.xyz += color_c[2]; + color_c_sum.xyz += color_c[3]; + color_c_sum.xyz += color_c[4]; + color_c_sum.xyz += color_c[5]; + color_c_sum.xyz += color_c[6]; + color_c_sum.xyz += color_c[7]; + color_c_sum.w = alpha; + color_c_sum *= multiplier; + gl_FragColor = v_color + color_c_sum; + } + ); + // clang-format on + + int counter = 6; + int matrixLocation = counter++; + int colorALocation = counter++; + int colorBLocation = counter++; + int alphaLocation = counter++; + int multiplierLocation = counter++; + int colorCLocation = counter++; + + GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); + + mProgram = glCreateProgram(); + + mBindUniformLocation(mProgram, matrixLocation, "matrix"); + mBindUniformLocation(mProgram, colorALocation, "color_a"); + mBindUniformLocation(mProgram, colorBLocation, "color_b"); + mBindUniformLocation(mProgram, alphaLocation, "alpha"); + mBindUniformLocation(mProgram, multiplierLocation, "multiplier"); + mBindUniformLocation(mProgram, colorCLocation, "color_c"); + + glAttachShader(mProgram, vs); + glDeleteShader(vs); + glAttachShader(mProgram, fs); + glDeleteShader(fs); + + // Link the mProgram + glLinkProgram(mProgram); + // Check the link status + GLint linked = 0; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); + ASSERT_EQ(1, linked); + + glUseProgram(mProgram); + + static const float colorA[] = { + 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, + }; + + static const float colorC[] = { + 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, + 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, 0.1f, + }; + + static const float identity[] = { + 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, + }; + + glUniformMatrix4fv(matrixLocation, 1, false, identity); + glUniform2fv(colorALocation, 4, colorA); + glUniform4f(colorBLocation, 0.2f, 0.2f, 0.2f, 0.2f); + glUniform1f(alphaLocation, 0.8f); + glUniform4f(multiplierLocation, 0.5f, 0.5f, 0.5f, 0.5f); + glUniform3fv(colorCLocation, 8, colorC); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + drawQuad(mProgram, "a_position", 0.5f); + + EXPECT_PIXEL_EQ(0, 0, 204, 204, 204, 204); +} + +// Test that unused uniforms don't conflict when bound to the same location +TEST_P(BindUniformLocationTest, UnusedUniformUpdate) +{ + if (!extensionEnabled("GL_CHROMIUM_bind_uniform_location")) + { + std::cout << "Test skipped because GL_CHROMIUM_bind_uniform_location is not available." + << std::endl; + return; + } + + ASSERT_NE(nullptr, mBindUniformLocation); + + // clang-format off + const std::string vsSource = SHADER_SOURCE + ( + attribute vec4 a_position; + void main() + { + gl_Position = a_position; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + precision mediump float; + uniform vec4 u_colorA; + uniform float u_colorU; + uniform vec4 u_colorC; + void main() + { + gl_FragColor = u_colorA + u_colorC; + } + ); + // clang-format on + + const GLint colorULocation = 1; + const GLint nonexistingLocation = 5; + const GLint unboundLocation = 6; + + GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); + + mProgram = glCreateProgram(); + mBindUniformLocation(mProgram, colorULocation, "u_colorU"); + // The non-existing uniform should behave like existing, but optimized away + // uniform. + mBindUniformLocation(mProgram, nonexistingLocation, "nonexisting"); + // Let A and C be assigned automatic locations. + glAttachShader(mProgram, vs); + glDeleteShader(vs); + glAttachShader(mProgram, fs); + glDeleteShader(fs); + glLinkProgram(mProgram); + GLint linked = 0; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); + ASSERT_EQ(1, linked); + glUseProgram(mProgram); + + // No errors on bound locations, since caller does not know + // if the driver optimizes them away or not. + glUniform1f(colorULocation, 0.25f); + EXPECT_GL_NO_ERROR(); + + // No errors on bound locations of names that do not exist + // in the shader. Otherwise it would be inconsistent wrt the + // optimization case. + glUniform1f(nonexistingLocation, 0.25f); + EXPECT_GL_NO_ERROR(); + + // The above are equal to updating -1. + glUniform1f(-1, 0.25f); + EXPECT_GL_NO_ERROR(); + + // No errors when updating with other type either. + // The type can not be known with the non-existing case. + glUniform2f(colorULocation, 0.25f, 0.25f); + EXPECT_GL_NO_ERROR(); + glUniform2f(nonexistingLocation, 0.25f, 0.25f); + EXPECT_GL_NO_ERROR(); + glUniform2f(-1, 0.25f, 0.25f); + EXPECT_GL_NO_ERROR(); + + // Ensure that driver or ANGLE has optimized the variable + // away and the test tests what it is supposed to. + EXPECT_EQ(-1, glGetUniformLocation(mProgram, "u_colorU")); + + // The bound location gets marked as used and the driver + // does not allocate other variables to that location. + EXPECT_NE(colorULocation, glGetUniformLocation(mProgram, "u_colorA")); + EXPECT_NE(colorULocation, glGetUniformLocation(mProgram, "u_colorC")); + EXPECT_NE(nonexistingLocation, glGetUniformLocation(mProgram, "u_colorA")); + EXPECT_NE(nonexistingLocation, glGetUniformLocation(mProgram, "u_colorC")); + + // Unintuitive: while specifying value works, getting the value does not. + GLfloat getResult = 0.0f; + glGetUniformfv(mProgram, colorULocation, &getResult); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + glGetUniformfv(mProgram, nonexistingLocation, &getResult); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + glGetUniformfv(mProgram, -1, &getResult); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // Updating an unbound, non-existing location still causes + // an error. + glUniform1f(unboundLocation, 0.25f); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test for a bug where using a sampler caused GL error if the mProgram had +// uniforms that were optimized away by the driver. This was only a problem with +// glBindUniformLocationCHROMIUM implementation. This could be reproed by +// binding the sampler to a location higher than the amount of active uniforms. +TEST_P(BindUniformLocationTest, UseSamplerWhenUnusedUniforms) +{ + if (!extensionEnabled("GL_CHROMIUM_bind_uniform_location")) + { + std::cout << "Test skipped because GL_CHROMIUM_bind_uniform_location is not available." + << std::endl; + return; + } + + ASSERT_NE(nullptr, mBindUniformLocation); + + // clang-format off + const std::string vsSource = SHADER_SOURCE + ( + void main() + { + gl_Position = vec4(0); + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + uniform sampler2D tex; + void main() + { + gl_FragColor = texture2D(tex, vec2(1)); + } + ); + // clang-format on + + const GLuint texLocation = 54; + + GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); + + mProgram = glCreateProgram(); + mBindUniformLocation(mProgram, texLocation, "tex"); + + glAttachShader(mProgram, vs); + glDeleteShader(vs); + glAttachShader(mProgram, fs); + glDeleteShader(fs); + + glLinkProgram(mProgram); + + GLint linked = 0; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); + EXPECT_NE(0, linked); + glUseProgram(mProgram); + glUniform1i(texLocation, 0); + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(BindUniformLocationTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp b/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp new file mode 100755 index 000000000..39f5251e5 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/BlendMinMaxTest.cpp @@ -0,0 +1,255 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class BlendMinMaxTest : public ANGLETest +{ + protected: + BlendMinMaxTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + + mProgram = 0; + mColorLocation = -1; + mFramebuffer = 0; + mColorRenderbuffer = 0; + } + + struct Color + { + float values[4]; + }; + + static float getExpected(bool blendMin, float curColor, float prevColor) + { + return blendMin ? std::min(curColor, prevColor) : std::max(curColor, prevColor); + } + + void runTest(GLenum colorFormat, GLenum type) + { + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_blend_minmax")) + { + std::cout << "Test skipped because ES3 or GL_EXT_blend_minmax is not available." << std::endl; + return; + } + + // TODO(geofflang): figure out why this fails + if (IsIntel() && GetParam() == ES2_OPENGL()) + { + std::cout << "Test skipped on OpenGL Intel due to flakyness." << std::endl; + return; + } + + SetUpFramebuffer(colorFormat); + + int minValue = 0; + int maxValue = 1; + if (type == GL_FLOAT) + { + minValue = -1024; + maxValue = 1024; + } + + const size_t colorCount = 128; + Color colors[colorCount]; + for (size_t i = 0; i < colorCount; i++) + { + for (size_t j = 0; j < 4; j++) + { + colors[i].values[j] = + static_cast<float>(minValue + (rand() % (maxValue - minValue))); + } + } + + float prevColor[4]; + for (size_t i = 0; i < colorCount; i++) + { + const Color &color = colors[i]; + glUseProgram(mProgram); + glUniform4f(mColorLocation, color.values[0], color.values[1], color.values[2], color.values[3]); + + bool blendMin = (rand() % 2 == 0); + glBlendEquation(blendMin ? GL_MIN : GL_MAX); + + drawQuad(mProgram, "aPosition", 0.5f); + + float pixel[4]; + if (type == GL_UNSIGNED_BYTE) + { + GLubyte ubytePixel[4]; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, ubytePixel); + for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++) + { + pixel[componentIdx] = ubytePixel[componentIdx] / 255.0f; + } + } + else if (type == GL_FLOAT) + { + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixel); + } + else + { + FAIL() << "Unexpected pixel type"; + } + + if (i > 0) + { + const float errorRange = 1.0f / 255.0f; + for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++) + { + EXPECT_NEAR( + getExpected(blendMin, color.values[componentIdx], prevColor[componentIdx]), + pixel[componentIdx], errorRange); + } + } + + memcpy(prevColor, pixel, sizeof(pixel)); + } + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string testVertexShaderSource = SHADER_SOURCE + ( + attribute highp vec4 aPosition; + + void main(void) + { + gl_Position = aPosition; + } + ); + + const std::string testFragmentShaderSource = SHADER_SOURCE + ( + uniform highp vec4 color; + void main(void) + { + gl_FragColor = color; + } + ); + + mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mColorLocation = glGetUniformLocation(mProgram, "color"); + + glUseProgram(mProgram); + + glClearColor(0, 0, 0, 0); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + } + + void SetUpFramebuffer(GLenum colorFormat) + { + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer); + glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer); + + glGenRenderbuffers(1, &mColorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight()); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteProgram(mProgram); + glDeleteFramebuffers(1, &mFramebuffer); + glDeleteRenderbuffers(1, &mColorRenderbuffer); + + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLint mColorLocation; + + GLuint mFramebuffer; + GLuint mColorRenderbuffer; +}; + +TEST_P(BlendMinMaxTest, RGBA8) +{ + runTest(GL_RGBA8, GL_UNSIGNED_BYTE); +} + +TEST_P(BlendMinMaxTest, RGBA32F) +{ + if (getClientMajorVersion() < 3 || !extensionEnabled("GL_EXT_color_buffer_float")) + { + std::cout << "Test skipped because ES3 and GL_EXT_color_buffer_float are not available." + << std::endl; + return; + } + + // TODO(jmadill): Figure out why this is broken on Intel + if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9())) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3 + if (IsD3D11_FL93()) + { + std::cout << "Test skipped on Feature Level 9_3." << std::endl; + return; + } + + runTest(GL_RGBA32F, GL_FLOAT); +} + +TEST_P(BlendMinMaxTest, RGBA16F) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_color_buffer_half_float")) + { + std::cout << "Test skipped because ES3 or GL_EXT_color_buffer_half_float is not available." + << std::endl; + return; + } + + // TODO(jmadill): figure out why this fails + if (IsIntel() && (GetParam() == ES2_D3D11() || GetParam() == ES2_D3D9())) + { + std::cout << "Test skipped on Intel due to failures." << std::endl; + return; + } + + runTest(GL_RGBA16F, GL_FLOAT); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(BlendMinMaxTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/gfx/angle/src/tests/gl_tests/BlitFramebufferANGLETest.cpp new file mode 100755 index 000000000..e40a411db --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/BlitFramebufferANGLETest.cpp @@ -0,0 +1,1070 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include "test_utils/gl_raii.h" + +using namespace angle; + +class BlitFramebufferANGLETest : public ANGLETest +{ + protected: + BlitFramebufferANGLETest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + setConfigStencilBits(8); + + mCheckerProgram = 0; + mBlueProgram = 0; + + mOriginalFBO = 0; + + mUserFBO = 0; + mUserColorBuffer = 0; + mUserDepthStencilBuffer = 0; + + mSmallFBO = 0; + mSmallColorBuffer = 0; + mSmallDepthStencilBuffer = 0; + + mColorOnlyFBO = 0; + mColorOnlyColorBuffer = 0; + + mDiffFormatFBO = 0; + mDiffFormatColorBuffer = 0; + + mDiffSizeFBO = 0; + mDiffSizeColorBuffer = 0; + + mMRTFBO = 0; + mMRTColorBuffer0 = 0; + mMRTColorBuffer1 = 0; + + mRGBAColorbuffer = 0; + mRGBAFBO = 0; + + mBGRAMultisampledRenderbuffer = 0; + mBGRAMultisampledFBO = 0; + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string passthroughVS = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec4 pos; + + void main() + { + gl_Position = position; + pos = position; + } + ); + + const std::string checkeredFS = SHADER_SOURCE + ( + precision highp float; + varying vec4 pos; + + void main() + { + if (pos.x * pos.y > 0.0) + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + else + { + gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); + } + } + ); + + const std::string blueFS = SHADER_SOURCE + ( + precision highp float; + varying vec4 pos; + + void main() + { + gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); + } + ); + + mCheckerProgram = CompileProgram(passthroughVS, checkeredFS); + mBlueProgram = CompileProgram(passthroughVS, blueFS); + if (mCheckerProgram == 0 || mBlueProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + EXPECT_GL_NO_ERROR(); + + GLint originalFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originalFBO); + if (originalFBO >= 0) + { + mOriginalFBO = (GLuint)originalFBO; + } + + GLenum format = GL_BGRA8_EXT; + + glGenFramebuffers(1, &mUserFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + glGenTextures(1, &mUserColorBuffer); + glGenRenderbuffers(1, &mUserDepthStencilBuffer); + glBindTexture(GL_TEXTURE_2D, mUserColorBuffer); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mUserColorBuffer, 0); + glBindRenderbuffer(GL_RENDERBUFFER, mUserDepthStencilBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(), getWindowHeight()); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mUserDepthStencilBuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mUserDepthStencilBuffer); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + ASSERT_GL_NO_ERROR(); + + glGenFramebuffers(1, &mSmallFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO); + glGenTextures(1, &mSmallColorBuffer); + glGenRenderbuffers(1, &mSmallDepthStencilBuffer); + glBindTexture(GL_TEXTURE_2D, mSmallColorBuffer); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth() / 2, getWindowHeight() / 2); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSmallColorBuffer, 0); + glBindRenderbuffer(GL_RENDERBUFFER, mSmallDepthStencilBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth() / 2, getWindowHeight() / 2); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mSmallDepthStencilBuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mSmallDepthStencilBuffer); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + ASSERT_GL_NO_ERROR(); + + glGenFramebuffers(1, &mColorOnlyFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO); + glGenTextures(1, &mColorOnlyColorBuffer); + glBindTexture(GL_TEXTURE_2D, mColorOnlyColorBuffer); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorOnlyColorBuffer, 0); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + ASSERT_GL_NO_ERROR(); + + glGenFramebuffers(1, &mDiffFormatFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mDiffFormatFBO); + glGenTextures(1, &mDiffFormatColorBuffer); + glBindTexture(GL_TEXTURE_2D, mDiffFormatColorBuffer); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB565, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mDiffFormatColorBuffer, 0); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + ASSERT_GL_NO_ERROR(); + + glGenFramebuffers(1, &mDiffSizeFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mDiffSizeFBO); + glGenTextures(1, &mDiffSizeColorBuffer); + glBindTexture(GL_TEXTURE_2D, mDiffSizeColorBuffer); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth()*2, getWindowHeight()*2); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mDiffSizeColorBuffer, 0); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + ASSERT_GL_NO_ERROR(); + + if (extensionEnabled("GL_EXT_draw_buffers")) + { + glGenFramebuffers(1, &mMRTFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO); + glGenTextures(1, &mMRTColorBuffer0); + glGenTextures(1, &mMRTColorBuffer1); + glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer0); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mMRTColorBuffer0, 0); + glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer1); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mMRTColorBuffer1, 0); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + ASSERT_GL_NO_ERROR(); + } + + if (extensionEnabled("GL_ANGLE_framebuffer_multisample")) + { + // Test blit between RGBA and multisampled BGRA + glGenTextures(1, &mRGBAColorbuffer); + glBindTexture(GL_TEXTURE_2D, mRGBAColorbuffer); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, getWindowWidth(), getWindowHeight()); + + glGenFramebuffers(1, &mRGBAFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mRGBAFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mRGBAColorbuffer, 0); + + ASSERT_GL_NO_ERROR(); + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + glGenRenderbuffers(1, &mBGRAMultisampledRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_BGRA8_EXT, getWindowWidth(), getWindowHeight()); + + glGenFramebuffers(1, &mBGRAMultisampledFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mBGRAMultisampledFBO); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer); + + ASSERT_GL_NO_ERROR(); + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + } + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + } + + virtual void TearDown() + { + glDeleteProgram(mCheckerProgram); + glDeleteProgram(mBlueProgram); + + glDeleteFramebuffers(1, &mUserFBO); + glDeleteTextures(1, &mUserColorBuffer); + glDeleteRenderbuffers(1, &mUserDepthStencilBuffer); + + glDeleteFramebuffers(1, &mSmallFBO); + glDeleteTextures(1, &mSmallColorBuffer); + glDeleteRenderbuffers(1, &mSmallDepthStencilBuffer); + + glDeleteFramebuffers(1, &mColorOnlyFBO); + glDeleteTextures(1, &mSmallDepthStencilBuffer); + + glDeleteFramebuffers(1, &mDiffFormatFBO); + glDeleteTextures(1, &mDiffFormatColorBuffer); + + glDeleteFramebuffers(1, &mDiffSizeFBO); + glDeleteTextures(1, &mDiffSizeColorBuffer); + + if (extensionEnabled("GL_EXT_draw_buffers")) + { + glDeleteFramebuffers(1, &mMRTFBO); + glDeleteTextures(1, &mMRTColorBuffer0); + glDeleteTextures(1, &mMRTColorBuffer1); + } + + if (mRGBAColorbuffer != 0) + { + glDeleteTextures(1, &mRGBAColorbuffer); + } + + if (mRGBAFBO != 0) + { + glDeleteFramebuffers(1, &mBGRAMultisampledFBO); + } + + if (mBGRAMultisampledRenderbuffer != 0) + { + glDeleteRenderbuffers(1, &mBGRAMultisampledRenderbuffer); + } + + if (mBGRAMultisampledFBO != 0) + { + glDeleteFramebuffers(1, &mBGRAMultisampledFBO); + } + + ANGLETest::TearDown(); + } + + GLuint mCheckerProgram; + GLuint mBlueProgram; + + GLuint mOriginalFBO; + + GLuint mUserFBO; + GLuint mUserColorBuffer; + GLuint mUserDepthStencilBuffer; + + GLuint mSmallFBO; + GLuint mSmallColorBuffer; + GLuint mSmallDepthStencilBuffer; + + GLuint mColorOnlyFBO; + GLuint mColorOnlyColorBuffer; + + GLuint mDiffFormatFBO; + GLuint mDiffFormatColorBuffer; + + GLuint mDiffSizeFBO; + GLuint mDiffSizeColorBuffer; + + GLuint mMRTFBO; + GLuint mMRTColorBuffer0; + GLuint mMRTColorBuffer1; + + GLuint mRGBAColorbuffer; + GLuint mRGBAFBO; + + GLuint mBGRAMultisampledRenderbuffer; + GLuint mBGRAMultisampledFBO; +}; + +// Draw to user-created framebuffer, blit whole-buffer color to original framebuffer. +TEST_P(BlitFramebufferANGLETest, BlitColorToDefault) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.8f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); +} + +// Draw to system framebuffer, blit whole-buffer color to user-created framebuffer. +TEST_P(BlitFramebufferANGLETest, ReverseColorBlit) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.8f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); +} + +// blit from user-created FBO to system framebuffer, with the scissor test enabled. +TEST_P(BlitFramebufferANGLETest, ScissoredBlit) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.8f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight()); + glEnable(GL_SCISSOR_TEST); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glDisable(GL_SCISSOR_TEST); + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255); +} + +// blit from system FBO to user-created framebuffer, with the scissor test enabled. +TEST_P(BlitFramebufferANGLETest, ReverseScissoredBlit) +{ + // TODO(jmadill): Triage this driver bug. + if (IsAMD() && IsD3D11()) + { + std::cout << "Test skipped on AMD D3D11." << std::endl; + return; + } + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.8f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight()); + glEnable(GL_SCISSOR_TEST); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glDisable(GL_SCISSOR_TEST); + + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255); +} + +// blit from user-created FBO to system framebuffer, using region larger than buffer. +TEST_P(BlitFramebufferANGLETest, OversizedBlit) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.8f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0, getWindowWidth() * 2, getWindowHeight() * 2, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); +} + +// blit from system FBO to user-created framebuffer, using region larger than buffer. +TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.8f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0, getWindowWidth() * 2, getWindowHeight() * 2, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); +} + +// blit from user-created FBO to system framebuffer, with depth buffer. +TEST_P(BlitFramebufferANGLETest, BlitWithDepth) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); + + drawQuad(mCheckerProgram, "position", 0.3f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + // if blit is happening correctly, this quad will not draw, because it is behind the blitted one + drawQuad(mBlueProgram, "position", 0.8f); + + glDisable(GL_DEPTH_TEST); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); +} + +// blit from system FBO to user-created framebuffer, with depth buffer. +TEST_P(BlitFramebufferANGLETest, ReverseBlitWithDepth) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glEnable(GL_DEPTH_TEST); + + drawQuad(mCheckerProgram, "position", 0.3f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO); + + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + // if blit is happening correctly, this quad will not draw, because it is behind the blitted one + + drawQuad(mBlueProgram, "position", 0.8f); + + glDisable(GL_DEPTH_TEST); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); +} + +// blit from one region of the system fbo to another-- this should fail. +TEST_P(BlitFramebufferANGLETest, BlitSameBufferOriginal) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.3f); + + EXPECT_GL_NO_ERROR(); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// blit from one region of the system fbo to another. +TEST_P(BlitFramebufferANGLETest, BlitSameBufferUser) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.3f); + + EXPECT_GL_NO_ERROR(); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +TEST_P(BlitFramebufferANGLETest, BlitPartialColor) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 255, 255, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); +} + +TEST_P(BlitFramebufferANGLETest, BlitDifferentSizes) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mSmallFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mCheckerProgram, "position", 0.3f); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + // depth blit request should be silently ignored, because the read FBO has no depth attachment + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); + + // unlike in the depth blit tests, this *should* draw a blue quad, because depth info + // has not been copied + glEnable(GL_DEPTH_TEST); + drawQuad(mBlueProgram, "position", 0.8f); + glDisable(GL_DEPTH_TEST); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 0, 255, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 0, 255, 255); +} + +TEST_P(BlitFramebufferANGLETest, BlitStencil) +{ + // TODO(jmadill): Figure out if we can fix this on D3D9. + // https://code.google.com/p/angleproject/issues/detail?id=809 + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE) + { + std::cout << "Test skipped on Intel D3D9." << std::endl; + return; + } + + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT); + // fill the stencil buffer with 0x1 + glStencilFunc(GL_ALWAYS, 0x1, 0xFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + glEnable(GL_STENCIL_TEST); + drawQuad(mCheckerProgram, "position", 0.3f); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glClearColor(1.0, 1.0, 1.0, 1.0); + glClearStencil(0x0); + glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + // depth blit request should be silently ignored, because the read FBO has no depth attachment + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); + + glStencilFunc(GL_EQUAL, 0x1, 0xFF); // only pass if stencil buffer at pixel reads 0x1 + drawQuad(mBlueProgram, "position", 0.8f); // blue quad will draw if stencil buffer was copied + glDisable(GL_STENCIL_TEST); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 0, 255, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 0, 255, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 0, 255, 255); +} + +// make sure that attempting to blit a partial depth buffer issues an error +TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, + getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test blit with MRT framebuffers +TEST_P(BlitFramebufferANGLETest, BlitMRT) +{ + if (!extensionEnabled("GL_EXT_draw_buffers")) + { + return; + } + + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; + + glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO); + glDrawBuffersEXT(2, drawBuffers); + + glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO); + + glClear(GL_COLOR_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.8f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mMRTFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0, 0); + + EXPECT_PIXEL_EQ( getWindowWidth() / 4, getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 0, 0, 255); + EXPECT_PIXEL_EQ( getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mMRTColorBuffer1, 0); +} + +// Make sure that attempts to stretch in a blit call issue an error +TEST_P(BlitFramebufferANGLETest, ErrorStretching) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, + getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Make sure that attempts to flip in a blit call issue an error +TEST_P(BlitFramebufferANGLETest, ErrorFlipping) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight() / 2, + 0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +TEST_P(BlitFramebufferANGLETest, Errors) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + drawQuad(mCheckerProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_LINEAR); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT | 234, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mDiffFormatFBO); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + if (extensionEnabled("GL_ANGLE_framebuffer_multisample")) + { + glBindFramebuffer(GL_READ_FRAMEBUFFER, mBGRAMultisampledFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mRGBAFBO); + EXPECT_GL_NO_ERROR(); + + glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } + +} + +// TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the +// default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/1289) + +class BlitFramebufferTest : public ANGLETest +{ + protected: + BlitFramebufferTest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + setConfigStencilBits(8); + } +}; + +// Tests resolving a multisample depth buffer. +TEST_P(BlitFramebufferTest, MultisampleDepth) +{ + // TODO(jmadill): Triage this driver bug. + if (IsAMD() && IsD3D11()) + { + std::cout << "Test skipped on AMD D3D11." << std::endl; + return; + } + + GLRenderbuffer renderbuf; + glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get()); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256); + + const std::string &vertex = + "#version 300 es\n" + "in vec2 position;\n" + "void main() {\n" + " gl_Position = vec4(position, 0.0, 0.5);\n" + "}"; + const std::string &fragment = + "#version 300 es\n" + "out mediump vec4 red;\n" + "void main() {\n" + " red = vec4(1.0, 0.0, 0.0, 1.0);\n" + " gl_FragDepth = 0.5;\n" + "}"; + + ANGLE_GL_PROGRAM(drawRed, vertex, fragment); + + GLFramebuffer framebuffer; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get()); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + renderbuf.get()); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + glClearDepthf(0.5f); + glClear(GL_DEPTH_BUFFER_BIT); + + GLRenderbuffer destRenderbuf; + glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get()); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256); + + GLFramebuffer resolved; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get()); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + destRenderbuf.get()); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get()); + glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_DEPTH_BUFFER_BIT, GL_NEAREST); + + glBindFramebuffer(GL_FRAMEBUFFER, resolved.get()); + + GLTexture colorbuf; + glBindTexture(GL_TEXTURE_2D, colorbuf.get()); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf.get(), 0); + + ASSERT_GL_NO_ERROR(); + + // Clear to green + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + // Draw with 0.5f test and the test should pass. + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_EQUAL); + drawQuad(drawRed.get(), "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + + ASSERT_GL_NO_ERROR(); +} + +// Test resolving a multisampled stencil buffer. +TEST_P(BlitFramebufferTest, MultisampleStencil) +{ + GLRenderbuffer renderbuf; + glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get()); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256); + + const std::string &vertex = + "#version 300 es\n" + "in vec2 position;\n" + "void main() {\n" + " gl_Position = vec4(position, 0.0, 1.0);\n" + "}"; + const std::string &fragment = + "#version 300 es\n" + "out mediump vec4 red;\n" + "void main() {\n" + " red = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}"; + + ANGLE_GL_PROGRAM(drawRed, vertex, fragment); + + GLFramebuffer framebuffer; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get()); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + renderbuf.get()); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // fill the stencil buffer with 0x1 + glStencilFunc(GL_ALWAYS, 0x1, 0xFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + glEnable(GL_STENCIL_TEST); + drawQuad(drawRed.get(), "position", 0.5f); + + GLTexture destColorbuf; + glBindTexture(GL_TEXTURE_2D, destColorbuf.get()); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256); + + GLRenderbuffer destRenderbuf; + glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get()); + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 256, 256); + + GLFramebuffer resolved; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get()); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + destColorbuf.get(), 0); + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + destRenderbuf.get()); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get()); + glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST); + + glBindFramebuffer(GL_FRAMEBUFFER, resolved.get()); + + ASSERT_GL_NO_ERROR(); + + // Clear to green + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + // Draw red if the stencil is 0x1, which should be true after the blit/resolve. + glStencilFunc(GL_EQUAL, 0x1, 0xFF); + drawQuad(drawRed.get(), "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + + ASSERT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest, + ES2_D3D9(), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE)); + +ANGLE_INSTANTIATE_TEST(BlitFramebufferTest, ES3_D3D11());
\ No newline at end of file diff --git a/gfx/angle/src/tests/gl_tests/BufferDataTest.cpp b/gfx/angle/src/tests/gl_tests/BufferDataTest.cpp new file mode 100755 index 000000000..7707a4a56 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/BufferDataTest.cpp @@ -0,0 +1,544 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +#include <stdint.h> + +using namespace angle; + +class BufferDataTest : public ANGLETest +{ + protected: + BufferDataTest() + { + setWindowWidth(16); + setWindowHeight(16); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + + mBuffer = 0; + mProgram = 0; + mAttribLocation = -1; + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const char * vsSource = SHADER_SOURCE + ( + attribute vec4 position; + attribute float in_attrib; + varying float v_attrib; + void main() + { + v_attrib = in_attrib; + gl_Position = position; + } + ); + + const char * fsSource = SHADER_SOURCE + ( + precision mediump float; + varying float v_attrib; + void main() + { + gl_FragColor = vec4(v_attrib, 0, 0, 1); + } + ); + + glGenBuffers(1, &mBuffer); + ASSERT_NE(mBuffer, 0U); + + mProgram = CompileProgram(vsSource, fsSource); + ASSERT_NE(mProgram, 0U); + + mAttribLocation = glGetAttribLocation(mProgram, "in_attrib"); + ASSERT_NE(mAttribLocation, -1); + + glClearColor(0, 0, 0, 0); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glDisable(GL_DEPTH_TEST); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteBuffers(1, &mBuffer); + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mBuffer; + GLuint mProgram; + GLint mAttribLocation; +}; + +TEST_P(BufferDataTest, NULLData) +{ + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + EXPECT_GL_NO_ERROR(); + + const int numIterations = 128; + for (int i = 0; i < numIterations; ++i) + { + GLsizei bufferSize = sizeof(GLfloat) * (i + 1); + glBufferData(GL_ARRAY_BUFFER, bufferSize, NULL, GL_STATIC_DRAW); + EXPECT_GL_NO_ERROR(); + + for (int j = 0; j < bufferSize; j++) + { + for (int k = 0; k < bufferSize - j; k++) + { + glBufferSubData(GL_ARRAY_BUFFER, k, j, NULL); + ASSERT_GL_NO_ERROR(); + } + } + } +} + +TEST_P(BufferDataTest, ZeroNonNULLData) +{ + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + EXPECT_GL_NO_ERROR(); + + char *zeroData = new char[0]; + glBufferData(GL_ARRAY_BUFFER, 0, zeroData, GL_STATIC_DRAW); + EXPECT_GL_NO_ERROR(); + + glBufferSubData(GL_ARRAY_BUFFER, 0, 0, zeroData); + EXPECT_GL_NO_ERROR(); + + delete [] zeroData; +} + +TEST_P(BufferDataTest, NULLResolvedData) +{ + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW); + + glUseProgram(mProgram); + glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL); + glEnableVertexAttribArray(mAttribLocation); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + drawQuad(mProgram, "position", 0.5f); +} + +// Tests that a huge allocation returns GL_OUT_OF_MEMORY +// TODO(jmadill): Figure out how to test this reliably on the Chromium bots +TEST_P(BufferDataTest, DISABLED_HugeSetDataShouldNotCrash) +{ + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + EXPECT_GL_NO_ERROR(); + + GLsizei allocSize = std::numeric_limits<GLsizei>::max() >> 2; + + uint8_t *data = NULL; + while (data == NULL && allocSize >= 4) + { + data = new (std::nothrow) uint8_t[allocSize]; + + if (data == NULL) + { + allocSize >>= 1; + } + } + + ASSERT_NE(static_cast<uint8_t*>(NULL), data); + memset(data, 0, allocSize); + + float * fValue = reinterpret_cast<float*>(data); + for (unsigned int f = 0; f < 6; f++) + { + fValue[f] = 1.0f; + } + + glBufferData(GL_ARRAY_BUFFER, allocSize, data, GL_STATIC_DRAW); + + GLenum error = glGetError(); + if (error == GL_NO_ERROR) + { + // If we didn't fail because of an out of memory error, try drawing a quad + // using the large buffer + + // DISABLED because it takes a long time, but left for posterity + + //glUseProgram(mProgram); + //glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, NULL); + //glEnableVertexAttribArray(mAttribLocation); + //glBindBuffer(GL_ARRAY_BUFFER, 0); + //drawQuad(mProgram, "position", 0.5f); + //swapBuffers(); + + //// Draw operations can also generate out-of-memory, which is in-spec + //error = glGetError(); + //if (error == GL_NO_ERROR) + //{ + // GLint viewportSize[4]; + // glGetIntegerv(GL_VIEWPORT, viewportSize); + + // GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2; + // GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2; + + // EXPECT_PIXEL_EQ(midPixelX, midPixelY, 255, 0, 0, 255); + //} + //else + //{ + // EXPECT_EQ(GL_OUT_OF_MEMORY, error); + //} + } + else + { + EXPECT_GLENUM_EQ(GL_OUT_OF_MEMORY, error); + } + + delete[] data; +} + +// Internally in D3D, we promote dynamic data to static after many draw loops. This code tests +// path. +TEST_P(BufferDataTest, RepeatedDrawWithDynamic) +{ + std::vector<GLfloat> data; + for (int i = 0; i < 16; ++i) + { + data.push_back(static_cast<GLfloat>(i)); + } + + glUseProgram(mProgram); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * data.size(), data.data(), GL_DYNAMIC_DRAW); + glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 0, nullptr); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glEnableVertexAttribArray(mAttribLocation); + + for (int drawCount = 0; drawCount < 40; ++drawCount) + { + drawQuad(mProgram, "position", 0.5f); + } + + EXPECT_GL_NO_ERROR(); +} + +class IndexedBufferCopyTest : public ANGLETest +{ + protected: + IndexedBufferCopyTest() + { + setWindowWidth(16); + setWindowHeight(16); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const char * vsSource = SHADER_SOURCE + ( + attribute vec3 in_attrib; + varying vec3 v_attrib; + void main() + { + v_attrib = in_attrib; + gl_Position = vec4(0.0, 0.0, 0.5, 1.0); + gl_PointSize = 100.0; + } + ); + + const char * fsSource = SHADER_SOURCE + ( + precision mediump float; + varying vec3 v_attrib; + void main() + { + gl_FragColor = vec4(v_attrib, 1); + } + ); + + glGenBuffers(2, mBuffers); + ASSERT_NE(mBuffers[0], 0U); + ASSERT_NE(mBuffers[1], 0U); + + glGenBuffers(1, &mElementBuffer); + ASSERT_NE(mElementBuffer, 0U); + + mProgram = CompileProgram(vsSource, fsSource); + ASSERT_NE(mProgram, 0U); + + mAttribLocation = glGetAttribLocation(mProgram, "in_attrib"); + ASSERT_NE(mAttribLocation, -1); + + glClearColor(0, 0, 0, 0); + glDisable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteBuffers(2, mBuffers); + glDeleteBuffers(1, &mElementBuffer); + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mBuffers[2]; + GLuint mElementBuffer; + GLuint mProgram; + GLint mAttribLocation; +}; + +// The following test covers an ANGLE bug where our index ranges +// weren't updated from CopyBufferSubData calls +// https://code.google.com/p/angleproject/issues/detail?id=709 +TEST_P(IndexedBufferCopyTest, IndexRangeBug) +{ + // TODO(geofflang): Figure out why this fails on AMD OpenGL (http://anglebug.com/1291) + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test disabled on AMD OpenGL." << std::endl; + return; + } + + unsigned char vertexData[] = { 255, 0, 0, 0, 0, 0 }; + unsigned int indexData[] = { 0, 1 }; + + glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(char) * 6, vertexData, GL_STATIC_DRAW); + + glUseProgram(mProgram); + glVertexAttribPointer(mAttribLocation, 3, GL_UNSIGNED_BYTE, GL_TRUE, 3, NULL); + glEnableVertexAttribArray(mAttribLocation); + + ASSERT_GL_NO_ERROR(); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mElementBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 1, indexData, GL_STATIC_DRAW); + + glUseProgram(mProgram); + + ASSERT_GL_NO_ERROR(); + + glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL); + + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + glBindBuffer(GL_COPY_READ_BUFFER, mBuffers[1]); + glBufferData(GL_COPY_READ_BUFFER, 4, &indexData[1], GL_STATIC_DRAW); + + glBindBuffer(GL_COPY_WRITE_BUFFER, mElementBuffer); + + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, sizeof(int)); + + ASSERT_GL_NO_ERROR(); + + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0); + + unsigned char newData[] = { 0, 255, 0 }; + glBufferSubData(GL_ARRAY_BUFFER, 3, 3, newData); + + glDrawElements(GL_POINTS, 1, GL_UNSIGNED_INT, NULL); + + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); +} + +class BufferDataTestES3 : public BufferDataTest +{ +}; + +// The following test covers an ANGLE bug where the buffer storage +// is not resized by Buffer11::getLatestBufferStorage when needed. +// https://code.google.com/p/angleproject/issues/detail?id=897 +TEST_P(BufferDataTestES3, BufferResizing) +{ + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + ASSERT_GL_NO_ERROR(); + + // Allocate a buffer with one byte + uint8_t singleByte[] = { 0xaa }; + glBufferData(GL_ARRAY_BUFFER, 1, singleByte, GL_STATIC_DRAW); + + // Resize the buffer + // To trigger the bug, the buffer need to be big enough because some hardware copy buffers + // by chunks of pages instead of the minimum number of bytes neeeded. + const size_t numBytes = 4096*4; + glBufferData(GL_ARRAY_BUFFER, numBytes, NULL, GL_STATIC_DRAW); + + // Copy the original data to the buffer + uint8_t srcBytes[numBytes]; + for (size_t i = 0; i < numBytes; ++i) + { + srcBytes[i] = static_cast<uint8_t>(i); + } + + void *dest = glMapBufferRange(GL_ARRAY_BUFFER, 0, numBytes, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); + + ASSERT_GL_NO_ERROR(); + + memcpy(dest, srcBytes, numBytes); + glUnmapBuffer(GL_ARRAY_BUFFER); + + EXPECT_GL_NO_ERROR(); + + // Create a new buffer and copy the data to it + GLuint readBuffer; + glGenBuffers(1, &readBuffer); + glBindBuffer(GL_COPY_WRITE_BUFFER, readBuffer); + uint8_t zeros[numBytes]; + for (size_t i = 0; i < numBytes; ++i) + { + zeros[i] = 0; + } + glBufferData(GL_COPY_WRITE_BUFFER, numBytes, zeros, GL_STATIC_DRAW); + glCopyBufferSubData(GL_ARRAY_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, numBytes); + + ASSERT_GL_NO_ERROR(); + + // Read back the data and compare it to the original + uint8_t *data = reinterpret_cast<uint8_t*>(glMapBufferRange(GL_COPY_WRITE_BUFFER, 0, numBytes, GL_MAP_READ_BIT)); + + ASSERT_GL_NO_ERROR(); + + for (size_t i = 0; i < numBytes; ++i) + { + EXPECT_EQ(srcBytes[i], data[i]); + } + glUnmapBuffer(GL_COPY_WRITE_BUFFER); + + glDeleteBuffers(1, &readBuffer); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(BufferDataTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(BufferDataTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(IndexedBufferCopyTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +#ifdef _WIN64 + +// Test a bug where an integer overflow bug could trigger a crash in D3D. +// The test uses 8 buffers with a size just under 0x2000000 to overflow max uint +// (with the internal D3D rounding to 16-byte values) and trigger the bug. +// Only handle this bug on 64-bit Windows for now. Harder to repro on 32-bit. +class BufferDataOverflowTest : public ANGLETest +{ + protected: + BufferDataOverflowTest() + { + } +}; + +// See description above. +TEST_P(BufferDataOverflowTest, VertexBufferIntegerOverflow) +{ + // These values are special, to trigger the rounding bug. + unsigned int numItems = 0x7FFFFFE; + constexpr GLsizei bufferCnt = 8; + + std::vector<GLBuffer> buffers(bufferCnt); + + std::stringstream vertexShaderStr; + + for (GLsizei bufferIndex = 0; bufferIndex < bufferCnt; ++bufferIndex) + { + vertexShaderStr << "attribute float attrib" << bufferIndex << ";\n"; + } + + vertexShaderStr << "attribute vec2 position;\n" + "varying float v_attrib;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + " v_attrib = 0.0;\n"; + + for (GLsizei bufferIndex = 0; bufferIndex < bufferCnt; ++bufferIndex) + { + vertexShaderStr << "v_attrib += attrib" << bufferIndex << ";\n"; + } + + vertexShaderStr << "}"; + + const std::string &fragmentShader = + "varying highp float v_attrib;\n" + "void main() {\n" + " gl_FragColor = vec4(v_attrib, 0, 0, 1);\n" + "}"; + + ANGLE_GL_PROGRAM(program, vertexShaderStr.str(), fragmentShader); + glUseProgram(program.get()); + + std::vector<GLfloat> data(numItems, 1.0f); + + for (GLsizei bufferIndex = 0; bufferIndex < bufferCnt; ++bufferIndex) + { + glBindBuffer(GL_ARRAY_BUFFER, buffers[bufferIndex].get()); + glBufferData(GL_ARRAY_BUFFER, numItems * sizeof(float), &data[0], GL_DYNAMIC_DRAW); + + std::stringstream attribNameStr; + attribNameStr << "attrib" << bufferIndex; + + GLint attribLocation = glGetAttribLocation(program.get(), attribNameStr.str().c_str()); + ASSERT_NE(-1, attribLocation); + + glVertexAttribPointer(attribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr); + glEnableVertexAttribArray(attribLocation); + } + + GLint positionLocation = glGetAttribLocation(program.get(), "position"); + ASSERT_NE(-1, positionLocation); + glDisableVertexAttribArray(positionLocation); + glVertexAttrib2f(positionLocation, 1.0f, 1.0f); + + EXPECT_GL_NO_ERROR(); + glDrawArrays(GL_TRIANGLES, 0, numItems); + EXPECT_GL_ERROR(GL_OUT_OF_MEMORY); +} + +// Tests a security bug in our CopyBufferSubData validation (integer overflow). +TEST_P(BufferDataOverflowTest, CopySubDataValidation) +{ + GLBuffer readBuffer, writeBuffer; + + glBindBuffer(GL_COPY_READ_BUFFER, readBuffer.get()); + glBindBuffer(GL_COPY_WRITE_BUFFER, writeBuffer.get()); + + constexpr int bufSize = 100; + + glBufferData(GL_COPY_READ_BUFFER, bufSize, nullptr, GL_STATIC_DRAW); + glBufferData(GL_COPY_WRITE_BUFFER, bufSize, nullptr, GL_STATIC_DRAW); + + GLintptr big = std::numeric_limits<GLintptr>::max() - bufSize + 90; + + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, big, 0, 50); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, big, 50); + EXPECT_GL_ERROR(GL_INVALID_VALUE); +} + +ANGLE_INSTANTIATE_TEST(BufferDataOverflowTest, ES3_D3D11()); + +#endif // _WIN64 diff --git a/gfx/angle/src/tests/gl_tests/BuiltinVariableTest.cpp b/gfx/angle/src/tests/gl_tests/BuiltinVariableTest.cpp new file mode 100755 index 000000000..cbb399dd6 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/BuiltinVariableTest.cpp @@ -0,0 +1,209 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// BuiltinVariableTest: +// Tests the correctness of the builtin GLSL variables. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class BuiltinVariableVertexIdTest : public ANGLETest +{ + protected: + BuiltinVariableVertexIdTest() + { + setWindowWidth(64); + setWindowHeight(64); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vsSource = + "#version 300 es\n" + "precision highp float;\n" + "in vec4 position;\n" + "in int expectedID;" + "out vec4 color;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " color = vec4(gl_VertexID != expectedID, gl_VertexID == expectedID, 0.0, 1.0);" + "}\n"; + + const std::string fsSource = + "#version 300 es\n" + "precision highp float;\n" + "in vec4 color;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " fragColor = color;\n" + "}\n"; + + mProgram = CompileProgram(vsSource, fsSource); + ASSERT_NE(0u, mProgram); + + mPositionLocation = glGetAttribLocation(mProgram, "position"); + ASSERT_NE(-1, mPositionLocation); + mExpectedIdLocation = glGetAttribLocation(mProgram, "expectedID"); + ASSERT_NE(-1, mExpectedIdLocation); + + static const float positions[] = + { + 0.5, 0.5, + -0.5, 0.5, + 0.5, -0.5, + -0.5, -0.5 + }; + glGenBuffers(1, &mPositionBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteBuffers(1, &mPositionBuffer); + glDeleteBuffers(1, &mExpectedIdBuffer); + glDeleteBuffers(1, &mIndexBuffer); + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + // Renders a primitive using the specified mode, each vertex color will + // be green if gl_VertexID is correct, red otherwise. + void runTest(GLuint drawMode, const std::vector<GLint> &indices, int count) + { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glGenBuffers(1, &mIndexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * indices.size(), indices.data(), + GL_STATIC_DRAW); + + std::vector<GLint> expectedIds = makeRange(count); + + glGenBuffers(1, &mExpectedIdBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mExpectedIdBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLint) * expectedIds.size(), expectedIds.data(), + GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer); + glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(mPositionLocation); + + glBindBuffer(GL_ARRAY_BUFFER, mExpectedIdBuffer); + glVertexAttribIPointer(mExpectedIdLocation, 1, GL_INT, 0, 0); + glEnableVertexAttribArray(mExpectedIdLocation); + + glUseProgram(mProgram); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + glDrawElements(drawMode, count, GL_UNSIGNED_INT, 0); + + std::vector<GLColor> pixels(getWindowWidth() * getWindowHeight()); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, + pixels.data()); + + ASSERT_GL_NO_ERROR(); + + const GLColor green(0, 255, 0, 255); + const GLColor black(0, 0, 0, 255); + + for (const auto &pixel : pixels) + { + EXPECT_TRUE(pixel == green || pixel == black); + } + } + + std::vector<GLint> makeRange(int n) const + { + std::vector<GLint> result; + for (int i = 0; i < n; i++) + { + result.push_back(i); + } + + return result; + } + + GLuint mPositionBuffer = 0; + GLuint mExpectedIdBuffer = 0; + GLuint mIndexBuffer = 0; + + GLuint mProgram = 0; + GLint mPositionLocation = -1; + GLint mExpectedIdLocation = -1; +}; + +// Test gl_VertexID when rendering points +TEST_P(BuiltinVariableVertexIdTest, Points) +{ + runTest(GL_POINTS, makeRange(4), 4); +} + +// Test gl_VertexID when rendering line strips +TEST_P(BuiltinVariableVertexIdTest, LineStrip) +{ + runTest(GL_LINE_STRIP, makeRange(4), 4); +} + +// Test gl_VertexID when rendering line loops +TEST_P(BuiltinVariableVertexIdTest, LineLoop) +{ + runTest(GL_LINE_LOOP, makeRange(4), 4); +} + +// Test gl_VertexID when rendering lines +TEST_P(BuiltinVariableVertexIdTest, Lines) +{ + runTest(GL_LINES, makeRange(4), 4); +} + +// Test gl_VertexID when rendering triangle strips +TEST_P(BuiltinVariableVertexIdTest, TriangleStrip) +{ + runTest(GL_TRIANGLE_STRIP, makeRange(4), 4); +} + +// Test gl_VertexID when rendering triangle fans +TEST_P(BuiltinVariableVertexIdTest, TriangleFan) +{ + std::vector<GLint> indices; + indices.push_back(0); + indices.push_back(1); + indices.push_back(3); + indices.push_back(2); + runTest(GL_TRIANGLE_FAN, indices, 4); +} + +// Test gl_VertexID when rendering triangles +TEST_P(BuiltinVariableVertexIdTest, Triangles) +{ + std::vector<GLint> indices; + indices.push_back(0); + indices.push_back(1); + indices.push_back(2); + indices.push_back(1); + indices.push_back(2); + indices.push_back(3); + runTest(GL_TRIANGLES, indices, 6); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(BuiltinVariableVertexIdTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/ClearTest.cpp b/gfx/angle/src/tests/gl_tests/ClearTest.cpp new file mode 100755 index 000000000..87ce041e6 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ClearTest.cpp @@ -0,0 +1,481 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include "random_utils.h" +#include "Vector.h" + +using namespace angle; + +namespace +{ + +Vector4 RandomVec4(int seed, float minValue, float maxValue) +{ + RNG rng(seed); + srand(seed); + return Vector4( + rng.randomFloatBetween(minValue, maxValue), rng.randomFloatBetween(minValue, maxValue), + rng.randomFloatBetween(minValue, maxValue), rng.randomFloatBetween(minValue, maxValue)); +} + +GLColor Vec4ToColor(const Vector4 &vec) +{ + GLColor color; + color.R = static_cast<uint8_t>(vec.x * 255.0f); + color.G = static_cast<uint8_t>(vec.y * 255.0f); + color.B = static_cast<uint8_t>(vec.z * 255.0f); + color.A = static_cast<uint8_t>(vec.w * 255.0f); + return color; +}; + +class ClearTestBase : public ANGLETest +{ + protected: + ClearTestBase() : mProgram(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + mFBOs.resize(2, 0); + glGenFramebuffers(2, mFBOs.data()); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + if (!mFBOs.empty()) + { + glDeleteFramebuffers(static_cast<GLsizei>(mFBOs.size()), mFBOs.data()); + } + + if (!mTextures.empty()) + { + glDeleteTextures(static_cast<GLsizei>(mTextures.size()), mTextures.data()); + } + + ANGLETest::TearDown(); + } + + void setupDefaultProgram() + { + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + + void main() + { + gl_Position = position; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + + void main() + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + } + + GLuint mProgram; + std::vector<GLuint> mFBOs; + std::vector<GLuint> mTextures; +}; + +class ClearTest : public ClearTestBase {}; +class ClearTestES3 : public ClearTestBase {}; + +// Test clearing the default framebuffer +TEST_P(ClearTest, DefaultFramebuffer) +{ + glClearColor(0.25f, 0.5f, 0.5f, 0.5f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 128, 1.0); +} + +// Test clearing a RGBA8 Framebuffer +TEST_P(ClearTest, RGBA8Framebuffer) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + + GLuint texture; + glGenTextures(1, &texture); + + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + glClearColor(0.5f, 0.5f, 0.5f, 0.5f); + glClear(GL_COLOR_BUFFER_BIT); + + EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0); +} + +TEST_P(ClearTest, ClearIssue) +{ + // TODO(geofflang): Figure out why this is broken on Intel OpenGL + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + glClearColor(0.0, 1.0, 0.0, 1.0); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + + GLuint rbo; + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 16, 16); + + EXPECT_GL_NO_ERROR(); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); + + EXPECT_GL_NO_ERROR(); + + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClearDepthf(1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + setupDefaultProgram(); + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); +} + +// Requires ES3 +// This tests a bug where in a masked clear when calling "ClearBuffer", we would +// mistakenly clear every channel (including the masked-out ones) +TEST_P(ClearTestES3, MaskedClearBufferBug) +{ + unsigned char pixelData[] = { 255, 255, 255, 255 }; + + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + + GLuint textures[2]; + glGenTextures(2, &textures[0]); + + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0); + + glBindTexture(GL_TEXTURE_2D, textures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255); + + float clearValue[] = { 0, 0.5f, 0.5f, 1.0f }; + GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT1 }; + glDrawBuffers(2, drawBuffers); + glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE); + glClearBufferfv(GL_COLOR, 1, clearValue); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255); + + glReadBuffer(GL_COLOR_ATTACHMENT1); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_NEAR(0, 0, 0, 127, 255, 255, 1); + + glDeleteTextures(2, textures); +} + +TEST_P(ClearTestES3, BadFBOSerialBug) +{ + // First make a simple framebuffer, and clear it to green + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + + GLuint textures[2]; + glGenTextures(2, &textures[0]); + + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0); + + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 }; + glDrawBuffers(1, drawBuffers); + + float clearValues1[] = { 0.0f, 1.0f, 0.0f, 1.0f }; + glClearBufferfv(GL_COLOR, 0, clearValues1); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + // Next make a second framebuffer, and draw it to red + // (Triggers bad applied render target serial) + GLuint fbo2; + glGenFramebuffers(1, &fbo2); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo2); + + glBindTexture(GL_TEXTURE_2D, textures[1]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0); + + glDrawBuffers(1, drawBuffers); + + setupDefaultProgram(); + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + // Check that the first framebuffer is still green. + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + glDeleteTextures(2, textures); + glDeleteFramebuffers(1, &fbo2); +} + +// Test that SRGB framebuffers clear to the linearized clear color +TEST_P(ClearTestES3, SRGBClear) +{ + // TODO(jmadill): figure out why this fails + if (IsIntel() && GetParam() == ES3_OPENGL()) + { + std::cout << "Test skipped on Intel due to failures." << std::endl; + return; + } + + // First make a simple framebuffer, and clear it + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + + GLuint texture; + glGenTextures(1, &texture); + + glBindTexture(GL_TEXTURE_2D, texture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + glClearColor(0.5f, 0.5f, 0.5f, 0.5f); + glClear(GL_COLOR_BUFFER_BIT); + + EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0); +} + +// Test that framebuffers with mixed SRGB/Linear attachments clear to the correct color for each +// attachment +TEST_P(ClearTestES3, MixedSRGBClear) +{ + // TODO(cwallez) figure out why it is broken on Intel on Mac +#if defined(ANGLE_PLATFORM_APPLE) + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel on Mac." << std::endl; + return; + } +#endif + + // TODO(jmadill): figure out why this fails + if (IsIntel() && GetParam() == ES3_OPENGL()) + { + std::cout << "Test skipped on Intel due to failures." << std::endl; + return; + } + + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + + GLuint textures[2]; + glGenTextures(2, &textures[0]); + + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0); + + glBindTexture(GL_TEXTURE_2D, textures[1]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0); + + GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; + glDrawBuffers(2, drawBuffers); + + // Clear both textures + glClearColor(0.5f, 0.5f, 0.5f, 0.5f); + glClear(GL_COLOR_BUFFER_BIT); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0); + + // Check value of texture0 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0); + EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0); + + // Check value of texture1 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0); + EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0); +} + +// This test covers a D3D11 bug where calling ClearRenderTargetView sometimes wouldn't sync +// before a draw call. The test draws small quads to a larger FBO (the default back buffer). +// Before each blit to the back buffer it clears the quad to a certain color using +// ClearBufferfv to give a solid color. The sync problem goes away if we insert a call to +// flush or finish after ClearBufferfv or each draw. +TEST_P(ClearTestES3, RepeatedClear) +{ + if (IsD3D11() && (IsNVIDIA() || IsIntel())) + { + std::cout << "Test skipped on Nvidia and Intel D3D11." << std::endl; + return; + } + + const std::string &vertexSource = + "#version 300 es\n" + "in highp vec2 position;\n" + "out highp vec2 v_coord;\n" + "void main(void)\n" + "{\n" + " gl_Position = vec4(position, 0, 1);\n" + " vec2 texCoord = (position * 0.5) + 0.5;\n" + " v_coord = texCoord;\n" + "}\n"; + + const std::string &fragmentSource = + "#version 300 es\n" + "in highp vec2 v_coord;\n" + "out highp vec4 color;\n" + "uniform sampler2D tex;\n" + "void main()\n" + "{\n" + " color = texture(tex, v_coord);\n" + "}\n"; + + mProgram = CompileProgram(vertexSource, fragmentSource); + ASSERT_NE(0u, mProgram); + + mTextures.resize(1, 0); + glGenTextures(1, mTextures.data()); + + GLenum format = GL_RGBA8; + const int numRowsCols = 3; + const int cellSize = 32; + const int fboSize = cellSize; + const int backFBOSize = cellSize * numRowsCols; + const float fmtValueMin = 0.0f; + const float fmtValueMax = 1.0f; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexStorage2D(GL_TEXTURE_2D, 1, format, fboSize, fboSize); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + ASSERT_GL_NO_ERROR(); + + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // larger fbo bound -- clear to transparent black + glUseProgram(mProgram); + GLint uniLoc = glGetUniformLocation(mProgram, "tex"); + ASSERT_NE(-1, uniLoc); + glUniform1i(uniLoc, 0); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + ASSERT_NE(-1, positionLocation); + + glUseProgram(mProgram); + + for (int cellY = 0; cellY < numRowsCols; cellY++) + { + for (int cellX = 0; cellX < numRowsCols; cellX++) + { + int seed = cellX + cellY * numRowsCols; + const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]); + glClearBufferfv(GL_COLOR, 0, color.data()); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // Method 1: Set viewport and draw full-viewport quad + glViewport(cellX * cellSize, cellY * cellSize, cellSize, cellSize); + drawQuad(mProgram, "position", 0.5f); + + // Uncommenting the glFinish call seems to make the test pass. + // glFinish(); + } + } + + std::vector<GLColor> pixelData(backFBOSize * backFBOSize); + glReadPixels(0, 0, backFBOSize, backFBOSize, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data()); + + for (int cellY = 0; cellY < numRowsCols; cellY++) + { + for (int cellX = 0; cellX < numRowsCols; cellX++) + { + int seed = cellX + cellY * numRowsCols; + const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax); + GLColor expectedColor = Vec4ToColor(color); + + int testN = cellX * cellSize + cellY * backFBOSize * cellSize + backFBOSize + 1; + GLColor actualColor = pixelData[testN]; + EXPECT_NEAR(expectedColor.R, actualColor.R, 1); + EXPECT_NEAR(expectedColor.G, actualColor.G, 1); + EXPECT_NEAR(expectedColor.B, actualColor.B, 1); + EXPECT_NEAR(expectedColor.A, actualColor.A, 1); + } + } + + ASSERT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(ClearTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ClearTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/ColorMaskTest.cpp b/gfx/angle/src/tests/gl_tests/ColorMaskTest.cpp new file mode 100755 index 000000000..d2ad638aa --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ColorMaskTest.cpp @@ -0,0 +1,110 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ColorMaskTest.cpp: Test GLES functionality related to color masks, particularly an AMD D3D9 +// driver bug. + +#include "test_utils/ANGLETest.h" + +namespace angle +{ +class ColorMaskTest : public ANGLETest +{ + protected: + ColorMaskTest() : mProgram(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vsSource = + "precision highp float;\n" + "attribute vec4 position;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + "}\n"; + + const std::string fsSource = + "precision highp float;\n" + "uniform vec4 color;\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = color;\n" + "}\n"; + + mProgram = CompileProgram(vsSource, fsSource); + ASSERT_NE(0u, mProgram) << "shader compilation failed."; + + mColorUniform = glGetUniformLocation(mProgram, "color"); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram = 0; + GLint mColorUniform = -1; +}; + +// Some ATI cards have a bug where a draw with a zero color write mask can cause later draws to have +// incorrect results. Test to make sure this bug is not exposed. +TEST_P(ColorMaskTest, AMDZeroColorMaskBug) +{ + int x = getWindowWidth() / 2; + int y = getWindowHeight() / 2; + + // Clear to blue + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(x, y, 0, 0, 255, 255); + + // Draw a quad with all colors masked and blending disabled, should remain blue + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glDisable(GL_BLEND); + glUseProgram(mProgram); + glUniform4f(mColorUniform, 1.0f, 0.0f, 0.0f, 0.0f); + EXPECT_GL_NO_ERROR(); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(x, y, 0, 0, 255, 255); + + // Re-enable the color mask, should be red (with blend disabled, the red should overwrite + // everything) + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glUseProgram(mProgram); + glUniform4f(mColorUniform, 1.0f, 0.0f, 0.0f, 0.0f); + EXPECT_GL_NO_ERROR(); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(x, y, 255, 0, 0, 0); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. D3D11 Feature Level 9_3 uses different D3D formats for vertex +// attribs compared to Feature Levels 10_0+, so we should test them separately. +ANGLE_INSTANTIATE_TEST(ColorMaskTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace angle diff --git a/gfx/angle/src/tests/gl_tests/ComputeShaderTest.cpp b/gfx/angle/src/tests/gl_tests/ComputeShaderTest.cpp new file mode 100755 index 000000000..61b1146c2 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ComputeShaderTest.cpp @@ -0,0 +1,226 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ComputeShaderTest: +// Compute shader specific tests. + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" +#include <vector> + +using namespace angle; + +namespace +{ + +class ComputeShaderTest : public ANGLETest +{ + protected: + ComputeShaderTest() {} +}; + +class ComputeShaderTestES3 : public ANGLETest +{ + protected: + ComputeShaderTestES3() {} +}; + +// link a simple compute program. It should be successful. +TEST_P(ComputeShaderTest, LinkComputeProgram) +{ + if (IsIntel() && IsLinux()) + { + std::cout << "Test skipped on Intel Linux due to failures." << std::endl; + return; + } + + const std::string csSource = + "#version 310 es\n" + "layout(local_size_x=1) in;\n" + "void main()\n" + "{\n" + "}\n"; + + ANGLE_GL_COMPUTE_PROGRAM(program, csSource); + + EXPECT_GL_NO_ERROR(); +} + +// link a simple compute program. There is no local size and linking should fail. +TEST_P(ComputeShaderTest, LinkComputeProgramNoLocalSizeLinkError) +{ + const std::string csSource = + "#version 310 es\n" + "void main()\n" + "{\n" + "}\n"; + + GLuint program = CompileComputeProgram(csSource, false); + EXPECT_EQ(0u, program); + + glDeleteProgram(program); + + EXPECT_GL_NO_ERROR(); +} + +// link a simple compute program. +// make sure that uniforms and uniform samplers get recorded +TEST_P(ComputeShaderTest, LinkComputeProgramWithUniforms) +{ + if (IsIntel() && IsLinux()) + { + std::cout << "Test skipped on Intel Linux due to failures." << std::endl; + return; + } + const std::string csSource = + "#version 310 es\n" + "precision mediump sampler2D;\n" + "layout(local_size_x=1) in;\n" + "uniform int myUniformInt;\n" + "uniform sampler2D myUniformSampler;\n" + "void main()\n" + "{\n" + "int q = myUniformInt;\n" + "texture(myUniformSampler, vec2(0.0));\n" + "}\n"; + + ANGLE_GL_COMPUTE_PROGRAM(program, csSource); + + GLint uniformLoc = glGetUniformLocation(program.get(), "myUniformInt"); + EXPECT_NE(-1, uniformLoc); + + uniformLoc = glGetUniformLocation(program.get(), "myUniformSampler"); + EXPECT_NE(-1, uniformLoc); + + EXPECT_GL_NO_ERROR(); +} + +// Attach both compute and non-compute shaders. A link time error should occur. +// OpenGL ES 3.10, 7.3 Program Objects +TEST_P(ComputeShaderTest, AttachMultipleShaders) +{ + if (IsIntel() && IsLinux()) + { + std::cout << "Test skipped on Intel Linux due to failures." << std::endl; + return; + } + const std::string csSource = + "#version 310 es\n" + "layout(local_size_x=1) in;\n" + "void main()\n" + "{\n" + "}\n"; + + const std::string vsSource = + "#version 310 es\n" + "void main()\n" + "{\n" + "}\n"; + + const std::string fsSource = + "#version 310 es\n" + "void main()\n" + "{\n" + "}\n"; + + GLuint program = glCreateProgram(); + + GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); + GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource); + + EXPECT_NE(0u, vs); + EXPECT_NE(0u, fs); + EXPECT_NE(0u, cs); + + glAttachShader(program, vs); + glDeleteShader(vs); + + glAttachShader(program, fs); + glDeleteShader(fs); + + glAttachShader(program, cs); + glDeleteShader(cs); + + glLinkProgram(program); + + GLint linkStatus; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + + EXPECT_EQ(0, linkStatus); + + EXPECT_GL_NO_ERROR(); +} + +// Attach a vertex, fragment and compute shader. +// Query for the number of attached shaders and check the count. +TEST_P(ComputeShaderTest, AttachmentCount) +{ + if (IsIntel() && IsLinux()) + { + std::cout << "Test skipped on Intel Linux due to failures." << std::endl; + return; + } + const std::string csSource = + "#version 310 es\n" + "layout(local_size_x=1) in;\n" + "void main()\n" + "{\n" + "}\n"; + + const std::string vsSource = + "#version 310 es\n" + "void main()\n" + "{\n" + "}\n"; + + const std::string fsSource = + "#version 310 es\n" + "void main()\n" + "{\n" + "}\n"; + + GLuint program = glCreateProgram(); + + GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource); + GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource); + GLuint cs = CompileShader(GL_COMPUTE_SHADER, csSource); + + EXPECT_NE(0u, vs); + EXPECT_NE(0u, fs); + EXPECT_NE(0u, cs); + + glAttachShader(program, vs); + glDeleteShader(vs); + + glAttachShader(program, fs); + glDeleteShader(fs); + + glAttachShader(program, cs); + glDeleteShader(cs); + + GLint numAttachedShaders; + glGetProgramiv(program, GL_ATTACHED_SHADERS, &numAttachedShaders); + + EXPECT_EQ(3, numAttachedShaders); + + glDeleteProgram(program); + + EXPECT_GL_NO_ERROR(); +} + +// Check that it is not possible to create a compute shader when the context does not support ES +// 3.10 +TEST_P(ComputeShaderTestES3, NotSupported) +{ + GLuint computeShaderHandle = glCreateShader(GL_COMPUTE_SHADER); + EXPECT_EQ(0u, computeShaderHandle); + EXPECT_GL_ERROR(GL_INVALID_ENUM); +} + +ANGLE_INSTANTIATE_TEST(ComputeShaderTest, ES31_OPENGL(), ES31_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ComputeShaderTestES3, ES3_OPENGL(), ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/CopyCompressedTextureTest.cpp b/gfx/angle/src/tests/gl_tests/CopyCompressedTextureTest.cpp new file mode 100644 index 000000000..4d4151949 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/CopyCompressedTextureTest.cpp @@ -0,0 +1,369 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CopyCompressedTextureTest.cpp: Tests of the GL_CHROMIUM_copy_compressed_texture extension + +#include "test_utils/ANGLETest.h" + +namespace angle +{ + +class CopyCompressedTextureTest : public ANGLETest +{ + protected: + CopyCompressedTextureTest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenTextures(2, mTextures); + + mProgram = CompileProgram( + "attribute vec2 a_position;\n" + "varying vec2 v_texcoord;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(a_position, 0.0, 1.0);\n" + " v_texcoord = (a_position + 1.0) * 0.5;\n" + "}\n", + "precision mediump float;\n" + "uniform sampler2D u_texture;\n" + "varying vec2 v_texcoord;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(u_texture, v_texcoord);\n" + "}\n"); + ASSERT_NE(0u, mProgram); + + if (extensionEnabled("GL_CHROMIUM_copy_compressed_texture")) + { + glCompressedCopyTextureCHROMIUM = + reinterpret_cast<PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC>( + eglGetProcAddress("glCompressedCopyTextureCHROMIUM")); + } + } + + void TearDown() override + { + glDeleteTextures(2, mTextures); + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + bool checkExtensions() const + { + if (!extensionEnabled("GL_CHROMIUM_copy_compressed_texture")) + { + std::cout + << "Test skipped because GL_CHROMIUM_copy_compressed_texture is not available." + << std::endl; + return false; + } + + EXPECT_NE(nullptr, glCompressedCopyTextureCHROMIUM); + if (glCompressedCopyTextureCHROMIUM == nullptr) + { + return false; + } + + return true; + } + + GLuint mProgram = 0; + GLuint mTextures[2] = {0, 0}; + + PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC glCompressedCopyTextureCHROMIUM = nullptr; +}; + +namespace +{ + +const GLColor &CompressedImageColor = GLColor::red; + +// Single compressed ATC block of source pixels all set to: +// CompressedImageColor. +const uint8_t CompressedImageATC[8] = {0x0, 0x7c, 0x0, 0xf8, 0x55, 0x55, 0x55, 0x55}; + +// Single compressed ATCIA block of source pixels all set to: +// CompressedImageColor. +const uint8_t CompressedImageATCIA[16] = {0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x7c, 0x0, 0xf8, 0x55, 0x55, 0x55, 0x55}; + +// Single compressed DXT1 block of source pixels all set to: +// CompressedImageColor. +const uint8_t CompressedImageDXT1[8] = {0x00, 0xf8, 0x00, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa}; + +// Single compressed DXT5 block of source pixels all set to: +// CompressedImageColor. +const uint8_t CompressedImageDXT5[16] = {0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xf8, 0x0, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa}; + +// Single compressed DXT1 block of source pixels all set to: +// CompressedImageColor. +const uint8_t CompressedImageETC1[8] = {0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0}; + +} // anonymous namespace + +// Test to ensure that the basic functionality of the extension works. +TEST_P(CopyCompressedTextureTest, Basic) +{ + if (!checkExtensions()) + { + return; + } + + if (!extensionEnabled("GL_EXT_texture_compression_dxt1")) + { + std::cout << "Test skipped because GL_EXT_texture_compression_dxt1 is not available." + << std::endl; + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, + sizeof(CompressedImageDXT1), CompressedImageDXT1); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]); + ASSERT_GL_NO_ERROR(); + + // Load texture. + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + GLint textureLoc = glGetUniformLocation(mProgram, "u_texture"); + glUseProgram(mProgram); + glUniform1i(textureLoc, 0); + + // Draw. + drawQuad(mProgram, "a_position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, CompressedImageColor); + ASSERT_GL_NO_ERROR(); +} + +// Test validation of compressed formats +TEST_P(CopyCompressedTextureTest, InternalFormat) +{ + if (!checkExtensions()) + { + return; + } + + struct Data + { + GLint format; + const uint8_t *data; + GLsizei dataSize; + + Data() : Data(GL_NONE, nullptr, 0) {} + Data(GLint format, const uint8_t *data, GLsizei dataSize) + : format(format), data(data), dataSize(dataSize) + { + } + }; + std::vector<Data> supportedFormats; + + if (extensionEnabled("GL_AMD_compressed_ATC_texture")) + { + supportedFormats.push_back( + Data(GL_ATC_RGB_AMD, CompressedImageATC, sizeof(CompressedImageATC))); + supportedFormats.push_back(Data(GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD, CompressedImageATCIA, + sizeof(CompressedImageATCIA))); + } + if (extensionEnabled("GL_EXT_texture_compression_dxt1")) + { + supportedFormats.push_back(Data(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedImageDXT1, + sizeof(CompressedImageDXT1))); + } + if (extensionEnabled("GL_ANGLE_texture_compression_dxt5")) + { + supportedFormats.push_back(Data(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, CompressedImageDXT5, + sizeof(CompressedImageDXT5))); + } + if (extensionEnabled("GL_OES_compressed_ETC1_RGB8_texture")) + { + supportedFormats.push_back( + Data(GL_ETC1_RGB8_OES, CompressedImageETC1, sizeof(CompressedImageETC1))); + } + + for (const auto &supportedFormat : supportedFormats) + { + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, supportedFormat.format, 4, 4, 0, + supportedFormat.dataSize, supportedFormat.data); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]); + ASSERT_GL_NO_ERROR(); + } +} + +// Test that uncompressed textures generate errors when copying +TEST_P(CopyCompressedTextureTest, InternalFormatNotSupported) +{ + if (!checkExtensions()) + { + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + // Check that the GL_RGBA format reports an error. + glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test validation of texture IDs +TEST_P(CopyCompressedTextureTest, InvalidTextureIds) +{ + if (!checkExtensions()) + { + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, + sizeof(CompressedImageDXT1), CompressedImageDXT1); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glCompressedCopyTextureCHROMIUM(mTextures[0], 99993); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCompressedCopyTextureCHROMIUM(99994, mTextures[1]); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCompressedCopyTextureCHROMIUM(99995, 99996); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]); + EXPECT_GL_NO_ERROR(); +} + +// Test that only 2D textures are valid +TEST_P(CopyCompressedTextureTest, BindingPoints) +{ + if (!checkExtensions()) + { + return; + } + + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[0]); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + face++) + { + glCompressedTexImage2D(face, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, + sizeof(CompressedImageDXT1), CompressedImageDXT1); + } + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[1]); + glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]); + EXPECT_GL_ERROR(GL_INVALID_VALUE); +} + +// Test the destination texture cannot be immutable +TEST_P(CopyCompressedTextureTest, Immutable) +{ + if (!checkExtensions() || getClientMajorVersion() < 3) + { + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, + sizeof(CompressedImageDXT1), CompressedImageDXT1); + ASSERT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(CopyCompressedTextureTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace angle diff --git a/gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp b/gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp new file mode 100755 index 000000000..b3b74261b --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp @@ -0,0 +1,343 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +namespace angle +{ + +class CopyTexImageTest : public ANGLETest +{ + protected: + CopyTexImageTest() + { + setWindowWidth(16); + setWindowHeight(16); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + GLuint createFramebuffer(GLenum format, GLenum type, GLfloat color[4]) const + { + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + GLuint texture = createTexture(format, type); + glBindTexture(GL_TEXTURE_2D, texture); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + glClearColor(color[0], color[1], color[2], color[3]); + glClear(GL_COLOR_BUFFER_BIT); + + return fbo; + } + + GLuint createTexture(GLenum format, GLenum type) const + { + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, format, 16, 16, 0, format, type, nullptr); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return tex; + } + + GLuint createTextureFromCopyTexImage(GLuint fbo, GLenum format) const + { + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, 16, 16, 0); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return tex; + } + + void copyTextureWithCopyTexSubImage(GLuint fbo, + GLuint texture, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei w, + GLsizei h) const + { + glBindTexture(GL_TEXTURE_2D, texture); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, w, h); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vsSource = + "precision highp float;\n" + "attribute vec4 position;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + " texcoord.y = 1.0 - texcoord.y;\n" + "}\n"; + + const std::string textureFSSource = + "precision highp float;\n" + "uniform sampler2D tex;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(tex, texcoord);\n" + "}\n"; + + mTextureProgram = CompileProgram(vsSource, textureFSSource); + if (mTextureProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mTextureProgram); + + ANGLETest::TearDown(); + } + + void verifyResults(GLuint texture, GLubyte data[4], GLint x, GLint y) + { + glViewport(0, 0, 16, 16); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // Draw a quad with the target texture + glUseProgram(mTextureProgram); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + // Expect that the rendered quad has the same color as the source texture + EXPECT_PIXEL_NEAR(x, y, data[0], data[1], data[2], data[3], 1.0); + } + + GLuint mTextureProgram; + GLint mTextureUniformLocation; +}; + +TEST_P(CopyTexImageTest, RGBAToL) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE); + + GLubyte expected[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, RGBToL) +{ + // TODO (geofflang): Figure out why CopyTex[Sub]Image doesn't work with + // RGB->L on older Intel chips + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE); + + GLubyte expected[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, RGBAToLA) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE_ALPHA); + + GLubyte expected[] = { + 64, 64, 64, 127, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, RGBAToA) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_ALPHA); + + GLubyte expected[] = { + 0, 0, 0, 127, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, SubImageRGBAToL) +{ + GLfloat color0[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + GLuint fbo0 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color0); + GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE); + + GLfloat color1[] = { + 0.5f, 0.25f, 1.0f, 0.75f, + }; + GLuint fbo1 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color1); + copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8); + + GLubyte expected0[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected0, 0, 0); + + GLubyte expected1[] = { + 127, 127, 127, 255, + }; + verifyResults(tex, expected1, 7, 7); +} + +TEST_P(CopyTexImageTest, SubImageRGBAToLA) +{ + GLfloat color0[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + GLuint fbo0 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color0); + GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE_ALPHA); + + GLfloat color1[] = { + 0.5f, 0.25f, 1.0f, 0.75f, + }; + GLuint fbo1 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color1); + copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8); + + GLubyte expected0[] = { + 64, 64, 64, 127, + }; + verifyResults(tex, expected0, 0, 0); + + GLubyte expected1[] = { + 127, 127, 127, 192, + }; + verifyResults(tex, expected1, 7, 7); +} + +TEST_P(CopyTexImageTest, SubImageRGBToL) +{ + // TODO (geofflang): Figure out why CopyTex[Sub]Image doesn't work with + // RGB->L on older Intel chips + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + GLfloat color0[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + GLuint fbo0 = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color0); + GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE); + + GLfloat color1[] = { + 0.5f, 0.25f, 1.0f, 0.75f, + }; + GLuint fbo1 = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color1); + copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8); + + GLubyte expected0[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected0, 0, 0); + + GLubyte expected1[] = { + 127, 127, 127, 255, + }; + verifyResults(tex, expected1, 7, 7); +} + +// specialization of CopyTexImageTest is added so that some tests can be explicitly run with an ES3 +// context +class CopyTexImageTestES3 : public CopyTexImageTest +{ +}; + +// The test verifies that glCopyTexSubImage2D generates a GL_INVALID_OPERATION error +// when the read buffer is GL_NONE. +// Reference: GLES 3.0.4, Section 3.8.5 Alternate Texture Image Specification Commands +TEST_P(CopyTexImageTestES3, ReadBufferIsNone) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_RGBA); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glBindTexture(GL_TEXTURE_2D, tex); + + glReadBuffer(GL_NONE); + + EXPECT_GL_NO_ERROR(); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(CopyTexImageTest, + ES2_D3D9(), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE), + ES2_OPENGL(), + ES2_OPENGL(3, 3), + ES2_OPENGLES()); + +ANGLE_INSTANTIATE_TEST(CopyTexImageTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +} diff --git a/gfx/angle/src/tests/gl_tests/CopyTextureTest.cpp b/gfx/angle/src/tests/gl_tests/CopyTextureTest.cpp new file mode 100755 index 000000000..553861e7d --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/CopyTextureTest.cpp @@ -0,0 +1,566 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// CopyTextureTest.cpp: Tests of the GL_CHROMIUM_copy_texture extension + +#include "test_utils/ANGLETest.h" + +namespace angle +{ + +class CopyTextureTest : public ANGLETest +{ + protected: + CopyTextureTest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenTextures(2, mTextures); + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], + 0); + + if (extensionEnabled("GL_CHROMIUM_copy_texture")) + { + glCopyTextureCHROMIUM = reinterpret_cast<PFNGLCOPYTEXTURECHROMIUMPROC>( + eglGetProcAddress("glCopyTextureCHROMIUM")); + glCopySubTextureCHROMIUM = reinterpret_cast<PFNGLCOPYSUBTEXTURECHROMIUMPROC>( + eglGetProcAddress("glCopySubTextureCHROMIUM")); + } + } + + void TearDown() override + { + glDeleteTextures(2, mTextures); + glDeleteFramebuffers(1, &mFramebuffer); + + ANGLETest::TearDown(); + } + + bool checkExtensions() const + { + if (!extensionEnabled("GL_CHROMIUM_copy_texture")) + { + std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available." + << std::endl; + return false; + } + + EXPECT_NE(nullptr, glCopyTextureCHROMIUM); + EXPECT_NE(nullptr, glCopySubTextureCHROMIUM); + return true; + } + + GLuint mTextures[2] = { + 0, 0, + }; + GLuint mFramebuffer = 0; + + PFNGLCOPYTEXTURECHROMIUMPROC glCopyTextureCHROMIUM = nullptr; + PFNGLCOPYSUBTEXTURECHROMIUMPROC glCopySubTextureCHROMIUM = nullptr; +}; + +// Test to ensure that the basic functionality of the extension works. +TEST_P(CopyTextureTest, BasicCopyTexture) +{ + if (!checkExtensions()) + { + return; + } + + GLColor pixels = GLColor::red; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels); + + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, + false); + + EXPECT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_EQ(0, 0, pixels); +} + +// Test to ensure that the basic functionality of the extension works. +TEST_P(CopyTextureTest, BasicCopySubTexture) +{ + if (!checkExtensions()) + { + return; + } + + GLColor pixels = GLColor::red; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, false); + + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_EQ(0, 0, pixels); + + EXPECT_GL_NO_ERROR(); +} + +// Test that CopyTexture cannot redefine an immutable texture and CopySubTexture can copy data to +// immutable textures +TEST_P(CopyTextureTest, ImmutableTexture) +{ + if (!checkExtensions()) + { + return; + } + + if (getClientMajorVersion() < 3 && + (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8"))) + { + std::cout + << "Test skipped due to missing ES3 or GL_EXT_texture_storage or GL_OES_rgb8_rgba8" + << std::endl; + return; + } + + GLColor pixels = GLColor::red; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0); + EXPECT_GL_NO_ERROR(); + + // Should generate an error when the texture is redefined + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, + false); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // Should succeed when using CopySubTexture + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, false); + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_EQ(0, 0, pixels); + + EXPECT_GL_NO_ERROR(); +} + +// Test validation of internal formats in CopyTexture and CopySubTexture +TEST_P(CopyTextureTest, InternalFormat) +{ + if (!checkExtensions()) + { + return; + } + + std::vector<GLint> sourceFormats; + sourceFormats.push_back(GL_ALPHA); + sourceFormats.push_back(GL_RGB); + sourceFormats.push_back(GL_RGBA); + sourceFormats.push_back(GL_LUMINANCE); + sourceFormats.push_back(GL_LUMINANCE_ALPHA); + + std::vector<GLint> destFormats; + destFormats.push_back(GL_RGB); + destFormats.push_back(GL_RGBA); + + if (extensionEnabled("GL_EXT_texture_format_BGRA8888")) + { + sourceFormats.push_back(GL_BGRA_EXT); + destFormats.push_back(GL_BGRA_EXT); + } + + // Test with glCopyTexture + for (GLint sourceFormat : sourceFormats) + { + for (GLint destFormat : destFormats) + { + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE, + nullptr); + EXPECT_GL_NO_ERROR(); + + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], destFormat, GL_UNSIGNED_BYTE, false, + false, false); + + EXPECT_GL_NO_ERROR(); + } + } + + // Test with glCopySubTexture + for (GLint sourceFormat : sourceFormats) + { + for (GLint destFormat : destFormats) + { + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE, + nullptr); + EXPECT_GL_NO_ERROR(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 1, 1, 0, destFormat, GL_UNSIGNED_BYTE, + nullptr); + EXPECT_GL_NO_ERROR(); + + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, + false); + + EXPECT_GL_NO_ERROR(); + } + } +} + +// Check that invalid internal formats return errors. +TEST_P(CopyTextureTest, InternalFormatNotSupported) +{ + if (!checkExtensions()) + { + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + EXPECT_GL_NO_ERROR(); + + std::vector<GLint> unsupportedDestFormats; + unsupportedDestFormats.push_back(GL_ALPHA); + unsupportedDestFormats.push_back(GL_LUMINANCE); + unsupportedDestFormats.push_back(GL_LUMINANCE_ALPHA); + + if (!extensionEnabled("GL_EXT_texture_format_BGRA8888")) + { + unsupportedDestFormats.push_back(GL_BGRA_EXT); + } + + // Check unsupported format reports an error. + for (GLint unsupportedDestFormat : unsupportedDestFormats) + { + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], unsupportedDestFormat, GL_UNSIGNED_BYTE, + false, false, false); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } + + for (GLint unsupportedDestFormat : unsupportedDestFormats) + { + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, unsupportedDestFormat, 1, 1, 0, unsupportedDestFormat, + GL_UNSIGNED_BYTE, nullptr); + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } +} + +// Test to ensure that the destination texture is redefined if the properties are different. +TEST_P(CopyTextureTest, RedefineDestinationTexture) +{ + if (!checkExtensions()) + { + return; + } + + GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red}; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); + EXPECT_GL_NO_ERROR(); + + // GL_INVALID_OPERATION due to "intrinsic format" != "internal format". + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + // GL_INVALID_VALUE due to bad dimensions. + glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // If the dest texture has different properties, glCopyTextureCHROMIUM() + // redefines them. + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, + false); + EXPECT_GL_NO_ERROR(); + + // glTexSubImage2D() succeeds because mTextures[1] is redefined into 2x2 + // dimension and GL_RGBA format. + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_EQ(1, 1, pixels[3]); + EXPECT_GL_NO_ERROR(); +} + +// Test that invalid dimensions in CopySubTexture are validated +TEST_P(CopyTextureTest, CopySubTextureDimension) +{ + if (!checkExtensions()) + { + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); + EXPECT_GL_NO_ERROR(); + + // xoffset < 0 + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], -1, 1, 0, 0, 1, 1, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // x < 0 + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, -1, 0, 1, 1, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // xoffset + width > dest_width + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 2, 2, 0, 0, 2, 2, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // x + width > source_width + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 1, 1, 2, 2, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); +} + +// Test that invalid IDs in CopyTexture are validated +TEST_P(CopyTextureTest, CopyTextureInvalidTextureIds) +{ + if (!checkExtensions()) + { + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glCopyTextureCHROMIUM(mTextures[0], 99993, GL_RGBA, GL_UNSIGNED_BYTE, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCopyTextureCHROMIUM(99994, mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCopyTextureCHROMIUM(99995, 99996, GL_RGBA, GL_UNSIGNED_BYTE, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, + false); + EXPECT_GL_NO_ERROR(); +} + +// Test that invalid IDs in CopySubTexture are validated +TEST_P(CopyTextureTest, CopySubTextureInvalidTextureIds) +{ + if (!checkExtensions()) + { + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glCopySubTextureCHROMIUM(mTextures[0], 99993, 1, 1, 0, 0, 1, 1, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCopySubTextureCHROMIUM(99994, mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCopySubTextureCHROMIUM(99995, 99996, 1, 1, 0, 0, 1, 1, false, false, false); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); + EXPECT_GL_NO_ERROR(); +} + +// Test that using an offset in CopySubTexture works correctly +TEST_P(CopyTextureTest, CopySubTextureOffset) +{ + if (!checkExtensions()) + { + return; + } + + GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black}; + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); + + GLColor transparentPixels[4 * 4] = {GLColor::transparentBlack, GLColor::transparentBlack, + GLColor::transparentBlack, GLColor::transparentBlack}; + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, transparentPixels); + + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); + EXPECT_GL_NO_ERROR(); + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 0, 1, 0, 1, 1, false, false, false); + EXPECT_GL_NO_ERROR(); + glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 1, 0, 1, 1, 1, false, false, false); + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack); + EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue); + EXPECT_GL_NO_ERROR(); +} + +// Test that flipping the Y component works correctly +TEST_P(CopyTextureTest, FlipY) +{ + if (!checkExtensions()) + { + return; + } + + GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(127u, 127u, 127u, 127u), + GLColor(63u, 63u, 63u, 127u), GLColor(255u, 255u, 255u, 0u)}; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); + + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, GL_TRUE, GL_FALSE, + GL_FALSE); + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_EQ(0, 0, rgbaPixels[2]); + EXPECT_PIXEL_COLOR_EQ(1, 0, rgbaPixels[3]); + EXPECT_PIXEL_COLOR_EQ(0, 1, rgbaPixels[0]); + EXPECT_PIXEL_COLOR_EQ(1, 1, rgbaPixels[1]); + EXPECT_GL_NO_ERROR(); +} + +// Test that premultipying the alpha on copy works correctly +TEST_P(CopyTextureTest, PremultiplyAlpha) +{ + if (!checkExtensions()) + { + return; + } + + GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(255u, 255u, 255u, 127u), + GLColor(127u, 127u, 127u, 127u), GLColor(255u, 255u, 255u, 0u)}; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); + + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE, GL_TRUE, + GL_FALSE); + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 255, 255, 255), 1.0); + EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(127, 127, 127, 127), 1.0); + EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(63, 63, 63, 127), 1.0); + EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(0, 0, 0, 0), 1.0); + EXPECT_GL_NO_ERROR(); +} + +// Test that unmultipying the alpha on copy works correctly +TEST_P(CopyTextureTest, UnmultiplyAlpha) +{ + if (!checkExtensions()) + { + return; + } + + GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(127u, 127u, 127u, 127u), + GLColor(63u, 63u, 63u, 127u), GLColor(255u, 255u, 255u, 0u)}; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); + + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE, GL_FALSE, + GL_TRUE); + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 255, 255, 255), 1.0); + EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(255, 255, 255, 127), 1.0); + EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(127, 127, 127, 127), 1.0); + EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(255, 255, 255, 0), 1.0); + EXPECT_GL_NO_ERROR(); +} + +// Test that unmultipying and premultiplying the alpha is the same as doing neither +TEST_P(CopyTextureTest, UnmultiplyAndPremultplyAlpha) +{ + if (!checkExtensions()) + { + return; + } + + GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(127u, 127u, 127u, 127u), + GLColor(63u, 63u, 63u, 127u), GLColor(255u, 255u, 255u, 0u)}; + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); + + glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE, GL_TRUE, + GL_TRUE); + EXPECT_GL_NO_ERROR(); + + // Check that FB is complete. + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 255, 255, 255), 1.0); + EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(127, 127, 127, 127), 1.0); + EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(63, 63, 63, 127), 1.0); + EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(255, 255, 255, 0), 1.0); + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(CopyTextureTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES()); + +} // namespace angle diff --git a/gfx/angle/src/tests/gl_tests/CubeMapTextureTest.cpp b/gfx/angle/src/tests/gl_tests/CubeMapTextureTest.cpp new file mode 100755 index 000000000..10fce15b0 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/CubeMapTextureTest.cpp @@ -0,0 +1,138 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class CubeMapTextureTest : public ANGLETest +{ + protected: + CubeMapTextureTest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vsSource = SHADER_SOURCE + ( + attribute highp vec4 position; + void main(void) + { + gl_Position = position; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + uniform highp vec4 color; + void main(void) + { + gl_FragColor = color; + } + ); + + mProgram = CompileProgram(vsSource, fsSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mColorLocation = glGetUniformLocation(mProgram, "color"); + + glUseProgram(mProgram); + + glClearColor(0, 0, 0, 0); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLint mColorLocation; +}; + +// Verify that rendering to the faces of a cube map consecutively will correctly render to each face. +TEST_P(CubeMapTextureTest, RenderToFacesConsecutively) +{ + const GLfloat faceColors[] = + { + 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 1.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 1.0f, + }; + + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_CUBE_MAP, tex); + glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8_OES, 1, 1); + EXPECT_GL_NO_ERROR(); + + GLuint fbo = 0; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + EXPECT_GL_NO_ERROR(); + + for (GLenum face = 0; face < 6; face++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0); + EXPECT_GL_NO_ERROR(); + + glUseProgram(mProgram); + + const GLfloat *faceColor = faceColors + (face * 4); + glUniform4f(mColorLocation, faceColor[0], faceColor[1], faceColor[2], faceColor[3]); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + } + + for (GLenum face = 0; face < 6; face++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0); + EXPECT_GL_NO_ERROR(); + + const GLfloat *faceColor = faceColors + (face * 4); + EXPECT_PIXEL_EQ(0, 0, faceColor[0] * 255, faceColor[1] * 255, faceColor[2] * 255, faceColor[3] * 255); + EXPECT_GL_NO_ERROR(); + } + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(CubeMapTextureTest, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp b/gfx/angle/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp new file mode 100755 index 000000000..c26cf0e08 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/D3D11EmulatedIndexedBufferTest.cpp @@ -0,0 +1,195 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// D3D11EmulatedIndexedBufferTest: +// Tests to validate our D3D11 support for emulating an indexed +// vertex buffer. +// + +#include "libANGLE/angletypes.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "test_utils/ANGLETest.h" +#include "test_utils/angle_test_instantiate.h" + +using namespace angle; + +namespace +{ + +class D3D11EmulatedIndexedBufferTest : public ANGLETest +{ + protected: + + void SetUp() override + { + ANGLETest::SetUp(); + ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer()); + + gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext()); + rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context); + mRenderer = context11->getRenderer(); + + mSourceBuffer = new rx::Buffer11(mBufferState, mRenderer); + GLfloat testData[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f }; + gl::Error error = + mSourceBuffer->setData(GL_ARRAY_BUFFER, testData, sizeof(testData), GL_STATIC_DRAW); + ASSERT_FALSE(error.isError()); + + mTranslatedAttribute.baseOffset = 0; + mTranslatedAttribute.usesFirstVertexOffset = false; + mTranslatedAttribute.stride = sizeof(GLfloat); + + GLubyte indices[] = {0, 0, 3, 4, 2, 1, 1}; + + for (size_t i = 0; i < ArraySize(indices); i++) + { + mExpectedExpandedData.push_back(testData[indices[i]]); + mubyteIndices.push_back(indices[i]); + muintIndices.push_back(indices[i]); + mushortIndices.push_back(indices[i]); + } + } + + void TearDown() override + { + SafeDelete(mSourceBuffer); + ANGLETest::TearDown(); + } + + void createMappableCompareBufferFromEmulatedBuffer(ID3D11Buffer *sourceBuffer, GLuint size, ID3D11Buffer **mappableBuffer) + { + *mappableBuffer = nullptr; + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = size; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + bufferDesc.Usage = D3D11_USAGE_STAGING; + bufferDesc.BindFlags = 0; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + + HRESULT hr = mRenderer->getDevice()->CreateBuffer(&bufferDesc, nullptr, mappableBuffer); + ASSERT_TRUE(SUCCEEDED(hr)); + + D3D11_BOX srcBox; + srcBox.left = 0; + srcBox.right = size; + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + mRenderer->getDeviceContext()->CopySubresourceRegion(*mappableBuffer, 0, 0, 0, 0, sourceBuffer, 0, &srcBox); + } + + void compareContents(ID3D11Buffer *actual) + { + ID3D11Buffer *compareBuffer = nullptr; + createMappableCompareBufferFromEmulatedBuffer( + actual, sizeof(GLfloat) * static_cast<GLuint>(mExpectedExpandedData.size()), + &compareBuffer); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT hr = mRenderer->getDeviceContext()->Map(compareBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); + ASSERT_TRUE(SUCCEEDED(hr)); + + GLfloat* compareData = static_cast<GLfloat*>(mappedResource.pData); + for (size_t i = 0; i < mExpectedExpandedData.size(); i++) + { + EXPECT_EQ(mExpectedExpandedData[i], compareData[i]); + } + + mRenderer->getDeviceContext()->Unmap(compareBuffer, 0); + SafeRelease(compareBuffer); + } + + void emulateAndCompare(rx::SourceIndexData *srcData) + { + auto bufferOrError = + mSourceBuffer->getEmulatedIndexedBuffer(srcData, mTranslatedAttribute, 0); + ASSERT_FALSE(bufferOrError.isError()); + ID3D11Buffer *emulatedBuffer = bufferOrError.getResult(); + ASSERT_TRUE(emulatedBuffer != nullptr); + compareContents(emulatedBuffer); + } + + protected: + rx::Buffer11 *mSourceBuffer; + rx::Renderer11 *mRenderer; + rx::TranslatedAttribute mTranslatedAttribute; + std::vector<GLfloat> mExpectedExpandedData; + std::vector<GLubyte> mubyteIndices; + std::vector<GLuint> muintIndices; + std::vector<GLushort> mushortIndices; + gl::BufferState mBufferState; +}; + +// This tests that a GL_UNSIGNED_BYTE indices list can be successfully expanded +// into a valid emulated indexed buffer. +TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLubyteIndices) +{ + rx::SourceIndexData srcData = {nullptr, mubyteIndices.data(), + static_cast<unsigned int>(mubyteIndices.size()), + GL_UNSIGNED_BYTE, false}; + emulateAndCompare(&srcData); +} + +// This tests that a GL_UNSIGNED_SHORT indices list can be successfully expanded +// into a valid emulated indexed buffer. +TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLushortIndices) +{ + rx::SourceIndexData srcData = {nullptr, mushortIndices.data(), + static_cast<unsigned int>(mushortIndices.size()), + GL_UNSIGNED_SHORT, false}; + emulateAndCompare(&srcData); +} + +// This tests that a GL_UNSIGNED_INT indices list can be successfully expanded +// into a valid emulated indexed buffer. +TEST_P(D3D11EmulatedIndexedBufferTest, TestNativeToExpandedUsingGLuintIndices) +{ + rx::SourceIndexData srcData = {nullptr, muintIndices.data(), + static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT, + false}; + emulateAndCompare(&srcData); +} + +// This tests verifies that a Buffer11 contents remain unchanged after calling getEmulatedIndexedBuffer +TEST_P(D3D11EmulatedIndexedBufferTest, TestSourceBufferRemainsUntouchedAfterExpandOperation) +{ + // Copy the original source buffer before any expand calls have been made + gl::BufferState cleanSourceState; + rx::Buffer11 *cleanSourceBuffer = new rx::Buffer11(cleanSourceState, mRenderer); + cleanSourceBuffer->copySubData(mSourceBuffer, 0, 0, mSourceBuffer->getSize()); + + // Do a basic exanded and compare test. + rx::SourceIndexData srcData = {nullptr, muintIndices.data(), + static_cast<unsigned int>(muintIndices.size()), GL_UNSIGNED_INT, + false}; + emulateAndCompare(&srcData); + + const uint8_t *sourceBufferMem = nullptr; + const uint8_t *cleanBufferMem = nullptr; + + gl::Error error = mSourceBuffer->getData(&sourceBufferMem); + ASSERT_FALSE(error.isError()); + + error = cleanSourceBuffer->getData(&cleanBufferMem); + ASSERT_FALSE(error.isError()); + + int result = memcmp(sourceBufferMem, cleanBufferMem, cleanSourceBuffer->getSize()); + ASSERT_EQ(result, 0); + + SafeDelete(cleanSourceBuffer); +} + +ANGLE_INSTANTIATE_TEST(D3D11EmulatedIndexedBufferTest, + ES2_D3D11()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp b/gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp new file mode 100755 index 000000000..e407d1190 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/D3D11FormatTablesTest.cpp @@ -0,0 +1,153 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// D3D11FormatTablesTest: +// Tests to validate our D3D11 support tables match hardware support. +// + +#include "libANGLE/angletypes.h" +#include "libANGLE/Context.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "test_utils/angle_test_instantiate.h" +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class D3D11FormatTablesTest : public ANGLETest +{ + +}; + +// This test enumerates all GL formats - for each, it queries the D3D support for +// using it as a texture, a render target, and sampling from it in the shader. It +// checks this against our speed-optimized baked tables, and validates they would +// give the same result. +// TODO(jmadill): Find out why in 9_3, some format queries return an error. +// The error seems to appear for formats that are not supported on 9_3. +TEST_P(D3D11FormatTablesTest, TestFormatSupport) +{ + ASSERT_EQ(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, GetParam().getRenderer()); + + // Hack the angle! + gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext()); + rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context); + rx::Renderer11 *renderer = context11->getRenderer(); + const auto &textureCaps = renderer->getNativeTextureCaps(); + + ID3D11Device *device = renderer->getDevice(); + + const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); + for (GLenum internalFormat : allFormats) + { + const rx::d3d11::Format &formatInfo = + rx::d3d11::Format::Get(internalFormat, renderer->getRenderer11DeviceCaps()); + const auto &textureInfo = textureCaps.get(internalFormat); + + // Bits for texturing + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); + + UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D; + if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0) + { + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE; + if (GetParam().majorVersion > 2) + { + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + } + } + + UINT texSupport = 0; + bool texSuccess = SUCCEEDED(device->CheckFormatSupport(formatInfo.texFormat, &texSupport)); + bool textureable = texSuccess && ((texSupport & texSupportMask) == texSupportMask); + EXPECT_EQ(textureable, textureInfo.texturable); + + // Bits for mipmap auto-gen. + bool expectedMipGen = texSuccess && ((texSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0); + auto featureLevel = renderer->getRenderer11DeviceCaps().featureLevel; + const auto &dxgiSupport = rx::d3d11::GetDXGISupport(formatInfo.texFormat, featureLevel); + bool actualMipGen = + ((dxgiSupport.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0); + EXPECT_EQ(0u, dxgiSupport.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN); + EXPECT_EQ(expectedMipGen, actualMipGen); + + // Bits for filtering + UINT filterSupport = 0; + bool filterSuccess = + SUCCEEDED(device->CheckFormatSupport(formatInfo.srvFormat, &filterSupport)); + bool filterable = filterSuccess && ((filterSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE) != 0); + EXPECT_EQ(filterable, textureInfo.filterable); + + // Bits for renderable + bool renderable = false; + UINT renderSupport = 0u; + DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN; + if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0) + { + renderFormat = formatInfo.dsvFormat; + bool depthSuccess = + SUCCEEDED(device->CheckFormatSupport(formatInfo.dsvFormat, &renderSupport)); + renderable = + depthSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL) != 0); + if (renderable) + { + EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.dsvFormat); + } + } + else + { + renderFormat = formatInfo.rtvFormat; + bool rtSuccess = + SUCCEEDED(device->CheckFormatSupport(formatInfo.rtvFormat, &renderSupport)); + renderable = rtSuccess && ((renderSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET) != 0); + if (renderable) + { + EXPECT_NE(DXGI_FORMAT_UNKNOWN, formatInfo.rtvFormat); + } + } + EXPECT_EQ(renderable, textureInfo.renderable); + if (!textureInfo.sampleCounts.empty()) + { + EXPECT_TRUE(renderable); + } + + // Multisample counts + if (renderable) + { + if ((renderSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET) != 0) + { + EXPECT_TRUE(!textureInfo.sampleCounts.empty()); + for (unsigned int sampleCount = 1; + sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2) + { + UINT qualityCount = 0; + bool sampleSuccess = SUCCEEDED(device->CheckMultisampleQualityLevels( + renderFormat, sampleCount, &qualityCount)); + GLuint expectedCount = (!sampleSuccess || qualityCount == 0) ? 0 : 1; + EXPECT_EQ(expectedCount, textureInfo.sampleCounts.count(sampleCount)); + } + } + else + { + EXPECT_TRUE(textureInfo.sampleCounts.empty()); + } + } + } +} + +ANGLE_INSTANTIATE_TEST(D3D11FormatTablesTest, + ES2_D3D11_FL9_3(), + ES2_D3D11_FL10_0(), + ES2_D3D11_FL10_1(), + ES2_D3D11_FL11_0()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp b/gfx/angle/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp new file mode 100755 index 000000000..7f182d2b1 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/D3D11InputLayoutCacheTest.cpp @@ -0,0 +1,126 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// D3D11InputLayoutCacheTest: +// Stress to to reproduce a bug where we weren't fluing the case correctly. +// + +#include <sstream> + +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "test_utils/ANGLETest.h" +#include "test_utils/angle_test_instantiate.h" + +using namespace angle; + +namespace +{ + +class D3D11InputLayoutCacheTest : public ANGLETest +{ + protected: + D3D11InputLayoutCacheTest() + { + setWindowWidth(64); + setWindowHeight(64); + setConfigRedBits(8); + setConfigAlphaBits(8); + } + + GLuint makeProgramWithAttribCount(unsigned int attribCount) + { + std::stringstream strstr; + + strstr << "attribute vec2 position;" << std::endl; + for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + strstr << "attribute float a" << attribIndex << ";" << std::endl; + } + strstr << "varying float v;" << std::endl + << "void main() {" << std::endl + << " v = 0.0;" << std::endl; + for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + strstr << " v += a" << attribIndex << ";" << std::endl; + } + strstr << " gl_Position = vec4(position, 0.0, 1.0);" << std::endl + << "}" << std::endl; + + const std::string basicFragmentShader = + "varying highp float v;\n" + "void main() {" + " gl_FragColor = vec4(v / 255.0, 0.0, 0.0, 1.0);\n" + "}\n"; + + return CompileProgram(strstr.str(), basicFragmentShader); + } +}; + +// Stress the cache by setting a small cache size and drawing with a bunch of shaders +// with different input signatures. +TEST_P(D3D11InputLayoutCacheTest, StressTest) +{ + // Hack the ANGLE! + gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext()); + rx::Context11 *context11 = rx::GetImplAs<rx::Context11>(context); + rx::Renderer11 *renderer11 = context11->getRenderer(); + rx::InputLayoutCache *inputLayoutCache = renderer11->getInputLayoutCache(); + + // Clamp the cache size to something tiny + inputLayoutCache->setCacheSize(4); + + GLint maxAttribs = 0; + context->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); + + // Reserve one attrib for position + unsigned int maxInputs = static_cast<unsigned int>(maxAttribs) - 2; + + std::vector<GLuint> programs; + for (unsigned int attribCount = 0; attribCount <= maxInputs; ++attribCount) + { + GLuint program = makeProgramWithAttribCount(attribCount); + ASSERT_NE(0u, program); + programs.push_back(program); + } + + // Iteratively do a simple drop operation, trying every attribute count from 0..MAX_ATTRIBS. + // This should thrash the cache. + for (unsigned int iterationCount = 0; iterationCount < 10; ++iterationCount) + { + ASSERT_GL_NO_ERROR(); + + for (unsigned int attribCount = 0; attribCount <= maxInputs; ++attribCount) + { + GLuint program = programs[attribCount]; + glUseProgram(program); + + for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + std::stringstream attribNameStr; + attribNameStr << "a" << attribIndex; + std::string attribName = attribNameStr.str(); + + GLint location = glGetAttribLocation(program, attribName.c_str()); + ASSERT_NE(-1, location); + glVertexAttrib1f(location, 1.0f); + glDisableVertexAttribArray(location); + } + + drawQuad(program, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, attribCount, 0, 0, 255u); + } + } + + for (GLuint program : programs) + { + glDeleteProgram(program); + } +} + +ANGLE_INSTANTIATE_TEST(D3D11InputLayoutCacheTest, ES2_D3D11()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/D3DImageFormatConversionTest.cpp b/gfx/angle/src/tests/gl_tests/D3DImageFormatConversionTest.cpp new file mode 100755 index 000000000..d6319d3f7 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/D3DImageFormatConversionTest.cpp @@ -0,0 +1,207 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// D3DImageFormatConversionTest: +// Basic tests to validate code relating to D3D Image format conversions. + +#include "test_utils/ANGLETest.h" + +#include "image_util/imageformats.h" + +using namespace angle; + +namespace +{ + +class D3DImageFormatConversionTest : public ANGLETest +{ + protected: + D3DImageFormatConversionTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = vec4(position.xy, 0.0, 1.0); + texcoord = (position.xy * 0.5) + 0.5; + } + ); + + const std::string fragmentShaderSource2D = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D); + mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex"); + } + + void TearDown() override + { + glDeleteProgram(m2DProgram); + + ANGLETest::TearDown(); + } + + // Uses ColorStructType::writeColor to populate initial data for a texture, pass it to glTexImage2D, then render with it. + // The resulting colors should match the colors passed into ::writeColor. + template <typename ColorStructType> + void runTest(GLenum tex2DFormat, GLenum tex2DType) + { + gl::ColorF srcColorF[4]; + ColorStructType pixels[4]; + + GLuint tex = 0; + GLuint fbo = 0; + glGenTextures(1, &tex); + glGenFramebuffers(1, &fbo); + EXPECT_GL_NO_ERROR(); + + srcColorF[0].red = 1.0f; srcColorF[0].green = 0.0f; srcColorF[0].blue = 0.0f; srcColorF[0].alpha = 1.0f; // Red + srcColorF[1].red = 0.0f; srcColorF[1].green = 1.0f; srcColorF[1].blue = 0.0f; srcColorF[1].alpha = 1.0f; // Green + srcColorF[2].red = 0.0f; srcColorF[2].green = 0.0f; srcColorF[2].blue = 1.0f; srcColorF[2].alpha = 1.0f; // Blue + srcColorF[3].red = 1.0f; srcColorF[3].green = 1.0f; srcColorF[3].blue = 0.0f; srcColorF[3].alpha = 1.0f; // Red + Green (Yellow) + + // Convert the ColorF into the pixels that will be fed to glTexImage2D + for (unsigned int i = 0; i < 4; i++) + { + ColorStructType::writeColor(&(pixels[i]), &(srcColorF[i])); + } + + // Generate the texture + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, tex2DFormat, 2, 2, 0, tex2DFormat, tex2DType, pixels); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + // Draw a quad using the texture + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(m2DProgram); + glUniform1i(mTexture2DUniformLocation, 0); + drawQuad(m2DProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + // Check that the pixel colors match srcColorF + EXPECT_PIXEL_EQ( 0, 0, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255); + EXPECT_PIXEL_EQ( 0, getWindowWidth() - 1, 0, 0, 255, 255); + EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255); + swapBuffers(); + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); + } + + GLuint m2DProgram; + GLint mTexture2DUniformLocation; +}; + +// Validation test for rx::R4G4B4A4's writeColor functions +TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR4G4B4A4) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + runTest<R4G4B4A4>(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); +} + +// Validation test for rx::R5G5B5A1's writeColor functions +TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G5B5A1) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + runTest<R5G5B5A1>(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); +} + +// Validation test for rx::R5G6B5's writeColor functions +TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR5G6B5) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + runTest<R5G6B5>(GL_RGB, GL_UNSIGNED_SHORT_5_6_5); +} + +// Validation test for rx::R8G8B8A8's writeColor functions +TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8A8) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + runTest<R8G8B8A8>(GL_RGBA, GL_UNSIGNED_BYTE); +} + +// Validation test for rx::R8G8B8's writeColor functions +TEST_P(D3DImageFormatConversionTest, WriteColorFunctionR8G8B8) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + runTest<R8G8B8>(GL_RGB, GL_UNSIGNED_BYTE); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +// Even though this test is only run on Windows (since it includes imageformats.h from the D3D renderer), we can still run the test +// against OpenGL. This is valuable, since it provides extra validation using a renderer that doesn't use imageformats.h itself. +ANGLE_INSTANTIATE_TEST(D3DImageFormatConversionTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/D3DTextureTest.cpp b/gfx/angle/src/tests/gl_tests/D3DTextureTest.cpp new file mode 100644 index 000000000..028b24a81 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/D3DTextureTest.cpp @@ -0,0 +1,326 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// D3DTextureTest: +// Tests of the EGL_ANGLE_d3d_texture_client_buffer extension + +#include "test_utils/ANGLETest.h" + +#include <d3d11.h> +#include <windows.h> + +#include "com_utils.h" + +namespace angle +{ + +class D3DTextureTest : public ANGLETest +{ + protected: + D3DTextureTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + // clang-format off + const std::string vsSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = position; + texcoord = (position.xy * 0.5) + 0.5; + texcoord.y = 1.0 - texcoord.y; + } + ); + + const std::string textureFSSource = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + // clang-format on + + mTextureProgram = CompileProgram(vsSource, textureFSSource); + ASSERT_NE(0u, mTextureProgram) << "shader compilation failed."; + + mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); + ASSERT_NE(-1, mTextureUniformLocation); + + mD3D11Module = LoadLibrary(TEXT("d3d11.dll")); + ASSERT_NE(nullptr, mD3D11Module); + + PFN_D3D11_CREATE_DEVICE createDeviceFunc = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>( + GetProcAddress(mD3D11Module, "D3D11CreateDevice")); + + EGLWindow *window = getEGLWindow(); + EGLDisplay display = window->getDisplay(); + if (eglDisplayExtensionEnabled(display, "EGL_EXT_device_query")) + { + PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT = + reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>( + eglGetProcAddress("eglQueryDisplayAttribEXT")); + PFNEGLQUERYDEVICEATTRIBEXTPROC eglQueryDeviceAttribEXT = + reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>( + eglGetProcAddress("eglQueryDeviceAttribEXT")); + + EGLDeviceEXT device = 0; + { + EGLAttrib result = 0; + EXPECT_EGL_TRUE(eglQueryDisplayAttribEXT(display, EGL_DEVICE_EXT, &result)); + device = reinterpret_cast<EGLDeviceEXT>(result); + } + + if (eglDeviceExtensionEnabled(device, "EGL_ANGLE_device_d3d")) + { + EGLAttrib result = 0; + if (eglQueryDeviceAttribEXT(device, EGL_D3D11_DEVICE_ANGLE, &result)) + { + mD3D11Device = reinterpret_cast<ID3D11Device *>(result); + mD3D11Device->AddRef(); + } + else if (eglQueryDeviceAttribEXT(device, EGL_D3D9_DEVICE_ANGLE, &result)) + { + mD3D9Device = reinterpret_cast<IDirect3DDevice9 *>(result); + mD3D9Device->AddRef(); + } + } + } + else + { + ASSERT_TRUE( + SUCCEEDED(createDeviceFunc(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, + 0, D3D11_SDK_VERSION, &mD3D11Device, nullptr, nullptr))); + } + } + + void TearDown() override + { + glDeleteProgram(mTextureProgram); + + if (mD3D11Device) + { + mD3D11Device->Release(); + mD3D11Device = nullptr; + } + + FreeLibrary(mD3D11Module); + mD3D11Module = nullptr; + + if (mD3D9Device) + { + mD3D9Device->Release(); + mD3D9Device = nullptr; + } + + ANGLETest::TearDown(); + } + + EGLSurface createPBuffer(size_t width, + size_t height, + EGLint eglTextureFormat, + EGLint eglTextureTarget) + { + EGLWindow *window = getEGLWindow(); + EGLDisplay display = window->getDisplay(); + EGLConfig config = window->getConfig(); + + EGLint attribs[] = { + EGL_TEXTURE_FORMAT, eglTextureFormat, EGL_TEXTURE_TARGET, + eglTextureTarget, EGL_NONE, EGL_NONE, + }; + + if (mD3D11Device) + { + ID3D11Texture2D *texture = nullptr; + CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_R8G8B8A8_UNORM, static_cast<UINT>(width), + static_cast<UINT>(height), 1, 1, + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET); + EXPECT_TRUE(SUCCEEDED(mD3D11Device->CreateTexture2D(&desc, nullptr, &texture))); + + EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE, + texture, config, attribs); + + texture->Release(); + + return pbuffer; + } + else if (mD3D9Device) + { + IDirect3DTexture9 *texture = nullptr; + EXPECT_TRUE(SUCCEEDED(mD3D9Device->CreateTexture( + static_cast<UINT>(width), static_cast<UINT>(height), 1, D3DUSAGE_RENDERTARGET, + D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, nullptr))); + + EGLSurface pbuffer = eglCreatePbufferFromClientBuffer(display, EGL_D3D_TEXTURE_ANGLE, + texture, config, attribs); + + texture->Release(); + + return pbuffer; + } + else + { + return EGL_NO_SURFACE; + } + } + + bool valid() const + { + EGLWindow *window = getEGLWindow(); + EGLDisplay display = window->getDisplay(); + if (!eglDisplayExtensionEnabled(display, "EGL_ANGLE_d3d_texture_client_buffer")) + { + std::cout << "Test skipped due to missing EGL_ANGLE_d3d_texture_client_buffer" + << std::endl; + return false; + } + + if (!mD3D11Device && !mD3D9Device) + { + std::cout << "Test skipped due to no D3D devices being available." << std::endl; + return false; + } + + if (IsWindows() && IsAMD() && IsOpenGL()) + { + std::cout << "Test skipped on Windows AMD OpenGL." << std::endl; + return false; + } + + if (IsWindows() && IsIntel() && IsOpenGL()) + { + std::cout << "Test skipped on Windows Intel OpenGL." << std::endl; + return false; + } + return true; + } + + GLuint mTextureProgram; + GLint mTextureUniformLocation; + + HMODULE mD3D11Module = nullptr; + ID3D11Device *mD3D11Device = nullptr; + + IDirect3DDevice9 *mD3D9Device = nullptr; +}; + +// Test creating a pbuffer from a d3d surface and clearing it +TEST_P(D3DTextureTest, Clear) +{ + if (!valid()) + { + return; + } + + EGLWindow *window = getEGLWindow(); + EGLDisplay display = window->getDisplay(); + + const size_t bufferSize = 32; + + EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE); + ASSERT_EGL_SUCCESS(); + ASSERT_NE(pbuffer, EGL_NO_SURFACE); + + // Apply the Pbuffer and clear it to purple and verify + eglMakeCurrent(display, pbuffer, pbuffer, window->getContext()); + ASSERT_EGL_SUCCESS(); + + glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize)); + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0, + 255, 255); + + eglDestroySurface(display, pbuffer); +} + +// Test creating a pbuffer from a d3d surface and binding it to a texture +TEST_P(D3DTextureTest, BindTexImage) +{ + if (!valid()) + { + return; + } + + EGLWindow *window = getEGLWindow(); + + const size_t bufferSize = 32; + + EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D); + ASSERT_EGL_SUCCESS(); + ASSERT_NE(pbuffer, EGL_NO_SURFACE); + + // Apply the Pbuffer and clear it to purple + eglMakeCurrent(window->getDisplay(), pbuffer, pbuffer, window->getContext()); + ASSERT_EGL_SUCCESS(); + + glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize)); + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0, + 255, 255); + + // Apply the window surface + eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), + window->getContext()); + + // Create a texture and bind the Pbuffer to it + GLuint texture = 0; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + EXPECT_GL_NO_ERROR(); + + eglBindTexImage(window->getDisplay(), pbuffer, EGL_BACK_BUFFER); + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + ASSERT_EGL_SUCCESS(); + + // Draw a quad and verify that it is purple + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + // Unbind the texture + eglReleaseTexImage(window->getDisplay(), pbuffer, EGL_BACK_BUFFER); + ASSERT_EGL_SUCCESS(); + + // Verify that purple was drawn + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255); + + glDeleteTextures(1, &texture); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(D3DTextureTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/DXT1CompressedTextureTest.cpp b/gfx/angle/src/tests/gl_tests/DXT1CompressedTextureTest.cpp new file mode 100755 index 000000000..34b6b9ec3 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DXT1CompressedTextureTest.cpp @@ -0,0 +1,326 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include "media/pixel.inl" + +using namespace angle; + +class DXT1CompressedTextureTest : public ANGLETest +{ + protected: + DXT1CompressedTextureTest() + { + setWindowWidth(512); + setWindowHeight(512); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vsSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = position; + texcoord = (position.xy * 0.5) + 0.5; + texcoord.y = 1.0 - texcoord.y; + } + ); + + const std::string textureFSSource = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + mTextureProgram = CompileProgram(vsSource, textureFSSource); + if (mTextureProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); + + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteProgram(mTextureProgram); + + ANGLETest::TearDown(); + } + + GLuint mTextureProgram; + GLint mTextureUniformLocation; +}; + +TEST_P(DXT1CompressedTextureTest, CompressedTexImage) +{ + if (!extensionEnabled("GL_EXT_texture_compression_dxt1")) + { + std::cout << "Test skipped because GL_EXT_texture_compression_dxt1 is not available." << std::endl; + return; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, 0, pixel_0_size, pixel_0_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_width, pixel_1_height, 0, pixel_1_size, pixel_1_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_width, pixel_2_height, 0, pixel_2_size, pixel_2_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 3, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_width, pixel_3_height, 0, pixel_3_size, pixel_3_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_width, pixel_4_height, 0, pixel_4_size, pixel_4_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 5, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_width, pixel_5_height, 0, pixel_5_size, pixel_5_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 6, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_width, pixel_6_height, 0, pixel_6_size, pixel_6_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 7, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_width, pixel_7_height, 0, pixel_7_size, pixel_7_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_width, pixel_8_height, 0, pixel_8_size, pixel_8_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 9, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_width, pixel_9_height, 0, pixel_9_size, pixel_9_data); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glDeleteTextures(1, &texture); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(DXT1CompressedTextureTest, CompressedTexStorage) +{ + if (!extensionEnabled("GL_EXT_texture_compression_dxt1")) + { + std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1" << std::endl; + return; + } + + if (getClientMajorVersion() < 3 && + (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8"))) + { + std::cout << "Test skipped due to missing ES3 or GL_EXT_texture_storage or GL_OES_rgb8_rgba8" << std::endl; + return; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (getClientMajorVersion() < 3) + { + glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height); + } + else + { + glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height); + } + EXPECT_GL_NO_ERROR(); + + glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, pixel_0_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, pixel_1_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, pixel_2_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, pixel_3_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, pixel_4_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, pixel_5_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, pixel_6_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, pixel_7_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, pixel_8_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, pixel_9_data); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glDeleteTextures(1, &texture); + + EXPECT_GL_NO_ERROR(); +} + +class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest { }; + +class DXT1CompressedTextureTestD3D11 : public DXT1CompressedTextureTest { }; + +TEST_P(DXT1CompressedTextureTestES3, PBOCompressedTexImage) +{ + if (!extensionEnabled("GL_EXT_texture_compression_dxt1")) + { + std::cout << "Test skipped because GL_EXT_texture_compression_dxt1 is not available." + << std::endl; + return; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, NULL, GL_STREAM_DRAW); + EXPECT_GL_NO_ERROR(); + + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, 0, pixel_0_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_width, pixel_1_height, 0, pixel_1_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_width, pixel_2_height, 0, pixel_2_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 3, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_width, pixel_3_height, 0, pixel_3_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_width, pixel_4_height, 0, pixel_4_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 5, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_width, pixel_5_height, 0, pixel_5_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 6, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_width, pixel_6_height, 0, pixel_6_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 7, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_width, pixel_7_height, 0, pixel_7_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_width, pixel_8_height, 0, pixel_8_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data); + glCompressedTexImage2D(GL_TEXTURE_2D, 9, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_width, pixel_9_height, 0, pixel_9_size, NULL); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glDeleteTextures(1, &buffer); + glDeleteTextures(1, &texture); + + EXPECT_GL_NO_ERROR(); +} + + +TEST_P(DXT1CompressedTextureTestD3D11, PBOCompressedTexStorage) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_compression_dxt1")) + { + return; + } + + if (getClientMajorVersion() < 3 && + (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8"))) + { + return; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (getClientMajorVersion() < 3) + { + glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height); + } + else + { + glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height); + } + EXPECT_GL_NO_ERROR(); + + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, NULL, GL_STREAM_DRAW); + EXPECT_GL_NO_ERROR(); + + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, NULL); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data); + glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, NULL); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glDeleteTextures(1, &texture); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +ANGLE_INSTANTIATE_TEST(DXT1CompressedTextureTestD3D11, ES2_D3D11(), ES3_D3D11(), ES2_D3D11_FL9_3()); diff --git a/gfx/angle/src/tests/gl_tests/DebugMarkerTest.cpp b/gfx/angle/src/tests/gl_tests/DebugMarkerTest.cpp new file mode 100755 index 000000000..6bd4a4322 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DebugMarkerTest.cpp @@ -0,0 +1,71 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DebugMarkerTest: +// Basic tests to ensure EXT_debug_marker entry points work. + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class DebugMarkerTest : public ANGLETest +{ + protected: + DebugMarkerTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } +}; + +// Simple test to ensure the various EXT_debug_marker entry points don't crash. +// The debug markers can be validated by capturing this test under PIX/Graphics Diagnostics. +TEST_P(DebugMarkerTest, BasicValidation) +{ + if (!extensionEnabled("GL_EXT_debug_marker")) + { + std::cout << "Test skipped due to missing GL_EXT_debug_marker" << std::endl; + return; + } + + std::string eventMarkerCaption = "Test event marker caption"; + std::string groupMarkerCaption = "Test group marker caption"; + + glPushGroupMarkerEXT(static_cast<GLsizei>(groupMarkerCaption.length()), + groupMarkerCaption.c_str()); + + // Do some basic operations between calls to extension entry points + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glInsertEventMarkerEXT(static_cast<GLsizei>(eventMarkerCaption.length()), + eventMarkerCaption.c_str()); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glPushGroupMarkerEXT(0, NULL); + glClearColor(0.0f, 1.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glPopGroupMarkerEXT(); + glClearColor(0.0f, 0.0f, 1.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glPopGroupMarkerEXT(); + + ASSERT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(DebugMarkerTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/DebugTest.cpp b/gfx/angle/src/tests/gl_tests/DebugTest.cpp new file mode 100755 index 000000000..fc79c5f64 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DebugTest.cpp @@ -0,0 +1,451 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// DebugTest.cpp : Tests of the GL_KHR_debug extension + +#include "test_utils/ANGLETest.h" + +namespace angle +{ + +class DebugTest : public ANGLETest +{ + protected: + DebugTest() : mDebugExtensionAvailable(false) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + setDebugEnabled(true); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + mDebugExtensionAvailable = extensionEnabled("GL_KHR_debug"); + if (mDebugExtensionAvailable) + { + glEnable(GL_DEBUG_OUTPUT); + } + } + + bool mDebugExtensionAvailable; +}; + +struct Message +{ + GLenum source; + GLenum type; + GLuint id; + GLenum severity; + std::string message; + const void *userParam; +}; + +static void GL_APIENTRY Callback(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *message, + const void *userParam) +{ + Message m{source, type, id, severity, std::string(message, length), userParam}; + std::vector<Message> *messages = + static_cast<std::vector<Message> *>(const_cast<void *>(userParam)); + messages->push_back(m); +} + +// Test that all ANGLE back-ends have GL_KHR_debug enabled +TEST_P(DebugTest, Enabled) +{ + ASSERT_TRUE(mDebugExtensionAvailable); +} + +// Test that when debug output is disabled, no message are outputted +TEST_P(DebugTest, DisabledOutput) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + glDisable(GL_DEBUG_OUTPUT); + + glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 1, + GL_DEBUG_SEVERITY_NOTIFICATION, -1, "discarded"); + + GLint numMessages = 0; + glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages); + ASSERT_EQ(0, numMessages); + + std::vector<Message> messages; + glDebugMessageCallbackKHR(Callback, &messages); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + + ASSERT_EQ(0u, messages.size()); +} + +// Test a basic flow of inserting a message and reading it back +TEST_P(DebugTest, InsertMessage) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + const GLenum source = GL_DEBUG_SOURCE_APPLICATION; + const GLenum type = GL_DEBUG_TYPE_OTHER; + const GLuint id = 1; + const GLenum severity = GL_DEBUG_SEVERITY_NOTIFICATION; + const std::string message = "Message"; + + glDebugMessageInsertKHR(source, type, id, severity, -1, message.c_str()); + + GLint numMessages = 0; + glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages); + ASSERT_EQ(1, numMessages); + + GLint messageLength = 0; + glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &messageLength); + EXPECT_EQ(static_cast<GLint>(message.length()), messageLength); + + GLenum sourceBuf = 0; + GLenum typeBuf = 0; + GLenum idBuf = 0; + GLenum severityBuf = 0; + GLsizei lengthBuf = 0; + std::vector<char> messageBuf(messageLength + 1); + GLuint ret = + glGetDebugMessageLogKHR(1, static_cast<GLsizei>(messageBuf.size()), &sourceBuf, &typeBuf, + &idBuf, &severityBuf, &lengthBuf, messageBuf.data()); + EXPECT_EQ(1u, ret); + EXPECT_EQ(source, sourceBuf); + EXPECT_EQ(type, typeBuf); + EXPECT_EQ(id, idBuf); + EXPECT_EQ(severity, severityBuf); + EXPECT_EQ(lengthBuf, messageLength); + EXPECT_STREQ(message.c_str(), messageBuf.data()); + + glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages); + EXPECT_EQ(0, numMessages); + + ASSERT_GL_NO_ERROR(); +} + +// Test inserting multiple messages +TEST_P(DebugTest, InsertMessageMultiple) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + const GLenum source = GL_DEBUG_SOURCE_APPLICATION; + const GLenum type = GL_DEBUG_TYPE_OTHER; + const GLuint startID = 1; + const GLenum severity = GL_DEBUG_SEVERITY_NOTIFICATION; + const char messageRepeatChar = 'm'; + const size_t messageCount = 32; + + for (size_t i = 0; i < messageCount; i++) + { + std::string message(i + 1, messageRepeatChar); + glDebugMessageInsertKHR(source, type, startID + static_cast<GLuint>(i), severity, -1, + message.c_str()); + } + + GLint numMessages = 0; + glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages); + ASSERT_EQ(static_cast<GLint>(messageCount), numMessages); + + for (size_t i = 0; i < messageCount; i++) + { + glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages); + EXPECT_EQ(static_cast<GLint>(messageCount - i), numMessages); + + std::string expectedMessage(i + 1, messageRepeatChar); + + GLint messageLength = 0; + glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH, &messageLength); + EXPECT_EQ(static_cast<GLint>(expectedMessage.length()), messageLength); + + GLenum sourceBuf = 0; + GLenum typeBuf = 0; + GLenum idBuf = 0; + GLenum severityBuf = 0; + GLsizei lengthBuf = 0; + std::vector<char> messageBuf(messageLength + 1); + GLuint ret = + glGetDebugMessageLogKHR(1, static_cast<GLsizei>(messageBuf.size()), &sourceBuf, + &typeBuf, &idBuf, &severityBuf, &lengthBuf, messageBuf.data()); + EXPECT_EQ(1u, ret); + EXPECT_EQ(source, sourceBuf); + EXPECT_EQ(type, typeBuf); + EXPECT_EQ(startID + i, idBuf); + EXPECT_EQ(severity, severityBuf); + EXPECT_EQ(lengthBuf, messageLength); + EXPECT_STREQ(expectedMessage.c_str(), messageBuf.data()); + } + + glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages); + EXPECT_EQ(0, numMessages); + + ASSERT_GL_NO_ERROR(); +} + +// Test using a debug callback +TEST_P(DebugTest, DebugCallback) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + std::vector<Message> messages; + + glDebugMessageCallbackKHR(Callback, &messages); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + + const GLenum source = GL_DEBUG_SOURCE_APPLICATION; + const GLenum type = GL_DEBUG_TYPE_OTHER; + const GLuint id = 1; + const GLenum severity = GL_DEBUG_SEVERITY_NOTIFICATION; + const std::string message = "Message"; + + glDebugMessageInsertKHR(source, type, id, severity, -1, message.c_str()); + + GLint numMessages = 0; + glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES, &numMessages); + EXPECT_EQ(0, numMessages); + + ASSERT_EQ(1u, messages.size()); + + const Message &m = messages.front(); + EXPECT_EQ(source, m.source); + EXPECT_EQ(type, m.type); + EXPECT_EQ(id, m.id); + EXPECT_EQ(severity, m.severity); + EXPECT_EQ(message, m.message); + + ASSERT_GL_NO_ERROR(); +} + +// Test the glGetPointervKHR entry point +TEST_P(DebugTest, GetPointer) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + std::vector<Message> messages; + + glDebugMessageCallbackKHR(Callback, &messages); + + void *callback = nullptr; + glGetPointervKHR(GL_DEBUG_CALLBACK_FUNCTION, &callback); + EXPECT_EQ(reinterpret_cast<void *>(Callback), callback); + + void *userData = nullptr; + glGetPointervKHR(GL_DEBUG_CALLBACK_USER_PARAM, &userData); + EXPECT_EQ(static_cast<void *>(&messages), userData); +} + +// Test usage of message control. Example taken from GL_KHR_debug spec. +TEST_P(DebugTest, MessageControl1) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + std::vector<Message> messages; + + glDebugMessageCallbackKHR(Callback, &messages); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + + // Setup of the default active debug group: Filter everything in + glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_TRUE); + + // Generate a debug marker debug output message + glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100, + GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 1"); + + // Push debug group 1 + glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Message 2"); + + // Setup of the debug group 1: Filter everything out + glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE); + + // This message won't appear in the debug output log of + glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100, + GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 3"); + + // Pop debug group 1, restore the volume control of the default debug group. + glPopDebugGroupKHR(); + + // Generate a debug marker debug output message + glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_MARKER, 100, + GL_DEBUG_SEVERITY_NOTIFICATION, -1, "Message 5"); + + // Expected debug output from the GL implementation + // Message 1 + // Message 2 + // Message 2 + // Message 5 + EXPECT_EQ(4u, messages.size()); + EXPECT_STREQ(messages[0].message.c_str(), "Message 1"); + EXPECT_STREQ(messages[1].message.c_str(), "Message 2"); + EXPECT_STREQ(messages[2].message.c_str(), "Message 2"); + EXPECT_STREQ(messages[3].message.c_str(), "Message 5"); + + ASSERT_GL_NO_ERROR(); +} + +// Test usage of message control. Example taken from GL_KHR_debug spec. +TEST_P(DebugTest, MessageControl2) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + std::vector<Message> messages; + + glDebugMessageCallbackKHR(Callback, &messages); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + + // Setup the control of de debug output for the default debug group + glDebugMessageControlKHR(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE); + glDebugMessageControlKHR(GL_DEBUG_SOURCE_THIRD_PARTY, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, + GL_FALSE); + std::vector<GLuint> ids0 = {1234, 2345, 3456, 4567}; + glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, + static_cast<GLuint>(ids0.size()), ids0.data(), GL_FALSE); + glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, GL_DONT_CARE, + static_cast<GLuint>(ids0.size()), ids0.data(), GL_FALSE); + + // Push debug group 1 + // Inherit of the default debug group debug output volume control + // Filtered out by glDebugMessageControl + glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 1, -1, "Message 1"); + + // In this section of the code, we are interested in performances. + glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, GL_DONT_CARE, + 0, NULL, GL_TRUE); + // But we already identify that some messages are not really useful for us. + std::vector<GLuint> ids1 = {5678, 6789}; + glDebugMessageControlKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, + static_cast<GLuint>(ids1.size()), ids1.data(), GL_FALSE); + + glDebugMessageInsertKHR(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PERFORMANCE, 1357, + GL_DEBUG_SEVERITY_MEDIUM, -1, "Message 2"); + glDebugMessageInsertKHR(GL_DEBUG_SOURCE_THIRD_PARTY, // We still filter out these messages. + GL_DEBUG_TYPE_OTHER, 3579, GL_DEBUG_SEVERITY_MEDIUM, -1, "Message 3"); + + glPopDebugGroupKHR(); + + // Expected debug output from the GL implementation + // Message 2 + EXPECT_EQ(1u, messages.size()); + EXPECT_STREQ(messages[0].message.c_str(), "Message 2"); + + ASSERT_GL_NO_ERROR(); +} + +// Test basic usage of setting and getting labels +TEST_P(DebugTest, ObjectLabels) +{ + if (!mDebugExtensionAvailable) + { + std::cout << "Test skipped because GL_KHR_debug is not available." << std::endl; + return; + } + + GLuint renderbuffer = 0; + glGenRenderbuffers(1, &renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + + const std::string &label = "renderbuffer"; + glObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, -1, label.c_str()); + + std::vector<char> labelBuf(label.length() + 1); + GLsizei labelLengthBuf = 0; + glGetObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, static_cast<GLsizei>(labelBuf.size()), + &labelLengthBuf, labelBuf.data()); + + EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf); + EXPECT_STREQ(label.c_str(), labelBuf.data()); + + ASSERT_GL_NO_ERROR(); + + glDeleteRenderbuffers(1, &renderbuffer); + + glObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, -1, label.c_str()); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glGetObjectLabelKHR(GL_RENDERBUFFER, renderbuffer, static_cast<GLsizei>(labelBuf.size()), + &labelLengthBuf, labelBuf.data()); + EXPECT_GL_ERROR(GL_INVALID_VALUE); +} + +// Test basic usage of setting and getting labels +TEST_P(DebugTest, ObjectPtrLabels) +{ + if (!mDebugExtensionAvailable || getClientMajorVersion() < 3) + { + std::cout << "Test skipped because GL_KHR_debug or ES3 is not available." << std::endl; + return; + } + + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + const std::string &label = "sync"; + glObjectPtrLabelKHR(sync, -1, label.c_str()); + + std::vector<char> labelBuf(label.length() + 1); + GLsizei labelLengthBuf = 0; + glGetObjectPtrLabelKHR(sync, static_cast<GLsizei>(labelBuf.size()), &labelLengthBuf, + labelBuf.data()); + + EXPECT_EQ(static_cast<GLsizei>(label.length()), labelLengthBuf); + EXPECT_STREQ(label.c_str(), labelBuf.data()); + + ASSERT_GL_NO_ERROR(); + + glDeleteSync(sync); + + glObjectPtrLabelKHR(sync, -1, label.c_str()); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glGetObjectPtrLabelKHR(sync, static_cast<GLsizei>(labelBuf.size()), &labelLengthBuf, + labelBuf.data()); + EXPECT_GL_ERROR(GL_INVALID_VALUE); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(DebugTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL()); + +} // namespace angle diff --git a/gfx/angle/src/tests/gl_tests/DepthStencilFormatsTest.cpp b/gfx/angle/src/tests/gl_tests/DepthStencilFormatsTest.cpp new file mode 100755 index 000000000..f62a16578 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DepthStencilFormatsTest.cpp @@ -0,0 +1,192 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class DepthStencilFormatsTestBase : public ANGLETest +{ + protected: + DepthStencilFormatsTestBase() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + bool checkTexImageFormatSupport(GLenum format, GLenum type) + { + EXPECT_GL_NO_ERROR(); + + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, NULL); + glDeleteTextures(1, &tex); + + return (glGetError() == GL_NO_ERROR); + } + + bool checkTexStorageFormatSupport(GLenum internalFormat) + { + EXPECT_GL_NO_ERROR(); + + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1); + glDeleteTextures(1, &tex); + + return (glGetError() == GL_NO_ERROR); + } + + bool checkRenderbufferFormatSupport(GLenum internalFormat) + { + EXPECT_GL_NO_ERROR(); + + GLuint rb = 0; + glGenRenderbuffers(1, &rb); + glBindRenderbuffer(GL_RENDERBUFFER, rb); + glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1); + glDeleteRenderbuffers(1, &rb); + + return (glGetError() == GL_NO_ERROR); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = position; + texcoord = (position.xy * 0.5) + 0.5; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mProgram, "tex"); + EXPECT_NE(-1, mTextureUniformLocation); + + glGenTextures(1, &mTexture); + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteProgram(mProgram); + glDeleteTextures(1, &mTexture); + + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLuint mTexture; + GLint mTextureUniformLocation; +}; + +class DepthStencilFormatsTest : public DepthStencilFormatsTestBase +{}; + +class DepthStencilFormatsTestES3 : public DepthStencilFormatsTestBase +{}; + +TEST_P(DepthStencilFormatsTest, DepthTexture) +{ + bool shouldHaveTextureSupport = extensionEnabled("GL_ANGLE_depth_texture"); + EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT)); + EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT)); + + if (extensionEnabled("GL_EXT_texture_storage")) + { + EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16)); + EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES)); + } +} + +TEST_P(DepthStencilFormatsTest, PackedDepthStencil) +{ + // Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present. + // Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not present. + + bool shouldHaveRenderbufferSupport = extensionEnabled("GL_OES_packed_depth_stencil"); + EXPECT_EQ(shouldHaveRenderbufferSupport, checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES)); + + bool shouldHaveTextureSupport = extensionEnabled("GL_OES_packed_depth_stencil") && + extensionEnabled("GL_ANGLE_depth_texture"); + EXPECT_EQ(shouldHaveTextureSupport, checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES)); + + if (extensionEnabled("GL_EXT_texture_storage")) + { + EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES)); + } +} + +TEST_P(DepthStencilFormatsTestES3, DrawWithDepthStencil) +{ + GLushort data[16]; + for (unsigned int i = 0; i < 16; i++) + { + data[i] = std::numeric_limits<GLushort>::max(); + } + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 4, 4); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glUseProgram(mProgram); + glUniform1i(mTextureUniformLocation, 0); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + + GLubyte pixel[4]; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); + + // Only require the red and alpha channels have the correct values, the depth texture extensions + // leave the green and blue channels undefined + ASSERT_NEAR(255, pixel[0], 2.0); + ASSERT_EQ(255, pixel[3]); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(DepthStencilFormatsTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(DepthStencilFormatsTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/DifferentStencilMasksTest.cpp b/gfx/angle/src/tests/gl_tests/DifferentStencilMasksTest.cpp new file mode 100755 index 000000000..7e1cd8a19 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DifferentStencilMasksTest.cpp @@ -0,0 +1,178 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DifferentStencilMasksTest: +// Tests the equality between stencilWriteMask and stencilBackWriteMask. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ +class DifferentStencilMasksTest : public ANGLETest +{ + protected: + DifferentStencilMasksTest() : mProgram(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + setConfigStencilBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + + void main() + { + gl_Position = position; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + + void main() + { + gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + + glEnable(GL_STENCIL_TEST); + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDisable(GL_STENCIL_TEST); + if (mProgram != 0) + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram; +}; + +// Tests that effectively same front and back masks are legal. +TEST_P(DifferentStencilMasksTest, DrawWithSameEffectiveMask) +{ + // 0x00ff and 0x01ff are effectively 0x00ff by being masked by the current stencil bits, 8. + glStencilMaskSeparate(GL_FRONT, 0x00ff); + glStencilMaskSeparate(GL_BACK, 0x01ff); + + glUseProgram(mProgram); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); +} + +// Tests that effectively different front and back masks are illegal. +TEST_P(DifferentStencilMasksTest, DrawWithDifferentMask) +{ + glStencilMaskSeparate(GL_FRONT, 0x0001); + glStencilMaskSeparate(GL_BACK, 0x0002); + + glUseProgram(mProgram); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +class DifferentStencilMasksWithoutStencilBufferTest : public ANGLETest +{ + protected: + DifferentStencilMasksWithoutStencilBufferTest() : mProgram(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(0); + setConfigStencilBits(0); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + + void main() + { + gl_Position = position; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + + void main() + { + gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + + glEnable(GL_STENCIL_TEST); + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDisable(GL_STENCIL_TEST); + if (mProgram != 0) + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram; +}; + +// Tests that effectively different front and back masks, without stencil bits, are legal. +TEST_P(DifferentStencilMasksWithoutStencilBufferTest, DrawWithDifferentMask) +{ + glStencilMaskSeparate(GL_FRONT, 0x0001); + glStencilMaskSeparate(GL_BACK, 0x0002); + + glUseProgram(mProgram); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(DifferentStencilMasksTest, ES2_D3D9(), ES2_D3D11(), ES3_D3D11(), ES2_OPENGL(), ES3_OPENGL()); +ANGLE_INSTANTIATE_TEST(DifferentStencilMasksWithoutStencilBufferTest, ES2_D3D9(), ES2_D3D11(), ES3_D3D11(), ES2_OPENGL(), ES3_OPENGL()); +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/DiscardFramebufferEXTTest.cpp b/gfx/angle/src/tests/gl_tests/DiscardFramebufferEXTTest.cpp new file mode 100755 index 000000000..1e09ed120 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DiscardFramebufferEXTTest.cpp @@ -0,0 +1,143 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class DiscardFramebufferEXTTest : public ANGLETest +{ +protected: + DiscardFramebufferEXTTest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + setConfigStencilBits(8); + } +}; + +TEST_P(DiscardFramebufferEXTTest, ExtensionEnabled) +{ + EGLPlatformParameters platform = GetParam().eglParameters; + + if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + EXPECT_TRUE(extensionEnabled("EXT_discard_framebuffer")); + } + else + { + // Other platforms don't currently implement this extension + EXPECT_FALSE(extensionEnabled("EXT_discard_framebuffer")); + } +} + +TEST_P(DiscardFramebufferEXTTest, DefaultFramebuffer) +{ + if (!extensionEnabled("EXT_discard_framebuffer")) + { + std::cout << "Test skipped because EXT_discard_framebuffer is not available." << std::endl; + return; + } + + // These should succeed on the default framebuffer + const GLenum discards1[] = { GL_COLOR_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards1); + EXPECT_GL_NO_ERROR(); + + const GLenum discards2[] = { GL_DEPTH_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards2); + EXPECT_GL_NO_ERROR(); + + const GLenum discards3[] = { GL_STENCIL_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards3); + EXPECT_GL_NO_ERROR(); + + const GLenum discards4[] = { GL_STENCIL_EXT, GL_COLOR_EXT, GL_DEPTH_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards4); + EXPECT_GL_NO_ERROR(); + + // These should fail on the default framebuffer + const GLenum discards5[] = { GL_COLOR_ATTACHMENT0 }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards5); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + const GLenum discards6[] = { GL_DEPTH_ATTACHMENT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards6); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + const GLenum discards7[] = { GL_STENCIL_ATTACHMENT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards7); + EXPECT_GL_ERROR(GL_INVALID_ENUM); +} + +TEST_P(DiscardFramebufferEXTTest, NonDefaultFramebuffer) +{ + if (!extensionEnabled("EXT_discard_framebuffer")) + { + std::cout << "Test skipped because EXT_discard_framebuffer is not available." << std::endl; + return; + } + + GLuint tex2D; + GLuint framebuffer; + + // Create a basic off-screen framebuffer + // Don't create a depth/stencil texture, to ensure that also works correctly + glGenTextures(1, &tex2D); + glGenFramebuffers(1, &framebuffer); + glBindTexture(GL_TEXTURE_2D, tex2D); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, 0); + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // These should fail on the non-default framebuffer + const GLenum discards1[] = { GL_COLOR_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards1); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + const GLenum discards2[] = { GL_DEPTH_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards2); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + const GLenum discards3[] = { GL_STENCIL_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards3); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + const GLenum discards4[] = { GL_STENCIL_EXT, GL_COLOR_EXT, GL_DEPTH_EXT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, discards4); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // These should succeed on the non-default framebuffer + const GLenum discards5[] = { GL_COLOR_ATTACHMENT0 }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards5); + EXPECT_GL_NO_ERROR(); + + const GLenum discards6[] = { GL_DEPTH_ATTACHMENT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards6); + EXPECT_GL_NO_ERROR(); + + const GLenum discards7[] = { GL_STENCIL_ATTACHMENT }; + glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards7); + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(DiscardFramebufferEXTTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/DrawBuffersTest.cpp b/gfx/angle/src/tests/gl_tests/DrawBuffersTest.cpp new file mode 100755 index 000000000..daf09e93c --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DrawBuffersTest.cpp @@ -0,0 +1,517 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +using namespace angle; + +class DrawBuffersTest : public ANGLETest +{ + protected: + DrawBuffersTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + mMaxDrawBuffers = 0; + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + // This test seems to fail on an nVidia machine when the window is hidden + SetWindowVisible(true); + + glGenFramebuffers(1, &mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + + glGenTextures(4, mTextures); + + for (size_t texIndex = 0; texIndex < ArraySize(mTextures); texIndex++) + { + glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + } + + GLfloat data[] = + { + -1.0f, 1.0f, + -1.0f, -2.0f, + 2.0f, 1.0f + }; + + glGenBuffers(1, &mBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6, data, GL_STATIC_DRAW); + + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &mMaxDrawBuffers); + + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteFramebuffers(1, &mFBO); + glDeleteTextures(4, mTextures); + glDeleteBuffers(1, &mBuffer); + + ANGLETest::TearDown(); + } + + void setupMRTProgramESSL3(bool bufferEnabled[8], GLuint *programOut) + { + const std::string vertexShaderSource = + "#version 300 es\n" + "in vec4 position;\n" + "void main() {\n" + " gl_Position = position;\n" + "}\n"; + + std::stringstream strstr; + + strstr << "#version 300 es\n" + "precision highp float;\n"; + + for (unsigned int index = 0; index < 8; index++) + { + if (bufferEnabled[index]) + { + strstr << "layout(location = " << index << ") " + "out vec4 value" << index << ";\n"; + } + } + + strstr << "void main()\n" + "{\n"; + + for (unsigned int index = 0; index < 8; index++) + { + if (bufferEnabled[index]) + { + unsigned int r = (index + 1) & 1; + unsigned int g = (index + 1) & 2; + unsigned int b = (index + 1) & 4; + + strstr << " value" << index << " = vec4(" + << r << ".0, " << g << ".0, " + << b << ".0, 1.0);\n"; + } + } + + strstr << "}\n"; + + *programOut = CompileProgram(vertexShaderSource, strstr.str()); + if (*programOut == 0) + { + FAIL() << "shader compilation failed."; + } + + glUseProgram(*programOut); + + GLint location = glGetAttribLocation(*programOut, "position"); + ASSERT_NE(location, -1); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 8, NULL); + glEnableVertexAttribArray(location); + } + + void setupMRTProgramESSL1(bool bufferEnabled[8], GLuint *programOut) + { + const std::string vertexShaderSource = + "attribute vec4 position;\n" + "void main() {\n" + " gl_Position = position;\n" + "}\n"; + + std::stringstream strstr; + + strstr << "#extension GL_EXT_draw_buffers : enable\n" + "precision highp float;\n" + "void main()\n" + "{\n"; + + for (unsigned int index = 0; index < 8; index++) + { + if (bufferEnabled[index]) + { + unsigned int r = (index + 1) & 1; + unsigned int g = (index + 1) & 2; + unsigned int b = (index + 1) & 4; + + strstr << " gl_FragData[" << index << "] = vec4(" + << r << ".0, " << g << ".0, " + << b << ".0, 1.0);\n"; + } + } + + strstr << "}\n"; + + *programOut = CompileProgram(vertexShaderSource, strstr.str()); + if (*programOut == 0) + { + FAIL() << "shader compilation failed."; + } + + glUseProgram(*programOut); + + GLint location = glGetAttribLocation(*programOut, "position"); + ASSERT_NE(location, -1); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, 8, NULL); + glEnableVertexAttribArray(location); + } + + void setupMRTProgram(bool bufferEnabled[8], GLuint *programOut) + { + if (getClientMajorVersion() == 3) + { + setupMRTProgramESSL3(bufferEnabled, programOut); + } + else + { + ASSERT_EQ(getClientMajorVersion(), 2); + setupMRTProgramESSL1(bufferEnabled, programOut); + } + } + + static GLColor getColorForIndex(unsigned int index) + { + GLubyte r = (((index + 1) & 1) > 0) ? 255 : 0; + GLubyte g = (((index + 1) & 2) > 0) ? 255 : 0; + GLubyte b = (((index + 1) & 4) > 0) ? 255 : 0; + return GLColor(r, g, b, 255u); + } + + void verifyAttachment2D(unsigned int index, GLuint textureName, GLenum target, GLint level) + { + for (GLint colorAttachment = 0; colorAttachment < mMaxDrawBuffers; colorAttachment++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttachment, GL_TEXTURE_2D, 0, 0); + } + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, textureName, level); + + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, getColorForIndex(index)); + } + + void verifyAttachmentLayer(unsigned int index, GLuint texture, GLint level, GLint layer) + { + for (GLint colorAttachment = 0; colorAttachment < mMaxDrawBuffers; colorAttachment++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorAttachment, + GL_TEXTURE_2D, 0, 0); + } + + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, level, layer); + + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, getColorForIndex(index)); + } + + GLuint mFBO; + GLuint mTextures[4]; + GLuint mBuffer; + GLint mMaxDrawBuffers; +}; + +// Verify that GL_MAX_DRAW_BUFFERS returns the expected values for D3D11 +TEST_P(DrawBuffersTest, VerifyD3DLimits) +{ + EGLPlatformParameters platform = GetParam().eglParameters; + if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + if (platform.majorVersion == 9 && platform.minorVersion == 3) + { + // D3D11 Feature Level 9_3 supports 4 draw buffers + ASSERT_EQ(mMaxDrawBuffers, 4); + } + else + { + // D3D11 Feature Level 10_0+ supports 8 draw buffers + ASSERT_EQ(mMaxDrawBuffers, 8); + } + } + else + { + std::cout << "Test skipped for non-D3D11 renderers." << std::endl; + return; + } +} + +TEST_P(DrawBuffersTest, Gaps) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_draw_buffers")) + { + std::cout << "Test skipped because ES3 or GL_EXT_draw_buffers is not available." + << std::endl; + return; + } + + if (IsWindows() && IsAMD() && IsDesktopOpenGL()) + { + // TODO(ynovikov): Investigate the failure (http://anglebug.com/1535) + std::cout << "Test disabled on Windows AMD OpenGL." << std::endl; + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[0], 0); + + bool flags[8] = { false, true }; + + GLuint program; + setupMRTProgram(flags, &program); + + const GLenum bufs[] = + { + GL_NONE, + GL_COLOR_ATTACHMENT1 + }; + glUseProgram(program); + glDrawBuffersEXT(2, bufs); + glDrawArrays(GL_TRIANGLES, 0, 3); + + verifyAttachment2D(1, mTextures[0], GL_TEXTURE_2D, 0); + + glDeleteProgram(program); +} + +TEST_P(DrawBuffersTest, FirstAndLast) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_draw_buffers")) + { + std::cout << "Test skipped because ES3 or GL_EXT_draw_buffers is not available." + << std::endl; + return; + } + + if (IsWindows() && IsAMD() && IsDesktopOpenGL()) + { + // TODO(ynovikov): Investigate the failure (https://anglebug.com/1533) + std::cout << "Test disabled on Windows AMD OpenGL." << std::endl; + return; + } + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, mTextures[1], 0); + + bool flags[8] = { true, false, false, true }; + + GLuint program; + setupMRTProgram(flags, &program); + + const GLenum bufs[] = + { + GL_COLOR_ATTACHMENT0, + GL_NONE, + GL_NONE, + GL_COLOR_ATTACHMENT3 + }; + + glUseProgram(program); + glDrawBuffersEXT(4, bufs); + glDrawArrays(GL_TRIANGLES, 0, 3); + + verifyAttachment2D(0, mTextures[0], GL_TEXTURE_2D, 0); + verifyAttachment2D(3, mTextures[1], GL_TEXTURE_2D, 0); + + EXPECT_GL_NO_ERROR(); + + glDeleteProgram(program); +} + +TEST_P(DrawBuffersTest, FirstHalfNULL) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_draw_buffers")) + { + std::cout << "Test skipped because ES3 or GL_EXT_draw_buffers is not available." + << std::endl; + return; + } + + if (IsWindows() && IsAMD() && IsDesktopOpenGL()) + { + // TODO(ynovikov): Investigate the failure (https://anglebug.com/1533) + std::cout << "Test disabled on Windows AMD OpenGL." << std::endl; + return; + } + + bool flags[8] = { false }; + GLenum bufs[8] = { GL_NONE }; + + GLuint halfMaxDrawBuffers = static_cast<GLuint>(mMaxDrawBuffers) / 2; + + for (GLuint texIndex = 0; texIndex < halfMaxDrawBuffers; texIndex++) + { + glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + halfMaxDrawBuffers + texIndex, GL_TEXTURE_2D, mTextures[texIndex], 0); + flags[texIndex + halfMaxDrawBuffers] = true; + bufs[texIndex + halfMaxDrawBuffers] = GL_COLOR_ATTACHMENT0 + halfMaxDrawBuffers + texIndex; + } + + GLuint program; + setupMRTProgram(flags, &program); + + glUseProgram(program); + glDrawBuffersEXT(mMaxDrawBuffers, bufs); + glDrawArrays(GL_TRIANGLES, 0, 3); + + for (GLuint texIndex = 0; texIndex < halfMaxDrawBuffers; texIndex++) + { + verifyAttachment2D(texIndex + halfMaxDrawBuffers, mTextures[texIndex], GL_TEXTURE_2D, 0); + } + + EXPECT_GL_NO_ERROR(); + + glDeleteProgram(program); +} + +TEST_P(DrawBuffersTest, UnwrittenOutputVariablesShouldNotCrash) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_draw_buffers")) + { + std::cout << "Test skipped because ES3 or GL_EXT_draw_buffers is not available." + << std::endl; + return; + } + + // Bind two render targets but use a shader which writes only to the first one. + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[1], 0); + + bool flags[8] = { true, false }; + + GLuint program; + setupMRTProgram(flags, &program); + + const GLenum bufs[] = + { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_NONE, + GL_NONE, + }; + + glUseProgram(program); + glDrawBuffersEXT(4, bufs); + + // This call should not crash when we dynamically generate the HLSL code. + glDrawArrays(GL_TRIANGLES, 0, 3); + + verifyAttachment2D(0, mTextures[0], GL_TEXTURE_2D, 0); + + EXPECT_GL_NO_ERROR(); + + glDeleteProgram(program); +} + +// Test that binding multiple layers of a 3D texture works correctly +TEST_P(DrawBuffersTest, 3DTextures) +{ + if (getClientMajorVersion() < 3) + { + std::cout << "Test skipped because ES3 is not available." << std::endl; + return; + } + + GLTexture texture; + glBindTexture(GL_TEXTURE_3D, texture.get()); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), getWindowWidth(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.get(), 0, 0); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture.get(), 0, 1); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, texture.get(), 0, 2); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, texture.get(), 0, 3); + + bool flags[8] = {true, true, true, true, false}; + + GLuint program; + setupMRTProgram(flags, &program); + + const GLenum bufs[] = { + GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, + }; + + glUseProgram(program); + glDrawBuffersEXT(4, bufs); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + verifyAttachmentLayer(0, texture.get(), 0, 0); + verifyAttachmentLayer(1, texture.get(), 0, 1); + verifyAttachmentLayer(2, texture.get(), 0, 2); + verifyAttachmentLayer(3, texture.get(), 0, 3); + + EXPECT_GL_NO_ERROR(); + + glDeleteProgram(program); +} + +// Test that binding multiple layers of a 2D array texture works correctly +TEST_P(DrawBuffersTest, 2DArrayTextures) +{ + if (getClientMajorVersion() < 3) + { + std::cout << "Test skipped because ES3 is not available." << std::endl; + return; + } + + GLTexture texture; + glBindTexture(GL_TEXTURE_2D_ARRAY, texture.get()); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), + getWindowWidth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.get(), 0, 0); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texture.get(), 0, 1); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, texture.get(), 0, 2); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, texture.get(), 0, 3); + + bool flags[8] = {true, true, true, true, false}; + + GLuint program; + setupMRTProgram(flags, &program); + + const GLenum bufs[] = { + GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, + }; + + glUseProgram(program); + glDrawBuffersEXT(4, bufs); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + verifyAttachmentLayer(0, texture.get(), 0, 0); + verifyAttachmentLayer(1, texture.get(), 0, 1); + verifyAttachmentLayer(2, texture.get(), 0, 2); + verifyAttachmentLayer(3, texture.get(), 0, 3); + + EXPECT_GL_NO_ERROR(); + + glDeleteProgram(program); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(DrawBuffersTest, + ES2_D3D11(), + ES3_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/DrawElementsTest.cpp b/gfx/angle/src/tests/gl_tests/DrawElementsTest.cpp new file mode 100755 index 000000000..91f3c1e9a --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/DrawElementsTest.cpp @@ -0,0 +1,226 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DrawElementsTest: +// Tests for indexed draws. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class DrawElementsTest : public ANGLETest +{ + protected: + DrawElementsTest() : mProgram(0u) + { + setWindowWidth(64); + setWindowHeight(64); + setConfigRedBits(8); + setConfigGreenBits(8); + } + + ~DrawElementsTest() + { + for (GLuint indexBuffer : mIndexBuffers) + { + if (indexBuffer != 0) + { + glDeleteBuffers(1, &indexBuffer); + } + } + + for (GLuint vertexArray : mVertexArrays) + { + if (vertexArray != 0) + { + glDeleteVertexArrays(1, &vertexArray); + } + } + + for (GLuint vertexBuffer : mVertexBuffers) + { + if (vertexBuffer != 0) + { + glDeleteBuffers(1, &vertexBuffer); + } + } + + if (mProgram != 0u) + { + glDeleteProgram(mProgram); + } + } + + std::vector<GLuint> mIndexBuffers; + std::vector<GLuint> mVertexArrays; + std::vector<GLuint> mVertexBuffers; + GLuint mProgram; +}; + +// Test a state desync that can occur when using a streaming index buffer in GL in concert with +// deleting the applied index buffer. +TEST_P(DrawElementsTest, DeletingAfterStreamingIndexes) +{ + // Init program + const std::string &vertexShader = + "attribute vec2 position;\n" + "attribute vec2 testFlag;\n" + "varying vec2 v_data;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + " v_data = testFlag;\n" + "}"; + + const std::string &fragmentShader = + "varying highp vec2 v_data;\n" + "void main() {\n" + " gl_FragColor = vec4(v_data, 0, 1);\n" + "}"; + + mProgram = CompileProgram(vertexShader, fragmentShader); + ASSERT_NE(0u, mProgram); + glUseProgram(mProgram); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + ASSERT_NE(-1, positionLocation); + + GLint testFlagLocation = glGetAttribLocation(mProgram, "testFlag"); + ASSERT_NE(-1, testFlagLocation); + + mIndexBuffers.resize(3u); + glGenBuffers(3, &mIndexBuffers[0]); + + mVertexArrays.resize(2); + glGenVertexArrays(2, &mVertexArrays[0]); + + mVertexBuffers.resize(2); + glGenBuffers(2, &mVertexBuffers[0]); + + std::vector<GLuint> indexData[2]; + indexData[0].push_back(0); + indexData[0].push_back(1); + indexData[0].push_back(2); + indexData[0].push_back(2); + indexData[0].push_back(3); + indexData[0].push_back(0); + + indexData[1] = indexData[0]; + for (GLuint &item : indexData[1]) + { + item += 4u; + } + + std::vector<GLfloat> positionData; + // quad verts + positionData.push_back(-1.0f); + positionData.push_back(1.0f); + positionData.push_back(-1.0f); + positionData.push_back(-1.0f); + positionData.push_back(1.0f); + positionData.push_back(-1.0f); + positionData.push_back(1.0f); + positionData.push_back(1.0f); + + // Repeat position data + positionData.push_back(-1.0f); + positionData.push_back(1.0f); + positionData.push_back(-1.0f); + positionData.push_back(-1.0f); + positionData.push_back(1.0f); + positionData.push_back(-1.0f); + positionData.push_back(1.0f); + positionData.push_back(1.0f); + + std::vector<GLfloat> testFlagData; + // red + testFlagData.push_back(1.0f); + testFlagData.push_back(0.0f); + testFlagData.push_back(1.0f); + testFlagData.push_back(0.0f); + testFlagData.push_back(1.0f); + testFlagData.push_back(0.0f); + testFlagData.push_back(1.0f); + testFlagData.push_back(0.0f); + + // green + testFlagData.push_back(0.0f); + testFlagData.push_back(1.0f); + testFlagData.push_back(0.0f); + testFlagData.push_back(1.0f); + testFlagData.push_back(0.0f); + testFlagData.push_back(1.0f); + testFlagData.push_back(0.0f); + testFlagData.push_back(1.0f); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0], + GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[2]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0], + GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[1].size(), &indexData[1][0], + GL_STATIC_DRAW); + + // Initialize first vertex array with second index buffer + glBindVertexArray(mVertexArrays[0]); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]); + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0], + GL_STATIC_DRAW); + glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr); + glEnableVertexAttribArray(positionLocation); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * testFlagData.size(), &testFlagData[0], + GL_STATIC_DRAW); + glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr); + glEnableVertexAttribArray(testFlagLocation); + + // Initialize second vertex array with first index buffer + glBindVertexArray(mVertexArrays[1]); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]); + glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr); + glEnableVertexAttribArray(positionLocation); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]); + glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr); + glEnableVertexAttribArray(testFlagLocation); + + ASSERT_GL_NO_ERROR(); + + glBindVertexArray(mVertexArrays[0]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + glBindVertexArray(mVertexArrays[1]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + glBindVertexArray(mVertexArrays[0]); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + // Trigger the bug here. + glDeleteBuffers(1, &mIndexBuffers[2]); + + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + ASSERT_GL_NO_ERROR(); +} + +ANGLE_INSTANTIATE_TEST(DrawElementsTest, ES3_OPENGL(), ES3_OPENGLES()); +} diff --git a/gfx/angle/src/tests/gl_tests/ETCTextureTest.cpp b/gfx/angle/src/tests/gl_tests/ETCTextureTest.cpp new file mode 100755 index 000000000..24fdd2263 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ETCTextureTest.cpp @@ -0,0 +1,85 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ETCTextureTest: +// Tests for ETC lossy decode formats. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class ETCTextureTest : public ANGLETest +{ + protected: + ETCTextureTest() : mTexture(0u) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenTextures(1, &mTexture); + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteTextures(1, &mTexture); + + ANGLETest::TearDown(); + } + + GLuint mTexture; +}; + +// Tests a texture with ETC1 lossy decode format +TEST_P(ETCTextureTest, ETC1Validation) +{ + bool supported = extensionEnabled("GL_ANGLE_lossy_etc_decode"); + + glBindTexture(GL_TEXTURE_2D, mTexture); + + GLubyte pixel[8] = { 0x0, 0x0, 0xf8, 0x2, 0x43, 0xff, 0x4, 0x12 }; + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, 4, 4, 0, + sizeof(pixel), pixel); + if (supported) + { + EXPECT_GL_NO_ERROR(); + + glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, + sizeof(pixel), pixel); + EXPECT_GL_NO_ERROR(); + + + glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, 2, 2, 0, + sizeof(pixel), pixel); + glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, 1, 1, 0, + sizeof(pixel), pixel); + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } +} + +ANGLE_INSTANTIATE_TEST(ETCTextureTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL()); +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp b/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp new file mode 100755 index 000000000..1568509f6 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/FenceSyncTests.cpp @@ -0,0 +1,282 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class FenceNVTest : public ANGLETest +{ + protected: + FenceNVTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } +}; + +class FenceSyncTest : public ANGLETest +{ + protected: + FenceSyncTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } +}; + +// FenceNV objects should respond false to glIsFenceNV until they've been set +TEST_P(FenceNVTest, IsFence) +{ + if (!extensionEnabled("GL_NV_fence")) + { + std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl; + return; + } + + GLuint fence = 0; + glGenFencesNV(1, &fence); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GL_FALSE, glIsFenceNV(fence)); + EXPECT_GL_NO_ERROR(); + + glSetFenceNV(fence, GL_ALL_COMPLETED_NV); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GL_TRUE, glIsFenceNV(fence)); + EXPECT_GL_NO_ERROR(); +} + +// Test error cases for all FenceNV functions +TEST_P(FenceNVTest, Errors) +{ + if (!extensionEnabled("GL_NV_fence")) + { + std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl; + return; + } + + // glTestFenceNV should still return TRUE for an invalid fence and generate an INVALID_OPERATION + EXPECT_EQ(GL_TRUE, glTestFenceNV(10)); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + GLuint fence = 20; + + // glGenFencesNV should generate INVALID_VALUE for a negative n and not write anything to the fences pointer + glGenFencesNV(-1, &fence); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + EXPECT_EQ(20u, fence); + + // Generate a real fence + glGenFencesNV(1, &fence); + EXPECT_GL_NO_ERROR(); + + // glTestFenceNV should still return TRUE for a fence that is not started and generate an INVALID_OPERATION + EXPECT_EQ(GL_TRUE, glTestFenceNV(fence)); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // glGetFenceivNV should generate an INVALID_OPERATION for an invalid or unstarted fence and not modify the params + GLint result = 30; + glGetFenceivNV(10, GL_FENCE_STATUS_NV, &result); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + EXPECT_EQ(30, result); + + glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &result); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + EXPECT_EQ(30, result); + + // glSetFenceNV should generate an error for any condition that is not ALL_COMPLETED_NV + glSetFenceNV(fence, 0); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // glSetFenceNV should generate INVALID_OPERATION for an invalid fence + glSetFenceNV(10, GL_ALL_COMPLETED_NV); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test that basic usage works and doesn't generate errors or crash +TEST_P(FenceNVTest, BasicOperations) +{ + if (!extensionEnabled("GL_NV_fence")) + { + std::cout << "Test skipped due to missing GL_NV_fence extension." << std::endl; + return; + } + + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + + GLuint fences[20] = { 0 }; + glGenFencesNV(static_cast<GLsizei>(ArraySize(fences)), fences); + EXPECT_GL_NO_ERROR(); + + for (GLuint fence : fences) + { + glSetFenceNV(fence, GL_ALL_COMPLETED_NV); + + glClear(GL_COLOR_BUFFER_BIT); + } + + glFinish(); + + for (GLuint fence : fences) + { + GLint status = 0; + glGetFenceivNV(fence, GL_FENCE_STATUS_NV, &status); + EXPECT_GL_NO_ERROR(); + + // Fence should be complete now that Finish has been called + EXPECT_EQ(GL_TRUE, status); + } + + EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255); +} + +// FenceSync objects should respond true to IsSync after they are created with glFenceSync +TEST_P(FenceSyncTest, IsSync) +{ + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GL_TRUE, glIsSync(sync)); + EXPECT_EQ(GL_FALSE, glIsSync(reinterpret_cast<GLsync>(40))); +} + +// Test error cases for all FenceSync function +TEST_P(FenceSyncTest, Errors) +{ + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + // DeleteSync generates INVALID_VALUE when the sync is not valid + glDeleteSync(reinterpret_cast<GLsync>(20)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glFenceSync generates GL_INVALID_ENUM if the condition is not GL_SYNC_GPU_COMMANDS_COMPLETE + EXPECT_EQ(0, glFenceSync(0, 0)); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // glFenceSync generates GL_INVALID_ENUM if the flags is not 0 + EXPECT_EQ(0, glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 10)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if flags contains more than just GL_SYNC_FLUSH_COMMANDS_BIT + EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT | 0x2, 0)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glClientWaitSync generates GL_INVALID_VALUE and returns GL_WAIT_FAILED if the sync object is not valid + EXPECT_GLENUM_EQ(GL_WAIT_FAILED, glClientWaitSync(reinterpret_cast<GLsync>(30), GL_SYNC_FLUSH_COMMANDS_BIT, 0)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glWaitSync generates GL_INVALID_VALUE if flags is non-zero + glWaitSync(sync, 1, GL_TIMEOUT_IGNORED); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glWaitSync generates GL_INVALID_VALUE if GLuint64 is not GL_TIMEOUT_IGNORED + glWaitSync(sync, 0, 0); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glWaitSync generates GL_INVALID_VALUE if the sync object is not valid + glWaitSync(reinterpret_cast<GLsync>(30), 0, GL_TIMEOUT_IGNORED); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // glGetSynciv generates GL_INVALID_VALUE if bufSize is less than zero, results should be untouched + GLsizei length = 20; + GLint value = 30; + glGetSynciv(sync, GL_OBJECT_TYPE, -1, &length, &value); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + EXPECT_EQ(20, length); + EXPECT_EQ(30, value); + + // glGetSynciv generates GL_INVALID_VALUE if the sync object tis not valid, results should be untouched + glGetSynciv(reinterpret_cast<GLsync>(30), GL_OBJECT_TYPE, 1, &length, &value); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + EXPECT_EQ(20, length); + EXPECT_EQ(30, value); +} + +// Test usage of glGetSynciv +TEST_P(FenceSyncTest, BasicQueries) +{ + GLsizei length = 0; + GLint value = 0; + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + glGetSynciv(sync, GL_SYNC_CONDITION, 1, &length, &value); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(GL_SYNC_GPU_COMMANDS_COMPLETE, value); + + glGetSynciv(sync, GL_OBJECT_TYPE, 1, &length, &value); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(GL_SYNC_FENCE, value); + + glGetSynciv(sync, GL_SYNC_FLAGS, 1, &length, &value); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(0, value); +} + +// Test that basic usage works and doesn't generate errors or crash +TEST_P(FenceSyncTest, BasicOperations) +{ + // TODO(geofflang): Figure out why this is broken on Intel OpenGL + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + + GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + glClear(GL_COLOR_BUFFER_BIT); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + EXPECT_GL_NO_ERROR(); + + GLsizei length = 0; + GLint value = 0; + unsigned int loopCount = 0; + + glFlush(); + + // Use 'loopCount' to make sure the test doesn't get stuck in an infinite loop + while (value != GL_SIGNALED && loopCount <= 1000000) + { + loopCount++; + + glGetSynciv(sync, GL_SYNC_STATUS, 1, &length, &value); + ASSERT_GL_NO_ERROR(); + } + + ASSERT_GLENUM_EQ(GL_SIGNALED, value); + + for (size_t i = 0; i < 20; i++) + { + glClear(GL_COLOR_BUFFER_BIT); + glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); + EXPECT_GL_NO_ERROR(); + } +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(FenceNVTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(FenceSyncTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp b/gfx/angle/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp new file mode 100755 index 000000000..5baf9303a --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp @@ -0,0 +1,291 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CHROMIUMFramebufferMixedSamplesTest +// Test CHROMIUM subset of NV_framebuffer_mixed_samples. +// This extension allows rendering to a framebuffer that has different +// sample counts for different render buffers (stencil, depth, color) + +#include "test_utils/ANGLETest.h" +#include "shader_utils.h" + +using namespace angle; + +namespace +{ + +const GLuint kWidth = 100; +const GLuint kHeight = 100; + +class CHROMIUMFramebufferMixedSamplesTest : public ANGLETest +{ + protected: + enum SetupFBOType + { + MixedSampleFBO, // 1 color sample, N stencil samples. + SingleSampleFBO, // 1 color sample, 1 stencil sample. + }; + + bool isApplicable() const + { + return extensionEnabled("GL_CHROMIUM_framebuffer_mixed_samples") && + extensionEnabled("GL_OES_rgb8_rgba8"); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + // clang-format off + static const char* kVertexShaderSource = + "attribute mediump vec4 position;\n" + "void main() {\n" + " gl_Position = position;\n" + "}\n"; + + static const char* kFragmentShaderSource = + "uniform mediump vec4 color;\n" + "void main() {\n" + " gl_FragColor = color;\n" + "}\n"; + + // clang-format on + mProgram = CompileProgram(kVertexShaderSource, kFragmentShaderSource); + + GLuint position_loc = glGetAttribLocation(mProgram, "position"); + mColorLoc = glGetUniformLocation(mProgram, "color"); + + glGenBuffers(1, &mVBO); + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + + static float vertices[] = { + 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, + }; + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(position_loc); + glVertexAttribPointer(position_loc, 2, GL_FLOAT, GL_FALSE, 0, 0); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteBuffers(1, &mVBO); + glDeleteProgram(mProgram); + + ASSERT_GL_NO_ERROR(); + + ANGLETest::TearDown(); + } + + void prepareForDraw(SetupFBOType fbo_type) + { + glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, + NULL); + glBindTexture(GL_TEXTURE_2D, 0); + + glGenRenderbuffers(1, &mStencilRB); + glBindRenderbuffer(GL_RENDERBUFFER, mStencilRB); + + if (fbo_type == MixedSampleFBO) + { + // Create a sample buffer. + GLsizei num_samples = 8, max_samples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + num_samples = std::min(num_samples, max_samples); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, num_samples, GL_STENCIL_INDEX8, + kWidth, kHeight); + GLint param = 0; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, ¶m); + EXPECT_GT(param, 1); + } + else + { + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kWidth, kHeight); + } + glBindRenderbuffer(GL_RENDERBUFFER, 0); + + glGenFramebuffers(1, &mSampleFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + mStencilRB); + EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + glUseProgram(mProgram); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glViewport(0, 0, kWidth, kHeight); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearStencil(1); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glEnable(GL_STENCIL_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glStencilMask(0xffffffff); + glStencilFunc(GL_EQUAL, 1, 0xffffffff); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + + ASSERT_GL_NO_ERROR(); + } + + void cleanup() + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &mSampleFBO); + glDeleteTextures(1, &mTexture); + glDeleteRenderbuffers(1, &mStencilRB); + + ASSERT_GL_NO_ERROR(); + } + + GLuint mSampleFBO; + GLuint mStencilRB; + GLuint mTexture; + + GLuint mProgram; + GLuint mVBO; + GLint mColorLoc; +}; + +} // + +TEST_P(CHROMIUMFramebufferMixedSamplesTest, StateSettingTest) +{ + if (!isApplicable()) + { + return; + } + + GLint value = -1; + glGetIntegerv(GL_COVERAGE_MODULATION_CHROMIUM, &value); + EXPECT_EQ(GL_NONE, value); + GLenum kValues[] = {GL_NONE, GL_RGB, GL_RGBA, GL_ALPHA}; + for (auto expect : kValues) + { + glCoverageModulationCHROMIUM(expect); + value = -1; + glGetIntegerv(GL_COVERAGE_MODULATION_CHROMIUM, &value); + EXPECT_EQ(expect, static_cast<GLenum>(value)); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); + } + + glCoverageModulationCHROMIUM(GL_BYTE); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + value = -1; + glGetIntegerv(GL_COVERAGE_MODULATION_CHROMIUM, &value); + EXPECT_EQ(static_cast<GLenum>(GL_ALPHA), static_cast<GLenum>(value)); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); +} + +// The test pattern is as follows: +// A green triangle (bottom left, top right, top left). +// A blue triangle (top left, bottom right, bottom left). +// The triangles will overlap but overlap only contains green pixels, +// due to each draw erasing its area from stencil. +// The blue triangle will fill only the area (bottom left, center, +// bottom right). + +// The test tests that CoverageModulation call works. +// The fractional pixels of both triangles end up being modulated +// by the coverage of the fragment. Test that drawing with and without +// CoverageModulation causes the result to be different. +TEST_P(CHROMIUMFramebufferMixedSamplesTest, CoverageModulation) +{ + if (!isApplicable()) + { + return; + } + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + std::unique_ptr<uint8_t[]> results[3]; + const GLint kResultSize = kWidth * kHeight * 4; + + for (int pass = 0; pass < 3; ++pass) + { + prepareForDraw(MixedSampleFBO); + if (pass == 1) + { + glCoverageModulationCHROMIUM(GL_RGBA); + } + glUniform4fv(mColorLoc, 1, kGreen); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glUniform4fv(mColorLoc, 1, kBlue); + glDrawArrays(GL_TRIANGLES, 3, 3); + if (pass == 1) + { + glCoverageModulationCHROMIUM(GL_NONE); + } + results[pass].reset(new uint8_t[kResultSize]); + memset(results[pass].get(), 123u, kResultSize); + glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, results[pass].get()); + + cleanup(); + } + + EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize)); + // Verify that rendering is deterministic, so that the pass above does not + // come from non-deterministic rendering. + EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize)); +} + +// The test tests that the stencil buffer can be multisampled, even though the +// color buffer is single-sampled. Draws the same pattern with single-sample +// stencil buffer and with multisample stencil buffer. The images should differ. +TEST_P(CHROMIUMFramebufferMixedSamplesTest, MultisampleStencilEffective) +{ + if (!isApplicable()) + { + return; + } + + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + + std::unique_ptr<uint8_t[]> results[3]; + const GLint kResultSize = kWidth * kHeight * 4; + + for (int pass = 0; pass < 3; ++pass) + { + if (pass == 1) + { + prepareForDraw(MixedSampleFBO); + } + else + { + prepareForDraw(SingleSampleFBO); + } + glUniform4fv(mColorLoc, 1, kGreen); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glUniform4fv(mColorLoc, 1, kBlue); + glDrawArrays(GL_TRIANGLES, 3, 3); + + results[pass].reset(new uint8_t[kResultSize]); + memset(results[pass].get(), 12u, kResultSize); + glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, results[pass].get()); + + cleanup(); + } + + EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize)); + // Verify that rendering is deterministic, so that the pass above does not + // come from non-deterministic rendering. + EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize)); +} + +ANGLE_INSTANTIATE_TEST(CHROMIUMFramebufferMixedSamplesTest, + ES2_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGL()); diff --git a/gfx/angle/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp b/gfx/angle/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp new file mode 100755 index 000000000..471bf5018 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/FramebufferRenderMipmapTest.cpp @@ -0,0 +1,204 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class FramebufferRenderMipmapTest : public ANGLETest +{ + protected: + FramebufferRenderMipmapTest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vsSource = SHADER_SOURCE + ( + attribute highp vec4 position; + void main(void) + { + gl_Position = position; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + uniform highp vec4 color; + void main(void) + { + gl_FragColor = color; + } + ); + + mProgram = CompileProgram(vsSource, fsSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mColorLocation = glGetUniformLocation(mProgram, "color"); + + glUseProgram(mProgram); + + glClearColor(0, 0, 0, 0); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLint mColorLocation; +}; + +// Validate that if we are in ES3 or GL_OES_fbo_render_mipmap exists, there are no validation errors +// when using a non-zero level in glFramebufferTexture2D. +TEST_P(FramebufferRenderMipmapTest, Validation) +{ + bool renderToMipmapSupported = + extensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2; + + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + const GLint levels = 5; + for (GLint i = 0; i < levels; i++) + { + GLsizei size = 1 << ((levels - 1) - i); + glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } + + EXPECT_GL_NO_ERROR(); + + GLuint fbo = 0; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + EXPECT_GL_NO_ERROR(); + + for (GLint i = 0; i < levels; i++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i); + + if (i > 0 && !renderToMipmapSupported) + { + EXPECT_GL_ERROR(GL_INVALID_VALUE); + } + else + { + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GLenum(GL_FRAMEBUFFER_COMPLETE)); + } + } + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); +} + +// Render to various levels of a texture and check that they have the correct color data via ReadPixels +TEST_P(FramebufferRenderMipmapTest, RenderToMipmap) +{ + // TODO(geofflang): Figure out why this is broken on Intel OpenGL + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + bool renderToMipmapSupported = + extensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2; + if (!renderToMipmapSupported) + { + std::cout << "Test skipped because GL_OES_fbo_render_mipmap or ES3 is not available." << std::endl; + return; + } + + const GLfloat levelColors[] = + { + 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 1.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 1.0f, 1.0f, + }; + const GLint testLevels = static_cast<GLint>(ArraySize(levelColors) / 4); + + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + for (GLint i = 0; i < testLevels; i++) + { + GLsizei size = 1 << ((testLevels - 1) - i); + glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } + + EXPECT_GL_NO_ERROR(); + + GLuint fbo = 0; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + EXPECT_GL_NO_ERROR(); + + // Render to the levels of the texture with different colors + for (GLint i = 0; i < testLevels; i++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i); + EXPECT_GL_NO_ERROR(); + + glUseProgram(mProgram); + glUniform4fv(mColorLocation, 1, levelColors + (i * 4)); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + } + + // Test that the levels of the texture are correct + for (GLint i = 0; i < testLevels; i++) + { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i); + EXPECT_GL_NO_ERROR(); + + const GLfloat *color = levelColors + (i * 4); + EXPECT_PIXEL_EQ(0, 0, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255); + } + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(FramebufferRenderMipmapTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp b/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp new file mode 100755 index 000000000..430ca8400 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp @@ -0,0 +1,379 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Framebuffer tests: +// Various tests related for Frambuffers. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class FramebufferFormatsTest : public ANGLETest +{ + protected: + FramebufferFormatsTest() : mFramebuffer(0), mTexture(0), mRenderbuffer(0), mProgram(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void checkBitCount(GLuint fbo, GLenum channel, GLint minBits) + { + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + GLint bits = 0; + glGetIntegerv(channel, &bits); + + if (minBits == 0) + { + EXPECT_EQ(minBits, bits); + } + else + { + EXPECT_GE(bits, minBits); + } + } + + void testBitCounts(GLuint fbo, + GLint minRedBits, + GLint minGreenBits, + GLint minBlueBits, + GLint minAlphaBits, + GLint minDepthBits, + GLint minStencilBits) + { + checkBitCount(fbo, GL_RED_BITS, minRedBits); + checkBitCount(fbo, GL_GREEN_BITS, minGreenBits); + checkBitCount(fbo, GL_BLUE_BITS, minBlueBits); + checkBitCount(fbo, GL_ALPHA_BITS, minAlphaBits); + checkBitCount(fbo, GL_DEPTH_BITS, minDepthBits); + checkBitCount(fbo, GL_STENCIL_BITS, minStencilBits); + } + + void testTextureFormat(GLenum internalFormat, + GLint minRedBits, + GLint minGreenBits, + GLint minBlueBits, + GLint minAlphaBits) + { + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0); + + testBitCounts(mFramebuffer, minRedBits, minGreenBits, minBlueBits, minAlphaBits, 0, 0); + } + + void testRenderbufferMultisampleFormat(int minESVersion, + GLenum attachmentType, + GLenum internalFormat) + { + // TODO(geofflang): Figure out why this is broken on Intel OpenGL + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + int clientVersion = getClientMajorVersion(); + if (clientVersion < minESVersion) + { + return; + } + + // Check that multisample is supported with at least two samples (minimum required is 1) + bool supports2Samples = false; + + if (clientVersion == 2) + { + if (extensionEnabled("ANGLE_framebuffer_multisample")) + { + int maxSamples; + glGetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSamples); + supports2Samples = maxSamples >= 2; + } + } + else + { + assert(clientVersion >= 3); + int maxSamples; + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + supports2Samples = maxSamples >= 2; + } + + if (!supports2Samples) + { + return; + } + + glGenRenderbuffers(1, &mRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + + EXPECT_GL_NO_ERROR(); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, internalFormat, 128, 128); + EXPECT_GL_NO_ERROR(); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentType, GL_RENDERBUFFER, mRenderbuffer); + EXPECT_GL_NO_ERROR(); + } + + void testZeroHeightRenderbuffer() + { + glGenRenderbuffers(1, &mRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + mRenderbuffer); + EXPECT_GL_NO_ERROR(); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + } + + void TearDown() override + { + ANGLETest::TearDown(); + + if (mTexture != 0) + { + glDeleteTextures(1, &mTexture); + mTexture = 0; + } + + if (mRenderbuffer != 0) + { + glDeleteRenderbuffers(1, &mRenderbuffer); + mRenderbuffer = 0; + } + + if (mFramebuffer != 0) + { + glDeleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + + if (mProgram != 0) + { + glDeleteProgram(mProgram); + mProgram = 0; + } + } + + GLuint mFramebuffer; + GLuint mTexture; + GLuint mRenderbuffer; + GLuint mProgram; +}; + +TEST_P(FramebufferFormatsTest, RGBA4) +{ + testTextureFormat(GL_RGBA4, 4, 4, 4, 4); +} + +TEST_P(FramebufferFormatsTest, RGB565) +{ + testTextureFormat(GL_RGB565, 5, 6, 5, 0); +} + +TEST_P(FramebufferFormatsTest, RGB8) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_rgb8_rgba8")) + { + std::cout << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8." << std::endl; + return; + } + + testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0); +} + +TEST_P(FramebufferFormatsTest, BGRA8) +{ + if (!extensionEnabled("GL_EXT_texture_format_BGRA8888")) + { + std::cout << "Test skipped due to missing GL_EXT_texture_format_BGRA8888." << std::endl; + return; + } + + testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8); +} + +TEST_P(FramebufferFormatsTest, RGBA8) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_rgb8_rgba8")) + { + std::cout << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8." << std::endl; + return; + } + + testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8); +} + +TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16) +{ + testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16); +} + +TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24) +{ + testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24); +} + +TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F) +{ + if (getClientMajorVersion() < 3) + { + std::cout << "Test skipped due to missing ES3." << std::endl; + return; + } + + testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F); +} + +TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8) +{ + testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8); +} + +TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8) +{ + if (getClientMajorVersion() < 3) + { + std::cout << "Test skipped due to missing ES3." << std::endl; + return; + } + + testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8); +} + +TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8) +{ + // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL + if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Desktop OpenGL." << std::endl; + return; + } + + testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8); +} + +// Test that binding an incomplete cube map is rejected by ANGLE. +TEST_P(FramebufferFormatsTest, IncompleteCubeMap) +{ + // First make a complete CubeMap. + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, + mTexture, 0); + + // Verify the framebuffer is complete. + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Make the CubeMap cube-incomplete. + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + + // Verify the framebuffer is incomplete. + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Verify drawing with the incomplete framebuffer produces a GL error + const std::string &vs = "attribute vec4 position; void main() { gl_Position = position; }"; + const std::string &ps = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }"; + mProgram = CompileProgram(vs, ps); + ASSERT_NE(0u, mProgram); + drawQuad(mProgram, "position", 0.5f); + ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION); +} + +// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts. +TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer) +{ + if (getClientMajorVersion() < 3) + { + std::cout << "Test skipped due to missing ES3" << std::endl; + return; + } + + testZeroHeightRenderbuffer(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +class FramebufferInvalidateTest : public ANGLETest +{ + protected: + FramebufferInvalidateTest() : mFramebuffer(0), mRenderbuffer(0) {} + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenFramebuffers(1, &mFramebuffer); + glGenRenderbuffers(1, &mRenderbuffer); + } + + void TearDown() override + { + glDeleteFramebuffers(1, &mFramebuffer); + glDeleteRenderbuffers(1, &mRenderbuffer); + ANGLETest::TearDown(); + } + + GLuint mFramebuffer; + GLuint mRenderbuffer; +}; + +// Covers invalidating an incomplete framebuffer. This should be a no-op, but should not error. +TEST_P(FramebufferInvalidateTest, Incomplete) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRenderbuffer); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + std::vector<GLenum> attachments; + attachments.push_back(GL_COLOR_ATTACHMENT0); + + glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data()); + EXPECT_GL_NO_ERROR(); +} + +ANGLE_INSTANTIATE_TEST(FramebufferInvalidateTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/GLSLTest.cpp b/gfx/angle/src/tests/gl_tests/GLSLTest.cpp new file mode 100755 index 000000000..00000612d --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/GLSLTest.cpp @@ -0,0 +1,2443 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Program.h" +#include "test_utils/gl_raii.h" + +using namespace angle; + +namespace +{ + +class GLSLTest : public ANGLETest +{ + protected: + GLSLTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + mSimpleVSSource = SHADER_SOURCE + ( + attribute vec4 inputAttribute; + void main() + { + gl_Position = inputAttribute; + } + ); + } + + std::string GenerateVaryingType(GLint vectorSize) + { + char varyingType[10]; + + if (vectorSize == 1) + { + sprintf(varyingType, "float"); + } + else + { + sprintf(varyingType, "vec%d", vectorSize); + } + + return std::string(varyingType); + } + + std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id) + { + char buff[100]; + + if (arraySize == 1) + { + sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id); + } + else + { + sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize); + } + + return std::string(buff); + } + + std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id) + { + std::string returnString; + char buff[100]; + + if (arraySize == 1) + { + sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str()); + returnString += buff; + } + else + { + for (int i = 0; i < arraySize; i++) + { + sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str()); + returnString += buff; + } + } + + return returnString; + } + + std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id) + { + if (arraySize == 1) + { + char buff[100]; + sprintf(buff, "v%d + ", id); + return std::string(buff); + } + else + { + std::string returnString; + for (int i = 0; i < arraySize; i++) + { + char buff[100]; + sprintf(buff, "v%d[%d] + ", id, i); + returnString += buff; + } + return returnString; + } + } + + void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount, + GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, + std::string* fragmentShader, std::string* vertexShader) + { + // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader. + std::string varyingDeclaration; + + unsigned int varyingCount = 0; + + for (GLint i = 0; i < floatCount; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount); + varyingCount += 1; + } + + for (GLint i = 0; i < floatArrayCount; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount); + varyingCount += 1; + } + + for (GLint i = 0; i < vec2Count; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount); + varyingCount += 1; + } + + for (GLint i = 0; i < vec2ArrayCount; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount); + varyingCount += 1; + } + + for (GLint i = 0; i < vec3Count; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount); + varyingCount += 1; + } + + for (GLint i = 0; i < vec3ArrayCount; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount); + varyingCount += 1; + } + + for (GLint i = 0; i < vec4Count; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount); + varyingCount += 1; + } + + for (GLint i = 0; i < vec4ArrayCount; i++) + { + varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount); + varyingCount += 1; + } + + // Generate the vertex shader + vertexShader->clear(); + vertexShader->append(varyingDeclaration); + vertexShader->append("\nvoid main()\n{\n"); + + unsigned int currentVSVarying = 0; + + for (GLint i = 0; i < floatCount; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying)); + currentVSVarying += 1; + } + + for (GLint i = 0; i < floatArrayCount; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying)); + currentVSVarying += 1; + } + + for (GLint i = 0; i < vec2Count; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying)); + currentVSVarying += 1; + } + + for (GLint i = 0; i < vec2ArrayCount; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying)); + currentVSVarying += 1; + } + + for (GLint i = 0; i < vec3Count; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying)); + currentVSVarying += 1; + } + + for (GLint i = 0; i < vec3ArrayCount; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying)); + currentVSVarying += 1; + } + + for (GLint i = 0; i < vec4Count; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying)); + currentVSVarying += 1; + } + + for (GLint i = 0; i < vec4ArrayCount; i++) + { + vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying)); + currentVSVarying += 1; + } + + if (usePointSize) + { + vertexShader->append("gl_PointSize = 1.0;\n"); + } + + vertexShader->append("}\n"); + + // Generate the fragment shader + fragmentShader->clear(); + fragmentShader->append("precision highp float;\n"); + fragmentShader->append(varyingDeclaration); + fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n"); + + unsigned int currentFSVarying = 0; + + // Make use of the float varyings + fragmentShader->append("\tretColor += vec4("); + + for (GLint i = 0; i < floatCount; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying)); + currentFSVarying += 1; + } + + for (GLint i = 0; i < floatArrayCount; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying)); + currentFSVarying += 1; + } + + fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n"); + + // Make use of the vec2 varyings + fragmentShader->append("\tretColor += vec4("); + + for (GLint i = 0; i < vec2Count; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying)); + currentFSVarying += 1; + } + + for (GLint i = 0; i < vec2ArrayCount; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying)); + currentFSVarying += 1; + } + + fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n"); + + // Make use of the vec3 varyings + fragmentShader->append("\tretColor += vec4("); + + for (GLint i = 0; i < vec3Count; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying)); + currentFSVarying += 1; + } + + for (GLint i = 0; i < vec3ArrayCount; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying)); + currentFSVarying += 1; + } + + fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n"); + + // Make use of the vec4 varyings + fragmentShader->append("\tretColor += "); + + for (GLint i = 0; i < vec4Count; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying)); + currentFSVarying += 1; + } + + for (GLint i = 0; i < vec4ArrayCount; i++) + { + fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying)); + currentFSVarying += 1; + } + + fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n"); + + // Set gl_FragColor, and use special variables if requested + fragmentShader->append("\tgl_FragColor = retColor"); + + if (useFragCoord) + { + fragmentShader->append(" + gl_FragCoord"); + } + + if (usePointCoord) + { + fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)"); + } + + fragmentShader->append(";\n}"); + } + + void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount, + GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess) + { + std::string fragmentShaderSource; + std::string vertexShaderSource; + + GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount, + vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize, + &fragmentShaderSource, &vertexShaderSource); + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + + if (expectSuccess) + { + EXPECT_NE(0u, program); + } + else + { + EXPECT_EQ(0u, program); + } + } + + void CompileGLSLWithUniformsAndSamplers(GLint vertexUniformCount, + GLint fragmentUniformCount, + GLint vertexSamplersCount, + GLint fragmentSamplersCount, + bool expectSuccess) + { + std::stringstream vertexShader; + std::stringstream fragmentShader; + + // Generate the vertex shader + vertexShader << "precision mediump float;\n"; + + for (int i = 0; i < vertexUniformCount; i++) + { + vertexShader << "uniform vec4 v" << i << ";\n"; + } + + for (int i = 0; i < vertexSamplersCount; i++) + { + vertexShader << "uniform sampler2D s" << i << ";\n"; + } + + vertexShader << "void main()\n{\n"; + + for (int i = 0; i < vertexUniformCount; i++) + { + vertexShader << " gl_Position += v" << i << ";\n"; + } + + for (int i = 0; i < vertexSamplersCount; i++) + { + vertexShader << " gl_Position += texture2D(s" << i << ", vec2(0.0, 0.0));\n"; + } + + if (vertexUniformCount == 0 && vertexSamplersCount == 0) + { + vertexShader << " gl_Position = vec4(0.0);\n"; + } + + vertexShader << "}\n"; + + // Generate the fragment shader + fragmentShader << "precision mediump float;\n"; + + for (int i = 0; i < fragmentUniformCount; i++) + { + fragmentShader << "uniform vec4 v" << i << ";\n"; + } + + for (int i = 0; i < fragmentSamplersCount; i++) + { + fragmentShader << "uniform sampler2D s" << i << ";\n"; + } + + fragmentShader << "void main()\n{\n"; + + for (int i = 0; i < fragmentUniformCount; i++) + { + fragmentShader << " gl_FragColor += v" << i << ";\n"; + } + + for (int i = 0; i < fragmentSamplersCount; i++) + { + fragmentShader << " gl_FragColor += texture2D(s" << i << ", vec2(0.0, 0.0));\n"; + } + + if (fragmentUniformCount == 0 && fragmentSamplersCount == 0) + { + fragmentShader << " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"; + } + + fragmentShader << "}\n"; + + GLuint program = CompileProgram(vertexShader.str(), fragmentShader.str()); + + if (expectSuccess) + { + EXPECT_NE(0u, program); + } + else + { + EXPECT_EQ(0u, program); + } + } + + std::string mSimpleVSSource; +}; + +class GLSLTest_ES3 : public GLSLTest +{ + void SetUp() override + { + ANGLETest::SetUp(); + + mSimpleVSSource = + "#version 300 es\n" + "in vec4 inputAttribute;" + "void main()" + "{" + " gl_Position = inputAttribute;" + "}"; + } +}; + +TEST_P(GLSLTest, NamelessScopedStructs) +{ + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + + void main() + { + struct + { + float q; + } b; + + gl_FragColor = vec4(1, 0, 0, 1); + gl_FragColor.a += b.q; + } + ); + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +TEST_P(GLSLTest, ScopedStructsOrderBug) +{ + // TODO(geofflang): Find out why this doesn't compile on Apple OpenGL drivers + // (http://anglebug.com/1292) + // TODO(geofflang): Find out why this doesn't compile on AMD OpenGL drivers + // (http://anglebug.com/1291) + if (IsDesktopOpenGL() && (IsOSX() || !IsNVIDIA())) + { + std::cout << "Test disabled on this OpenGL configuration." << std::endl; + return; + } + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + + struct T + { + float f; + }; + + void main() + { + T a; + + struct T + { + float q; + }; + + T b; + + gl_FragColor = vec4(1, 0, 0, 1); + gl_FragColor.a += a.f; + gl_FragColor.a += b.q; + } + ); + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +TEST_P(GLSLTest, ScopedStructsBug) +{ + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + + struct T_0 + { + float f; + }; + + void main() + { + gl_FragColor = vec4(1, 0, 0, 1); + + struct T + { + vec2 v; + }; + + T_0 a; + T b; + + gl_FragColor.a += a.f; + gl_FragColor.a += b.v.x; + } + ); + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +TEST_P(GLSLTest, DxPositionBug) +{ + const std::string &vertexShaderSource = SHADER_SOURCE + ( + attribute vec4 inputAttribute; + varying float dx_Position; + void main() + { + gl_Position = vec4(inputAttribute); + dx_Position = 0.0; + } + ); + + const std::string &fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + + varying float dx_Position; + + void main() + { + gl_FragColor = vec4(dx_Position, 0, 0, 1); + } + ); + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +TEST_P(GLSLTest, ElseIfRewriting) +{ + const std::string &vertexShaderSource = + "attribute vec4 a_position;\n" + "varying float v;\n" + "void main() {\n" + " gl_Position = a_position;\n" + " v = 1.0;\n" + " if (a_position.x <= 0.5) {\n" + " v = 0.0;\n" + " } else if (a_position.x >= 0.5) {\n" + " v = 2.0;\n" + " }\n" + "}\n"; + + const std::string &fragmentShaderSource = + "precision highp float;\n" + "varying float v;\n" + "void main() {\n" + " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n" + " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n" + " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n" + " gl_FragColor = color;\n" + "}\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, program); + + drawQuad(program, "a_position", 0.5f); + + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255); +} + +TEST_P(GLSLTest, TwoElseIfRewriting) +{ + const std::string &vertexShaderSource = + "attribute vec4 a_position;\n" + "varying float v;\n" + "void main() {\n" + " gl_Position = a_position;\n" + " if (a_position.x == 0.0) {\n" + " v = 1.0;\n" + " } else if (a_position.x > 0.5) {\n" + " v = 0.0;\n" + " } else if (a_position.x > 0.75) {\n" + " v = 0.5;\n" + " }\n" + "}\n"; + + const std::string &fragmentShaderSource = + "precision highp float;\n" + "varying float v;\n" + "void main() {\n" + " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n" + "}\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +TEST_P(GLSLTest, FrontFacingAndVarying) +{ + EGLPlatformParameters platform = GetParam().eglParameters; + + const std::string vertexShaderSource = SHADER_SOURCE + ( + attribute vec4 a_position; + varying float v_varying; + void main() + { + v_varying = a_position.x; + gl_Position = a_position; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + varying float v_varying; + void main() + { + vec4 c; + + if (gl_FrontFacing) + { + c = vec4(v_varying, 0, 0, 1.0); + } + else + { + c = vec4(0, v_varying, 0, 1.0); + } + gl_FragColor = c; + } + ); + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + + // Compilation should fail on D3D11 feature level 9_3, since gl_FrontFacing isn't supported. + if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + if (platform.majorVersion == 9 && platform.minorVersion == 3) + { + EXPECT_EQ(0u, program); + return; + } + } + + // Otherwise, compilation should succeed + EXPECT_NE(0u, program); +} + +// Verify that linking shaders declaring different shading language versions fails. +TEST_P(GLSLTest_ES3, VersionMismatch) +{ + const std::string fragmentShaderSource100 = + "precision mediump float;\n" + "varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource100 = + "attribute vec4 a_position;\n" + "varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + const std::string fragmentShaderSource300 = + "#version 300 es\n" + "precision mediump float;\n" + "in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource300 = + "#version 300 es\n" + "in vec4 a_position;\n" + "out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource300, fragmentShaderSource100); + EXPECT_EQ(0u, program); + + program = CompileProgram(vertexShaderSource100, fragmentShaderSource300); + EXPECT_EQ(0u, program); +} + +// Verify that declaring varying as invariant only in vertex shader fails in ESSL 1.00. +TEST_P(GLSLTest, InvariantVaryingOut) +{ + const std::string fragmentShaderSource = + "precision mediump float;\n" + "varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "attribute vec4 a_position;\n" + "invariant varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that declaring varying as invariant only in vertex shader succeeds in ESSL 3.00. +TEST_P(GLSLTest_ES3, InvariantVaryingOut) +{ + // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader + // for varyings which are invariant in vertex shader (http://anglebug.com/1293) + if (IsDesktopOpenGL()) + { + std::cout << "Test disabled on OpenGL." << std::endl; + return; + } + + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "in vec4 a_position;\n" + "invariant out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that declaring varying as invariant only in fragment shader fails in ESSL 1.00. +TEST_P(GLSLTest, InvariantVaryingIn) +{ + const std::string fragmentShaderSource = + "precision mediump float;\n" + "invariant varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "attribute vec4 a_position;\n" + "varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that declaring varying as invariant only in fragment shader fails in ESSL 3.00. +TEST_P(GLSLTest_ES3, InvariantVaryingIn) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "invariant in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "in vec4 a_position;\n" + "out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that declaring varying as invariant in both shaders succeeds in ESSL 1.00. +TEST_P(GLSLTest, InvariantVaryingBoth) +{ + const std::string fragmentShaderSource = + "precision mediump float;\n" + "invariant varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "attribute vec4 a_position;\n" + "invariant varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that declaring varying as invariant in both shaders fails in ESSL 3.00. +TEST_P(GLSLTest_ES3, InvariantVaryingBoth) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "invariant in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "in vec4 a_position;\n" + "invariant out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that declaring gl_Position as invariant succeeds in ESSL 1.00. +TEST_P(GLSLTest, InvariantGLPosition) +{ + const std::string fragmentShaderSource = + "precision mediump float;\n" + "varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "attribute vec4 a_position;\n" + "invariant gl_Position;\n" + "varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that declaring gl_Position as invariant succeeds in ESSL 3.00. +TEST_P(GLSLTest_ES3, InvariantGLPosition) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "in vec4 a_position;\n" + "invariant gl_Position;\n" + "out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that using invariant(all) in both shaders succeeds in ESSL 1.00. +TEST_P(GLSLTest, InvariantAllBoth) +{ + // TODO: ESSL 1.00 -> GLSL 1.20 translation should add "invariant" in fragment shader + // for varyings which are invariant in vertex shader individually, + // and remove invariant(all) from fragment shader (http://anglebug.com/1293) + if (IsDesktopOpenGL()) + { + std::cout << "Test disabled on OpenGL." << std::endl; + return; + } + + const std::string fragmentShaderSource = + "#pragma STDGL invariant(all)\n" + "precision mediump float;\n" + "varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#pragma STDGL invariant(all)\n" + "attribute vec4 a_position;\n" + "varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest, MissingReturnFloat) +{ + const std::string vertexShaderSource = + "varying float v_varying;\n" + "float f() { if (v_varying > 0.0) return 1.0; }\n" + "void main() { gl_Position = vec4(f(), 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest, MissingReturnVec2) +{ + const std::string vertexShaderSource = + "varying float v_varying;\n" + "vec2 f() { if (v_varying > 0.0) return vec2(1.0, 1.0); }\n" + "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest, MissingReturnVec3) +{ + const std::string vertexShaderSource = + "varying float v_varying;\n" + "vec3 f() { if (v_varying > 0.0) return vec3(1.0, 1.0, 1.0); }\n" + "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest, MissingReturnVec4) +{ + const std::string vertexShaderSource = + "varying float v_varying;\n" + "vec4 f() { if (v_varying > 0.0) return vec4(1.0, 1.0, 1.0, 1.0); }\n" + "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest, MissingReturnIVec4) +{ + const std::string vertexShaderSource = + "varying float v_varying;\n" + "ivec4 f() { if (v_varying > 0.0) return ivec4(1, 1, 1, 1); }\n" + "void main() { gl_Position = vec4(f().x, 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest, MissingReturnMat4) +{ + const std::string vertexShaderSource = + "varying float v_varying;\n" + "mat4 f() { if (v_varying > 0.0) return mat4(1.0); }\n" + "void main() { gl_Position = vec4(f()[0][0], 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest, MissingReturnStruct) +{ + const std::string vertexShaderSource = + "varying float v_varying;\n" + "struct s { float a; int b; vec2 c; };\n" + "s f() { if (v_varying > 0.0) return s(1.0, 1, vec2(1.0, 1.0)); }\n" + "void main() { gl_Position = vec4(f().a, 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main() { gl_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest_ES3, MissingReturnArray) +{ + const std::string vertexShaderSource = + "#version 300 es\n" + "in float v_varying;\n" + "vec2[2] f() { if (v_varying > 0.0) { return vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0)); } }\n" + "void main() { gl_Position = vec4(f()[0].x, 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest_ES3, MissingReturnArrayOfStructs) +{ + const std::string vertexShaderSource = + "#version 300 es\n" + "in float v_varying;\n" + "struct s { float a; int b; vec2 c; };\n" + "s[2] f() { if (v_varying > 0.0) { return s[2](s(1.0, 1, vec2(1.0, 1.0)), s(1.0, 1, " + "vec2(1.0, 1.0))); } }\n" + "void main() { gl_Position = vec4(f()[0].a, 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that functions without return statements still compile +TEST_P(GLSLTest_ES3, MissingReturnStructOfArrays) +{ + // TODO(cwallez) remove the suppression once NVIDIA removes the restriction for + // GLSL >= 300. It was defined only in GLSL 2.0, section 6.1. + if (IsNVIDIA() && IsOpenGLES()) + { + std::cout << "Test skipped on NVIDIA OpenGL ES because it disallows returning " + "structure of arrays" + << std::endl; + return; + } + + const std::string vertexShaderSource = + "#version 300 es\n" + "in float v_varying;\n" + "struct s { float a[2]; int b[2]; vec2 c[2]; };\n" + "s f() { if (v_varying > 0.0) { return s(float[2](1.0, 1.0), int[2](1, 1)," + "vec2[2](vec2(1.0, 1.0), vec2(1.0, 1.0))); } }\n" + "void main() { gl_Position = vec4(f().a[0], 0, 0, 1); }\n"; + + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(0, 0, 0, 1); }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Verify that using invariant(all) in both shaders fails in ESSL 3.00. +TEST_P(GLSLTest_ES3, InvariantAllBoth) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "#pragma STDGL invariant(all)\n" + "precision mediump float;\n" + "in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "#pragma STDGL invariant(all)\n" + "in vec4 a_position;\n" + "out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that using invariant(all) only in fragment shader fails in ESSL 1.00. +TEST_P(GLSLTest, InvariantAllIn) +{ + const std::string fragmentShaderSource = + "#pragma STDGL invariant(all)\n" + "precision mediump float;\n" + "varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "attribute vec4 a_position;\n" + "varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that using invariant(all) only in fragment shader fails in ESSL 3.00. +TEST_P(GLSLTest_ES3, InvariantAllIn) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "#pragma STDGL invariant(all)\n" + "precision mediump float;\n" + "in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "in vec4 a_position;\n" + "out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that using invariant(all) only in vertex shader fails in ESSL 1.00. +TEST_P(GLSLTest, InvariantAllOut) +{ + const std::string fragmentShaderSource = + "precision mediump float;\n" + "varying float v_varying;\n" + "void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#pragma STDGL invariant(all)\n" + "attribute vec4 a_position;\n" + "varying float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_EQ(0u, program); +} + +// Verify that using invariant(all) only in vertex shader succeeds in ESSL 3.00. +TEST_P(GLSLTest_ES3, InvariantAllOut) +{ + // TODO: ESSL 3.00 -> GLSL 1.20 translation should add "invariant" in fragment shader + // for varyings which are invariant in vertex shader, + // because of invariant(all) being used in vertex shader (http://anglebug.com/1293) + if (IsDesktopOpenGL()) + { + std::cout << "Test disabled on OpenGL." << std::endl; + return; + } + + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "in float v_varying;\n" + "out vec4 my_FragColor;\n" + "void main() { my_FragColor = vec4(v_varying, 0, 0, 1.0); }\n"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "#pragma STDGL invariant(all)\n" + "in vec4 a_position;\n" + "out float v_varying;\n" + "void main() { v_varying = a_position.x; gl_Position = a_position; }\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +TEST_P(GLSLTest, MaxVaryingVec4) +{ +#if defined(__APPLE__) + // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers + // (http://anglebug.com/1291) + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test disabled on Apple AMD OpenGL." << std::endl; + return; + } +#endif + + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true); +} + +TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables. + VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true); +} + +TEST_P(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables) +{ + // TODO(geofflang): Figure out why this fails on OpenGL AMD (http://anglebug.com/1291) + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test disabled on OpenGL." << std::endl; + return; + } + + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize. + VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true); +} + +// Disabled because drivers are allowed to successfully compile shaders that have more than the +// maximum number of varyings. (http://anglebug.com/1296) +TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusFragCoord) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + // Generate shader code that uses gl_FragCoord, a special fragment shader variables. + // This test should fail, since we are really using (maxVaryings + 1) varyings. + VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false); +} + +// Disabled because drivers are allowed to successfully compile shaders that have more than the +// maximum number of varyings. (http://anglebug.com/1296) +TEST_P(GLSLTest, DISABLED_MaxVaryingVec4PlusPointCoord) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + // Generate shader code that uses gl_FragCoord, a special fragment shader variables. + // This test should fail, since we are really using (maxVaryings + 1) varyings. + VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false); +} + +TEST_P(GLSLTest, MaxVaryingVec3) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true); +} + +TEST_P(GLSLTest, MaxVaryingVec3Array) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true); +} + +// Disabled because of a failure in D3D9 +TEST_P(GLSLTest, MaxVaryingVec3AndOneFloat) +{ + if (IsD3D9()) + { + std::cout << "Test disabled on D3D9." << std::endl; + return; + } + + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true); +} + +// Disabled because of a failure in D3D9 +TEST_P(GLSLTest, MaxVaryingVec3ArrayAndOneFloatArray) +{ + if (IsD3D9()) + { + std::cout << "Test disabled on D3D9." << std::endl; + return; + } + + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true); +} + +// Disabled because of a failure in D3D9 +TEST_P(GLSLTest, TwiceMaxVaryingVec2) +{ + if (IsD3D9()) + { + std::cout << "Test disabled on D3D9." << std::endl; + return; + } + + if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver + std::cout << "Test disabled on OpenGL ES." << std::endl; + return; + } + +#if defined(__APPLE__) + // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers + // (http://anglebug.com/1291) + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test disabled on Apple AMD OpenGL." << std::endl; + return; + } +#endif + + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true); +} + +// Disabled because of a failure in D3D9 +TEST_P(GLSLTest, MaxVaryingVec2Arrays) +{ + if (IsD3DSM3()) + { + std::cout << "Test disabled on SM3." << std::endl; + return; + } + + if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + // TODO(geofflang): Figure out why this fails on NVIDIA's GLES driver + std::cout << "Test disabled on OpenGL ES." << std::endl; + return; + } + +#if defined(__APPLE__) + // TODO(geofflang): Find out why this doesn't compile on Apple AND OpenGL drivers + // (http://anglebug.com/1291) + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test disabled on Apple AMD OpenGL." << std::endl; + return; + } +#endif + + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true); +} + +// Disabled because drivers are allowed to successfully compile shaders that have more than the +// maximum number of varyings. (http://anglebug.com/1296) +TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false); +} + +// Disabled because drivers are allowed to successfully compile shaders that have more than the +// maximum number of varyings. (http://anglebug.com/1296) +TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec3Array) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false); +} + +// Disabled because drivers are allowed to successfully compile shaders that have more than the +// maximum number of varyings. (http://anglebug.com/1296) +TEST_P(GLSLTest, DISABLED_MaxVaryingVec3AndOneVec2) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false); +} + +// Disabled because drivers are allowed to successfully compile shaders that have more than the +// maximum number of varyings. (http://anglebug.com/1296) +TEST_P(GLSLTest, DISABLED_MaxPlusOneVaryingVec2) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false); +} + +// Disabled because drivers are allowed to successfully compile shaders that have more than the +// maximum number of varyings. (http://anglebug.com/1296) +TEST_P(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndMaxPlusOneFloatArray) +{ + GLint maxVaryings = 0; + glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings); + + VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false); +} + +// Verify shader source with a fixed length that is less than the null-terminated length will compile. +TEST_P(GLSLTest, FixedShaderLength) +{ + GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); + + const std::string appendGarbage = "abcasdfasdfasdfasdfasdf"; + const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage; + const char *sourceArray[1] = { source.c_str() }; + GLint lengths[1] = { static_cast<GLint>(source.length() - appendGarbage.length()) }; + glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths); + glCompileShader(shader); + + GLint compileResult; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult); + EXPECT_NE(compileResult, 0); +} + +// Verify that a negative shader source length is treated as a null-terminated length. +TEST_P(GLSLTest, NegativeShaderLength) +{ + GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); + + const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" }; + GLint lengths[1] = { -10 }; + glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths); + glCompileShader(shader); + + GLint compileResult; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult); + EXPECT_NE(compileResult, 0); +} + +// Check that having an invalid char after the "." doesn't cause an assert. +TEST_P(GLSLTest, InvalidFieldFirstChar) +{ + GLuint shader = glCreateShader(GL_VERTEX_SHADER); + const char *source = "void main() {vec4 x; x.}"; + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); + + GLint compileResult; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult); + EXPECT_EQ(0, compileResult); +} + +// Verify that a length array with mixed positive and negative values compiles. +TEST_P(GLSLTest, MixedShaderLengths) +{ + GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); + + const char *sourceArray[] = + { + "void main()", + "{", + " gl_FragColor = vec4(0, 0, 0, 0);", + "}", + }; + GLint lengths[] = + { + -10, + 1, + static_cast<GLint>(strlen(sourceArray[2])), + -1, + }; + ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths)); + + glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths); + glCompileShader(shader); + + GLint compileResult; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult); + EXPECT_NE(compileResult, 0); +} + +// Verify that zero-length shader source does not affect shader compilation. +TEST_P(GLSLTest, ZeroShaderLength) +{ + GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); + + const char *sourceArray[] = + { + "adfasdf", + "34534", + "void main() { gl_FragColor = vec4(0, 0, 0, 0); }", + "", + "asdfasdfsdsdf", + }; + GLint lengths[] = + { + 0, + 0, + -1, + 0, + 0, + }; + ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths)); + + glShaderSource(shader, static_cast<GLsizei>(ArraySize(sourceArray)), sourceArray, lengths); + glCompileShader(shader); + + GLint compileResult; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult); + EXPECT_NE(compileResult, 0); +} + +// Tests that bad index expressions don't crash ANGLE's translator. +// https://code.google.com/p/angleproject/issues/detail?id=857 +TEST_P(GLSLTest, BadIndexBug) +{ + const std::string &fragmentShaderSourceVec = + "precision mediump float;\n" + "uniform vec4 uniformVec;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(uniformVec[int()]);\n" + "}"; + + GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec); + EXPECT_EQ(0u, shader); + + if (shader != 0) + { + glDeleteShader(shader); + } + + const std::string &fragmentShaderSourceMat = + "precision mediump float;\n" + "uniform mat4 uniformMat;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(uniformMat[int()]);\n" + "}"; + + shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat); + EXPECT_EQ(0u, shader); + + if (shader != 0) + { + glDeleteShader(shader); + } + + const std::string &fragmentShaderSourceArray = + "precision mediump float;\n" + "uniform vec4 uniformArray;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(uniformArray[int()]);\n" + "}"; + + shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray); + EXPECT_EQ(0u, shader); + + if (shader != 0) + { + glDeleteShader(shader); + } +} + +// Test that structs defined in uniforms are translated correctly. +TEST_P(GLSLTest, StructSpecifiersUniforms) +{ + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + + uniform struct S { float field;} s; + + void main() + { + gl_FragColor = vec4(1, 0, 0, 1); + gl_FragColor.a += s.field; + } + ); + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Test that gl_DepthRange is not stored as a uniform location. Since uniforms +// beginning with "gl_" are filtered out by our validation logic, we must +// bypass the validation to test the behaviour of the implementation. +// (note this test is still Impl-independent) +TEST_P(GLSLTest, DepthRangeUniforms) +{ + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + + void main() + { + gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1); + } + ); + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + EXPECT_NE(0u, program); + + // dive into the ANGLE internals, so we can bypass validation. + gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext()); + gl::Program *glProgram = context->getProgram(program); + GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near"); + EXPECT_EQ(-1, nearIndex); + + // Test drawing does not throw an exception. + drawQuad(program, "inputAttribute", 0.5f); + + EXPECT_GL_NO_ERROR(); + + glDeleteProgram(program); +} + +std::string GenerateSmallPowShader(double base, double exponent) +{ + std::stringstream stream; + + stream.precision(8); + + double result = pow(base, exponent); + + stream << "precision highp float;\n" + << "float fun(float arg)\n" + << "{\n" + << " return pow(arg, " << std::fixed << exponent << ");\n" + << "}\n" + << "\n" + << "void main()\n" + << "{\n" + << " const float a = " << std::scientific << base << ";\n" + << " float b = fun(a);\n" + << " if (abs(" << result << " - b) < " << std::abs(result * 0.001) << ")\n" + << " {\n" + << " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" + << " }\n" + << " else\n" + << " {\n" + << " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + << " }\n" + << "}\n"; + + return stream.str(); +} + +// Covers the WebGL test 'glsl/bugs/pow-of-small-constant-in-user-defined-function' +// See http://anglebug.com/851 +TEST_P(GLSLTest, PowOfSmallConstant) +{ + std::vector<double> bads; + for (int eps = -1; eps <= 1; ++eps) + { + for (int i = -4; i <= 5; ++i) + { + if (i >= -1 && i <= 1) + continue; + const double epsilon = 1.0e-8; + double bad = static_cast<double>(i) + static_cast<double>(eps) * epsilon; + bads.push_back(bad); + } + } + + for (double bad : bads) + { + const std::string &fragmentShaderSource = GenerateSmallPowShader(1.0e-6, bad); + + ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShaderSource); + + drawQuad(program.get(), "inputAttribute", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + EXPECT_GL_NO_ERROR(); + } +} + +// Test that fragment shaders which contain non-constant loop indexers and compiled for FL9_3 and +// below +// fail with a specific error message. +// Additionally test that the same fragment shader compiles successfully with feature levels greater +// than FL9_3. +TEST_P(GLSLTest, LoopIndexingValidation) +{ + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision mediump float; + + uniform float loopMax; + + void main() + { + gl_FragColor = vec4(1, 0, 0, 1); + for (float l = 0.0; l < loopMax; l++) + { + if (loopMax > 3.0) + { + gl_FragColor.a += 0.1; + } + } + } + ); + + GLuint shader = glCreateShader(GL_FRAGMENT_SHADER); + + const char *sourceArray[1] = {fragmentShaderSource.c_str()}; + glShaderSource(shader, 1, sourceArray, nullptr); + glCompileShader(shader); + + GLint compileResult; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult); + + // If the test is configured to run limited to Feature Level 9_3, then it is + // assumed that shader compilation will fail with an expected error message containing + // "Loop index cannot be compared with non-constant expression" + if ((GetParam() == ES2_D3D11_FL9_3() || GetParam() == ES2_D3D9())) + { + if (compileResult != 0) + { + FAIL() << "Shader compilation succeeded, expected failure"; + } + else + { + GLint infoLogLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + + std::string infoLog; + infoLog.resize(infoLogLength); + glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]); + + if (infoLog.find("Loop index cannot be compared with non-constant expression") == + std::string::npos) + { + FAIL() << "Shader compilation failed with unexpected error message"; + } + } + } + else + { + EXPECT_NE(0, compileResult); + } + + if (shader != 0) + { + glDeleteShader(shader); + } +} + +// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS +// can actually be used. +TEST_P(GLSLTest, VerifyMaxVertexUniformVectors) +{ + int maxUniforms = 10000; + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms); + EXPECT_GL_NO_ERROR(); + std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl; + + CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, 0, 0, true); +} + +// Tests that the maximum uniforms count returned from querying GL_MAX_VERTEX_UNIFORM_VECTORS +// can actually be used along with the maximum number of texture samplers. +TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsWithSamplers) +{ + if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE || + GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + std::cout << "Test disabled on OpenGL." << std::endl; + return; + } + + int maxUniforms = 10000; + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms); + EXPECT_GL_NO_ERROR(); + std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS = " << maxUniforms << std::endl; + + int maxTextureImageUnits = 0; + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits); + + CompileGLSLWithUniformsAndSamplers(maxUniforms, 0, maxTextureImageUnits, 0, true); +} + +// Tests that the maximum uniforms count + 1 from querying GL_MAX_VERTEX_UNIFORM_VECTORS +// fails shader compilation. +TEST_P(GLSLTest, VerifyMaxVertexUniformVectorsExceeded) +{ + int maxUniforms = 10000; + glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &maxUniforms); + EXPECT_GL_NO_ERROR(); + std::cout << "Validating GL_MAX_VERTEX_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 << std::endl; + + CompileGLSLWithUniformsAndSamplers(maxUniforms + 1, 0, 0, 0, false); +} + +// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS +// can actually be used. +TEST_P(GLSLTest, VerifyMaxFragmentUniformVectors) +{ + int maxUniforms = 10000; + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms); + EXPECT_GL_NO_ERROR(); + std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS = " << maxUniforms << std::endl; + + CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, 0, true); +} + +// Tests that the maximum uniforms count returned from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS +// can actually be used along with the maximum number of texture samplers. +TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsWithSamplers) +{ + if (GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE || + GetParam().eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + std::cout << "Test disabled on OpenGL." << std::endl; + return; + } + + int maxUniforms = 10000; + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms); + EXPECT_GL_NO_ERROR(); + + int maxTextureImageUnits = 0; + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits); + + CompileGLSLWithUniformsAndSamplers(0, maxUniforms, 0, maxTextureImageUnits, true); +} + +// Tests that the maximum uniforms count + 1 from querying GL_MAX_FRAGMENT_UNIFORM_VECTORS +// fails shader compilation. +TEST_P(GLSLTest, VerifyMaxFragmentUniformVectorsExceeded) +{ + int maxUniforms = 10000; + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &maxUniforms); + EXPECT_GL_NO_ERROR(); + std::cout << "Validating GL_MAX_FRAGMENT_UNIFORM_VECTORS + 1 = " << maxUniforms + 1 + << std::endl; + + CompileGLSLWithUniformsAndSamplers(0, maxUniforms + 1, 0, 0, false); +} + +// Test that two constructors which have vec4 and mat2 parameters get disambiguated (issue in +// HLSL). +TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x2) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "out vec4 my_FragColor;\n" + "void main()\n" + "{\n" + " my_FragColor = vec4(0.0);\n" + "}"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "in vec4 a_vec;\n" + "in mat2 a_mat;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(a_vec) + vec4(a_mat);\n" + "}"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Test that two constructors which have mat2x3 and mat3x2 parameters get disambiguated. +// This was suspected to be an issue in HLSL, but HLSL seems to be able to natively choose between +// the function signatures in this case. +TEST_P(GLSLTest_ES3, AmbiguousConstructorCall2x3) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "out vec4 my_FragColor;\n" + "void main()\n" + "{\n" + " my_FragColor = vec4(0.0);\n" + "}"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "in mat3x2 a_matA;\n" + "in mat2x3 a_matB;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(a_matA) + vec4(a_matB);\n" + "}"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Test that two functions which have vec4 and mat2 parameters get disambiguated (issue in HLSL). +TEST_P(GLSLTest_ES3, AmbiguousFunctionCall2x2) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "out vec4 my_FragColor;\n" + "void main()\n" + "{\n" + " my_FragColor = vec4(0.0);\n" + "}"; + + const std::string vertexShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "in vec4 a_vec;\n" + "in mat2 a_mat;\n" + "vec4 foo(vec4 a)\n" + "{\n" + " return a;\n" + "}\n" + "vec4 foo(mat2 a)\n" + "{\n" + " return vec4(a[0][0]);\n" + "}\n" + "void main()\n" + "{\n" + " gl_Position = foo(a_vec) + foo(a_mat);\n" + "}"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Test that an user-defined function with a large number of float4 parameters doesn't fail due to +// the function name being too long. +TEST_P(GLSLTest_ES3, LargeNumberOfFloat4Parameters) +{ + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "out vec4 my_FragColor;\n" + "void main()\n" + "{\n" + " my_FragColor = vec4(0.0);\n" + "}"; + + std::stringstream vertexShaderStream; + const unsigned int paramCount = 1024u; + + vertexShaderStream << "#version 300 es\n" + "precision highp float;\n" + "in vec4 a_vec;\n" + "vec4 lotsOfVec4Parameters("; + for (unsigned int i = 0; i < paramCount; ++i) + { + vertexShaderStream << "vec4 a" << i << ", "; + } + vertexShaderStream << "vec4 aLast)\n" + "{\n" + " return "; + for (unsigned int i = 0; i < paramCount; ++i) + { + vertexShaderStream << "a" << i << " + "; + } + vertexShaderStream << "aLast;\n" + "}\n" + "void main()\n" + "{\n" + " gl_Position = lotsOfVec4Parameters("; + for (unsigned int i = 0; i < paramCount; ++i) + { + vertexShaderStream << "a_vec, "; + } + vertexShaderStream << "a_vec);\n" + "}"; + + GLuint program = CompileProgram(vertexShaderStream.str(), fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// This test was written specifically to stress DeferGlobalInitializers AST transformation. +// Test a shader where a global constant array is initialized with an expression containing array +// indexing. This initializer is tricky to constant fold, so if it's not constant folded it needs to +// be handled in a way that doesn't generate statements in the global scope in HLSL output. +// Also includes multiple array initializers in one declaration, where only the second one has +// array indexing. This makes sure that the qualifier for the declaration is set correctly if +// transformations are applied to the declaration also in the case of ESSL output. +TEST_P(GLSLTest_ES3, InitGlobalArrayWithArrayIndexing) +{ + // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1428 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + + const std::string vertexShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "in vec4 a_vec;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(a_vec);\n" + "}"; + + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "out vec4 my_FragColor;\n" + "const highp float f[2] = float[2](0.1, 0.2);\n" + "const highp float[2] g = float[2](0.3, 0.4), h = float[2](0.5, f[1]);\n" + "void main()\n" + "{\n" + " my_FragColor = vec4(h[1]);\n" + "}"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Test that index-constant sampler array indexing is supported. +TEST_P(GLSLTest, IndexConstantSamplerArrayIndexing) +{ + if (IsD3D11_FL93()) { + std::cout << "Test skipped on D3D11 FL 9.3." << std::endl; + return; + } + + const std::string vertexShaderSource = + "attribute vec4 vPosition;\n" + "void main()\n" + "{\n" + " gl_Position = vPosition;\n" + "}"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "uniform sampler2D uni[2];\n" + "\n" + "float zero(int x)\n" + "{\n" + " return float(x) - float(x);\n" + "}\n" + "\n" + "void main()\n" + "{\n" + " vec4 c = vec4(0,0,0,0);\n" + " for (int ii = 1; ii < 3; ++ii) {\n" + " if (c.x > 255.0) {\n" + " c.x = 255.0 + zero(ii);\n" + " break;\n" + " }\n" + // Index the sampler array with a predictable loop index (index-constant) as opposed to + // a true constant. This is valid in OpenGL ES but isn't in many Desktop OpenGL versions, + // without an extension. + " c += texture2D(uni[ii - 1], vec2(0.5, 0.5));\n" + " }\n" + " gl_FragColor = c;\n" + "}"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Test that the #pragma directive is supported and doesn't trigger a compilation failure on the +// native driver. The only pragma that gets passed to the OpenGL driver is "invariant" but we don't +// want to test its behavior, so don't use any varyings. +TEST_P(GLSLTest, PragmaDirective) +{ + const std::string vertexShaderSource = + "#pragma STDGL invariant(all)\n" + "void main()\n" + "{\n" + " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; + + const std::string fragmentShaderSource = + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0);\n" + "}\n"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + EXPECT_NE(0u, program); +} + +// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9). +// The function call that returns the array needs to be evaluated after ++j for the expression to +// return the correct value (true). +TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderArray) +{ + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 my_FragColor; \n" + "int[2] func(int param) {\n" + " return int[2](param, param);\n" + "}\n" + "void main() {\n" + " int a[2]; \n" + " for (int i = 0; i < 2; ++i) {\n" + " a[i] = 1;\n" + " }\n" + " int j = 0; \n" + " bool result = ((++j), (a == func(j)));\n" + " my_FragColor = vec4(0.0, (result ? 1.0 : 0.0), 0.0, 1.0);\n" + "}\n"; + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + ASSERT_NE(0u, program); + + drawQuad(program, "inputAttribute", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9). +// The short-circuiting expression needs to be evaluated after ++j for the expression to return the +// correct value (true). +TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderShortCircuit) +{ + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 my_FragColor; \n" + "void main() {\n" + " int j = 0; \n" + " bool result = ((++j), (j == 1 ? true : (++j == 3)));\n" + " my_FragColor = vec4(0.0, ((result && j == 1) ? 1.0 : 0.0), 0.0, 1.0);\n" + "}\n"; + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + ASSERT_NE(0u, program); + + drawQuad(program, "inputAttribute", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Sequence operator evaluates operands from left to right (ESSL 3.00 section 5.9). +// Indexing the vector needs to be evaluated after func() for the right result. +TEST_P(GLSLTest_ES3, SequenceOperatorEvaluationOrderDynamicVectorIndexingInLValue) +{ + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 my_FragColor;\n" + "uniform int u_zero;\n" + "int sideEffectCount = 0;\n" + "float func() {\n" + " ++sideEffectCount;\n" + " return -1.0;\n" + "}\n" + "void main() {\n" + " vec4 v = vec4(0.0, 2.0, 4.0, 6.0); \n" + " float f = (func(), (++v[u_zero + sideEffectCount]));\n" + " bool green = abs(f - 3.0) < 0.01 && abs(v[1] - 3.0) < 0.01 && sideEffectCount == 1;\n" + " my_FragColor = vec4(0.0, (green ? 1.0 : 0.0), 0.0, 1.0);\n" + "}\n"; + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource); + ASSERT_NE(0u, program); + + drawQuad(program, "inputAttribute", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that using gl_PointCoord with GL_TRIANGLES doesn't produce a link error. +// From WebGL test conformance/rendering/point-specific-shader-variables.html +// See http://anglebug.com/1380 +TEST_P(GLSLTest, RenderTrisWithPointCoord) +{ + const std::string &vert = + "attribute vec2 aPosition;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(aPosition, 0, 1);\n" + " gl_PointSize = 1.0;\n" + "}"; + const std::string &frag = + "void main()\n" + "{\n" + " gl_FragColor = vec4(gl_PointCoord.xy, 0, 1);\n" + " gl_FragColor = vec4(0, 1, 0, 1);\n" + "}"; + + ANGLE_GL_PROGRAM(prog, vert, frag); + drawQuad(prog.get(), "aPosition", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Convers a bug with the integer pow statement workaround. +TEST_P(GLSLTest, NestedPowStatements) +{ + const std::string &vert = + "attribute vec2 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position, 0, 1);\n" + "}"; + const std::string &frag = + "precision mediump float;\n" + "float func(float v)\n" + "{\n" + " float f1 = pow(v, 2.0);\n" + " return pow(f1 + v, 2.0);\n" + "}\n" + "void main()\n" + "{\n" + " float v = func(2.0);\n" + " gl_FragColor = abs(v - 36.0) < 0.001 ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n" + "}"; + + ANGLE_GL_PROGRAM(prog, vert, frag); + drawQuad(prog.get(), "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Convers a bug with the unary minus operator on signed integer workaround. +TEST_P(GLSLTest_ES3, UnaryMinusOperatorSignedInt) +{ + const std::string &vert = + "#version 300 es\n" + "in highp vec4 position;\n" + "out mediump vec4 v_color;\n" + "uniform int ui_one;\n" + "uniform int ui_two;\n" + "uniform int ui_three;\n" + "void main() {\n" + " int s[3];\n" + " s[0] = ui_one;\n" + " s[1] = -(-(-ui_two + 1) + 1);\n" // s[1] = -ui_two + " s[2] = ui_three;\n" + " int result = 0;\n" + " for (int i = 0; i < ui_three; i++) {\n" + " result += s[i];\n" + " }\n" + " v_color = (result == 2) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n" + " gl_Position = position;\n" + "}\n"; + const std::string &frag = + "#version 300 es\n" + "in mediump vec4 v_color;\n" + "layout(location=0) out mediump vec4 o_color;\n" + "void main() {\n" + " o_color = v_color;\n" + "}\n"; + + ANGLE_GL_PROGRAM(prog, vert, frag); + + gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext()); + gl::Program *glProgram = context->getProgram(prog.get()); + GLint oneIndex = glProgram->getUniformLocation("ui_one"); + ASSERT_NE(-1, oneIndex); + GLint twoIndex = glProgram->getUniformLocation("ui_two"); + ASSERT_NE(-1, twoIndex); + GLint threeIndex = glProgram->getUniformLocation("ui_three"); + ASSERT_NE(-1, threeIndex); + glUseProgram(prog.get()); + glUniform1i(oneIndex, 1); + glUniform1i(twoIndex, 2); + glUniform1i(threeIndex, 3); + + drawQuad(prog.get(), "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Convers a bug with the unary minus operator on unsigned integer workaround. +TEST_P(GLSLTest_ES3, UnaryMinusOperatorUnsignedInt) +{ + const std::string &vert = + "#version 300 es\n" + "in highp vec4 position;\n" + "out mediump vec4 v_color;\n" + "uniform uint ui_one;\n" + "uniform uint ui_two;\n" + "uniform uint ui_three;\n" + "void main() {\n" + " uint s[3];\n" + " s[0] = ui_one;\n" + " s[1] = -(-(-ui_two + 1u) + 1u);\n" // s[1] = -ui_two + " s[2] = ui_three;\n" + " uint result = 0u;\n" + " for (uint i = 0u; i < ui_three; i++) {\n" + " result += s[i];\n" + " }\n" + " v_color = (result == 2u) ? vec4(0, 1, 0, 1) : vec4(1, 0, 0, 1);\n" + " gl_Position = position;\n" + "}\n"; + const std::string &frag = + "#version 300 es\n" + "in mediump vec4 v_color;\n" + "layout(location=0) out mediump vec4 o_color;\n" + "void main() {\n" + " o_color = v_color;\n" + "}\n"; + + ANGLE_GL_PROGRAM(prog, vert, frag); + + gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext()); + gl::Program *glProgram = context->getProgram(prog.get()); + GLint oneIndex = glProgram->getUniformLocation("ui_one"); + ASSERT_NE(-1, oneIndex); + GLint twoIndex = glProgram->getUniformLocation("ui_two"); + ASSERT_NE(-1, twoIndex); + GLint threeIndex = glProgram->getUniformLocation("ui_three"); + ASSERT_NE(-1, threeIndex); + glUseProgram(prog.get()); + glUniform1ui(oneIndex, 1u); + glUniform1ui(twoIndex, 2u); + glUniform1ui(threeIndex, 3u); + + drawQuad(prog.get(), "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test a nested sequence operator with a ternary operator inside. The ternary operator is +// intended to be such that it gets converted to an if statement on the HLSL backend. +TEST_P(GLSLTest, NestedSequenceOperatorWithTernaryInside) +{ + const std::string &vert = + "attribute vec2 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position, 0, 1);\n" + "}"; + + // Note that the uniform keep_flop_positive doesn't need to be set - the test expects it to have + // its default value false. + const std::string &frag = + "precision mediump float;\n" + "uniform bool keep_flop_positive;\n" + "float flop;\n" + "void main() {\n" + " flop = -1.0,\n" + " (flop *= -1.0,\n" + " keep_flop_positive ? 0.0 : flop *= -1.0),\n" + " gl_FragColor = vec4(0, -flop, 0, 1);\n" + "}"; + + ANGLE_GL_PROGRAM(prog, vert, frag); + drawQuad(prog.get(), "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that using a sampler2D and samplerExternalOES in the same shader works (anglebug.com/1534) +TEST_P(GLSLTest, ExternalAnd2DSampler) +{ + if (!extensionEnabled("GL_OES_EGL_image_external")) + { + std::cout << "Test skipped because GL_OES_EGL_image_external is not available." + << std::endl; + return; + } + + const std::string fragmentShader = + "precision mediump float;\n" + "uniform samplerExternalOES tex0;\n" + "uniform sampler2D tex1;\n" + "void main(void)\n" + "{\n" + " vec2 uv = vec2(0.0, 0.0);" + " gl_FragColor = texture2D(tex0, uv) + texture2D(tex1, uv);\n" + "}\n"; + + ANGLE_GL_PROGRAM(program, mSimpleVSSource, fragmentShader); +} + +// Test that using an invalid constant right-shift produces an error. +TEST_P(GLSLTest_ES3, FoldedInvalidRightShift) +{ + const std::string &fragmentShader = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 color;\n" + "void main(void)\n" + "{\n" + " int diff = -100 >> -100;\n" + " color = vec4(float(diff));\n" + "}\n"; + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShader); + EXPECT_EQ(0u, program); + glDeleteProgram(program); +} + +// Test that using an invalid constant left-shift produces an error. +TEST_P(GLSLTest_ES3, FoldedInvalidLeftShift) +{ + const std::string &fragmentShader = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 color;\n" + "void main(void)\n" + "{\n" + " int diff = -100 << -100;\n" + " color = vec4(float(diff));\n" + "}\n"; + + GLuint program = CompileProgram(mSimpleVSSource, fragmentShader); + EXPECT_EQ(0u, program); + glDeleteProgram(program); +} + +} // anonymous namespace + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(GLSLTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(GLSLTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/ImageTest.cpp b/gfx/angle/src/tests/gl_tests/ImageTest.cpp new file mode 100755 index 000000000..cb88c489d --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ImageTest.cpp @@ -0,0 +1,1973 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ImageTest: +// Tests the correctness of eglImage. +// + +#include "test_utils/ANGLETest.h" + +namespace angle +{ +class ImageTest : public ANGLETest +{ + protected: + ImageTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vsSource = + "precision highp float;\n" + "attribute vec4 position;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + " texcoord.y = 1.0 - texcoord.y;\n" + "}\n"; + const std::string vsESSL3Source = + "#version 300 es\n" + "precision highp float;\n" + "in vec4 position;\n" + "out vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + " texcoord.y = 1.0 - texcoord.y;\n" + "}\n"; + + const std::string textureFSSource = + "precision highp float;\n" + "uniform sampler2D tex;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(tex, texcoord);\n" + "}\n"; + const std::string textureExternalFSSource = + "#extension GL_OES_EGL_image_external : require\n" + "precision highp float;\n" + "uniform samplerExternalOES tex;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(tex, texcoord);\n" + "}\n"; + const std::string textureExternalESSL3FSSource = + "#version 300 es\n" + "#extension GL_OES_EGL_image_external_essl3 : require\n" + "precision highp float;\n" + "uniform samplerExternalOES tex;\n" + "in vec2 texcoord;\n" + "out vec4 color;" + "\n" + "void main()\n" + "{\n" + " color = texture(tex, texcoord);\n" + "}\n"; + + mTextureProgram = CompileProgram(vsSource, textureFSSource); + if (mTextureProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); + + if (extensionEnabled("GL_OES_EGL_image_external")) + { + mTextureExternalProgram = CompileProgram(vsSource, textureExternalFSSource); + ASSERT_NE(0u, mTextureExternalProgram) << "shader compilation failed."; + + mTextureExternalUniformLocation = glGetUniformLocation(mTextureExternalProgram, "tex"); + } + + if (extensionEnabled("GL_OES_EGL_image_external_essl3")) + { + mTextureExternalESSL3Program = + CompileProgram(vsESSL3Source, textureExternalESSL3FSSource); + ASSERT_NE(0u, mTextureExternalESSL3Program) << "shader compilation failed."; + + mTextureExternalESSL3UniformLocation = + glGetUniformLocation(mTextureExternalESSL3Program, "tex"); + } + + eglCreateImageKHR = + reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR")); + eglDestroyImageKHR = + reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR")); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mTextureProgram); + glDeleteProgram(mTextureExternalProgram); + glDeleteProgram(mTextureExternalESSL3Program); + + ANGLETest::TearDown(); + } + + void createEGLImage2DTextureSource(size_t width, + size_t height, + GLenum format, + GLenum type, + void *data, + GLuint *outSourceTexture, + EGLImageKHR *outSourceImage) + { + // Create a source 2D texture + GLuint source; + glGenTextures(1, &source); + glBindTexture(GL_TEXTURE_2D, source); + + glTexImage2D(GL_TEXTURE_2D, 0, format, static_cast<GLsizei>(width), + static_cast<GLsizei>(height), 0, format, type, data); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + ASSERT_GL_NO_ERROR(); + + // Create an image from the source texture + EGLWindow *window = getEGLWindow(); + EGLImageKHR image = + eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(source), nullptr); + + ASSERT_EGL_SUCCESS(); + + *outSourceTexture = source; + *outSourceImage = image; + } + + void createEGLImageCubemapTextureSource(size_t width, + size_t height, + GLenum format, + GLenum type, + uint8_t *data, + size_t dataStride, + EGLenum imageTarget, + GLuint *outSourceTexture, + EGLImageKHR *outSourceImage) + { + // Create a source cube map texture + GLuint source; + glGenTextures(1, &source); + glBindTexture(GL_TEXTURE_CUBE_MAP, source); + + for (GLenum faceIdx = 0; faceIdx < 6; faceIdx++) + { + glTexImage2D(faceIdx + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, + static_cast<GLsizei>(width), static_cast<GLsizei>(height), 0, format, type, + data + (faceIdx * dataStride)); + } + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + ASSERT_GL_NO_ERROR(); + + // Create an image from the source texture + EGLWindow *window = getEGLWindow(); + EGLImageKHR image = + eglCreateImageKHR(window->getDisplay(), window->getContext(), imageTarget, + reinterpretHelper<EGLClientBuffer>(source), nullptr); + + ASSERT_EGL_SUCCESS(); + + *outSourceTexture = source; + *outSourceImage = image; + } + + void createEGLImage3DTextureSource(size_t width, + size_t height, + size_t depth, + GLenum format, + GLenum type, + void *data, + size_t imageLayer, + GLuint *outSourceTexture, + EGLImageKHR *outSourceImage) + { + // Create a source 3D texture + GLuint source; + glGenTextures(1, &source); + glBindTexture(GL_TEXTURE_3D, source); + + glTexImage3D(GL_TEXTURE_3D, 0, format, static_cast<GLsizei>(width), + static_cast<GLsizei>(height), static_cast<GLsizei>(depth), 0, format, type, + data); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + ASSERT_GL_NO_ERROR(); + + // Create an image from the source texture + EGLWindow *window = getEGLWindow(); + + EGLint attribs[] = { + EGL_GL_TEXTURE_ZOFFSET_KHR, static_cast<EGLint>(imageLayer), EGL_NONE, + }; + EGLImageKHR image = + eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_3D_KHR, + reinterpretHelper<EGLClientBuffer>(source), attribs); + + ASSERT_EGL_SUCCESS(); + + *outSourceTexture = source; + *outSourceImage = image; + } + + void createEGLImageRenderbufferSource(size_t width, + size_t height, + GLenum internalFormat, + GLubyte data[4], + GLuint *outSourceRenderbuffer, + EGLImageKHR *outSourceImage) + { + // Create a source renderbuffer + GLuint source; + glGenRenderbuffers(1, &source); + glBindRenderbuffer(GL_RENDERBUFFER, source); + glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, static_cast<GLsizei>(width), + static_cast<GLsizei>(height)); + + // Create a framebuffer and clear it to set the data + GLuint framebuffer; + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, source); + + glClearColor(data[0] / 255.0f, data[1] / 255.0f, data[2] / 255.0f, data[3] / 255.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glDeleteFramebuffers(1, &framebuffer); + + ASSERT_GL_NO_ERROR(); + + // Create an image from the source renderbuffer + EGLWindow *window = getEGLWindow(); + EGLImageKHR image = + eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_RENDERBUFFER_KHR, + reinterpretHelper<EGLClientBuffer>(source), nullptr); + + ASSERT_EGL_SUCCESS(); + + *outSourceRenderbuffer = source; + *outSourceImage = image; + } + + void createEGLImageTargetTexture2D(EGLImageKHR image, GLuint *outTargetTexture) + { + // Create a target texture from the image + GLuint target; + glGenTextures(1, &target); + glBindTexture(GL_TEXTURE_2D, target); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + ASSERT_GL_NO_ERROR(); + + *outTargetTexture = target; + } + + void createEGLImageTargetTextureExternal(EGLImageKHR image, GLuint *outTargetTexture) + { + // Create a target texture from the image + GLuint target; + glGenTextures(1, &target); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, target); + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, image); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + ASSERT_GL_NO_ERROR(); + + *outTargetTexture = target; + } + + void createEGLImageTargetRenderbuffer(EGLImageKHR image, GLuint *outTargetRenderbuffer) + { + // Create a target texture from the image + GLuint target; + glGenRenderbuffers(1, &target); + glBindRenderbuffer(GL_RENDERBUFFER, target); + glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image); + + ASSERT_GL_NO_ERROR(); + + *outTargetRenderbuffer = target; + } + + void verifyResultsTexture(GLuint texture, + GLubyte data[4], + GLenum textureTarget, + GLuint program, + GLuint textureUniform) + { + // Draw a quad with the target texture + glUseProgram(program); + glBindTexture(textureTarget, texture); + glUniform1i(textureUniform, 0); + + drawQuad(program, "position", 0.5f); + + // Expect that the rendered quad has the same color as the source texture + EXPECT_PIXEL_EQ(0, 0, data[0], data[1], data[2], data[3]); + } + + void verifyResults2D(GLuint texture, GLubyte data[4]) + { + verifyResultsTexture(texture, data, GL_TEXTURE_2D, mTextureProgram, + mTextureUniformLocation); + } + + void verifyResultsExternal(GLuint texture, GLubyte data[4]) + { + verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalProgram, + mTextureExternalUniformLocation); + } + + void verifyResultsExternalESSL3(GLuint texture, GLubyte data[4]) + { + verifyResultsTexture(texture, data, GL_TEXTURE_EXTERNAL_OES, mTextureExternalESSL3Program, + mTextureExternalESSL3UniformLocation); + } + + void verifyResultsRenderbuffer(GLuint renderbuffer, GLubyte data[4]) + { + // Bind the renderbuffer to a framebuffer + GLuint framebuffer; + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + renderbuffer); + + // Expect that the rendered quad has the same color as the source texture + EXPECT_PIXEL_EQ(0, 0, data[0], data[1], data[2], data[3]); + + glDeleteFramebuffers(1, &framebuffer); + } + + template <typename destType, typename sourcetype> + destType reinterpretHelper(sourcetype source) + { + static_assert(sizeof(destType) == sizeof(size_t), + "destType should be the same size as a size_t"); + size_t sourceSizeT = static_cast<size_t>(source); + return reinterpret_cast<destType>(sourceSizeT); + } + + GLuint mTextureProgram; + GLint mTextureUniformLocation; + + GLuint mTextureExternalProgram = 0; + GLint mTextureExternalUniformLocation = -1; + + GLuint mTextureExternalESSL3Program = 0; + GLint mTextureExternalESSL3UniformLocation = -1; + + PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; + PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; +}; + +class ImageTestES3 : public ImageTest +{ +}; + +// Check validation from the EGL_KHR_image_base extension +TEST_P(ImageTest, ValidationImageBase) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLuint glTexture2D; + glGenTextures(1, &glTexture2D); + glBindTexture(GL_TEXTURE_2D, glTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + EGLDisplay display = window->getDisplay(); + EGLContext context = window->getContext(); + EGLConfig config = window->getConfig(); + EGLImageKHR image = EGL_NO_IMAGE_KHR; + EGLClientBuffer texture2D = reinterpretHelper<EGLClientBuffer>(glTexture2D); + + // Test validation of eglCreateImageKHR + + // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is + // generated. + image = eglCreateImageKHR(reinterpretHelper<EGLDisplay>(0xBAADF00D), context, + EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_DISPLAY); + + // If <ctx> is neither the handle of a valid EGLContext object on <dpy> nor EGL_NO_CONTEXT, the + // error EGL_BAD_CONTEXT is generated. + image = eglCreateImageKHR(display, reinterpretHelper<EGLContext>(0xBAADF00D), + EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_CONTEXT); + + // Test EGL_NO_CONTEXT with a 2D texture target which does require a context. + image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_CONTEXT); + + // If an attribute specified in <attrib_list> is not one of the attributes listed in Table bbb, + // the error EGL_BAD_PARAMETER is generated. + EGLint badAttributes[] = { + static_cast<EGLint>(0xDEADBEEF), 0, EGL_NONE, + }; + + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, badAttributes); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> has an off - + // screen buffer bound to it(e.g., by a + // previous call to eglBindTexImage), the error EGL_BAD_ACCESS is generated. + EGLint surfaceType = 0; + eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType); + + EGLint bindToTextureRGBA = 0; + eglGetConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBA); + if ((surfaceType & EGL_PBUFFER_BIT) != 0 && bindToTextureRGBA == EGL_TRUE) + { + EGLint pbufferAttributes[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, + EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, + EGL_NONE, EGL_NONE, + }; + EGLSurface pbuffer = eglCreatePbufferSurface(display, config, pbufferAttributes); + ASSERT_NE(pbuffer, EGL_NO_SURFACE); + EXPECT_EGL_SUCCESS(); + + eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER); + EXPECT_EGL_SUCCESS(); + + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_ACCESS); + + eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER); + eglDestroySurface(display, pbuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + EXPECT_EGL_SUCCESS(); + EXPECT_GL_NO_ERROR(); + } + + // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and + // <attrib_list> is itself an EGLImage sibling, the error EGL_BAD_ACCESS is generated. + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, texture2D, nullptr); + EXPECT_NE(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_SUCCESS(); + + /* TODO(geofflang): Enable this validation when it passes. + EGLImageKHR image2 = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, + reinterpret_cast<EGLClientBuffer>(texture2D), nullptr); + EXPECT_EQ(image2, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_ACCESS); + */ + + // Test validation of eglDestroyImageKHR + // Note: image is now a valid EGL image + EGLBoolean result = EGL_FALSE; + + // If <dpy> is not the handle of a valid EGLDisplay object, the error EGL_BAD_DISPLAY is + // generated. + result = eglDestroyImageKHR(reinterpretHelper<EGLDisplay>(0xBAADF00D), image); + EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE)); + EXPECT_EGL_ERROR(EGL_BAD_DISPLAY); + + // If <image> is not a valid EGLImageKHR object created with respect to <dpy>, the error + // EGL_BAD_PARAMETER is generated. + result = eglDestroyImageKHR(display, reinterpretHelper<EGLImageKHR>(0xBAADF00D)); + EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_FALSE)); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + // Clean up and validate image is destroyed + result = eglDestroyImageKHR(display, image); + EXPECT_EQ(result, static_cast<EGLBoolean>(EGL_TRUE)); + EXPECT_EGL_SUCCESS(); + + glDeleteTextures(1, &glTexture2D); + EXPECT_GL_NO_ERROR(); +} + +// Check validation from the EGL_KHR_gl_texture_2D_image extension +TEST_P(ImageTest, ValidationImagePixmap) +{ + // This extension is not implemented anywhere yet. This makes sure that it is tested once it is + // added. + EGLWindow *window = getEGLWindow(); + EXPECT_FALSE(eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_pixmap")); +} + +// Check validation from the EGL_KHR_gl_texture_2D_image, EGL_KHR_gl_texture_cubemap_image, +// EGL_KHR_gl_texture_3D_image and EGL_KHR_gl_renderbuffer_image extensions +TEST_P(ImageTest, ValidationGLImage) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base")) + { + std::cout << "Test skipped because OES_EGL_image or EGL_KHR_image_base is not available." + << std::endl; + return; + } + + EGLDisplay display = window->getDisplay(); + EGLContext context = window->getContext(); + EGLImageKHR image = EGL_NO_IMAGE_KHR; + + if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR or + // EGL_GL_TEXTURE_3D_KHR and <buffer> is not the name of a texture object of type <target>, + // the error EGL_BAD_PARAMETER is generated. + GLuint textureCube; + glGenTextures(1, &textureCube); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube); + for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + face++) + { + glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + } + + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(textureCube), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR, + // EGL_GL_TEXTURE_CUBE_MAP_*_KHR or EGL_GL_TEXTURE_3D_KHR, <buffer> is the name of an + // incomplete GL texture object, and any mipmap levels other than mipmap level 0 are + // specified, the error EGL_BAD_PARAMETER is generated. + GLuint incompleteTexture; + glGenTextures(1, &incompleteTexture); + glBindTexture(GL_TEXTURE_2D, incompleteTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + EGLint level0Attribute[] = { + EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE, + }; + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(incompleteTexture), + level0Attribute); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_2D_KHR or + // EGL_GL_TEXTURE_3D_KHR, <buffer> is not the name of a complete GL texture object, and + // mipmap level 0 is not specified, the error EGL_BAD_PARAMETER is generated. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(incompleteTexture), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR, + // EGL_GL_RENDERBUFFER_KHR or EGL_GL_TEXTURE_3D_KHR and <buffer> refers to the default GL + // texture object(0) for the corresponding GL target, the error EGL_BAD_PARAMETER is + // generated. + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, 0, nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + // If <target> is EGL_GL_TEXTURE_2D_KHR, EGL_GL_TEXTURE_CUBE_MAP_*_KHR, or + // EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for + // EGL_GL_TEXTURE_LEVEL_KHR is not a valid mipmap level for the specified GL texture object + // <buffer>, the error EGL_BAD_MATCH is generated. + EGLint level2Attribute[] = { + EGL_GL_TEXTURE_LEVEL_KHR, 2, EGL_NONE, + }; + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(incompleteTexture), + level2Attribute); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + else + { + GLuint texture2D; + glGenTextures(1, &texture2D); + glBindTexture(GL_TEXTURE_2D, texture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + // From EGL_KHR_image_base: + // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is + // generated. + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(texture2D), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + + if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image")) + { + // If EGL_GL_TEXTURE_LEVEL_KHR is 0, <target> is EGL_GL_TEXTURE_CUBE_MAP_*_KHR, <buffer> is + // not the name of a complete GL texture object, and one or more faces do not have mipmap + // level 0 specified, the error EGL_BAD_PARAMETER is generated. + GLuint incompleteTextureCube; + glGenTextures(1, &incompleteTextureCube); + glBindTexture(GL_TEXTURE_CUBE_MAP, incompleteTextureCube); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + + EGLint level0Attribute[] = { + EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE, + }; + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, + reinterpretHelper<EGLClientBuffer>(incompleteTextureCube), + level0Attribute); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + else + { + GLuint textureCube; + glGenTextures(1, &textureCube); + glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube); + for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + face++) + { + glTexImage2D(face, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + } + + // From EGL_KHR_image_base: + // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is + // generated. + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, + reinterpretHelper<EGLClientBuffer>(textureCube), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + + if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image") && + getClientMajorVersion() >= 3) + { + // If <target> is EGL_GL_TEXTURE_3D_KHR, and the value specified in <attr_list> for + // EGL_GL_TEXTURE_ZOFFSET_KHR exceeds the depth of the specified mipmap level - of - detail + // in <buffer>, the error EGL_BAD_PARAMETER is generated. + GLuint texture3D; + glGenTextures(1, &texture3D); + glBindTexture(GL_TEXTURE_3D, texture3D); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + EGLint zOffset3Parameter[] = { + EGL_GL_TEXTURE_ZOFFSET_KHR, 3, EGL_NONE, + }; + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR, + reinterpretHelper<EGLClientBuffer>(texture3D), zOffset3Parameter); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + EGLint zOffsetNegative1Parameter[] = { + EGL_GL_TEXTURE_ZOFFSET_KHR, -1, EGL_NONE, + }; + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR, + reinterpretHelper<EGLClientBuffer>(texture3D), + zOffsetNegative1Parameter); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + else + { + if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + GLuint texture2D; + glGenTextures(1, &texture2D); + glBindTexture(GL_TEXTURE_2D, texture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + // Verify EGL_GL_TEXTURE_ZOFFSET_KHR is not a valid parameter + EGLint zOffset0Parameter[] = { + EGL_GL_TEXTURE_ZOFFSET_KHR, 0, EGL_NONE, + }; + + image = + eglCreateImageKHR(display, context, EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(texture2D), zOffset0Parameter); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + + if (getClientMajorVersion() >= 3) + { + GLuint texture3D; + glGenTextures(1, &texture3D); + glBindTexture(GL_TEXTURE_3D, texture3D); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + // From EGL_KHR_image_base: + // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is + // generated. + image = eglCreateImageKHR(display, context, EGL_GL_TEXTURE_3D_KHR, + reinterpretHelper<EGLClientBuffer>(texture3D), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + } + + if (eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image")) + { + // If <target> is EGL_GL_RENDERBUFFER_KHR and <buffer> is not the name of a renderbuffer + // object, or if <buffer> is the name of a multisampled renderbuffer object, the error + // EGL_BAD_PARAMETER is generated. + image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR, + reinterpret_cast<EGLClientBuffer>(0), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + + if (extensionEnabled("GL_ANGLE_framebuffer_multisample")) + { + GLuint renderbuffer; + glGenRenderbuffers(1, &renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1); + EXPECT_GL_NO_ERROR(); + + image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR, + reinterpret_cast<EGLClientBuffer>(0), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } + } + else + { + GLuint renderbuffer; + glGenRenderbuffers(1, &renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, 1, 1); + + // From EGL_KHR_image_base: + // If <target> is not one of the values in Table aaa, the error EGL_BAD_PARAMETER is + // generated. + image = eglCreateImageKHR(display, context, EGL_GL_RENDERBUFFER_KHR, + reinterpretHelper<EGLClientBuffer>(renderbuffer), nullptr); + EXPECT_EQ(image, EGL_NO_IMAGE_KHR); + EXPECT_EGL_ERROR(EGL_BAD_PARAMETER); + } +} + +// Check validation from the GL_OES_EGL_image extension +TEST_P(ImageTest, ValidationGLEGLImage) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image); + + // If <target> is not TEXTURE_2D, the error INVALID_ENUM is generated. + glEGLImageTargetTexture2DOES(GL_TEXTURE_CUBE_MAP_POSITIVE_X, image); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // If <image> does not refer to a valid eglImageOES object, the error INVALID_VALUE is + // generated. + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, reinterpretHelper<GLeglImageOES>(0xBAADF00D)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // <target> must be RENDERBUFFER_OES, and <image> must be the handle of a valid EGLImage + // resource, cast into the type + // eglImageOES. + glEGLImageTargetRenderbufferStorageOES(GL_TEXTURE_2D, image); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // If the GL is unable to create a renderbuffer using the specified eglImageOES, the error + // INVALID_OPERATION is generated.If <image> + // does not refer to a valid eglImageOES object, the error INVALID_VALUE is generated. + GLuint renderbuffer; + glGenRenderbuffers(1, &renderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); + glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, + reinterpretHelper<GLeglImageOES>(0xBAADF00D)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &texture); + glDeleteRenderbuffers(1, &renderbuffer); +} + +// Check validation from the GL_OES_EGL_image_external extension +TEST_P(ImageTest, ValidationGLEGLImageExternal) +{ + if (!extensionEnabled("GL_OES_EGL_image_external")) + { + std::cout << "Test skipped because GL_OES_EGL_image_external is not available." + << std::endl; + return; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture); + + // In the initial state of a TEXTURE_EXTERNAL_OES texture object, the value assigned to + // TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER is LINEAR, and the s and t wrap modes are both set + // to CLAMP_TO_EDGE + auto getTexParam = [](GLenum target, GLenum pname) + { + GLint value = 0; + glGetTexParameteriv(target, pname, &value); + EXPECT_GL_NO_ERROR(); + return value; + }; + EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER)); + EXPECT_GLENUM_EQ(GL_LINEAR, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER)); + EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S)); + EXPECT_GLENUM_EQ(GL_CLAMP_TO_EDGE, getTexParam(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T)); + + // "When <target> is TEXTURE_EXTERNAL_OES only NEAREST and LINEAR are accepted as + // TEXTURE_MIN_FILTER, only CLAMP_TO_EDGE is accepted as TEXTURE_WRAP_S and TEXTURE_WRAP_T, and + // only FALSE is accepted as GENERATE_MIPMAP. Attempting to set other values for + // TEXTURE_MIN_FILTER, TEXTURE_WRAP_S, TEXTURE_WRAP_T, or GENERATE_MIPMAP will result in an + // INVALID_ENUM error. + GLenum validMinFilters[]{ + GL_NEAREST, GL_LINEAR, + }; + for (auto minFilter : validMinFilters) + { + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter); + EXPECT_GL_NO_ERROR(); + } + + GLenum invalidMinFilters[]{ + GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, + GL_LINEAR_MIPMAP_NEAREST, + }; + for (auto minFilter : invalidMinFilters) + { + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, minFilter); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } + + GLenum validWrapModes[]{ + GL_CLAMP_TO_EDGE, + }; + for (auto minFilter : validWrapModes) + { + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, minFilter); + EXPECT_GL_NO_ERROR(); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, minFilter); + EXPECT_GL_NO_ERROR(); + } + + GLenum invalidWrapModes[]{ + GL_REPEAT, GL_MIRRORED_REPEAT, + }; + for (auto minFilter : invalidWrapModes) + { + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, minFilter); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, minFilter); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } + + // When <target> is set to TEXTURE_EXTERNAL_OES, GenerateMipmap always fails and generates an + // INVALID_ENUM error. + glGenerateMipmap(GL_TEXTURE_EXTERNAL_OES); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glDeleteTextures(1, &texture); +} + +// Check validation from the GL_OES_EGL_image_external_essl3 extension +TEST_P(ImageTest, ValidationGLEGLImageExternalESSL3) +{ + if (!extensionEnabled("GL_OES_EGL_image_external_essl3")) + { + std::cout << "Test skipped because GL_OES_EGL_image_external is not available." + << std::endl; + return; + } + + // Make sure this extension is not exposed without ES3. + ASSERT_GE(getClientMajorVersion(), 3); + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture); + + // It is an INVALID_OPERATION error to set the TEXTURE_BASE_LEVEL to a value other than zero. + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 1); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 10); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BASE_LEVEL, 0); + EXPECT_GL_NO_ERROR(); + + glDeleteTextures(1, &texture); +} + +TEST_P(ImageTest, Source2DTarget2D) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTexture2D(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResults2D(target, data); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); +} + +TEST_P(ImageTest, Source2DTargetRenderbuffer) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetRenderbuffer(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResultsRenderbuffer(target, data); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteRenderbuffers(1, &target); +} + +TEST_P(ImageTest, Source2DTargetExternal) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout + << "Test skipped because OES_EGL_image, OES_EGL_image_external, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResultsExternal(target, data); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteRenderbuffers(1, &target); +} + +TEST_P(ImageTestES3, Source2DTargetExternalESSL3) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, OES_EGL_image_external_essl3, " + "EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResultsExternalESSL3(target, data); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteRenderbuffers(1, &target); +} + +TEST_P(ImageTest, SourceCubeTarget2D) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_cubemap_image is not available." + << std::endl; + return; + } + + GLubyte data[24] = { + 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, + 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255, + }; + + for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageCubemapTextureSource( + 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4, + EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTexture2D(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResults2D(target, &data[faceIdx * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); + } +} + +TEST_P(ImageTest, SourceCubeTargetRenderbuffer) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_cubemap_image is not available." + << std::endl; + return; + } + + GLubyte data[24] = { + 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, + 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255, + }; + + for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageCubemapTextureSource( + 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4, + EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetRenderbuffer(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResultsRenderbuffer(target, &data[faceIdx * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteRenderbuffers(1, &target); + } +} + +// Test cubemap -> external texture EGL images. +TEST_P(ImageTest, SourceCubeTargetExternal) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image")) + { + std::cout + << "Test skipped because OES_EGL_image, OES_EGL_image_external, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_cubemap_image is not available." + << std::endl; + return; + } + + GLubyte data[24] = { + 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, + 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255, + }; + + for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageCubemapTextureSource( + 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4, + EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResultsExternal(target, &data[faceIdx * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteRenderbuffers(1, &target); + } +} + +// Test cubemap -> external texture EGL images using ESSL3 shaders. +TEST_P(ImageTestES3, SourceCubeTargetExternalESSL3) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_cubemap_image")) + { + std::cout << "Test skipped because OES_EGL_image, OES_EGL_image_external_essl3, " + "EGL_KHR_image_base or " + "EGL_KHR_gl_texture_cubemap_image is not available." + << std::endl; + return; + } + + GLubyte data[24] = { + 255, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, + 0, 0, 255, 255, 0, 255, 0, 255, 0, 0, 0, 255, + }; + + for (EGLenum faceIdx = 0; faceIdx < 6; faceIdx++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageCubemapTextureSource( + 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<uint8_t *>(data), sizeof(GLubyte) * 4, + EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + faceIdx, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResultsExternalESSL3(target, &data[faceIdx * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteRenderbuffers(1, &target); + } +} + +TEST_P(ImageTest, Source3DTargetTexture) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_3D_image is not available." + << std::endl; + return; + } + + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D")) + { + std::cout << "Test skipped because 3D textures are not available." << std::endl; + return; + } + + const size_t depth = 2; + GLubyte data[4 * depth] = { + 255, 0, 255, 255, 255, 255, 0, 255, + }; + + for (size_t layer = 0; layer < depth; layer++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source, + &image); + + // Create the target + GLuint target; + createEGLImageTargetTexture2D(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResults2D(target, &data[layer * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); + } +} + +TEST_P(ImageTest, Source3DTargetRenderbuffer) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_3D_image is not available." + << std::endl; + return; + } + + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D")) + { + std::cout << "Test skipped because 3D textures are not available." << std::endl; + return; + } + + const size_t depth = 2; + GLubyte data[4 * depth] = { + 255, 0, 255, 255, 255, 255, 0, 255, + }; + + for (size_t layer = 0; layer < depth; layer++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source, + &image); + + // Create the target + GLuint target; + createEGLImageTargetRenderbuffer(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResultsRenderbuffer(target, &data[layer * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); + } +} + +// Test 3D -> external texture EGL images. +TEST_P(ImageTest, Source3DTargetExternal) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image")) + { + std::cout + << "Test skipped because OES_EGL_image, OES_EGL_image_external, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_3D_image is not available." + << std::endl; + return; + } + + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D")) + { + std::cout << "Test skipped because 3D textures are not available." << std::endl; + return; + } + + const size_t depth = 2; + GLubyte data[4 * depth] = { + 255, 0, 255, 255, 255, 255, 0, 255, + }; + + for (size_t layer = 0; layer < depth; layer++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source, + &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResultsExternal(target, &data[layer * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); + } +} + +// Test 3D -> external texture EGL images using ESSL3 shaders. +TEST_P(ImageTestES3, Source3DTargetExternalESSL3) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_3D_image")) + { + std::cout << "Test skipped because OES_EGL_image, OES_EGL_image_external_essl3, " + "EGL_KHR_image_base or " + "EGL_KHR_gl_texture_3D_image is not available." + << std::endl; + return; + } + + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_texture_3D")) + { + std::cout << "Test skipped because 3D textures are not available." << std::endl; + return; + } + + const size_t depth = 2; + GLubyte data[4 * depth] = { + 255, 0, 255, 255, 255, 255, 0, 255, + }; + + for (size_t layer = 0; layer < depth; layer++) + { + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage3DTextureSource(1, 1, depth, GL_RGBA, GL_UNSIGNED_BYTE, data, layer, &source, + &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResultsExternalESSL3(target, &data[layer * 4]); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); + } +} + +TEST_P(ImageTest, SourceRenderbufferTargetTexture) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_renderbuffer_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTexture2D(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResults2D(target, data); + + // Clean up + glDeleteRenderbuffers(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); +} + +// Test renderbuffer -> external texture EGL images. +TEST_P(ImageTest, SourceRenderbufferTargetTextureExternal) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image")) + { + std::cout + << "Test skipped because OES_EGL_image, OES_EGL_image_external, EGL_KHR_image_base or " + "EGL_KHR_gl_renderbuffer_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResultsExternal(target, data); + + // Clean up + glDeleteRenderbuffers(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); +} + +// Test renderbuffer -> external texture EGL images using ESSL3 shaders. +TEST_P(ImageTestES3, SourceRenderbufferTargetTextureExternalESSL3) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || !extensionEnabled("OES_EGL_image_external_essl3") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image")) + { + std::cout + << "Test skipped because OES_EGL_image, OES_EGL_image_external, EGL_KHR_image_base or " + "EGL_KHR_gl_renderbuffer_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTextureExternal(image, &target); + + // Expect that the target texture has the same color as the source texture + verifyResultsExternalESSL3(target, data); + + // Clean up + glDeleteRenderbuffers(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); +} + +TEST_P(ImageTest, SourceRenderbufferTargetRenderbuffer) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_renderbuffer_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_renderbuffer_image is not available." + << std::endl; + return; + } + + GLubyte data[4] = {255, 0, 255, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImageRenderbufferSource(1, 1, GL_RGBA8_OES, data, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetRenderbuffer(image, &target); + + // Expect that the target renderbuffer has the same color as the source texture + verifyResultsRenderbuffer(target, data); + + // Clean up + glDeleteRenderbuffers(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteRenderbuffers(1, &target); +} + +// Delete the source texture and EGL image. The image targets should still have the same data +// because +// they hold refs to the image. +TEST_P(ImageTest, Deletion) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte originalData[4] = {255, 0, 255, 255}; + GLubyte updateData[4] = {0, 255, 0, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image); + + // Create multiple targets + GLuint targetTexture; + createEGLImageTargetTexture2D(image, &targetTexture); + + GLuint targetRenderbuffer; + createEGLImageTargetRenderbuffer(image, &targetRenderbuffer); + + // Delete the source texture + glDeleteTextures(1, &source); + source = 0; + + // Expect that both the targets have the original data + verifyResults2D(targetTexture, originalData); + verifyResultsRenderbuffer(targetRenderbuffer, originalData); + + // Update the data of the target + glBindTexture(GL_TEXTURE_2D, targetTexture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData); + + // Expect that both targets have the updated data + verifyResults2D(targetTexture, updateData); + verifyResultsRenderbuffer(targetRenderbuffer, updateData); + + // Delete the EGL image + eglDestroyImageKHR(window->getDisplay(), image); + image = EGL_NO_IMAGE_KHR; + + // Update the data of the target back to the original data + glBindTexture(GL_TEXTURE_2D, targetTexture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData); + + // Expect that both targets have the original data again + verifyResults2D(targetTexture, originalData); + verifyResultsRenderbuffer(targetRenderbuffer, originalData); + + // Clean up + glDeleteTextures(1, &targetTexture); + glDeleteRenderbuffers(1, &targetRenderbuffer); +} + +TEST_P(ImageTest, MipLevels) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + const size_t mipLevels = 3; + const size_t textureSize = 4; + std::vector<GLuint> mip0Data(textureSize * textureSize, 0xFFFF0000); + std::vector<GLuint> mip1Data(mip0Data.size() << 1, 0xFF00FF00); + std::vector<GLuint> mip2Data(mip0Data.size() << 2, 0xFF0000FF); + GLubyte *data[mipLevels] = { + reinterpret_cast<GLubyte *>(&mip0Data[0]), reinterpret_cast<GLubyte *>(&mip1Data[0]), + reinterpret_cast<GLubyte *>(&mip2Data[0]), + }; + + GLuint source; + glGenTextures(1, &source); + glBindTexture(GL_TEXTURE_2D, source); + + for (size_t level = 0; level < mipLevels; level++) + { + glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(level), GL_RGBA, textureSize >> level, + textureSize >> level, 0, GL_RGBA, GL_UNSIGNED_BYTE, data[level]); + } + + ASSERT_GL_NO_ERROR(); + + for (size_t level = 0; level < mipLevels; level++) + { + // Create the Image + EGLint attribs[] = { + EGL_GL_TEXTURE_LEVEL_KHR, static_cast<EGLint>(level), EGL_NONE, + }; + EGLImageKHR image = + eglCreateImageKHR(window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR, + reinterpretHelper<EGLClientBuffer>(source), attribs); + ASSERT_EGL_SUCCESS(); + + // Create a texture and renderbuffer target + GLuint textureTarget; + createEGLImageTargetTexture2D(image, &textureTarget); + + // Disable mipmapping + glBindTexture(GL_TEXTURE_2D, textureTarget); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + GLuint renderbufferTarget; + createEGLImageTargetRenderbuffer(image, &renderbufferTarget); + + // Expect that the targets have the same color as the source texture + verifyResults2D(textureTarget, data[level]); + verifyResultsRenderbuffer(renderbufferTarget, data[level]); + + // Clean up + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &textureTarget); + glDeleteRenderbuffers(1, &renderbufferTarget); + } + + // Clean up + glDeleteTextures(1, &source); +} + +// Respecify the source texture, orphaning it. The target texture should not have updated data. +TEST_P(ImageTest, Respecification) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte originalData[4] = {255, 0, 255, 255}; + GLubyte updateData[4] = {0, 255, 0, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTexture2D(image, &target); + + // Respecify source + glBindTexture(GL_TEXTURE_2D, source); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData); + + // Expect that the target texture has the original data + verifyResults2D(target, originalData); + + // Expect that the source texture has the updated data + verifyResults2D(source, updateData); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); +} + +// First render to a target texture, then respecify the source texture, orphaning it. +// The target texture's FBO should be notified of the target texture's orphaning. +TEST_P(ImageTest, RespecificationWithFBO) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + // Simple shader + const std::string &vertexSource = + "attribute vec2 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position, 0, 1);\n" + "}"; + const std::string &fragmentSource = + "void main()\n" + "{\n" + " gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);\n" + "}"; + GLuint program = CompileProgram(vertexSource, fragmentSource); + ASSERT_NE(0u, program); + + GLubyte originalData[4] = {255, 0, 255, 255}; + GLubyte updateData[4] = {0, 255, 0, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTexture2D(image, &target); + + // Render to the target texture + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, target, 0); + drawQuad(program, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 0, 0, 255, 255); + + // Respecify source with same parameters. This should not change the texture storage in D3D11. + glBindTexture(GL_TEXTURE_2D, source); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData); + + // Expect that the source texture has the updated data + verifyResults2D(source, updateData); + + // Render to the target texture again and verify it gets the rendered pixels. + drawQuad(program, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 0, 0, 255, 255); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); + glDeleteProgram(program); + glDeleteFramebuffers(1, &fbo); +} + +// Test that respecifying a level of the target texture orphans it and keeps a copy of the EGLimage +// data +TEST_P(ImageTest, RespecificationOfOtherLevel) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte originalData[2 * 2 * 4] = { + 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, 255, 0, 255, 255, + }; + + GLubyte updateData[2 * 2 * 4] = { + 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, + }; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(2, 2, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image); + + // Create the target + GLuint target; + createEGLImageTargetTexture2D(image, &target); + + // Expect that the target and source textures have the original data + verifyResults2D(source, originalData); + verifyResults2D(target, originalData); + + // Add a new mipLevel to the target, orphaning it + glBindTexture(GL_TEXTURE_2D, target); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, originalData); + EXPECT_GL_NO_ERROR(); + + // Expect that the target and source textures still have the original data + verifyResults2D(source, originalData); + verifyResults2D(target, originalData); + + // Update the source's data + glBindTexture(GL_TEXTURE_2D, source); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, updateData); + + // Expect that the target still has the original data and source has the updated data + verifyResults2D(source, updateData); + verifyResults2D(target, originalData); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &target); +} + +// Update the data of the source and target textures. All image siblings should have the new data. +TEST_P(ImageTest, UpdatedData) +{ + EGLWindow *window = getEGLWindow(); + if (!extensionEnabled("OES_EGL_image") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_image_base") || + !eglDisplayExtensionEnabled(window->getDisplay(), "EGL_KHR_gl_texture_2D_image")) + { + std::cout << "Test skipped because OES_EGL_image, EGL_KHR_image_base or " + "EGL_KHR_gl_texture_2D_image is not available." + << std::endl; + return; + } + + GLubyte originalData[4] = {255, 0, 255, 255}; + GLubyte updateData[4] = {0, 255, 0, 255}; + + // Create the Image + GLuint source; + EGLImageKHR image; + createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image); + + // Create multiple targets + GLuint targetTexture; + createEGLImageTargetTexture2D(image, &targetTexture); + + GLuint targetRenderbuffer; + createEGLImageTargetRenderbuffer(image, &targetRenderbuffer); + + // Expect that both the source and targets have the original data + verifyResults2D(source, originalData); + verifyResults2D(targetTexture, originalData); + verifyResultsRenderbuffer(targetRenderbuffer, originalData); + + // Update the data of the source + glBindTexture(GL_TEXTURE_2D, source); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, updateData); + + // Expect that both the source and targets have the updated data + verifyResults2D(source, updateData); + verifyResults2D(targetTexture, updateData); + verifyResultsRenderbuffer(targetRenderbuffer, updateData); + + // Update the data of the target back to the original data + glBindTexture(GL_TEXTURE_2D, targetTexture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData); + + // Expect that both the source and targets have the original data again + verifyResults2D(source, originalData); + verifyResults2D(targetTexture, originalData); + verifyResultsRenderbuffer(targetRenderbuffer, originalData); + + // Clean up + glDeleteTextures(1, &source); + eglDestroyImageKHR(window->getDisplay(), image); + glDeleteTextures(1, &targetTexture); + glDeleteRenderbuffers(1, &targetRenderbuffer); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(ImageTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ImageTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +} diff --git a/gfx/angle/src/tests/gl_tests/IncompleteTextureTest.cpp b/gfx/angle/src/tests/gl_tests/IncompleteTextureTest.cpp new file mode 100755 index 000000000..d7a113915 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/IncompleteTextureTest.cpp @@ -0,0 +1,170 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include <vector> + +using namespace angle; + +class IncompleteTextureTest : public ANGLETest +{ + protected: + IncompleteTextureTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = position; + texcoord = (position.xy * 0.5) + 0.5; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mProgram, "tex"); + } + + virtual void TearDown() + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + void fillTextureData(std::vector<GLubyte> &buffer, GLubyte r, GLubyte g, GLubyte b, GLubyte a) + { + size_t count = buffer.size() / 4; + for (size_t i = 0; i < count; i++) + { + buffer[i * 4 + 0] = r; + buffer[i * 4 + 1] = g; + buffer[i * 4 + 2] = b; + buffer[i * 4 + 3] = a; + } + } + + GLuint mProgram; + GLint mTextureUniformLocation; +}; + +TEST_P(IncompleteTextureTest, IncompleteTexture2D) +{ + GLuint tex; + glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + + glUseProgram(mProgram); + glUniform1i(mTextureUniformLocation, 0); + + const GLsizei textureWidth = 2; + const GLsizei textureHeight = 2; + std::vector<GLubyte> textureData(textureWidth * textureHeight * 4); + fillTextureData(textureData, 255, 0, 0, 255); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &textureData[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 255); + + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, textureWidth >> 1, textureHeight >> 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &textureData[0]); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + glDeleteTextures(1, &tex); +} + +TEST_P(IncompleteTextureTest, UpdateTexture) +{ + GLuint tex; + glGenTextures(1, &tex); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + + glUseProgram(mProgram); + glUniform1i(mTextureUniformLocation, 0); + + const GLsizei redTextureWidth = 64; + const GLsizei redTextureHeight = 64; + std::vector<GLubyte> redTextureData(redTextureWidth * redTextureHeight * 4); + fillTextureData(redTextureData, 255, 0, 0, 255); + for (size_t i = 0; i < 7; i++) + { + glTexImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), GL_RGBA, redTextureWidth >> i, + redTextureHeight >> i, 0, GL_RGBA, GL_UNSIGNED_BYTE, &redTextureData[0]); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + const GLsizei greenTextureWidth = 32; + const GLsizei greenTextureHeight = 32; + std::vector<GLubyte> greenTextureData(greenTextureWidth * greenTextureHeight * 4); + fillTextureData(greenTextureData, 0, 255, 0, 255); + + for (size_t i = 0; i < 6; i++) + { + glTexSubImage2D(GL_TEXTURE_2D, static_cast<GLint>(i), greenTextureWidth >> i, + greenTextureHeight >> i, greenTextureWidth >> i, greenTextureHeight >> i, + GL_RGBA, GL_UNSIGNED_BYTE, &greenTextureData[0]); + } + + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(getWindowWidth() - greenTextureWidth, getWindowHeight() - greenTextureWidth, 0, 255, 0, 255); + + glDeleteTextures(1, &tex); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(IncompleteTextureTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_OPENGL(), + ES2_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/IndexBufferOffsetTest.cpp b/gfx/angle/src/tests/gl_tests/IndexBufferOffsetTest.cpp new file mode 100755 index 000000000..28f032eee --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/IndexBufferOffsetTest.cpp @@ -0,0 +1,156 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexBufferOffsetTest.cpp: Test glDrawElements with an offset and an index buffer + +#include "test_utils/ANGLETest.h" +#include "system_utils.h" + +using namespace angle; + +class IndexBufferOffsetTest : public ANGLETest +{ + protected: + IndexBufferOffsetTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = + SHADER_SOURCE(precision highp float; attribute vec2 position; + + void main() + { + gl_Position = vec4(position, 0.0, 1.0); + }); + + const std::string fragmentShaderSource = + SHADER_SOURCE(precision highp float; uniform vec4 color; + + void main() + { + gl_FragColor = color; + }); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + + mColorUniformLocation = glGetUniformLocation(mProgram, "color"); + mPositionAttributeLocation = glGetAttribLocation(mProgram, "position"); + + const GLfloat vertices[] = + { + -1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, -1.0f, + 1.0f, 1.0f + }; + glGenBuffers(1, &mVertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW); + + glGenBuffers(1, &mIndexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + } + + void TearDown() override + { + glDeleteBuffers(1, &mVertexBuffer); + glDeleteBuffers(1, &mIndexBuffer); + glDeleteProgram(mProgram); + ANGLETest::TearDown(); + } + + void runTest(GLenum type, int typeWidth, void *indexData) + { + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + GLuint nullIndexData[] = {0, 0, 0, 0, 0, 0}; + + size_t indexDataWidth = 6 * typeWidth; + + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * indexDataWidth, nullptr, GL_DYNAMIC_DRAW); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indexDataWidth, nullIndexData); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, indexDataWidth, indexDataWidth, indexData); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 2 * indexDataWidth, indexDataWidth, nullIndexData); + + glUseProgram(mProgram); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glVertexAttribPointer(mPositionAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(mPositionAttributeLocation); + + glUniform4f(mColorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f); + + for (int i = 0; i < 16; i++) + { + glDrawElements(GL_TRIANGLES, 6, type, reinterpret_cast<GLvoid *>(indexDataWidth)); + EXPECT_PIXEL_EQ(64, 64, 255, 0, 0, 255); + } + + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, indexDataWidth, indexDataWidth, nullIndexData); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 2 * indexDataWidth, indexDataWidth, indexData); + + glUniform4f(mColorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f); + glDrawElements(GL_TRIANGLES, 6, type, reinterpret_cast<GLvoid *>(indexDataWidth * 2)); + EXPECT_PIXEL_EQ(64, 64, 0, 255, 0, 255); + + EXPECT_GL_NO_ERROR(); + swapBuffers(); + } + + GLuint mProgram; + GLint mColorUniformLocation; + GLint mPositionAttributeLocation; + GLuint mVertexBuffer; + GLuint mIndexBuffer; +}; + +// Test using an offset for an UInt8 index buffer +TEST_P(IndexBufferOffsetTest, UInt8Index) +{ + GLubyte indexData[] = {0, 1, 2, 1, 2, 3}; + runTest(GL_UNSIGNED_BYTE, 1, indexData); +} + +// Test using an offset for an UInt16 index buffer +TEST_P(IndexBufferOffsetTest, UInt16Index) +{ + GLushort indexData[] = {0, 1, 2, 1, 2, 3}; + runTest(GL_UNSIGNED_SHORT, 2, indexData); +} + +// Test using an offset for an UInt32 index buffer +TEST_P(IndexBufferOffsetTest, UInt32Index) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + std::cout << "Test skipped because ES3 or GL_OES_element_index_uint is not available." << std::endl; + return; + } + + GLuint indexData[] = {0, 1, 2, 1, 2, 3}; + runTest(GL_UNSIGNED_INT, 4, indexData); +} + +ANGLE_INSTANTIATE_TEST(IndexBufferOffsetTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/IndexedPointsTest.cpp b/gfx/angle/src/tests/gl_tests/IndexedPointsTest.cpp new file mode 100755 index 000000000..73b16d8bf --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/IndexedPointsTest.cpp @@ -0,0 +1,403 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +template <typename IndexType, GLenum IndexTypeName> +class IndexedPointsTest : public ANGLETest +{ + protected: + IndexedPointsTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + float getIndexPositionX(size_t idx) + { + return (idx == 0 || idx == 3) ? -0.5f : 0.5f; + } + + float getIndexPositionY(size_t idx) + { + return (idx == 2 || idx == 3) ? -0.5f : 0.5f; + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec2 position; + + void main() + { + gl_PointSize = 5.0; + gl_Position = vec4(position, 0.0, 1.0); + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + + void main() + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + + const std::string vertexShaderSource2 = SHADER_SOURCE + ( + precision highp float; + attribute vec2 position; + attribute vec4 color; + varying vec4 vcolor; + + void main() + { + gl_PointSize = 5.0; + gl_Position = vec4(position, 0.0, 1.0); + vcolor = color; + } + ); + + const std::string fragmentShaderSource2 = SHADER_SOURCE + ( + precision highp float; + varying vec4 vcolor; + void main() + { + gl_FragColor = vec4(vcolor.xyz, 1.0); + } + ); + + mVertexWithColorBufferProgram = CompileProgram(vertexShaderSource2, fragmentShaderSource2); + ASSERT_NE(0u, mVertexWithColorBufferProgram); + + // Construct a vertex buffer of position values and color values + // contained in a single structure + const float verticesWithColor[] = + { + getIndexPositionX(0), getIndexPositionY(0), 0.0f, 1.0f, 0.0f, + getIndexPositionX(2), getIndexPositionY(2), 0.0f, 1.0f, 0.0f, + getIndexPositionX(1), getIndexPositionY(1), 0.0f, 1.0f, 0.0f, + getIndexPositionX(3), getIndexPositionY(3), 0.0f, 1.0f, 0.0f, + }; + + glGenBuffers(1, &mVertexWithColorBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(verticesWithColor), &verticesWithColor[0], GL_STATIC_DRAW); + + // Construct a vertex buffer of position values only + const GLfloat vertices[] = + { + getIndexPositionX(0), getIndexPositionY(0), + getIndexPositionX(2), getIndexPositionY(2), + getIndexPositionX(1), getIndexPositionY(1), + getIndexPositionX(3), getIndexPositionY(3), + }; + glGenBuffers(1, &mVertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW); + + // The indices buffer is shared between both variations of tests + const IndexType indices[] = { 0, 2, 1, 3 }; + glGenBuffers(1, &mIndexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW); + } + + virtual void TearDown() + { + glDeleteBuffers(1, &mVertexBuffer); + glDeleteBuffers(1, &mIndexBuffer); + glDeleteProgram(mProgram); + + glDeleteBuffers(1, &mVertexWithColorBuffer); + glDeleteProgram(mVertexWithColorBufferProgram); + ANGLETest::TearDown(); + } + + void runTest(GLuint firstIndex, bool useVertexBufferWithColor = false) + { + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + GLint viewportSize[4]; + glGetIntegerv(GL_VIEWPORT, viewportSize); + + // Choose appropriate program to apply for the test + GLuint program = useVertexBufferWithColor ? mVertexWithColorBufferProgram : mProgram; + + if (useVertexBufferWithColor) + { + glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer); + GLint vertexLocation = glGetAttribLocation(program, "position"); + glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, + static_cast<const GLsizei>(VertexWithColorSize), 0); + glEnableVertexAttribArray(vertexLocation); + + GLint vertexColorLocation = glGetAttribLocation(program, "color"); + glVertexAttribPointer(vertexColorLocation, 3, GL_FLOAT, GL_FALSE, + static_cast<const GLsizei>(VertexWithColorSize), + (GLvoid *)((sizeof(float) * 2))); + glEnableVertexAttribArray(vertexColorLocation); + } + else + { + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + GLint vertexLocation = glGetAttribLocation(program, "position"); + glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(vertexLocation); + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); + glUseProgram(program); + + glDrawElements(GL_POINTS, mPointCount - firstIndex, IndexTypeName, reinterpret_cast<void*>(firstIndex * sizeof(IndexType))); + + for (size_t i = 0; i < mPointCount; i++) + { + GLuint x = static_cast<GLuint>(viewportSize[0] + (getIndexPositionX(i) * 0.5f + 0.5f) * (viewportSize[2] - viewportSize[0])); + GLuint y = static_cast<GLuint>(viewportSize[1] + (getIndexPositionY(i) * 0.5f + 0.5f) * (viewportSize[3] - viewportSize[1])); + + if (i < firstIndex) + { + EXPECT_PIXEL_EQ(x, y, 0, 0, 0, 255); + } + else + { + if (useVertexBufferWithColor) + { + // Pixel data is assumed to be GREEN + EXPECT_PIXEL_EQ(x, y, 0, 255, 0, 255); + } + else + { + // Pixel data is assumed to be RED + EXPECT_PIXEL_EQ(x, y, 255, 0, 0, 255); + } + } + } + swapBuffers(); + } + + GLuint mProgram; + GLuint mVertexBuffer; + GLuint mIndexBuffer; + + GLuint mVertexWithColorBufferProgram; + GLuint mVertexWithColorBuffer; + + static const GLuint mPointCount = 4; + + private: + const size_t VertexWithColorSize = sizeof(float) * 5; +}; + +typedef IndexedPointsTest<GLubyte, GL_UNSIGNED_BYTE> IndexedPointsTestUByte; + +TEST_P(IndexedPointsTestUByte, UnsignedByteOffset0) +{ + runTest(0); +} + +TEST_P(IndexedPointsTestUByte, UnsignedByteOffset1) +{ + runTest(1); +} + +TEST_P(IndexedPointsTestUByte, UnsignedByteOffset2) +{ + runTest(2); +} + +TEST_P(IndexedPointsTestUByte, UnsignedByteOffset3) +{ + runTest(3); +} + +TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset0) +{ + runTest(0, true); +} + +TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset1) +{ + runTest(1, true); +} + +TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset2) +{ + runTest(2, true); +} + +TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset3) +{ + runTest(3, true); +} + +typedef IndexedPointsTest<GLushort, GL_UNSIGNED_SHORT> IndexedPointsTestUShort; + +TEST_P(IndexedPointsTestUShort, UnsignedShortOffset0) +{ + runTest(0); +} + +TEST_P(IndexedPointsTestUShort, UnsignedShortOffset1) +{ + runTest(1); +} + +TEST_P(IndexedPointsTestUShort, UnsignedShortOffset2) +{ + runTest(2); +} + +TEST_P(IndexedPointsTestUShort, UnsignedShortOffset3) +{ + runTest(3); +} + +TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset0) +{ + runTest(0, true); +} + +TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset1) +{ + runTest(1, true); +} + +TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset2) +{ + runTest(2, true); +} + +TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset3) +{ + runTest(3, true); +} + +TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffsetChangingIndices) +{ + runTest(3, true); + runTest(1, true); + runTest(0, true); + runTest(2, true); +} + +typedef IndexedPointsTest<GLuint, GL_UNSIGNED_INT> IndexedPointsTestUInt; + +TEST_P(IndexedPointsTestUInt, UnsignedIntOffset0) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(0); +} + +TEST_P(IndexedPointsTestUInt, UnsignedIntOffset1) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(1); +} + +TEST_P(IndexedPointsTestUInt, UnsignedIntOffset2) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(2); +} + +TEST_P(IndexedPointsTestUInt, UnsignedIntOffset3) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(3); +} + +TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset0) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(0, false); +} + +TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset1) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(1, false); +} + +TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset2) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(2, false); +} + +TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset3) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + runTest(3, false); +} + +// TODO(geofflang): Figure out why this test fails on Intel OpenGL +ANGLE_INSTANTIATE_TEST(IndexedPointsTestUByte, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(IndexedPointsTestUShort, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(IndexedPointsTestUInt, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/InstancingTest.cpp b/gfx/angle/src/tests/gl_tests/InstancingTest.cpp new file mode 100755 index 000000000..633f96892 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/InstancingTest.cpp @@ -0,0 +1,468 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class InstancingTest : public ANGLETest +{ + protected: + InstancingTest() : mProgram(0), mVertexBuffer(0) + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + ~InstancingTest() override + { + glDeleteBuffers(1, &mVertexBuffer); + glDeleteProgram(mProgram); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + mVertexAttribDivisorANGLE = NULL; + mDrawArraysInstancedANGLE = NULL; + mDrawElementsInstancedANGLE = NULL; + + char *extensionString = (char*)glGetString(GL_EXTENSIONS); + if (strstr(extensionString, "GL_ANGLE_instanced_arrays")) + { + mVertexAttribDivisorANGLE = (PFNGLVERTEXATTRIBDIVISORANGLEPROC)eglGetProcAddress("glVertexAttribDivisorANGLE"); + mDrawArraysInstancedANGLE = (PFNGLDRAWARRAYSINSTANCEDANGLEPROC)eglGetProcAddress("glDrawArraysInstancedANGLE"); + mDrawElementsInstancedANGLE = (PFNGLDRAWELEMENTSINSTANCEDANGLEPROC)eglGetProcAddress("glDrawElementsInstancedANGLE"); + } + + ASSERT_TRUE(mVertexAttribDivisorANGLE != NULL); + ASSERT_TRUE(mDrawArraysInstancedANGLE != NULL); + ASSERT_TRUE(mDrawElementsInstancedANGLE != NULL); + + // Initialize the vertex and index vectors + GLfloat qvertex1[3] = {-quadRadius, quadRadius, 0.0f}; + GLfloat qvertex2[3] = {-quadRadius, -quadRadius, 0.0f}; + GLfloat qvertex3[3] = { quadRadius, -quadRadius, 0.0f}; + GLfloat qvertex4[3] = { quadRadius, quadRadius, 0.0f}; + mQuadVertices.insert(mQuadVertices.end(), qvertex1, qvertex1 + 3); + mQuadVertices.insert(mQuadVertices.end(), qvertex2, qvertex2 + 3); + mQuadVertices.insert(mQuadVertices.end(), qvertex3, qvertex3 + 3); + mQuadVertices.insert(mQuadVertices.end(), qvertex4, qvertex4 + 3); + + GLfloat coord1[2] = {0.0f, 0.0f}; + GLfloat coord2[2] = {0.0f, 1.0f}; + GLfloat coord3[2] = {1.0f, 1.0f}; + GLfloat coord4[2] = {1.0f, 0.0f}; + mTexcoords.insert(mTexcoords.end(), coord1, coord1 + 2); + mTexcoords.insert(mTexcoords.end(), coord2, coord2 + 2); + mTexcoords.insert(mTexcoords.end(), coord3, coord3 + 2); + mTexcoords.insert(mTexcoords.end(), coord4, coord4 + 2); + + mIndices.push_back(0); + mIndices.push_back(1); + mIndices.push_back(2); + mIndices.push_back(0); + mIndices.push_back(2); + mIndices.push_back(3); + + for (size_t vertexIndex = 0; vertexIndex < 6; ++vertexIndex) + { + mNonIndexedVertices.insert(mNonIndexedVertices.end(), + mQuadVertices.begin() + mIndices[vertexIndex] * 3, + mQuadVertices.begin() + mIndices[vertexIndex] * 3 + 3); + } + + for (size_t vertexIndex = 0; vertexIndex < 6; ++vertexIndex) + { + mNonIndexedVertices.insert(mNonIndexedVertices.end(), + mQuadVertices.begin() + mIndices[vertexIndex] * 3, + mQuadVertices.begin() + mIndices[vertexIndex] * 3 + 3); + } + + // Tile a 2x2 grid of the tiles + for (float y = -1.0f + quadRadius; y < 1.0f - quadRadius; y += quadRadius * 3) + { + for (float x = -1.0f + quadRadius; x < 1.0f - quadRadius; x += quadRadius * 3) + { + GLfloat instance[3] = {x + quadRadius, y + quadRadius, 0.0f}; + mInstances.insert(mInstances.end(), instance, instance + 3); + } + } + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + + glGenBuffers(1, &mVertexBuffer); + + ASSERT_GL_NO_ERROR(); + } + + void setupDrawArraysTest(const std::string &vs) + { + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + void main() + { + gl_FragColor = vec4(1.0, 0, 0, 1.0); + } + ); + + mProgram = CompileProgram(vs, fs); + ASSERT_NE(0u, mProgram); + + // Set the viewport + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + + // Clear the color buffer + glClear(GL_COLOR_BUFFER_BIT); + + // Use the program object + glUseProgram(mProgram); + } + + void setupInstancedPointsTest() + { + mIndices.clear(); + mIndices.push_back(0); + mIndices.push_back(1); + mIndices.push_back(2); + mIndices.push_back(3); + + // clang-format off + const std::string vs = SHADER_SOURCE + ( + attribute vec3 a_position; + attribute vec3 a_instancePos; + void main() + { + gl_Position = vec4(a_position.xyz, 1.0); + gl_Position = vec4(a_instancePos.xyz, 1.0); + gl_PointSize = 6.0; + } + ); + + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + void main() + { + gl_FragColor = vec4(1.0, 0, 0, 1.0); + } + ); + // clang-format on + + mProgram = CompileProgram(vs, fs); + ASSERT_NE(0u, mProgram); + + // Set the viewport + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + + // Clear the color buffer + glClear(GL_COLOR_BUFFER_BIT); + + // Use the program object + glUseProgram(mProgram); + } + + void runDrawArraysTest(GLint first, GLsizei count, GLsizei instanceCount, float *offset) + { + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, mInstances.size() * sizeof(mInstances[0]), &mInstances[0], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // Get the attribute locations + GLint positionLoc = glGetAttribLocation(mProgram, "a_position"); + GLint instancePosLoc = glGetAttribLocation(mProgram, "a_instancePos"); + + // Load the vertex position + glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, mNonIndexedVertices.data()); + glEnableVertexAttribArray(positionLoc); + + // Load the instance position + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glVertexAttribPointer(instancePosLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glEnableVertexAttribArray(instancePosLoc); + + // Enable instancing + mVertexAttribDivisorANGLE(instancePosLoc, 1); + + // Offset + GLint uniformLoc = glGetUniformLocation(mProgram, "u_offset"); + ASSERT_NE(uniformLoc, -1); + glUniform3fv(uniformLoc, 1, offset); + + // Do the instanced draw + mDrawArraysInstancedANGLE(GL_TRIANGLES, first, count, instanceCount); + + ASSERT_GL_NO_ERROR(); + } + + virtual void runDrawElementsTest(std::string vs, bool shouldAttribZeroBeInstanced) + { + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + void main() + { + gl_FragColor = vec4(1.0, 0, 0, 1.0); + } + ); + + GLuint program = CompileProgram(vs, fs); + ASSERT_NE(program, 0u); + + // Get the attribute locations + GLint positionLoc = glGetAttribLocation(program, "a_position"); + GLint instancePosLoc = glGetAttribLocation(program, "a_instancePos"); + + // If this ASSERT fails then the vertex shader code should be refactored + ASSERT_EQ(shouldAttribZeroBeInstanced, (instancePosLoc == 0)); + + // Set the viewport + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + + // Clear the color buffer + glClear(GL_COLOR_BUFFER_BIT); + + // Use the program object + glUseProgram(program); + + // Load the vertex position + glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, mQuadVertices.data()); + glEnableVertexAttribArray(positionLoc); + + // Load the instance position + glVertexAttribPointer(instancePosLoc, 3, GL_FLOAT, GL_FALSE, 0, mInstances.data()); + glEnableVertexAttribArray(instancePosLoc); + + // Enable instancing + mVertexAttribDivisorANGLE(instancePosLoc, 1); + + // Do the instanced draw + mDrawElementsInstancedANGLE(GL_TRIANGLES, static_cast<GLsizei>(mIndices.size()), + GL_UNSIGNED_SHORT, mIndices.data(), + static_cast<GLsizei>(mInstances.size()) / 3); + + ASSERT_GL_NO_ERROR(); + + checkQuads(); + } + + void checkQuads() + { + // Check that various pixels are the expected color. + for (unsigned int quadIndex = 0; quadIndex < 4; ++quadIndex) + { + unsigned int baseOffset = quadIndex * 3; + + int quadx = static_cast<int>(((mInstances[baseOffset + 0]) * 0.5f + 0.5f) * getWindowWidth()); + int quady = static_cast<int>(((mInstances[baseOffset + 1]) * 0.5f + 0.5f) * getWindowHeight()); + + EXPECT_PIXEL_EQ(quadx, quady, 255, 0, 0, 255); + } + } + + // Loaded entry points + PFNGLVERTEXATTRIBDIVISORANGLEPROC mVertexAttribDivisorANGLE; + PFNGLDRAWARRAYSINSTANCEDANGLEPROC mDrawArraysInstancedANGLE; + PFNGLDRAWELEMENTSINSTANCEDANGLEPROC mDrawElementsInstancedANGLE; + + // Vertex data + std::vector<GLfloat> mQuadVertices; + std::vector<GLfloat> mNonIndexedVertices; + std::vector<GLfloat> mTexcoords; + std::vector<GLfloat> mInstances; + std::vector<GLushort> mIndices; + + const GLfloat quadRadius = 0.30f; + + GLuint mProgram; + GLuint mVertexBuffer; +}; + +class InstancingTestAllConfigs : public InstancingTest +{ + protected: + InstancingTestAllConfigs() {} +}; + +class InstancingTestNo9_3 : public InstancingTest +{ + protected: + InstancingTestNo9_3() {} +}; + +class InstancingTestPoints : public InstancingTest +{ + protected: + InstancingTestPoints() {} +}; + +// This test uses a vertex shader with the first attribute (attribute zero) instanced. +// On D3D9 and D3D11 FL9_3, this triggers a special codepath that rearranges the input layout sent to D3D, +// to ensure that slot/stream zero of the input layout doesn't contain per-instance data. +TEST_P(InstancingTestAllConfigs, AttributeZeroInstanced) +{ + const std::string vs = SHADER_SOURCE + ( + attribute vec3 a_instancePos; + attribute vec3 a_position; + void main() + { + gl_Position = vec4(a_position.xyz + a_instancePos.xyz, 1.0); + } + ); + + runDrawElementsTest(vs, true); +} + +// Same as AttributeZeroInstanced, but attribute zero is not instanced. +// This ensures the general instancing codepath (i.e. without rearranging the input layout) works as expected. +TEST_P(InstancingTestAllConfigs, AttributeZeroNotInstanced) +{ + const std::string vs = SHADER_SOURCE + ( + attribute vec3 a_position; + attribute vec3 a_instancePos; + void main() + { + gl_Position = vec4(a_position.xyz + a_instancePos.xyz, 1.0); + } + ); + + runDrawElementsTest(vs, false); +} + +// Tests that the "first" parameter to glDrawArraysInstancedANGLE is only an offset into +// the non-instanced vertex attributes. +TEST_P(InstancingTestNo9_3, DrawArraysWithOffset) +{ + const std::string vs = SHADER_SOURCE + ( + attribute vec3 a_position; + attribute vec3 a_instancePos; + uniform vec3 u_offset; + void main() + { + gl_Position = vec4(a_position.xyz + a_instancePos.xyz + u_offset, 1.0); + } + ); + + setupDrawArraysTest(vs); + + float offset1[3] = { 0, 0, 0 }; + runDrawArraysTest(0, 6, 2, offset1); + + float offset2[3] = { 0.0f, 1.0f, 0 }; + runDrawArraysTest(6, 6, 2, offset2); + + checkQuads(); +} + +// This test verifies instancing with GL_POINTS with glDrawArraysInstanced works. +// On D3D11 FL9_3, this triggers a special codepath that emulates instanced points rendering. +TEST_P(InstancingTestPoints, DrawArrays) +{ + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + // On Win7, the D3D SDK Layers emits a false warning for these tests. + // This doesn't occur on Windows 10 (Version 1511) though. + ignoreD3D11SDKLayersWarnings(); + + setupInstancedPointsTest(); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, mInstances.size() * sizeof(mInstances[0]), &mInstances[0], + GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // Get the attribute locations + GLint positionLoc = glGetAttribLocation(mProgram, "a_position"); + GLint instancePosLoc = glGetAttribLocation(mProgram, "a_instancePos"); + + // Load the vertex position + GLfloat pos[3] = {0, 0, 0}; + glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, pos); + glEnableVertexAttribArray(positionLoc); + + // Load the instance position + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glVertexAttribPointer(instancePosLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glEnableVertexAttribArray(instancePosLoc); + + // Enable instancing + mVertexAttribDivisorANGLE(instancePosLoc, 1); + + // Do the instanced draw + mDrawArraysInstancedANGLE(GL_POINTS, 0, 1, static_cast<GLsizei>(mInstances.size()) / 3); + + ASSERT_GL_NO_ERROR(); + + checkQuads(); +} + +// This test verifies instancing with GL_POINTS with glDrawElementsInstanced works. +// On D3D11 FL9_3, this triggers a special codepath that emulates instanced points rendering. +TEST_P(InstancingTestPoints, DrawElements) +{ + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + // On Win7, the D3D SDK Layers emits a false warning for these tests. + // This doesn't occur on Windows 10 (Version 1511) though. + ignoreD3D11SDKLayersWarnings(); + + setupInstancedPointsTest(); + + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glBufferData(GL_ARRAY_BUFFER, mInstances.size() * sizeof(mInstances[0]), &mInstances[0], + GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // Get the attribute locations + GLint positionLoc = glGetAttribLocation(mProgram, "a_position"); + GLint instancePosLoc = glGetAttribLocation(mProgram, "a_instancePos"); + + // Load the vertex position + GLfloat pos[3] = {0, 0, 0}; + glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, pos); + glEnableVertexAttribArray(positionLoc); + + // Load the instance position + glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); + glVertexAttribPointer(instancePosLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glEnableVertexAttribArray(instancePosLoc); + + // Enable instancing + mVertexAttribDivisorANGLE(instancePosLoc, 1); + + // Do the instanced draw + mDrawElementsInstancedANGLE(GL_POINTS, static_cast<GLsizei>(mIndices.size()), GL_UNSIGNED_SHORT, + mIndices.data(), static_cast<GLsizei>(mInstances.size()) / 3); + + ASSERT_GL_NO_ERROR(); + + checkQuads(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +// We test on D3D9 and D3D11 9_3 because they use special codepaths when attribute zero is instanced, unlike D3D11. +ANGLE_INSTANTIATE_TEST(InstancingTestAllConfigs, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); + +// TODO(jmadill): Figure out the situation with DrawInstanced on FL 9_3 +ANGLE_INSTANTIATE_TEST(InstancingTestNo9_3, ES2_D3D9(), ES2_D3D11()); + +ANGLE_INSTANTIATE_TEST(InstancingTestPoints, ES2_D3D11(), ES2_D3D11_FL9_3()); diff --git a/gfx/angle/src/tests/gl_tests/LineLoopTest.cpp b/gfx/angle/src/tests/gl_tests/LineLoopTest.cpp new file mode 100755 index 000000000..778fee9fe --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/LineLoopTest.cpp @@ -0,0 +1,226 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class LineLoopTest : public ANGLETest +{ + protected: + LineLoopTest() + { + setWindowWidth(256); + setWindowHeight(256); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vsSource = SHADER_SOURCE + ( + attribute highp vec4 position; + + void main(void) + { + gl_Position = position; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + uniform highp vec4 color; + void main(void) + { + gl_FragColor = color; + } + ); + + mProgram = CompileProgram(vsSource, fsSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mPositionLocation = glGetAttribLocation(mProgram, "position"); + mColorLocation = glGetUniformLocation(mProgram, "color"); + + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_BLEND); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + void runTest(GLenum indexType, GLuint indexBuffer, const GLvoid *indexPtr) + { + glClear(GL_COLOR_BUFFER_BIT); + + static const GLfloat loopPositions[] = + { + 0.0f, 0.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + 0.0f, 0.0f, + -0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + 0.5f, -0.5f + }; + + static const GLfloat stripPositions[] = + { + -0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + 0.5f, -0.5f + }; + static const GLubyte stripIndices[] = + { + 1, 0, 3, 2, 1 + }; + + glUseProgram(mProgram); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); + glEnableVertexAttribArray(mPositionLocation); + glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, loopPositions); + glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f); + glDrawElements(GL_LINE_LOOP, 4, indexType, indexPtr); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, stripPositions); + glUniform4f(mColorLocation, 0, 1, 0, 1); + glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, stripIndices); + + std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]); + + ASSERT_GL_NO_ERROR(); + + for (int y = 0; y < getWindowHeight(); y++) + { + for (int x = 0; x < getWindowWidth(); x++) + { + const GLubyte* pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4); + + EXPECT_EQ(pixel[0], 0); + EXPECT_EQ(pixel[1], pixel[2]); + EXPECT_EQ(pixel[3], 255); + } + } + } + + GLuint mProgram; + GLint mPositionLocation; + GLint mColorLocation; +}; + +TEST_P(LineLoopTest, LineLoopUByteIndices) +{ + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + // On Win7, the D3D SDK Layers emits a false warning for these tests. + // This doesn't occur on Windows 10 (Version 1511) though. + ignoreD3D11SDKLayersWarnings(); + + static const GLubyte indices[] = { 0, 7, 6, 9, 8, 0 }; + runTest(GL_UNSIGNED_BYTE, 0, indices + 1); +} + +TEST_P(LineLoopTest, LineLoopUShortIndices) +{ + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + ignoreD3D11SDKLayersWarnings(); + + static const GLushort indices[] = { 0, 7, 6, 9, 8, 0 }; + runTest(GL_UNSIGNED_SHORT, 0, indices + 1); +} + +TEST_P(LineLoopTest, LineLoopUIntIndices) +{ + if (!extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + ignoreD3D11SDKLayersWarnings(); + + static const GLuint indices[] = { 0, 7, 6, 9, 8, 0 }; + runTest(GL_UNSIGNED_INT, 0, indices + 1); +} + +TEST_P(LineLoopTest, LineLoopUByteIndexBuffer) +{ + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + ignoreD3D11SDKLayersWarnings(); + + static const GLubyte indices[] = { 0, 7, 6, 9, 8, 0 }; + + GLuint buf; + glGenBuffers(1, &buf); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + runTest(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte))); + + glDeleteBuffers(1, &buf); +} + +TEST_P(LineLoopTest, LineLoopUShortIndexBuffer) +{ + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + ignoreD3D11SDKLayersWarnings(); + + static const GLushort indices[] = { 0, 7, 6, 9, 8, 0 }; + + GLuint buf; + glGenBuffers(1, &buf); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + runTest(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort))); + + glDeleteBuffers(1, &buf); +} + +TEST_P(LineLoopTest, LineLoopUIntIndexBuffer) +{ + if (!extensionEnabled("GL_OES_element_index_uint")) + { + return; + } + + // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details + ignoreD3D11SDKLayersWarnings(); + + static const GLuint indices[] = { 0, 7, 6, 9, 8, 0 }; + + GLuint buf; + glGenBuffers(1, &buf); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + + runTest(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint))); + + glDeleteBuffers(1, &buf); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(LineLoopTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/MaxTextureSizeTest.cpp b/gfx/angle/src/tests/gl_tests/MaxTextureSizeTest.cpp new file mode 100755 index 000000000..ab46d6f76 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/MaxTextureSizeTest.cpp @@ -0,0 +1,299 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class MaxTextureSizeTest : public ANGLETest +{ + protected: + MaxTextureSizeTest() + { + setWindowWidth(512); + setWindowHeight(512); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vsSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = position; + texcoord = (position.xy * 0.5) + 0.5; + } + ); + + const std::string textureFSSource = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + const std::string blueFSSource = SHADER_SOURCE + ( + precision highp float; + + void main() + { + gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); + } + ); + + mTextureProgram = CompileProgram(vsSource, textureFSSource); + mBlueProgram = CompileProgram(vsSource, blueFSSource); + if (mTextureProgram == 0 || mBlueProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTexture2DSize); + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxTextureCubeSize); + glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mTextureProgram); + glDeleteProgram(mBlueProgram); + + ANGLETest::TearDown(); + } + + GLuint mTextureProgram; + GLint mTextureUniformLocation; + + GLuint mBlueProgram; + + GLint mMaxTexture2DSize; + GLint mMaxTextureCubeSize; + GLint mMaxRenderbufferSize; +}; + +TEST_P(MaxTextureSizeTest, SpecificationTexImage) +{ + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + GLsizei textureWidth = mMaxTexture2DSize; + GLsizei textureHeight = 64; + + std::vector<GLubyte> data(textureWidth * textureHeight * 4); + for (int y = 0; y < textureHeight; y++) + { + for (int x = 0; x < textureWidth; x++) + { + GLubyte* pixel = &data[0] + ((y * textureWidth + x) * 4); + + // Draw a gradient, red in direction, green in y direction + pixel[0] = static_cast<GLubyte>((float(x) / textureWidth) * 255); + pixel[1] = static_cast<GLubyte>((float(y) / textureHeight) * 255); + pixel[2] = 0; + pixel[3] = 255; + } + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]); + + for (int y = 1; y < getWindowHeight(); y++) + { + for (int x = 1; x < getWindowWidth(); x++) + { + const GLubyte* prevPixel = &pixels[0] + (((y - 1) * getWindowWidth() + (x - 1)) * 4); + const GLubyte* curPixel = &pixels[0] + ((y * getWindowWidth() + x) * 4); + + EXPECT_GE(curPixel[0], prevPixel[0]); + EXPECT_GE(curPixel[1], prevPixel[1]); + EXPECT_EQ(curPixel[2], prevPixel[2]); + EXPECT_EQ(curPixel[3], prevPixel[3]); + } + } +} + +TEST_P(MaxTextureSizeTest, SpecificationTexStorage) +{ + if (getClientMajorVersion() < 3 && + (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8"))) + { + return; + } + + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + GLsizei textureWidth = 64; + GLsizei textureHeight = mMaxTexture2DSize; + + std::vector<GLubyte> data(textureWidth * textureHeight * 4); + for (int y = 0; y < textureHeight; y++) + { + for (int x = 0; x < textureWidth; x++) + { + GLubyte* pixel = &data[0] + ((y * textureWidth + x) * 4); + + // Draw a gradient, red in direction, green in y direction + pixel[0] = static_cast<GLubyte>((float(x) / textureWidth) * 255); + pixel[1] = static_cast<GLubyte>((float(y) / textureHeight) * 255); + pixel[2] = 0; + pixel[3] = 255; + } + } + + if (getClientMajorVersion() < 3) + { + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, textureWidth, textureHeight); + } + else + { + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8_OES, textureWidth, textureHeight); + } + EXPECT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]); + + for (int y = 1; y < getWindowHeight(); y++) + { + for (int x = 1; x < getWindowWidth(); x++) + { + const GLubyte* prevPixel = &pixels[0] + (((y - 1) * getWindowWidth() + (x - 1)) * 4); + const GLubyte* curPixel = &pixels[0] + ((y * getWindowWidth() + x) * 4); + + EXPECT_GE(curPixel[0], prevPixel[0]); + EXPECT_GE(curPixel[1], prevPixel[1]); + EXPECT_EQ(curPixel[2], prevPixel[2]); + EXPECT_EQ(curPixel[3], prevPixel[3]); + } + } +} + +TEST_P(MaxTextureSizeTest, RenderToTexture) +{ + if (getClientMajorVersion() < 3 && (!extensionEnabled("GL_ANGLE_framebuffer_blit"))) + { + std::cout << "Test skipped due to missing glBlitFramebuffer[ANGLE] support." << std::endl; + return; + } + + GLuint fbo = 0; + GLuint textureId = 0; + // create a 1-level texture at maximum size + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + + GLsizei textureWidth = 64; + GLsizei textureHeight = mMaxTexture2DSize; + + // texture setup code + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, textureWidth, textureHeight, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL); + EXPECT_GL_NO_ERROR(); + + // create an FBO and attach the texture + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0); + + EXPECT_GL_NO_ERROR(); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + const int frameCount = 64; + for (int i = 0; i < frameCount; i++) + { + // clear the screen + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + GLubyte clearRed = static_cast<GLubyte>((float(i) / frameCount) * 255); + GLubyte clearGreen = 255 - clearRed; + GLubyte clearBlue = 0; + + glClearColor(clearRed / 255.0f, clearGreen / 255.0f, clearBlue / 255.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // render blue into the texture + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + drawQuad(mBlueProgram, "position", 0.5f); + + // copy corner of texture to LL corner of window + glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, fbo); + glBlitFramebufferANGLE(0, 0, textureWidth - 1, getWindowHeight() - 1, + 0, 0, textureWidth - 1, getWindowHeight() - 1, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, 0); + EXPECT_GL_NO_ERROR(); + + EXPECT_PIXEL_EQ(textureWidth / 2, getWindowHeight() / 2, 0, 0, 255, 255); + EXPECT_PIXEL_EQ(textureWidth + 10, getWindowHeight() / 2, clearRed, clearGreen, clearBlue, 255); + + swapBuffers(); + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &textureId); +} + +// TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the +// default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/1289) + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(MaxTextureSizeTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3()); diff --git a/gfx/angle/src/tests/gl_tests/MipmapTest.cpp b/gfx/angle/src/tests/gl_tests/MipmapTest.cpp new file mode 100755 index 000000000..2ab9411a8 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/MipmapTest.cpp @@ -0,0 +1,1135 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +void TexImageCubeMapFaces(GLint level, + GLenum internalformat, + GLsizei width, + GLenum format, + GLenum type, + void *pixels) +{ + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internalformat, width, width, 0, format, + type, pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internalformat, width, width, 0, format, + type, pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internalformat, width, width, 0, format, + type, pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internalformat, width, width, 0, format, + type, pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internalformat, width, width, 0, format, + type, pixels); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internalformat, width, width, 0, format, + type, pixels); +} + +class BaseMipmapTest : public ANGLETest +{ + protected: + void clearAndDrawQuad(GLuint program, GLsizei viewportWidth, GLsizei viewportHeight) + { + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glViewport(0, 0, viewportWidth, viewportHeight); + ASSERT_GL_NO_ERROR(); + + drawQuad(program, "position", 0.0f); + } +}; + +} // namespace + +class MipmapTest : public BaseMipmapTest +{ + protected: + MipmapTest() + : m2DProgram(0), + mCubeProgram(0), + mTexture2D(0), + mTextureCube(0), + mLevelZeroBlueInitData(nullptr), + mLevelZeroWhiteInitData(nullptr), + mLevelOneInitData(nullptr), + mLevelTwoInitData(nullptr), + mOffscreenFramebuffer(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void setUp2DProgram() + { + // Vertex Shader source + // clang-format off + const std::string vs = SHADER_SOURCE + ( + attribute vec4 position; + varying vec2 vTexCoord; + + void main() + { + gl_Position = position; + vTexCoord = (position.xy * 0.5) + 0.5; + } + ); + + // Fragment Shader source + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + + uniform sampler2D uTexture; + varying vec2 vTexCoord; + + void main() + { + gl_FragColor = texture2D(uTexture, vTexCoord); + } + ); + // clang-format on + + m2DProgram = CompileProgram(vs, fs); + ASSERT_NE(0u, m2DProgram); + } + + void setUpCubeProgram() + { + // A simple vertex shader for the texture cube + // clang-format off + const std::string cubeVS = SHADER_SOURCE + ( + attribute vec4 position; + varying vec4 vPosition; + void main() + { + gl_Position = position; + vPosition = position; + } + ); + + // A very simple fragment shader to sample from the negative-Y face of a texture cube. + const std::string cubeFS = SHADER_SOURCE + ( + precision mediump float; + uniform samplerCube uTexture; + varying vec4 vPosition; + + void main() + { + gl_FragColor = textureCube(uTexture, vec3(vPosition.x, -1, vPosition.y)); + } + ); + // clang-format on + + mCubeProgram = CompileProgram(cubeVS, cubeFS); + ASSERT_NE(0u, mCubeProgram); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + setUp2DProgram(); + + setUpCubeProgram(); + + mLevelZeroBlueInitData = createRGBInitData(getWindowWidth(), getWindowHeight(), 0, 0, 255); // Blue + mLevelZeroWhiteInitData = createRGBInitData(getWindowWidth(), getWindowHeight(), 255, 255, 255); // White + mLevelOneInitData = createRGBInitData((getWindowWidth() / 2), (getWindowHeight() / 2), 0, 255, 0); // Green + mLevelTwoInitData = createRGBInitData((getWindowWidth() / 4), (getWindowHeight() / 4), 255, 0, 0); // Red + + glGenFramebuffers(1, &mOffscreenFramebuffer); + glGenTextures(1, &mTexture2D); + + // Initialize the texture2D to be empty, and don't use mips. + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + ASSERT_EQ(getWindowWidth(), getWindowHeight()); + + // Create a non-mipped texture cube. Set the negative-Y face to be blue. + glGenTextures(1, &mTextureCube); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + TexImageCubeMapFaces(0, GL_RGB, getWindowWidth(), GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, getWindowWidth(), getWindowWidth(), + 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroBlueInitData); + + // Complete the texture cube without mipmaps to start with. + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(m2DProgram); + glDeleteProgram(mCubeProgram); + glDeleteFramebuffers(1, &mOffscreenFramebuffer); + glDeleteTextures(1, &mTexture2D); + glDeleteTextures(1, &mTextureCube); + + SafeDeleteArray(mLevelZeroBlueInitData); + SafeDeleteArray(mLevelZeroWhiteInitData); + SafeDeleteArray(mLevelOneInitData); + SafeDeleteArray(mLevelTwoInitData); + + ANGLETest::TearDown(); + } + + GLubyte *createRGBInitData(GLint width, GLint height, GLint r, GLint g, GLint b) + { + GLubyte *data = new GLubyte[3 * width * height]; + + for (int i = 0; i < width * height; i+=1) + { + data[3 * i + 0] = static_cast<GLubyte>(r); + data[3 * i + 1] = static_cast<GLubyte>(g); + data[3 * i + 2] = static_cast<GLubyte>(b); + } + + return data; + } + + void clearTextureLevel0(GLenum textarget, + GLuint texture, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha) + { + glBindFramebuffer(GL_FRAMEBUFFER, mOffscreenFramebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textarget, texture, 0); + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + glClearColor(red, green, blue, alpha); + glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + GLuint m2DProgram; + GLuint mCubeProgram; + GLuint mTexture2D; + GLuint mTextureCube; + + GLubyte* mLevelZeroBlueInitData; + GLubyte* mLevelZeroWhiteInitData; + GLubyte* mLevelOneInitData; + GLubyte* mLevelTwoInitData; + + private: + GLuint mOffscreenFramebuffer; +}; + +class MipmapTestES3 : public BaseMipmapTest +{ + protected: + MipmapTestES3() + : mTexture(0), + mArrayProgram(0), + mTextureArraySliceUniformLocation(-1), + m3DProgram(0), + mTexture3DSliceUniformLocation(-1), + mTexture3DLODUniformLocation(-1), + m2DProgram(0) + + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + std::string vertexShaderSource() + { + // Don't put "#version ..." on its own line. See [cpp]p1: + // "If there are sequences of preprocessing tokens within the list of arguments that + // would otherwise act as preprocessing directives, the behavior is undefined" + // clang-format off + return SHADER_SOURCE + ( #version 300 es\n + precision highp float; + in vec4 position; + out vec2 texcoord; + + void main() + { + gl_Position = vec4(position.xy, 0.0, 1.0); + texcoord = (position.xy * 0.5) + 0.5; + } + ); + // clang-format on + } + + void setUpArrayProgram() + { + const std::string fragmentShaderSourceArray = SHADER_SOURCE + ( #version 300 es\n + precision highp float; + uniform highp sampler2DArray tex; + uniform int slice; + in vec2 texcoord; + out vec4 out_FragColor; + + void main() + { + out_FragColor = texture(tex, vec3(texcoord, float(slice))); + } + ); + + mArrayProgram = CompileProgram(vertexShaderSource(), fragmentShaderSourceArray); + if (mArrayProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureArraySliceUniformLocation = glGetUniformLocation(mArrayProgram, "slice"); + ASSERT_NE(-1, mTextureArraySliceUniformLocation); + + glUseProgram(mArrayProgram); + glUseProgram(0); + ASSERT_GL_NO_ERROR(); + } + + void setUp3DProgram() + { + const std::string fragmentShaderSource3D = SHADER_SOURCE + ( #version 300 es\n + precision highp float; + uniform highp sampler3D tex; + uniform float slice; + uniform float lod; + in vec2 texcoord; + out vec4 out_FragColor; + + void main() + { + out_FragColor = textureLod(tex, vec3(texcoord, slice), lod); + } + ); + + m3DProgram = CompileProgram(vertexShaderSource(), fragmentShaderSource3D); + if (m3DProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTexture3DSliceUniformLocation = glGetUniformLocation(m3DProgram, "slice"); + ASSERT_NE(-1, mTexture3DSliceUniformLocation); + + mTexture3DLODUniformLocation = glGetUniformLocation(m3DProgram, "lod"); + ASSERT_NE(-1, mTexture3DLODUniformLocation); + + glUseProgram(m3DProgram); + glUniform1f(mTexture3DLODUniformLocation, 0); + glUseProgram(0); + ASSERT_GL_NO_ERROR(); + } + + void setUp2DProgram() + { + // clang-format off + const std::string fragmentShaderSource2D = SHADER_SOURCE + ( #version 300 es\n + precision highp float; + uniform highp sampler2D tex; + in vec2 texcoord; + out vec4 out_FragColor; + + void main() + { + out_FragColor = texture(tex, texcoord); + } + ); + // clang-format on + + m2DProgram = CompileProgram(vertexShaderSource(), fragmentShaderSource2D); + ASSERT_NE(0u, m2DProgram); + + ASSERT_GL_NO_ERROR(); + } + + void setUpCubeProgram() + { + // A very simple fragment shader to sample from the negative-Y face of a texture cube. + // clang-format off + const std::string cubeFS = SHADER_SOURCE + ( #version 300 es\n + precision mediump float; + uniform samplerCube uTexture; + in vec2 texcoord; + out vec4 out_FragColor; + + void main() + { + out_FragColor = texture(uTexture, vec3(texcoord.x, -1, texcoord.y)); + } + ); + // clang-format on + + mCubeProgram = CompileProgram(vertexShaderSource(), cubeFS); + ASSERT_NE(0u, mCubeProgram); + + ASSERT_GL_NO_ERROR(); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenTextures(1, &mTexture); + ASSERT_GL_NO_ERROR(); + + setUpArrayProgram(); + setUp3DProgram(); + setUp2DProgram(); + setUpCubeProgram(); + } + + void TearDown() override + { + glDeleteTextures(1, &mTexture); + + glDeleteProgram(mArrayProgram); + glDeleteProgram(m3DProgram); + glDeleteProgram(m2DProgram); + glDeleteProgram(mCubeProgram); + + ANGLETest::TearDown(); + } + + GLuint mTexture; + + GLuint mArrayProgram; + GLint mTextureArraySliceUniformLocation; + + GLuint m3DProgram; + GLint mTexture3DSliceUniformLocation; + GLint mTexture3DLODUniformLocation; + + GLuint m2DProgram; + + GLuint mCubeProgram; +}; + +// This test uses init data for the first three levels of the texture. It passes the level 0 data in, then renders, then level 1, then renders, etc. +// This ensures that renderers using the zero LOD workaround (e.g. D3D11 FL9_3) correctly pass init data to the mipmapped texture, +// even if the the zero-LOD texture is currently in use. +TEST_P(MipmapTest, DISABLED_ThreeLevelsInitData) +{ + // Pass in level zero init data. + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroBlueInitData); + ASSERT_GL_NO_ERROR(); + + // Disable mips. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + // Draw a full-sized quad, and check it's blue. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Draw a half-sized quad, and check it's blue. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue); + + // Draw a quarter-sized quad, and check it's blue. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue); + + // Complete the texture by initializing the remaining levels. + int n = 1; + while (getWindowWidth() / (1U << n) >= 1) + { + glTexImage2D(GL_TEXTURE_2D, n, GL_RGB, getWindowWidth() / (1U << n), getWindowWidth() / (1U << n), 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + ASSERT_GL_NO_ERROR(); + n+=1; + } + + // Pass in level one init data. + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelOneInitData); + ASSERT_GL_NO_ERROR(); + + // Draw a full-sized quad, and check it's blue. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Draw a half-sized quad, and check it's blue. We've not enabled mipmaps yet, so our init data for level one shouldn't be used. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue); + + // Enable mipmaps. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + + // Draw a half-sized quad, and check it's green. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green); + + // Draw a quarter-sized quad, and check it's black, since we've not passed any init data for level two. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::black); + + // Pass in level two init data. + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, getWindowWidth() / 4, getWindowHeight() / 4, 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelTwoInitData); + ASSERT_GL_NO_ERROR(); + + // Draw a full-sized quad, and check it's blue. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Draw a half-sized quad, and check it's green. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green); + + // Draw a quarter-sized quad, and check it's red. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red); + + // Now disable mipmaps again, and render multiple sized quads. They should all be blue, since level 0 is blue. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue); + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue); + + // Now reset level 0 to white, keeping mipmaps disabled. Then, render various sized quads. They should be white. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroWhiteInitData); + ASSERT_GL_NO_ERROR(); + + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::white); + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white); + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::white); + + // Then enable mipmaps again. The quads should be white, green, red respectively. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::white); + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green); + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red); +} + +// This test generates (and uses) mipmaps on a texture using init data. D3D11 will use a non-renderable TextureStorage for this. +// The test then disables mips, renders to level zero of the texture, and reenables mips before using the texture again. +// To do this, D3D11 has to convert the TextureStorage into a renderable one. +// This test ensures that the conversion works correctly. +// In particular, on D3D11 Feature Level 9_3 it ensures that both the zero LOD workaround texture AND the 'normal' texture are copied during conversion. +TEST_P(MipmapTest, GenerateMipmapFromInitDataThenRender) +{ + // Pass in initial data so the texture is blue. + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, mLevelZeroBlueInitData); + + // Then generate the mips. + glGenerateMipmap(GL_TEXTURE_2D); + ASSERT_GL_NO_ERROR(); + + // Enable mipmaps. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + + // Now draw the texture to various different sized areas. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Use mip level 1 + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue); + + // Use mip level 2 + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue); + + ASSERT_GL_NO_ERROR(); + + // Disable mips. Render a quad using the texture and ensure it's blue. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Clear level 0 of the texture to red. + clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 1.0f, 0.0f, 0.0f, 1.0f); + + // Reenable mips, and try rendering different-sized quads. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + + // Level 0 is now red, so this should render red. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red); + + // Use mip level 1, blue. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue); + + // Use mip level 2, blue. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue); +} + +// This test ensures that mips are correctly generated from a rendered image. +// In particular, on D3D11 Feature Level 9_3, the clear call will be performed on the zero-level texture, rather than the mipped one. +// The test ensures that the zero-level texture is correctly copied into the mipped texture before the mipmaps are generated. +TEST_P(MipmapTest, GenerateMipmapFromRenderedImage) +{ + glBindTexture(GL_TEXTURE_2D, mTexture2D); + // Clear the texture to blue. + clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 0.0f, 0.0f, 1.0f, 1.0f); + + // Then generate the mips + glGenerateMipmap(GL_TEXTURE_2D); + ASSERT_GL_NO_ERROR(); + + // Enable mips. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + + // Now draw the texture to various different sized areas. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Use mip level 1 + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue); + + // Use mip level 2 + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue); +} + +// Test to ensure that rendering to a mipmapped texture works, regardless of whether mipmaps are enabled or not. +// TODO: This test hits a texture rebind bug in the D3D11 renderer. Fix this. +TEST_P(MipmapTest, RenderOntoLevelZeroAfterGenerateMipmap) +{ + // TODO(geofflang): Figure out why this is broken on AMD OpenGL + if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel/AMD OpenGL." << std::endl; + return; + } + + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + // Clear the texture to blue. + clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 0.0f, 0.0f, 1.0f, 1.0f); + + // Now, draw the texture to a quad that's the same size as the texture. This draws to the default framebuffer. + // The quad should be blue. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Now go back to the texture, and generate mips on it. + glGenerateMipmap(GL_TEXTURE_2D); + ASSERT_GL_NO_ERROR(); + + // Now try rendering the textured quad again. Note: we've not told GL to use the generated mips. + // The quad should be blue. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Now tell GL to use the generated mips. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + EXPECT_GL_NO_ERROR(); + + // Now render the textured quad again. It should be still be blue. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); + + // Now render the textured quad to an area smaller than the texture (i.e. to force minification). This should be blue. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue); + + // Now clear the texture to green. This just clears the top level. The lower mips should remain blue. + clearTextureLevel0(GL_TEXTURE_2D, mTexture2D, 0.0f, 1.0f, 0.0f, 1.0f); + + // Render a textured quad equal in size to the texture. This should be green, since we just cleared level 0. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green); + + // Render a small textured quad. This forces minification, so should render blue (the color of levels 1+). + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::blue); + + // Disable mipmaps again + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ASSERT_GL_NO_ERROR(); + + // Render a textured quad equal in size to the texture. This should be green, the color of level 0 in the texture. + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green); + + // Render a small textured quad. This would force minification if mips were enabled, but they're not. Therefore, this should be green. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::green); +} + +// This test ensures that the level-zero workaround for TextureCubes (on D3D11 Feature Level 9_3) +// works as expected. It tests enabling/disabling mipmaps, generating mipmaps, and rendering to level zero. +TEST_P(MipmapTest, TextureCubeGeneralLevelZero) +{ + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + + // Draw. Since the negative-Y face's is blue, this should be blue. + clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); + + // Generate mipmaps, and render. This should be blue. + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); + + // Draw using a smaller viewport (to force a lower LOD of the texture). This should still be blue. + clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); + + // Now clear the negative-Y face of the cube to red. + clearTextureLevel0(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mTextureCube, 1.0f, 0.0f, 0.0f, 1.0f); + + // Draw using a full-size viewport. This should be red. + clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + + // Draw using a quarter-size viewport, to force a lower LOD. This should be *BLUE*, since we only cleared level zero + // of the negative-Y face to red, and left its mipmaps blue. + clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); + + // Disable mipmaps again, and draw a to a quarter-size viewport. + // Since this should use level zero of the texture, this should be *RED*. + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); +} + +// This test ensures that rendering to level-zero of a TextureCube works as expected. +TEST_P(MipmapTest, TextureCubeRenderToLevelZero) +{ + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + + // Draw. Since the negative-Y face's is blue, this should be blue. + clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); + + // Now clear the negative-Y face of the cube to red. + clearTextureLevel0(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, mTextureCube, 1.0f, 0.0f, 0.0f, 1.0f); + + // Draw using a full-size viewport. This should be red. + clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + + // Draw a to a quarter-size viewport. This should also be red. + clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); +} + +// Creates a mipmapped 2D array texture with three layers, and calls ANGLE's GenerateMipmap. +// Then tests if the mipmaps are rendered correctly for all three layers. +TEST_P(MipmapTestES3, MipmapsForTextureArray) +{ + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture); + + glTexStorage3D(GL_TEXTURE_2D_ARRAY, 5, GL_RGBA8, 16, 16, 3); + + // Fill the first layer with red + std::vector<GLColor> pixelsRed(16 * 16, GLColor::red); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsRed.data()); + + // Fill the second layer with green + std::vector<GLColor> pixelsGreen(16 * 16, GLColor::green); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsGreen.data()); + + // Fill the third layer with blue + std::vector<GLColor> pixelsBlue(16 * 16, GLColor::blue); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 2, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsBlue.data()); + + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + EXPECT_GL_NO_ERROR(); + + glGenerateMipmap(GL_TEXTURE_2D_ARRAY); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mArrayProgram); + + EXPECT_GL_NO_ERROR(); + + // Draw the first slice + glUniform1i(mTextureArraySliceUniformLocation, 0); + drawQuad(mArrayProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red); + + // Draw the second slice + glUniform1i(mTextureArraySliceUniformLocation, 1); + drawQuad(mArrayProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green); + + // Draw the third slice + glUniform1i(mTextureArraySliceUniformLocation, 2); + drawQuad(mArrayProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::blue); +} + +// Create a mipmapped 2D array texture with more layers than width / height, and call +// GenerateMipmap. +TEST_P(MipmapTestES3, MipmapForDeepTextureArray) +{ + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + glBindTexture(GL_TEXTURE_2D_ARRAY, mTexture); + + // Fill the whole texture with red. + std::vector<GLColor> pixelsRed(2 * 2 * 4, GLColor::red); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 2, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsRed.data()); + + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + EXPECT_GL_NO_ERROR(); + + glGenerateMipmap(GL_TEXTURE_2D_ARRAY); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mArrayProgram); + + EXPECT_GL_NO_ERROR(); + + // Draw the first slice + glUniform1i(mTextureArraySliceUniformLocation, 0); + drawQuad(mArrayProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red); + + // Draw the fourth slice + glUniform1i(mTextureArraySliceUniformLocation, 3); + drawQuad(mArrayProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red); +} + +// Creates a mipmapped 3D texture with two layers, and calls ANGLE's GenerateMipmap. +// Then tests if the mipmaps are rendered correctly for all two layers. +TEST_P(MipmapTestES3, MipmapsForTexture3D) +{ + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + glBindTexture(GL_TEXTURE_3D, mTexture); + + glTexStorage3D(GL_TEXTURE_3D, 5, GL_RGBA8, 16, 16, 2); + + // Fill the first layer with red + std::vector<GLColor> pixelsRed(16 * 16, GLColor::red); + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsRed.data()); + + // Fill the second layer with green + std::vector<GLColor> pixelsGreen(16 * 16, GLColor::green); + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsGreen.data()); + + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + EXPECT_GL_NO_ERROR(); + + glGenerateMipmap(GL_TEXTURE_3D); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(m3DProgram); + + EXPECT_GL_NO_ERROR(); + + // Mipmap level 0 + // Draw the first slice + glUniform1f(mTexture3DLODUniformLocation, 0.); + glUniform1f(mTexture3DSliceUniformLocation, 0.25f); + drawQuad(m3DProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red); + + // Draw the second slice + glUniform1f(mTexture3DSliceUniformLocation, 0.75f); + drawQuad(m3DProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green); + + // Mipmap level 1 + // The second mipmap should only have one slice. + glUniform1f(mTexture3DLODUniformLocation, 1.); + drawQuad(m3DProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(px, py, 127, 127, 0, 255, 1.0); + + glUniform1f(mTexture3DSliceUniformLocation, 0.75f); + drawQuad(m3DProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(px, py, 127, 127, 0, 255, 1.0); +} + +// Create a 2D texture with levels 0-2, call GenerateMipmap with base level 1 so that level 0 stays +// the same, and then sample levels 0 and 2. +// GLES 3.0.4 section 3.8.10: +// "Mipmap generation replaces texel array levels levelbase + 1 through q with arrays derived from +// the levelbase array, regardless of their previous contents. All other mipmap arrays, including +// the levelbase array, are left unchanged by this computation." +TEST_P(MipmapTestES3, GenerateMipmapBaseLevel) +{ + if (IsAMD() && IsDesktopOpenGL()) + { + // Observed incorrect rendering on AMD, sampling level 2 returns black. + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + + glBindTexture(GL_TEXTURE_2D, mTexture); + + ASSERT(getWindowWidth() == getWindowHeight()); + + // Fill level 0 with blue + std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowHeight(), GLColor::blue); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, pixelsBlue.data()); + + // Fill level 1 with red + std::vector<GLColor> pixelsRed(getWindowWidth() * getWindowHeight() / 4, GLColor::red); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data()); + + // Fill level 2 with green + std::vector<GLColor> pixelsGreen(getWindowWidth() * getWindowHeight() / 16, GLColor::green); + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, getWindowWidth() / 4, getWindowHeight() / 4, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixelsGreen.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + // The blue level 0 should be untouched by this since base level is 1. + glGenerateMipmap(GL_TEXTURE_2D); + + EXPECT_GL_NO_ERROR(); + + // Draw using level 2. It should be set to red by GenerateMipmap. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red); + + // Draw using level 0. It should still be blue. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); +} + +// Create a cube map with levels 0-2, call GenerateMipmap with base level 1 so that level 0 stays +// the same, and then sample levels 0 and 2. +// GLES 3.0.4 section 3.8.10: +// "Mipmap generation replaces texel array levels levelbase + 1 through q with arrays derived from +// the levelbase array, regardless of their previous contents. All other mipmap arrays, including +// the levelbase array, are left unchanged by this computation." +TEST_P(MipmapTestES3, GenerateMipmapCubeBaseLevel) +{ + if (IsAMD() && IsDesktopOpenGL()) + { + // Observed incorrect rendering on AMD, sampling level 2 returns black. + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + + ASSERT_EQ(getWindowWidth(), getWindowHeight()); + + glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture); + std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowWidth(), GLColor::blue); + TexImageCubeMapFaces(0, GL_RGBA8, getWindowWidth(), GL_RGBA, GL_UNSIGNED_BYTE, + pixelsBlue.data()); + + // Fill level 1 with red + std::vector<GLColor> pixelsRed(getWindowWidth() * getWindowWidth() / 4, GLColor::red); + TexImageCubeMapFaces(1, GL_RGBA8, getWindowWidth() / 2, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsRed.data()); + + // Fill level 2 with green + std::vector<GLColor> pixelsGreen(getWindowWidth() * getWindowWidth() / 16, GLColor::green); + TexImageCubeMapFaces(2, GL_RGBA8, getWindowWidth() / 4, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsGreen.data()); + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + // The blue level 0 should be untouched by this since base level is 1. + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + + EXPECT_GL_NO_ERROR(); + + // Draw using level 2. It should be set to red by GenerateMipmap. + clearAndDrawQuad(mCubeProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::red); + + if (IsNVIDIA() && IsOpenGL()) + { + // Observed incorrect rendering on NVIDIA, level zero seems to be incorrectly affected by + // GenerateMipmap. + std::cout << "Test partially skipped on NVIDIA OpenGL." << std::endl; + return; + } + + // Draw using level 0. It should still be blue. + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); + clearAndDrawQuad(mCubeProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); +} + +// Create a texture with levels 0-2, call GenerateMipmap with max level 1 so that level 2 stays the +// same, and then sample levels 1 and 2. +// GLES 3.0.4 section 3.8.10: +// "Mipmap generation replaces texel array levels levelbase + 1 through q with arrays derived from +// the levelbase array, regardless of their previous contents. All other mipmap arrays, including +// the levelbase array, are left unchanged by this computation." +TEST_P(MipmapTestES3, GenerateMipmapMaxLevel) +{ + glBindTexture(GL_TEXTURE_2D, mTexture); + + // Fill level 0 with blue + std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowHeight(), GLColor::blue); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, pixelsBlue.data()); + + // Fill level 1 with red + std::vector<GLColor> pixelsRed(getWindowWidth() * getWindowHeight() / 4, GLColor::red); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data()); + + // Fill level 2 with green + std::vector<GLColor> pixelsGreen(getWindowWidth() * getWindowHeight() / 16, GLColor::green); + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, getWindowWidth() / 4, getWindowHeight() / 4, 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixelsGreen.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + // The green level 2 should be untouched by this since max level is 1. + glGenerateMipmap(GL_TEXTURE_2D); + + EXPECT_GL_NO_ERROR(); + + // Draw using level 1. It should be set to blue by GenerateMipmap. + clearAndDrawQuad(m2DProgram, getWindowWidth() / 2, getWindowHeight() / 2); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue); + + // Draw using level 2. It should still be green. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); + clearAndDrawQuad(m2DProgram, getWindowWidth() / 4, getWindowHeight() / 4); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 8, getWindowHeight() / 8, GLColor::green); +} + +// Call GenerateMipmap with out-of-range base level. The spec is interpreted so that an out-of-range +// base level does not have a color-renderable/texture-filterable internal format, so the +// GenerateMipmap call generates INVALID_OPERATION. GLES 3.0.4 section 3.8.10: +// "If the levelbase array was not specified with an unsized internal format from table 3.3 or a +// sized internal format that is both color-renderable and texture-filterable according to table +// 3.13, an INVALID_OPERATION error is generated." +TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRange) +{ + glBindTexture(GL_TEXTURE_2D, mTexture); + + // Fill level 0 with blue + std::vector<GLColor> pixelsBlue(getWindowWidth() * getWindowHeight(), GLColor::blue); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, pixelsBlue.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1000); + + EXPECT_GL_NO_ERROR(); + + // Expecting the out-of-range base level to be treated as not color-renderable and + // texture-filterable. + glGenerateMipmap(GL_TEXTURE_2D); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // Draw using level 0. It should still be blue. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::blue); +} + +// Call GenerateMipmap with out-of-range base level on an immutable texture. The base level should +// be clamped, so the call doesn't generate an error. +TEST_P(MipmapTestES3, GenerateMipmapBaseLevelOutOfRangeImmutableTexture) +{ + glBindTexture(GL_TEXTURE_2D, mTexture); + + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1000); + + EXPECT_GL_NO_ERROR(); + + // This is essentially a no-op, since the texture only has one level. + glGenerateMipmap(GL_TEXTURE_2D); + + EXPECT_GL_NO_ERROR(); + + // The only level of the texture should still be green. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + clearAndDrawQuad(m2DProgram, getWindowWidth(), getWindowHeight()); + EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +// Note: we run these tests against 9_3 on WARP due to hardware driver issues on Win7 +ANGLE_INSTANTIATE_TEST(MipmapTest, + ES2_D3D9(), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE), + ES2_D3D11_FL9_3_WARP(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(MipmapTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/MultisampleCompatibilityTest.cpp b/gfx/angle/src/tests/gl_tests/MultisampleCompatibilityTest.cpp new file mode 100755 index 000000000..0edc221d7 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/MultisampleCompatibilityTest.cpp @@ -0,0 +1,438 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// StateChangeTest: +// Specifically designed for an ANGLE implementation of GL, these tests validate that +// ANGLE's dirty bits systems don't get confused by certain sequences of state changes. +// + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" +#include "shader_utils.h" + +using namespace angle; + +namespace +{ + +const GLint kWidth = 64; +const GLint kHeight = 64; + +// test drawing with GL_MULTISAMPLE_EXT enabled/disabled. +class EXTMultisampleCompatibilityTest : public ANGLETest +{ + +protected: + EXTMultisampleCompatibilityTest() + { + setWindowWidth(64); + setWindowHeight(64); + setConfigRedBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + static const char* v_shader_str = + "attribute vec4 a_Position;\n" + "void main()\n" + "{ gl_Position = a_Position; }"; + + static const char* f_shader_str = + "precision mediump float;\n" + "uniform vec4 color;" + "void main() { gl_FragColor = color; }"; + + mProgram = CompileProgram(v_shader_str, f_shader_str); + + GLuint position_loc = glGetAttribLocation(mProgram, "a_Position"); + mColorLoc = glGetUniformLocation(mProgram, "color"); + + glGenBuffers(1, &mVBO); + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + static float vertices[] = { + 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, + -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, + }; + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(position_loc); + glVertexAttribPointer(position_loc, 2, GL_FLOAT, GL_FALSE, 0, 0); + } + + void TearDown() override + { + glDeleteBuffers(1, &mVBO); + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + void prepareForDraw() + { + // Create a sample buffer. + GLsizei num_samples = 4, max_samples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + num_samples = std::min(num_samples, max_samples); + + glGenRenderbuffers(1, &mSampleRB); + glBindRenderbuffer(GL_RENDERBUFFER, mSampleRB); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, num_samples, + GL_RGBA8_OES, kWidth, kHeight); + GLint param = 0; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, + ¶m); + EXPECT_GE(param, num_samples); + + glGenFramebuffers(1, &mSampleFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, mSampleRB); + EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // Create another FBO to resolve the multisample buffer into. + glGenTextures(1, &mResolveTex); + glBindTexture(GL_TEXTURE_2D, mResolveTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, + GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glGenFramebuffers(1, &mResolveFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mResolveFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + mResolveTex, 0); + EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + glUseProgram(mProgram); + glViewport(0, 0, kWidth, kHeight); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + } + + void prepareForVerify() + { + // Resolve. + glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mResolveFBO); + glClearColor(1.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + glBlitFramebufferANGLE(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, mResolveFBO); + + ASSERT_GL_NO_ERROR(); + } + + void cleanup() + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &mResolveFBO); + glDeleteFramebuffers(1, &mSampleFBO); + glDeleteTextures(1, &mResolveTex); + glDeleteRenderbuffers(1, &mSampleRB); + + ASSERT_GL_NO_ERROR(); + + } + + bool isApplicable() const + { + return extensionEnabled("GL_EXT_multisample_compatibility") && + extensionEnabled("GL_ANGLE_framebuffer_multisample") && + extensionEnabled("GL_OES_rgb8_rgba8") && + !IsAMD(); + } + GLuint mSampleFBO; + GLuint mResolveFBO; + GLuint mSampleRB; + GLuint mResolveTex; + + GLuint mColorLoc; + GLuint mProgram; + GLuint mVBO; +}; + +} // + +// Test simple state tracking +TEST_P(EXTMultisampleCompatibilityTest, TestStateTracking) +{ + if (!isApplicable()) + return; + + EXPECT_TRUE(glIsEnabled(GL_MULTISAMPLE_EXT)); + glDisable(GL_MULTISAMPLE_EXT); + EXPECT_FALSE(glIsEnabled(GL_MULTISAMPLE_EXT)); + glEnable(GL_MULTISAMPLE_EXT); + EXPECT_TRUE(glIsEnabled(GL_MULTISAMPLE_EXT)); + + EXPECT_FALSE(glIsEnabled(GL_SAMPLE_ALPHA_TO_ONE_EXT)); + glEnable(GL_SAMPLE_ALPHA_TO_ONE_EXT); + EXPECT_TRUE(glIsEnabled(GL_SAMPLE_ALPHA_TO_ONE_EXT)); + glDisable(GL_SAMPLE_ALPHA_TO_ONE_EXT); + EXPECT_FALSE(glIsEnabled(GL_SAMPLE_ALPHA_TO_ONE_EXT)); + + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); +} + +// Test that disabling GL_MULTISAMPLE_EXT is handled correctly. +TEST_P(EXTMultisampleCompatibilityTest, DrawAndResolve) +{ + if (!isApplicable()) + return; + + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + static const float kRed[] = {1.0f, 0.0f, 0.0f, 1.0f}; + + // Different drivers seem to behave differently with respect to resulting + // values. These might be due to different MSAA sample counts causing + // different samples to hit. Other option is driver bugs. Just test that + // disabling multisample causes a difference. + std::unique_ptr<uint8_t[]> results[3]; + const GLint kResultSize = kWidth * kHeight * 4; + for (int pass = 0; pass < 3; pass++) + { + prepareForDraw(); + // Green: from top right to bottom left. + glUniform4fv(mColorLoc, 1, kGreen); + glDrawArrays(GL_TRIANGLES, 0, 3); + + // Blue: from top left to bottom right. + glUniform4fv(mColorLoc, 1, kBlue); + glDrawArrays(GL_TRIANGLES, 3, 3); + + // Red, with and without MSAA: from bottom left to top right. + if (pass == 1) + { + glDisable(GL_MULTISAMPLE_EXT); + } + glUniform4fv(mColorLoc, 1, kRed); + glDrawArrays(GL_TRIANGLES, 6, 3); + if (pass == 1) + { + glEnable(GL_MULTISAMPLE_EXT); + } + prepareForVerify(); + results[pass].reset(new uint8_t[kResultSize]); + memset(results[pass].get(), 123u, kResultSize); + glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + results[pass].get()); + + cleanup(); + } + EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize)); + // Verify that rendering is deterministic, so that the pass above does not + // come from non-deterministic rendering. + EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize)); +} + +// Test that enabling GL_SAMPLE_ALPHA_TO_ONE_EXT affects rendering. +TEST_P(EXTMultisampleCompatibilityTest, DrawAlphaOneAndResolve) +{ + if (!isApplicable()) + return; + + // SAMPLE_ALPHA_TO_ONE is specified to transform alpha values of + // covered samples to 1.0. In order to detect it, we use non-1.0 + // alpha. + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 0.5f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 0.5f}; + static const float kRed[] = {1.0f, 0.0f, 0.0f, 0.5f}; + + // Different drivers seem to behave differently with respect to resulting + // alpha value. These might be due to different MSAA sample counts causing + // different samples to hit. Other option is driver bugs. Testing exact or + // even approximate sample values is not that easy. Thus, just test + // representative positions which have fractional pixels, inspecting that + // normal rendering is different to SAMPLE_ALPHA_TO_ONE rendering. + std::unique_ptr<uint8_t[]> results[3]; + const GLint kResultSize = kWidth * kHeight * 4; + + for (int pass = 0; pass < 3; ++pass) + { + prepareForDraw(); + if (pass == 1) + { + glEnable(GL_SAMPLE_ALPHA_TO_ONE_EXT); + } + glEnable(GL_MULTISAMPLE_EXT); + glUniform4fv(mColorLoc, 1, kGreen); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glUniform4fv(mColorLoc, 1, kBlue); + glDrawArrays(GL_TRIANGLES, 3, 3); + + glDisable(GL_MULTISAMPLE_EXT); + glUniform4fv(mColorLoc, 1, kRed); + glDrawArrays(GL_TRIANGLES, 6, 3); + + prepareForVerify(); + results[pass].reset(new uint8_t[kResultSize]); + memset(results[pass].get(), 123u, kResultSize); + glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, + results[pass].get()); + if (pass == 1) + { + glDisable(GL_SAMPLE_ALPHA_TO_ONE_EXT); + } + + cleanup(); + } + EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize)); + // Verify that rendering is deterministic, so that the pass above does not + // come from non-deterministic rendering. + EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize)); +} + +ANGLE_INSTANTIATE_TEST(EXTMultisampleCompatibilityTest, ES2_OPENGL(), ES2_OPENGLES(), ES3_OPENGL()); + +class MultisampleCompatibilityTest : public ANGLETest +{ + + protected: + MultisampleCompatibilityTest() + { + setWindowWidth(64); + setWindowHeight(64); + setConfigRedBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void prepareForDraw(GLsizei numSamples) + { + // Create a sample buffer. + glGenRenderbuffers(1, &mSampleRB); + glBindRenderbuffer(GL_RENDERBUFFER, mSampleRB); + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, numSamples, GL_RGBA8, kWidth, + kHeight); + GLint param = 0; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, ¶m); + EXPECT_GE(param, numSamples); + glGenFramebuffers(1, &mSampleFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleRB); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + // Create another FBO to resolve the multisample buffer into. + glGenTextures(1, &mResolveTex); + glBindTexture(GL_TEXTURE_2D, mResolveTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, + NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glGenFramebuffers(1, &mResolveFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mResolveFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mResolveTex, 0); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + glViewport(0, 0, kWidth, kHeight); + glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + } + + void prepareForVerify() + { + // Resolve. + glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleFBO); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mResolveFBO); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glBlitFramebufferANGLE(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT, + GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, mResolveFBO); + + ASSERT_GL_NO_ERROR(); + } + + void cleanup() + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &mResolveFBO); + glDeleteFramebuffers(1, &mSampleFBO); + glDeleteTextures(1, &mResolveTex); + glDeleteRenderbuffers(1, &mSampleRB); + + ASSERT_GL_NO_ERROR(); + } + + bool isApplicable() const + { + return extensionEnabled("GL_ANGLE_framebuffer_multisample") && + extensionEnabled("GL_OES_rgb8_rgba8"); + } + + GLuint mSampleFBO; + GLuint mResolveFBO; + GLuint mSampleRB; + GLuint mResolveTex; +}; + +// Test that enabling GL_SAMPLE_COVERAGE affects rendering. +TEST_P(MultisampleCompatibilityTest, DrawCoverageAndResolve) +{ + if (!isApplicable()) + return; + + // TODO: Figure out why this fails on Android. + if (IsAndroid()) + { + std::cout << "Test skipped on Android." << std::endl; + return; + } + + const std::string &vertex = + "attribute vec4 position;\n" + "void main()\n" + "{ gl_Position = position; }"; + const std::string &fragment = + "void main()\n" + "{ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }"; + + ANGLE_GL_PROGRAM(drawRed, vertex, fragment); + + GLsizei maxSamples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); + int iterationCount = maxSamples + 1; + for (int samples = 1; samples < iterationCount; samples++) + { + prepareForDraw(samples); + glEnable(GL_SAMPLE_COVERAGE); + glSampleCoverage(1.0, false); + drawQuad(drawRed.get(), "position", 0.5f); + + prepareForVerify(); + GLsizei pixelCount = kWidth * kHeight; + std::vector<GLColor> actual(pixelCount, GLColor::black); + glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, actual.data()); + glDisable(GL_SAMPLE_COVERAGE); + cleanup(); + + std::vector<GLColor> expected(pixelCount, GLColor::red); + EXPECT_EQ(expected, actual); + } +} + +ANGLE_INSTANTIATE_TEST(MultisampleCompatibilityTest, + ES2_D3D9(), + ES2_OPENGL(), + ES2_OPENGLES(), + ES3_D3D11(), + ES3_OPENGL(), + ES3_OPENGLES());
\ No newline at end of file diff --git a/gfx/angle/src/tests/gl_tests/ObjectAllocationTest.cpp b/gfx/angle/src/tests/gl_tests/ObjectAllocationTest.cpp new file mode 100755 index 000000000..b0e59f7fc --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ObjectAllocationTest.cpp @@ -0,0 +1,54 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ObjectAllocationTest +// Tests for object allocations and lifetimes. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class ObjectAllocationTest : public ANGLETest +{ + protected: + ObjectAllocationTest() {} +}; + +// Test that we don't re-allocate a bound framebuffer ID. +TEST_P(ObjectAllocationTest, BindFramebufferBeforeGen) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 1); + GLuint fbo = 0; + glGenFramebuffers(1, &fbo); + EXPECT_NE(1u, fbo); + glDeleteFramebuffers(1, &fbo); + EXPECT_GL_NO_ERROR(); +} + +// Test that we don't re-allocate a bound framebuffer ID, other pattern. +TEST_P(ObjectAllocationTest, BindFramebufferAfterGen) +{ + GLuint firstFBO = 0; + glGenFramebuffers(1, &firstFBO); + glBindFramebuffer(GL_FRAMEBUFFER, 1); + glDeleteFramebuffers(1, &firstFBO); + + glBindFramebuffer(GL_FRAMEBUFFER, 2); + GLuint secondFBOs[2] = {0}; + glGenFramebuffers(2, secondFBOs); + EXPECT_NE(2u, secondFBOs[0]); + EXPECT_NE(2u, secondFBOs[1]); + glDeleteFramebuffers(2, secondFBOs); + + EXPECT_GL_NO_ERROR(); +} + +} // anonymous namespace + +ANGLE_INSTANTIATE_TEST(ObjectAllocationTest, ES3_OPENGL(), ES3_D3D11());
\ No newline at end of file diff --git a/gfx/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp b/gfx/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp new file mode 100755 index 000000000..5c24f8bd7 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/OcclusionQueriesTest.cpp @@ -0,0 +1,366 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "system_utils.h" +#include "test_utils/ANGLETest.h" +#include "random_utils.h" + +using namespace angle; + +class OcclusionQueriesTest : public ANGLETest +{ + protected: + OcclusionQueriesTest() : mProgram(0), mRNG(1) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string passthroughVS = SHADER_SOURCE + ( + attribute highp vec4 position; + void main(void) + { + gl_Position = position; + } + ); + + const std::string passthroughPS = SHADER_SOURCE + ( + precision highp float; + void main(void) + { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + + mProgram = CompileProgram(passthroughVS, passthroughPS); + ASSERT_NE(0u, mProgram); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram; + RNG mRNG; +}; + +TEST_P(OcclusionQueriesTest, IsOccluded) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_occlusion_query_boolean")) + { + std::cout << "Test skipped because ES3 or GL_EXT_occlusion_query_boolean are not available." + << std::endl; + return; + } + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + // draw a quad at depth 0.3 + glEnable(GL_DEPTH_TEST); + glUseProgram(mProgram); + drawQuad(mProgram, "position", 0.3f); + glUseProgram(0); + + EXPECT_GL_NO_ERROR(); + + GLuint query = 0; + glGenQueriesEXT(1, &query); + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); + drawQuad(mProgram, "position", 0.8f); // this quad should be occluded by first quad + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); + + EXPECT_GL_NO_ERROR(); + + swapBuffers(); + + GLuint ready = GL_FALSE; + while (ready == GL_FALSE) + { + angle::Sleep(0); + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); + } + + GLuint result = GL_TRUE; + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result); + + EXPECT_GL_NO_ERROR(); + + glDeleteQueriesEXT(1, &query); + + EXPECT_GLENUM_EQ(GL_FALSE, result); +} + +TEST_P(OcclusionQueriesTest, IsNotOccluded) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_occlusion_query_boolean")) + { + std::cout << "Test skipped because ES3 or GL_EXT_occlusion_query_boolean are not available." + << std::endl; + return; + } + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + EXPECT_GL_NO_ERROR(); + + GLuint query = 0; + glGenQueriesEXT(1, &query); + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); + drawQuad(mProgram, "position", 0.8f); // this quad should not be occluded + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); + + EXPECT_GL_NO_ERROR(); + + swapBuffers(); + + GLuint result = GL_TRUE; + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result); // will block waiting for result + + EXPECT_GL_NO_ERROR(); + + glDeleteQueriesEXT(1, &query); + + EXPECT_GLENUM_EQ(GL_TRUE, result); +} + +TEST_P(OcclusionQueriesTest, Errors) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_occlusion_query_boolean")) + { + std::cout << "Test skipped because ES3 or GL_EXT_occlusion_query_boolean are not available." + << std::endl; + return; + } + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + EXPECT_GL_NO_ERROR(); + + GLuint query = 0; + GLuint query2 = 0; + glGenQueriesEXT(1, &query); + + EXPECT_EQ(glIsQueryEXT(query), GL_FALSE); + EXPECT_EQ(glIsQueryEXT(query2), GL_FALSE); + + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0); // can't pass 0 as query id + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query); + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // can't initiate a query while one's already active + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + EXPECT_EQ(glIsQueryEXT(query), GL_TRUE); + EXPECT_EQ(glIsQueryEXT(query2), GL_FALSE); // have not called begin + + drawQuad(mProgram, "position", 0.8f); // this quad should not be occluded + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); // no active query for this target + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); + + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query); // can't begin a query as a different type than previously used + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // have to call genqueries first + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glGenQueriesEXT(1, &query2); + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, query2); // should be ok now + EXPECT_EQ(glIsQueryEXT(query2), GL_TRUE); + + drawQuad(mProgram, "position", 0.3f); // this should draw in front of other quad + glDeleteQueriesEXT(1, &query2); // should delete when query becomes inactive + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); // should not incur error; should delete query + 1 at end of execution. + EXPECT_GL_NO_ERROR(); + + swapBuffers(); + + EXPECT_GL_NO_ERROR(); + + GLuint ready = GL_FALSE; + glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); // this query is now deleted + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + EXPECT_GL_NO_ERROR(); +} + +// Test that running multiple simultaneous queries from multiple EGL contexts returns the correct +// result for each query. Helps expose bugs in ANGLE's virtual contexts. +TEST_P(OcclusionQueriesTest, MultiContext) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_occlusion_query_boolean")) + { + std::cout << "Test skipped because ES3 or GL_EXT_occlusion_query_boolean are not available." + << std::endl; + return; + } + + if (GetParam() == ES2_D3D9() || GetParam() == ES2_D3D11() || GetParam() == ES3_D3D11()) + { + std::cout << "Test skipped because the D3D backends cannot support simultaneous queries on " + "multiple contexts yet." + << std::endl; + return; + } + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + // draw a quad at depth 0.5 + glEnable(GL_DEPTH_TEST); + drawQuad(mProgram, "position", 0.5f); + + EGLWindow *window = getEGLWindow(); + + EGLDisplay display = window->getDisplay(); + EGLConfig config = window->getConfig(); + EGLSurface surface = window->getSurface(); + + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, + GetParam().majorVersion, + EGL_CONTEXT_MINOR_VERSION_KHR, + GetParam().minorVersion, + EGL_NONE, + }; + + const size_t passCount = 5; + struct ContextInfo + { + EGLContext context; + GLuint program; + GLuint query; + bool visiblePasses[passCount]; + bool shouldPass; + }; + + ContextInfo contexts[] = { + { + EGL_NO_CONTEXT, 0, 0, {false, false, false, false, false}, false, + }, + { + EGL_NO_CONTEXT, 0, 0, {false, true, false, true, false}, true, + }, + { + EGL_NO_CONTEXT, 0, 0, {false, false, false, false, false}, false, + }, + { + EGL_NO_CONTEXT, 0, 0, {true, true, false, true, true}, true, + }, + { + EGL_NO_CONTEXT, 0, 0, {false, true, true, true, true}, true, + }, + { + EGL_NO_CONTEXT, 0, 0, {true, false, false, true, false}, true, + }, + { + EGL_NO_CONTEXT, 0, 0, {false, false, false, false, false}, false, + }, + { + EGL_NO_CONTEXT, 0, 0, {false, false, false, false, false}, false, + }, + }; + + for (auto &context : contexts) + { + context.context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); + ASSERT_NE(context.context, EGL_NO_CONTEXT); + + eglMakeCurrent(display, surface, surface, context.context); + + const std::string passthroughVS = SHADER_SOURCE + ( + attribute highp vec4 position; + void main(void) + { + gl_Position = position; + } + ); + + const std::string passthroughPS = SHADER_SOURCE + ( + precision highp float; + void main(void) + { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + + context.program = CompileProgram(passthroughVS, passthroughPS); + ASSERT_NE(context.program, 0u); + + glDepthMask(GL_FALSE); + glEnable(GL_DEPTH_TEST); + + glGenQueriesEXT(1, &context.query); + glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, context.query); + + ASSERT_GL_NO_ERROR(); + } + + for (size_t pass = 0; pass < passCount; pass++) + { + for (const auto &context : contexts) + { + eglMakeCurrent(display, surface, surface, context.context); + + float depth = context.visiblePasses[pass] ? mRNG.randomFloatBetween(0.0f, 0.4f) + : mRNG.randomFloatBetween(0.6f, 1.0f); + drawQuad(context.program, "position", depth); + + EXPECT_GL_NO_ERROR(); + } + } + + for (const auto &context : contexts) + { + eglMakeCurrent(display, surface, surface, context.context); + glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); + + GLuint result = GL_TRUE; + glGetQueryObjectuivEXT(context.query, GL_QUERY_RESULT_EXT, &result); + + EXPECT_GL_NO_ERROR(); + + GLuint expectation = context.shouldPass ? GL_TRUE : GL_FALSE; + EXPECT_EQ(expectation, result); + } + + eglMakeCurrent(display, surface, surface, window->getContext()); + + for (auto &context : contexts) + { + eglDestroyContext(display, context.context); + context.context = EGL_NO_CONTEXT; + } +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(OcclusionQueriesTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/PBOExtensionTest.cpp b/gfx/angle/src/tests/gl_tests/PBOExtensionTest.cpp new file mode 100755 index 000000000..f0c0bd393 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/PBOExtensionTest.cpp @@ -0,0 +1,153 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class PBOExtensionTest : public ANGLETest +{ + protected: + PBOExtensionTest() + { + setWindowWidth(32); + setWindowHeight(32); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + if (extensionEnabled("NV_pixel_buffer_object")) + { + glGenBuffers(1, &mPBO); + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), NULL, GL_STATIC_DRAW); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + const char *vertexShaderSrc = SHADER_SOURCE + ( + attribute vec4 aTest; + attribute vec2 aPosition; + varying vec4 vTest; + + void main() + { + vTest = aTest; + gl_Position = vec4(aPosition, 0.0, 1.0); + gl_PointSize = 1.0; + } + ); + + const char *fragmentShaderSrc = SHADER_SOURCE + ( + precision mediump float; + varying vec4 vTest; + + void main() + { + gl_FragColor = vTest; + } + ); + + mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc); + + glGenBuffers(1, &mPositionVBO); + glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO); + glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + ANGLETest::TearDown(); + + glDeleteBuffers(1, &mPBO); + glDeleteProgram(mProgram); + } + + GLuint mPBO; + GLuint mProgram; + GLuint mPositionVBO; +}; + +TEST_P(PBOExtensionTest, PBOWithOtherTarget) +{ + if (extensionEnabled("NV_pixel_buffer_object")) + { + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, mPBO); + + GLvoid *mappedPtr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT); + unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(255, dataPtr[0]); + EXPECT_EQ(0, dataPtr[1]); + EXPECT_EQ(0, dataPtr[2]); + EXPECT_EQ(255, dataPtr[3]); + + glUnmapBufferOES(GL_ARRAY_BUFFER); + } + EXPECT_GL_NO_ERROR(); +} + +TEST_P(PBOExtensionTest, PBOWithExistingData) +{ + if (extensionEnabled("NV_pixel_buffer_object")) + { + // Clear backbuffer to red + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + // Read 16x16 region from red backbuffer to PBO + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + // Clear backbuffer to green + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + // Read 16x16 region from green backbuffer to PBO at offset 16 + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16)); + GLvoid * mappedPtr = glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT); + unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr); + EXPECT_GL_NO_ERROR(); + + // Test pixel 0 is red (existing data) + EXPECT_EQ(255, dataPtr[0]); + EXPECT_EQ(0, dataPtr[1]); + EXPECT_EQ(0, dataPtr[2]); + EXPECT_EQ(255, dataPtr[3]); + + // Test pixel 16 is green (new data) + EXPECT_EQ(0, dataPtr[16 * 4 + 0]); + EXPECT_EQ(255, dataPtr[16 * 4 + 1]); + EXPECT_EQ(0, dataPtr[16 * 4 + 2]); + EXPECT_EQ(255, dataPtr[16 * 4 + 3]); + + glUnmapBufferOES(GL_PIXEL_PACK_BUFFER); + } + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(PBOExtensionTest, ES2_D3D11(), ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp b/gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp new file mode 100755 index 000000000..032504b80 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp @@ -0,0 +1,268 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PackUnpackTest: +// Tests the corrrectness of opengl 4.1 emulation of pack/unpack built-in functions. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class PackUnpackTest : public ANGLETest +{ + protected: + PackUnpackTest() + { + setWindowWidth(16); + setWindowHeight(16); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + // Vertex Shader source + const std::string vs = SHADER_SOURCE + ( #version 300 es\n + precision mediump float; + in vec4 position; + + void main() + { + gl_Position = position; + } + ); + + // clang-format off + // Fragment Shader source + const std::string sNormFS = SHADER_SOURCE + ( #version 300 es\n + precision mediump float; + uniform mediump vec2 v; + layout(location = 0) out mediump vec4 fragColor; + + void main() + { + uint u = packSnorm2x16(v); + vec2 r = unpackSnorm2x16(u); + fragColor = vec4(r, 0.0, 1.0); + } + ); + + // Fragment Shader source + const std::string uNormFS = SHADER_SOURCE + ( #version 300 es\n + precision mediump float; + uniform mediump vec2 v; + layout(location = 0) out mediump vec4 fragColor; + + void main() + { + uint u = packUnorm2x16(v); + vec2 r = unpackUnorm2x16(u); + fragColor = vec4(r, 0.0, 1.0); + } + ); + + // Fragment Shader source + const std::string halfFS = SHADER_SOURCE + ( #version 300 es\n + precision mediump float; + uniform mediump vec2 v; + layout(location = 0) out mediump vec4 fragColor; + + void main() + { + uint u = packHalf2x16(v); + vec2 r = unpackHalf2x16(u); + fragColor = vec4(r, 0.0, 1.0); + } + ); + // clang-format on + + mSNormProgram = CompileProgram(vs, sNormFS); + mUNormProgram = CompileProgram(vs, uNormFS); + mHalfProgram = CompileProgram(vs, halfFS); + if (mSNormProgram == 0 || mUNormProgram == 0 || mHalfProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + glGenTextures(1, &mOffscreenTexture2D); + glBindTexture(GL_TEXTURE_2D, mOffscreenTexture2D); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, getWindowWidth(), getWindowHeight()); + + glGenFramebuffers(1, &mOffscreenFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mOffscreenFramebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mOffscreenTexture2D, 0); + + glViewport(0, 0, 16, 16); + + const GLfloat color[] = { 1.0f, 1.0f, 0.0f, 1.0f }; + glClearBufferfv(GL_COLOR, 0, color); + } + + void TearDown() override + { + glDeleteTextures(1, &mOffscreenTexture2D); + glDeleteFramebuffers(1, &mOffscreenFramebuffer); + glDeleteProgram(mSNormProgram); + glDeleteProgram(mUNormProgram); + glDeleteProgram(mHalfProgram); + + ANGLETest::TearDown(); + } + + void compareBeforeAfter(GLuint program, float input1, float input2) + { + compareBeforeAfter(program, input1, input2, input1, input2); + } + + void compareBeforeAfter(GLuint program, float input1, float input2, float expect1, float expect2) + { + GLint vec2Location = glGetUniformLocation(program, "v"); + + glUseProgram(program); + glUniform2f(vec2Location, input1, input2); + + drawQuad(program, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + + GLfloat p[2] = { 0 }; + glReadPixels(8, 8, 1, 1, GL_RG, GL_FLOAT, p); + + ASSERT_GL_NO_ERROR(); + + static const double epsilon = 0.0005; + EXPECT_NEAR(p[0], expect1, epsilon); + EXPECT_NEAR(p[1], expect2, epsilon); + } + + GLuint mSNormProgram; + GLuint mUNormProgram; + GLuint mHalfProgram; + GLuint mOffscreenFramebuffer; + GLuint mOffscreenTexture2D; +}; + +// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating numbers. +TEST_P(PackUnpackTest, PackUnpackSnormNormal) +{ + // Expect the shader to output the same value as the input + compareBeforeAfter(mSNormProgram, 0.5f, -0.2f); + compareBeforeAfter(mSNormProgram, -0.35f, 0.75f); + compareBeforeAfter(mSNormProgram, 0.00392f, -0.99215f); + compareBeforeAfter(mSNormProgram, 1.0f, -0.00392f); +} + +// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating +// numbers. +TEST_P(PackUnpackTest, PackUnpackUnormNormal) +{ + // Expect the shader to output the same value as the input + compareBeforeAfter(mUNormProgram, 0.5f, 0.2f, 0.5f, 0.2f); + compareBeforeAfter(mUNormProgram, 0.35f, 0.75f, 0.35f, 0.75f); + compareBeforeAfter(mUNormProgram, 0.00392f, 0.99215f, 0.00392f, 0.99215f); + compareBeforeAfter(mUNormProgram, 1.0f, 0.00392f, 1.0f, 0.00392f); +} + +// Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating normal floating numbers. +TEST_P(PackUnpackTest, PackUnpackHalfNormal) +{ + // TODO(cwallez) figure out why it is broken on Intel on Mac +#if defined(ANGLE_PLATFORM_APPLE) + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel on Mac." << std::endl; + return; + } +#endif + + // Expect the shader to output the same value as the input + compareBeforeAfter(mHalfProgram, 0.5f, -0.2f); + compareBeforeAfter(mHalfProgram, -0.35f, 0.75f); + compareBeforeAfter(mHalfProgram, 0.00392f, -0.99215f); + compareBeforeAfter(mHalfProgram, 1.0f, -0.00392f); +} + +// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating subnormal floating numbers. +TEST_P(PackUnpackTest, PackUnpackSnormSubnormal) +{ + // Expect the shader to output the same value as the input + compareBeforeAfter(mSNormProgram, 0.00001f, -0.00001f); +} + +// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating subnormal +// floating numbers. +TEST_P(PackUnpackTest, PackUnpackUnormSubnormal) +{ + // Expect the shader to output the same value as the input for positive numbers and clamp + // to [0, 1] + compareBeforeAfter(mUNormProgram, 0.00001f, -0.00001f, 0.00001f, 0.0f); +} + +// Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating subnormal floating numbers. +TEST_P(PackUnpackTest, PackUnpackHalfSubnormal) +{ + // Expect the shader to output the same value as the input + compareBeforeAfter(mHalfProgram, 0.00001f, -0.00001f); +} + +// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating zero floating numbers. +TEST_P(PackUnpackTest, PackUnpackSnormZero) +{ + // Expect the shader to output the same value as the input + compareBeforeAfter(mSNormProgram, 0.00000f, -0.00000f); +} + +// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating zero floating +// numbers. +TEST_P(PackUnpackTest, PackUnpackUnormZero) +{ + compareBeforeAfter(mUNormProgram, 0.00000f, -0.00000f, 0.00000f, 0.00000f); +} + +// Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating zero floating numbers. +TEST_P(PackUnpackTest, PackUnpackHalfZero) +{ + // Expect the shader to output the same value as the input + compareBeforeAfter(mHalfProgram, 0.00000f, -0.00000f); +} + +// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating overflow floating +// numbers. +TEST_P(PackUnpackTest, PackUnpackUnormOverflow) +{ + // Expect the shader to clamp the input to [0, 1] + compareBeforeAfter(mUNormProgram, 67000.0f, -67000.0f, 1.0f, 0.0f); +} + +// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating overflow floating numbers. +TEST_P(PackUnpackTest, PackUnpackSnormOverflow) +{ + // Expect the shader to clamp the input to [-1, 1] + compareBeforeAfter(mSNormProgram, 67000.0f, -67000.0f, 1.0f, -1.0f); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(PackUnpackTest, + ES3_OPENGL(3, 3), + ES3_OPENGL(4, 0), + ES3_OPENGL(4, 1), + ES3_OPENGL(4, 2), + ES3_OPENGL(4, 3), + ES3_OPENGL(4, 4), + ES3_OPENGL(4, 5), + ES3_OPENGLES()); +} diff --git a/gfx/angle/src/tests/gl_tests/PathRenderingTest.cpp b/gfx/angle/src/tests/gl_tests/PathRenderingTest.cpp new file mode 100755 index 000000000..962531071 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/PathRenderingTest.cpp @@ -0,0 +1,1984 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CHROMIUMPathRenderingTest +// Test CHROMIUM subset of NV_path_rendering +// This extension allows to render geometric paths as first class GL objects. + +#include "test_utils/ANGLETest.h" +#include "shader_utils.h" + +#include "common/angleutils.h" + +#include <cmath> +#include <cstring> +#include <cstddef> +#include <fstream> + +using namespace angle; + +namespace +{ + +bool CheckPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint tolerance, + const angle::GLColor &color) +{ + for (GLint yy = 0; yy < height; ++yy) + { + for (GLint xx = 0; xx < width; ++xx) + { + const auto px = x + xx; + const auto py = y + yy; + EXPECT_PIXEL_NEAR(px, py, color.R, color.G, color.B, color.A, tolerance); + } + } + + return true; +} + +void ExpectEqualMatrix(const GLfloat *expected, const GLfloat *actual) +{ + for (size_t i = 0; i < 16; ++i) + { + EXPECT_EQ(expected[i], actual[i]); + } +} + +void ExpectEqualMatrix(const GLfloat *expected, const GLint *actual) +{ + for (size_t i = 0; i < 16; ++i) + { + EXPECT_EQ(static_cast<GLint>(std::roundf(expected[i])), actual[i]); + } +} + +const int kResolution = 300; + +class CHROMIUMPathRenderingTest : public ANGLETest +{ + protected: + CHROMIUMPathRenderingTest() + { + setWindowWidth(kResolution); + setWindowHeight(kResolution); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(8); + setConfigStencilBits(8); + } + + bool isApplicable() const { return extensionEnabled("GL_CHROMIUM_path_rendering"); } + + void tryAllDrawFunctions(GLuint path, GLenum err) + { + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); + EXPECT_GL_ERROR(err); + + glStencilFillPathCHROMIUM(path, GL_COUNT_DOWN_CHROMIUM, 0x7F); + EXPECT_GL_ERROR(err); + + glStencilStrokePathCHROMIUM(path, 0x80, 0x80); + EXPECT_GL_ERROR(err); + + glCoverFillPathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_GL_ERROR(err); + + glCoverStrokePathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_GL_ERROR(err); + + glStencilThenCoverStrokePathCHROMIUM(path, 0x80, 0x80, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_GL_ERROR(err); + + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_GL_ERROR(err); + } +}; + +// Test setting and getting of path rendering matrices. +TEST_P(CHROMIUMPathRenderingTest, TestMatrix) +{ + if (!isApplicable()) + return; + + static const GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; + + static const GLfloat kSeqMatrix[16] = {0.5f, -0.5f, -0.1f, -0.8f, 4.4f, 5.5f, + 6.6f, 7.7f, 8.8f, 9.9f, 10.11f, 11.22f, + 12.33f, 13.44f, 14.55f, 15.66f}; + + static const GLenum kMatrixModes[] = {GL_PATH_MODELVIEW_CHROMIUM, GL_PATH_PROJECTION_CHROMIUM}; + + static const GLenum kGetMatrixModes[] = {GL_PATH_MODELVIEW_MATRIX_CHROMIUM, + GL_PATH_PROJECTION_MATRIX_CHROMIUM}; + + for (size_t i = 0; i < 2; ++i) + { + GLfloat mf[16]; + GLint mi[16]; + std::memset(mf, 0, sizeof(mf)); + std::memset(mi, 0, sizeof(mi)); + glGetFloatv(kGetMatrixModes[i], mf); + glGetIntegerv(kGetMatrixModes[i], mi); + ExpectEqualMatrix(kIdentityMatrix, mf); + ExpectEqualMatrix(kIdentityMatrix, mi); + + glMatrixLoadfCHROMIUM(kMatrixModes[i], kSeqMatrix); + std::memset(mf, 0, sizeof(mf)); + std::memset(mi, 0, sizeof(mi)); + glGetFloatv(kGetMatrixModes[i], mf); + glGetIntegerv(kGetMatrixModes[i], mi); + ExpectEqualMatrix(kSeqMatrix, mf); + ExpectEqualMatrix(kSeqMatrix, mi); + + glMatrixLoadIdentityCHROMIUM(kMatrixModes[i]); + std::memset(mf, 0, sizeof(mf)); + std::memset(mi, 0, sizeof(mi)); + glGetFloatv(kGetMatrixModes[i], mf); + glGetIntegerv(kGetMatrixModes[i], mi); + ExpectEqualMatrix(kIdentityMatrix, mf); + ExpectEqualMatrix(kIdentityMatrix, mi); + + ASSERT_GL_NO_ERROR(); + } +} + +// Test that trying to set incorrect matrix target results +// in a GL error. +TEST_P(CHROMIUMPathRenderingTest, TestMatrixErrors) +{ + if (!isApplicable()) + return; + + GLfloat mf[16]; + std::memset(mf, 0, sizeof(mf)); + + glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM, mf); + ASSERT_GL_NO_ERROR(); + + glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM); + ASSERT_GL_NO_ERROR(); + + // Test that invalid matrix targets fail. + glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM - 1, mf); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // Test that invalid matrix targets fail. + glMatrixLoadIdentityCHROMIUM(GL_PATH_PROJECTION_CHROMIUM + 1); + EXPECT_GL_ERROR(GL_INVALID_ENUM); +} + +// Test basic path create and delete. +TEST_P(CHROMIUMPathRenderingTest, TestGenDelete) +{ + if (!isApplicable()) + return; + + // This is unspecified in NV_path_rendering. + EXPECT_EQ(0u, glGenPathsCHROMIUM(0)); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + GLuint path = glGenPathsCHROMIUM(1); + EXPECT_NE(0u, path); + glDeletePathsCHROMIUM(path, 1); + ASSERT_GL_NO_ERROR(); + + GLuint first_path = glGenPathsCHROMIUM(5); + EXPECT_NE(0u, first_path); + glDeletePathsCHROMIUM(first_path, 5); + ASSERT_GL_NO_ERROR(); + + // Test deleting paths that are not actually allocated: + // "unused names in /paths/ are silently ignored". + first_path = glGenPathsCHROMIUM(5); + EXPECT_NE(0u, first_path); + glDeletePathsCHROMIUM(first_path, 6); + ASSERT_GL_NO_ERROR(); + + GLsizei big_range = 0xffff; + first_path = glGenPathsCHROMIUM(big_range); + EXPECT_NE(0u, first_path); + glDeletePathsCHROMIUM(first_path, big_range); + ASSERT_GL_NO_ERROR(); + + // Test glIsPathCHROMIUM(). A path object is not considered a path untill + // it has actually been specified with a path data. + + path = glGenPathsCHROMIUM(1); + ASSERT_TRUE(glIsPathCHROMIUM(path) == GL_FALSE); + + // specify the data. + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + glPathCommandsCHROMIUM(path, 2, commands, 2, GL_FLOAT, coords); + ASSERT_TRUE(glIsPathCHROMIUM(path) == GL_TRUE); + glDeletePathsCHROMIUM(path, 1); + ASSERT_TRUE(glIsPathCHROMIUM(path) == GL_FALSE); +} + +// Test incorrect path creation and deletion and expect GL errors. +TEST_P(CHROMIUMPathRenderingTest, TestGenDeleteErrors) +{ + if (!isApplicable()) + return; + + // GenPaths / DeletePaths tests. + // std::numeric_limits<GLuint>::max() is wrong for GLsizei. + GLuint first_path = glGenPathsCHROMIUM(std::numeric_limits<GLuint>::max()); + EXPECT_EQ(first_path, 0u); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + first_path = glGenPathsCHROMIUM(-1); + EXPECT_EQ(0u, first_path); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glDeletePathsCHROMIUM(1, -5); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + first_path = glGenPathsCHROMIUM(-1); + EXPECT_EQ(0u, first_path); + EXPECT_GL_ERROR(GL_INVALID_VALUE); +} + +// Test setting and getting path parameters. +TEST_P(CHROMIUMPathRenderingTest, TestPathParameter) +{ + if (!isApplicable()) + return; + + GLuint path = glGenPathsCHROMIUM(1); + + // specify the data. + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + glPathCommandsCHROMIUM(path, 2, commands, 2, GL_FLOAT, coords); + ASSERT_GL_NO_ERROR(); + EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_TRUE); + + static const GLenum kEndCaps[] = {GL_FLAT_CHROMIUM, GL_SQUARE_CHROMIUM, GL_ROUND_CHROMIUM}; + for (std::size_t i = 0; i < 3; ++i) + { + GLint x; + glPathParameteriCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, static_cast<GLenum>(kEndCaps[i])); + ASSERT_GL_NO_ERROR(); + glGetPathParameterivCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, &x); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(kEndCaps[i], static_cast<GLenum>(x)); + + GLfloat f; + glPathParameterfCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, + static_cast<GLfloat>(kEndCaps[(i + 1) % 3])); + glGetPathParameterfvCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, &f); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(kEndCaps[(i + 1) % 3], static_cast<GLenum>(f)); + } + + static const GLenum kJoinStyles[] = {GL_MITER_REVERT_CHROMIUM, GL_BEVEL_CHROMIUM, + GL_ROUND_CHROMIUM}; + for (std::size_t i = 0; i < 3; ++i) + { + GLint x; + glPathParameteriCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, + static_cast<GLenum>(kJoinStyles[i])); + ASSERT_GL_NO_ERROR(); + glGetPathParameterivCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, &x); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(kJoinStyles[i], static_cast<GLenum>(x)); + + GLfloat f; + glPathParameterfCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, + static_cast<GLfloat>(kJoinStyles[(i + 1) % 3])); + ASSERT_GL_NO_ERROR(); + glGetPathParameterfvCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, &f); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(kJoinStyles[(i + 1) % 3], static_cast<GLenum>(f)); + } + + { + glPathParameterfCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, 5.0f); + ASSERT_GL_NO_ERROR(); + + GLfloat f; + glGetPathParameterfvCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, &f); + EXPECT_EQ(5.0f, f); + } + + glDeletePathsCHROMIUM(path, 1); +} + +// Test that setting incorrect path parameter generates GL error. +TEST_P(CHROMIUMPathRenderingTest, TestPathParameterErrors) +{ + if (!isApplicable()) + return; + + GLuint path = glGenPathsCHROMIUM(1); + + // PathParameter*: Wrong value for the pname should fail. + glPathParameteriCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, GL_FLAT_CHROMIUM); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glPathParameterfCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, GL_MITER_REVERT_CHROMIUM); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // PathParameter*: Wrong floating-point value should fail. + glPathParameterfCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, -0.1f); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // PathParameter*: Wrong pname should fail. + glPathParameteriCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM - 1, 5); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glDeletePathsCHROMIUM(path, 1); +} + +// Test expected path object state. +TEST_P(CHROMIUMPathRenderingTest, TestPathObjectState) +{ + if (!isApplicable()) + return; + + glViewport(0, 0, kResolution, kResolution); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glStencilMask(0xffffffff); + glClearStencil(0); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + ASSERT_GL_NO_ERROR(); + + // Test that trying to draw non-existing paths does not produce errors or results. + GLuint non_existing_paths[] = {0, 55, 74744}; + for (auto &p : non_existing_paths) + { + EXPECT_TRUE(glIsPathCHROMIUM(p) == GL_FALSE); + ASSERT_GL_NO_ERROR(); + tryAllDrawFunctions(p, GL_NO_ERROR); + } + + // Path name marked as used but without path object state causes + // a GL error upon any draw command. + GLuint path = glGenPathsCHROMIUM(1); + EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_FALSE); + tryAllDrawFunctions(path, GL_INVALID_OPERATION); + glDeletePathsCHROMIUM(path, 1); + + // Document a bit of an inconsistency: path name marked as used but without + // path object state causes a GL error upon any draw command (tested above). + // Path name that had path object state, but then was "cleared", still has a + // path object state, even though the state is empty. + path = glGenPathsCHROMIUM(1); + EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_FALSE); + + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + glPathCommandsCHROMIUM(path, 2, commands, 2, GL_FLOAT, coords); + EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_TRUE); + + glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); + EXPECT_TRUE(glIsPathCHROMIUM(path) == GL_TRUE); // The surprise. + + tryAllDrawFunctions(path, GL_NO_ERROR); + glDeletePathsCHROMIUM(path, 1); + + // Make sure nothing got drawn by the drawing commands that should not produce + // anything. + const angle::GLColor black = {0, 0, 0, 0}; + EXPECT_TRUE(CheckPixels(0, 0, kResolution, kResolution, 0, black)); +} + +// Test that trying to use path object that doesn't exist generates +// a GL error. +TEST_P(CHROMIUMPathRenderingTest, TestUnnamedPathsErrors) +{ + if (!isApplicable()) + return; + + // Unnamed paths: Trying to create a path object with non-existing path name + // produces error. (Not a error in real NV_path_rendering). + ASSERT_GL_NO_ERROR(); + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + glPathCommandsCHROMIUM(555, 2, commands, 2, GL_FLOAT, coords); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // PathParameter*: Using non-existing path object produces error. + ASSERT_GL_NO_ERROR(); + glPathParameterfCHROMIUM(555, GL_PATH_STROKE_WIDTH_CHROMIUM, 5.0f); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + ASSERT_GL_NO_ERROR(); + glPathParameteriCHROMIUM(555, GL_PATH_JOIN_STYLE_CHROMIUM, GL_ROUND_CHROMIUM); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test that setting incorrect path data generates a GL error. +TEST_P(CHROMIUMPathRenderingTest, TestPathCommandsErrors) +{ + if (!isApplicable()) + return; + + static const GLenum kInvalidCoordType = GL_NONE; + + GLuint path = glGenPathsCHROMIUM(1); + GLubyte commands[] = {GL_MOVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + GLfloat coords[] = {50.0f, 50.0f}; + + glPathCommandsCHROMIUM(path, 2, commands, -4, GL_FLOAT, coords); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glPathCommandsCHROMIUM(path, -1, commands, 2, GL_FLOAT, coords); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glPathCommandsCHROMIUM(path, 2, commands, 2, kInvalidCoordType, coords); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // incorrect number of coordinates + glPathCommandsCHROMIUM(path, 2, commands, std::numeric_limits<GLsizei>::max(), GL_FLOAT, + coords); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // This should fail due to cmd count + coord count * short size. + glPathCommandsCHROMIUM(path, 2, commands, std::numeric_limits<GLsizei>::max(), GL_SHORT, + coords); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glDeletePathsCHROMIUM(path, 1); +} + +// Test that trying to render a path with invalid arguments +// generates a GL error. +TEST_P(CHROMIUMPathRenderingTest, TestPathRenderingInvalidArgs) +{ + if (!isApplicable()) + return; + + GLuint path = glGenPathsCHROMIUM(1); + glPathCommandsCHROMIUM(path, 0, NULL, 0, GL_FLOAT, NULL); + + // Verify that normal calls work. + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); + ASSERT_GL_NO_ERROR(); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, GL_BOUNDING_BOX_CHROMIUM); + ASSERT_GL_NO_ERROR(); + + // Using invalid fill mode causes INVALID_ENUM. + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM - 1, 0x7F); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM - 1, 0x7F, + GL_BOUNDING_BOX_CHROMIUM); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // Using invalid cover mode causes INVALID_ENUM. + glCoverFillPathCHROMIUM(path, GL_CONVEX_HULL_CHROMIUM - 1); + EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError()); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_BOUNDING_BOX_CHROMIUM + 1); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // Using mask+1 not being power of two causes INVALID_VALUE with up/down fill mode + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x40); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_DOWN_CHROMIUM, 12, GL_BOUNDING_BOX_CHROMIUM); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // check incorrect instance parameters. + + // CoverFillPathInstanced + { + glCoverFillPathInstancedCHROMIUM(-1, GL_UNSIGNED_INT, &path, 0, GL_CONVEX_HULL_CHROMIUM, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCoverFillPathInstancedCHROMIUM(1, GL_FLOAT, &path, 0, GL_CONVEX_HULL_CHROMIUM, GL_NONE, + NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, NULL, 0, GL_CONVEX_HULL_CHROMIUM, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_UNSIGNED_INT, GL_NONE, + NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_CONVEX_HULL_CHROMIUM, + GL_UNSIGNED_INT, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_CONVEX_HULL_CHROMIUM, + GL_TRANSLATE_X_CHROMIUM, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + } + + // CoverStrokePathInstanced + { + glCoverStrokePathInstancedCHROMIUM(-1, GL_UNSIGNED_INT, &path, 0, GL_CONVEX_HULL_CHROMIUM, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCoverStrokePathInstancedCHROMIUM(1, GL_FLOAT, &path, 0, GL_CONVEX_HULL_CHROMIUM, GL_NONE, + NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, NULL, 0, GL_CONVEX_HULL_CHROMIUM, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_UNSIGNED_INT, GL_NONE, + NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_CONVEX_HULL_CHROMIUM, + GL_UNSIGNED_INT, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_CONVEX_HULL_CHROMIUM, + GL_TRANSLATE_X_CHROMIUM, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + } + + // StencilFillPathInstanced + { + glStencilFillPathInstancedCHROMIUM(-1, GL_UNSIGNED_INT, &path, 0, GL_COUNT_UP_CHROMIUM, 0x0, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilFillPathInstancedCHROMIUM(1, GL_FLOAT, &path, 0, GL_COUNT_UP_CHROMIUM, 0x0, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, NULL, 0, GL_COUNT_UP_CHROMIUM, 0x0, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_UNSIGNED_INT, 0x0, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_COUNT_UP_CHROMIUM, 0x2, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_COUNT_UP_CHROMIUM, 0x0, + GL_UNSIGNED_INT, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_COUNT_UP_CHROMIUM, 0x0, + GL_TRANSLATE_X_CHROMIUM, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + } + + // StencilStrokePathInstanced + { + glStencilStrokePathInstancedCHROMIUM(-1, GL_UNSIGNED_INT, &path, 0, 0x00, 0x00, GL_NONE, + NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilStrokePathInstancedCHROMIUM(1, GL_FLOAT, &path, 0, 0x00, 0x00, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, nullptr, 0, 0x00, 0x00, GL_NONE, + NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, 0x00, 0x00, + GL_UNSIGNED_INT, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, 0x00, 0x00, + GL_TRANSLATE_X_CHROMIUM, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + } + + // StencilThenCoverFillPathInstanced + { + glStencilThenCoverFillPathInstancedCHROMIUM(-1, GL_UNSIGNED_INT, &path, 0, + GL_COUNT_UP_CHROMIUM, 0, GL_COUNT_UP_CHROMIUM, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilThenCoverFillPathInstancedCHROMIUM(1, GL_FLOAT, &path, 0, GL_CONVEX_HULL_CHROMIUM, + 0, GL_COUNT_UP_CHROMIUM, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilThenCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, NULL, 0, + GL_CONVEX_HULL_CHROMIUM, 0, + GL_COUNT_UP_CHROMIUM, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilThenCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, GL_UNSIGNED_INT, + 0, GL_COUNT_UP_CHROMIUM, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilThenCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, + GL_CONVEX_HULL_CHROMIUM, 0, GL_UNSIGNED_INT, + GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilThenCoverFillPathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, + GL_CONVEX_HULL_CHROMIUM, 0, + GL_COUNT_UP_CHROMIUM, GL_FLOAT, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilThenCoverFillPathInstancedCHROMIUM( + 1, GL_UNSIGNED_INT, &path, 0, GL_CONVEX_HULL_CHROMIUM, 0, GL_COUNT_UP_CHROMIUM, + GL_TRANSLATE_X_CHROMIUM, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + } + + // StencilThenCoverStrokePathInstanced + { + glStencilThenCoverStrokePathInstancedCHROMIUM(-1, GL_UNSIGNED_INT, &path, 0, 0x0, 0x0, + GL_CONVEX_HULL_CHROMIUM, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilThenCoverStrokePathInstancedCHROMIUM(1, GL_FLOAT, &path, 0, 0x0, 0x0, + GL_CONVEX_HULL_CHROMIUM, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilThenCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, NULL, 0, 0x0, 0x0, + GL_CONVEX_HULL_CHROMIUM, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glStencilThenCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, 0x0, 0x0, + GL_FLOAT, GL_NONE, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilThenCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, 0x0, 0x0, + GL_CONVEX_HULL_CHROMIUM, GL_FLOAT, NULL); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glStencilThenCoverStrokePathInstancedCHROMIUM(1, GL_UNSIGNED_INT, &path, 0, 0x0, 0x0, + GL_CONVEX_HULL_CHROMIUM, + GL_TRANSLATE_X_CHROMIUM, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + } + + glDeletePathsCHROMIUM(path, 1); +} + +const GLfloat kProjectionMatrix[16] = {2.0f / kResolution, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + 2.0f / kResolution, + 0.0f, + 0.0f, + 0.0f, + 0.0f, + -1.0f, + 0.0f, + -1.0f, + -1.0f, + 0.0f, + 1.0f}; + +class CHROMIUMPathRenderingDrawTest : public ANGLETest +{ + protected: + CHROMIUMPathRenderingDrawTest() + { + setWindowWidth(kResolution); + setWindowHeight(kResolution); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(8); + setConfigStencilBits(8); + } + + bool isApplicable() const { return extensionEnabled("GL_CHROMIUM_path_rendering"); } + + void setupStateForTestPattern() + { + glViewport(0, 0, kResolution, kResolution); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glStencilMask(0xffffffff); + glClearStencil(0); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glEnable(GL_STENCIL_TEST); + + static const char *kVertexShaderSource = + "void main() {\n" + " gl_Position = vec4(1.0); \n" + "}"; + + static const char *kFragmentShaderSource = + "precision mediump float;\n" + "uniform vec4 color;\n" + "void main() {\n" + " gl_FragColor = color;\n" + "}"; + + GLuint program = CompileProgram(kVertexShaderSource, kFragmentShaderSource); + glUseProgram(program); + mColorLoc = glGetUniformLocation(program, "color"); + glDeleteProgram(program); + + // Set up orthogonal projection with near/far plane distance of 2. + glMatrixLoadfCHROMIUM(GL_PATH_PROJECTION_CHROMIUM, kProjectionMatrix); + glMatrixLoadIdentityCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM); + + ASSERT_GL_NO_ERROR(); + } + + void setupPathStateForTestPattern(GLuint path) + { + static const GLubyte kCommands[] = {GL_MOVE_TO_CHROMIUM, GL_LINE_TO_CHROMIUM, + GL_QUADRATIC_CURVE_TO_CHROMIUM, + GL_CUBIC_CURVE_TO_CHROMIUM, GL_CLOSE_PATH_CHROMIUM}; + + static const GLfloat kCoords[] = {50.0f, 50.0f, 75.0f, 75.0f, 100.0f, 62.5f, 50.0f, + 25.5f, 0.0f, 62.5f, 50.0f, 50.0f, 25.0f, 75.0f}; + + glPathCommandsCHROMIUM(path, 5, kCommands, 14, GL_FLOAT, kCoords); + glPathParameterfCHROMIUM(path, GL_PATH_STROKE_WIDTH_CHROMIUM, 5.0f); + glPathParameterfCHROMIUM(path, GL_PATH_MITER_LIMIT_CHROMIUM, 1.0f); + glPathParameterfCHROMIUM(path, GL_PATH_STROKE_BOUND_CHROMIUM, .02f); + glPathParameteriCHROMIUM(path, GL_PATH_JOIN_STYLE_CHROMIUM, GL_ROUND_CHROMIUM); + glPathParameteriCHROMIUM(path, GL_PATH_END_CAPS_CHROMIUM, GL_SQUARE_CHROMIUM); + ASSERT_GL_NO_ERROR(); + } + + void verifyTestPatternFill(GLfloat flx, GLfloat fly) + { + static const GLint kFillCoords[] = {55, 54, 50, 28, 66, 63}; + static const angle::GLColor kBlue = {0, 0, 255, 255}; + + GLint x = static_cast<GLint>(flx); + GLint y = static_cast<GLint>(fly); + + for (size_t i = 0; i < 6; i += 2) + { + GLint fx = kFillCoords[i]; + GLint fy = kFillCoords[i + 1]; + EXPECT_TRUE(CheckPixels(x + fx, y + fy, 1, 1, 0, kBlue)); + } + } + void verifyTestPatternBg(GLfloat fx, GLfloat fy) + { + static const GLint kBackgroundCoords[] = {80, 80, 20, 20, 90, 1}; + static const angle::GLColor kExpectedColor = {0, 0, 0, 0}; + + GLint x = static_cast<GLint>(fx); + GLint y = static_cast<GLint>(fy); + + for (size_t i = 0; i < 6; i += 2) + { + GLint bx = kBackgroundCoords[i]; + GLint by = kBackgroundCoords[i + 1]; + EXPECT_TRUE(CheckPixels(x + bx, y + by, 1, 1, 0, kExpectedColor)); + } + } + + void verifyTestPatternStroke(GLfloat fx, GLfloat fy) + { + GLint x = static_cast<GLint>(fx); + GLint y = static_cast<GLint>(fy); + + // Inside the stroke we should have green. + static const angle::GLColor kGreen = {0, 255, 0, 255}; + EXPECT_TRUE(CheckPixels(x + 50, y + 53, 1, 1, 0, kGreen)); + EXPECT_TRUE(CheckPixels(x + 26, y + 76, 1, 1, 0, kGreen)); + + // Outside the path we should have black. + static const angle::GLColor black = {0, 0, 0, 0}; + EXPECT_TRUE(CheckPixels(x + 10, y + 10, 1, 1, 0, black)); + EXPECT_TRUE(CheckPixels(x + 80, y + 80, 1, 1, 0, black)); + } + + GLuint mColorLoc; +}; + +// Tests that basic path rendering functions work. +TEST_P(CHROMIUMPathRenderingDrawTest, TestPathRendering) +{ + if (!isApplicable()) + return; + + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + + setupStateForTestPattern(); + + GLuint path = glGenPathsCHROMIUM(1); + setupPathStateForTestPattern(path); + + // Do the stencil fill, cover fill, stencil stroke, cover stroke + // in unconventional order: + // 1) stencil the stroke in stencil high bit + // 2) stencil the fill in low bits + // 3) cover the fill + // 4) cover the stroke + // This is done to check that glPathStencilFunc works, eg the mask + // goes through. Stencil func is not tested ATM, for simplicity. + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilStrokePathCHROMIUM(path, 0x80, 0x80); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); + glStencilFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F); + + glStencilFunc(GL_LESS, 0, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(mColorLoc, 1, kBlue); + glCoverFillPathCHROMIUM(path, GL_BOUNDING_BOX_CHROMIUM); + + glStencilFunc(GL_EQUAL, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(mColorLoc, 1, kGreen); + glCoverStrokePathCHROMIUM(path, GL_CONVEX_HULL_CHROMIUM); + + glDeletePathsCHROMIUM(path, 1); + + ASSERT_GL_NO_ERROR(); + + // Verify the image. + verifyTestPatternFill(0, 0); + verifyTestPatternBg(0, 0); + verifyTestPatternStroke(0, 0); +} + +// Test that StencilThen{Stroke,Fill} path rendering functions work +TEST_P(CHROMIUMPathRenderingDrawTest, TestPathRenderingThenFunctions) +{ + if (!isApplicable()) + return; + + static float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + + setupStateForTestPattern(); + + GLuint path = glGenPathsCHROMIUM(1); + setupPathStateForTestPattern(path); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilFunc(GL_EQUAL, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(mColorLoc, 1, kGreen); + glStencilThenCoverStrokePathCHROMIUM(path, 0x80, 0x80, GL_BOUNDING_BOX_CHROMIUM); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); + glStencilFunc(GL_LESS, 0, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(mColorLoc, 1, kBlue); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, GL_CONVEX_HULL_CHROMIUM); + + glDeletePathsCHROMIUM(path, 1); + + // Verify the image. + verifyTestPatternFill(0, 0); + verifyTestPatternBg(0, 0); + verifyTestPatternStroke(0, 0); +} + +// Tests that drawing with *Instanced functions work. +TEST_P(CHROMIUMPathRenderingDrawTest, TestPathRenderingInstanced) +{ + if (!isApplicable()) + return; + + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + + setupStateForTestPattern(); + + GLuint path = glGenPathsCHROMIUM(1); + setupPathStateForTestPattern(path); + + const GLuint kPaths[] = {1, 1, 1, 1, 1}; + const GLsizei kPathCount = 5; + const GLfloat kShapeSize = 80.0f; + static const GLfloat kTransforms[kPathCount * 12] = { + 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, kShapeSize, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, kShapeSize * 2, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, kShapeSize, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, kShapeSize, kShapeSize, 0.0f}; + + // The test pattern is the same as in the simple draw case above, + // except that the path is drawn kPathCount times with different offsets. + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilStrokePathInstancedCHROMIUM(kPathCount, GL_UNSIGNED_INT, kPaths, path - 1, 0x80, 0x80, + GL_AFFINE_3D_CHROMIUM, kTransforms); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); + glUniform4fv(mColorLoc, 1, kBlue); + glStencilFillPathInstancedCHROMIUM(kPathCount, GL_UNSIGNED_INT, kPaths, path - 1, + GL_COUNT_UP_CHROMIUM, 0x7F, GL_AFFINE_3D_CHROMIUM, + kTransforms); + + ASSERT_GL_NO_ERROR(); + + glStencilFunc(GL_LESS, 0, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glCoverFillPathInstancedCHROMIUM(kPathCount, GL_UNSIGNED_INT, kPaths, path - 1, + GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, + GL_AFFINE_3D_CHROMIUM, kTransforms); + + ASSERT_GL_NO_ERROR(); + + glStencilFunc(GL_EQUAL, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(mColorLoc, 1, kGreen); + glCoverStrokePathInstancedCHROMIUM(kPathCount, GL_UNSIGNED_INT, kPaths, path - 1, + GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, + GL_AFFINE_3D_CHROMIUM, kTransforms); + + ASSERT_GL_NO_ERROR(); + + glDeletePathsCHROMIUM(path, 1); + + // Verify the image. + verifyTestPatternFill(0.0f, 0.0f); + verifyTestPatternBg(0.0f, 0.0f); + verifyTestPatternStroke(0.0f, 0.0f); + + verifyTestPatternFill(kShapeSize, 0.0f); + verifyTestPatternBg(kShapeSize, 0.0f); + verifyTestPatternStroke(kShapeSize, 0.0f); + + verifyTestPatternFill(kShapeSize * 2, 0.0f); + verifyTestPatternBg(kShapeSize * 2, 0.0f); + verifyTestPatternStroke(kShapeSize * 2, 0.0f); + + verifyTestPatternFill(0.0f, kShapeSize); + verifyTestPatternBg(0.0f, kShapeSize); + verifyTestPatternStroke(0.0f, kShapeSize); + + verifyTestPatternFill(kShapeSize, kShapeSize); + verifyTestPatternBg(kShapeSize, kShapeSize); + verifyTestPatternStroke(kShapeSize, kShapeSize); +} + +// Test that instanced fill/stroke then cover functions work. +TEST_P(CHROMIUMPathRenderingDrawTest, TestPathRenderingThenFunctionsInstanced) +{ + if (!isApplicable()) + return; + + static const float kBlue[] = {0.0f, 0.0f, 1.0f, 1.0f}; + static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f}; + + setupStateForTestPattern(); + + GLuint path = glGenPathsCHROMIUM(1); + setupPathStateForTestPattern(path); + + const GLuint kPaths[] = {1, 1, 1, 1, 1}; + const GLsizei kPathCount = 5; + const GLfloat kShapeSize = 80.0f; + static const GLfloat kTransforms[] = { + 0.0f, 0.0f, kShapeSize, 0.0f, kShapeSize * 2, + 0.0f, 0.0f, kShapeSize, kShapeSize, kShapeSize, + }; + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0xFF); + glStencilFunc(GL_EQUAL, 0x80, 0x80); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(mColorLoc, 1, kGreen); + glStencilThenCoverStrokePathInstancedCHROMIUM( + kPathCount, GL_UNSIGNED_INT, kPaths, path - 1, 0x80, 0x80, + GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_TRANSLATE_2D_CHROMIUM, kTransforms); + + ASSERT_GL_NO_ERROR(); + + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); + glStencilFunc(GL_LESS, 0, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glUniform4fv(mColorLoc, 1, kBlue); + glStencilThenCoverFillPathInstancedCHROMIUM( + kPathCount, GL_UNSIGNED_INT, kPaths, path - 1, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM, GL_TRANSLATE_2D_CHROMIUM, kTransforms); + + ASSERT_GL_NO_ERROR(); + + glDeletePathsCHROMIUM(path, 1); + + // Verify the image. + verifyTestPatternFill(0.0f, 0.0f); + verifyTestPatternBg(0.0f, 0.0f); + verifyTestPatternStroke(0.0f, 0.0f); + + verifyTestPatternFill(kShapeSize, 0.0f); + verifyTestPatternBg(kShapeSize, 0.0f); + verifyTestPatternStroke(kShapeSize, 0.0f); + + verifyTestPatternFill(kShapeSize * 2, 0.0f); + verifyTestPatternBg(kShapeSize * 2, 0.0f); + verifyTestPatternStroke(kShapeSize * 2, 0.0f); + + verifyTestPatternFill(0.0f, kShapeSize); + verifyTestPatternBg(0.0f, kShapeSize); + verifyTestPatternStroke(0.0f, kShapeSize); + + verifyTestPatternFill(kShapeSize, kShapeSize); + verifyTestPatternBg(kShapeSize, kShapeSize); + verifyTestPatternStroke(kShapeSize, kShapeSize); +} + + +// This class implements a test that draws a grid of v-shapes. The grid is +// drawn so that even rows (from the bottom) are drawn with DrawArrays and odd +// rows are drawn with path rendering. It can be used to test various texturing +// modes, comparing how the fill would work in normal GL rendering and how to +// setup same sort of fill with path rendering. +// The texturing test is parametrized to run the test with and without +// ANGLE name hashing. +class CHROMIUMPathRenderingWithTexturingTest : public ANGLETest +{ + protected: + CHROMIUMPathRenderingWithTexturingTest() : mProgram(0) + { + setWindowWidth(kResolution); + setWindowHeight(kResolution); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(8); + setConfigStencilBits(8); + } + + bool isApplicable() const { return extensionEnabled("GL_CHROMIUM_path_rendering"); } + + void TearDown() override + { + if (mProgram) + { + glDeleteProgram(mProgram); + ASSERT_GL_NO_ERROR(); + } + + ANGLETest::TearDown(); + } + + void SetUp() override + { + ANGLETest::SetUp(); + mBindUniformLocation = reinterpret_cast<PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC>( + eglGetProcAddress("glBindUniformLocationCHROMIUM")); + } + + // Sets up the GL program state for the test. + // Vertex shader needs at least following variables: + // uniform mat4 view_matrix; + // uniform mat? color_matrix; (accessible with kColorMatrixLocation) + // uniform vec2 model_translate; + // attribute vec2 position; + // varying vec4 color; + // + // Fragment shader needs at least following variables: + // varying vec4 color; + // + // (? can be anything) + void compileProgram(const char *vertexShaderSource, const char *fragmentShaderSource) + { + glViewport(0, 0, kResolution, kResolution); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glStencilMask(0xffffffff); + glClearStencil(0); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + ASSERT_GL_NO_ERROR(); + + GLuint vShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource); + GLuint fShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource); + ASSERT_NE(0u, vShader); + ASSERT_NE(0u, fShader); + + mProgram = glCreateProgram(); + + glAttachShader(mProgram, vShader); + glAttachShader(mProgram, fShader); + glDeleteShader(vShader); + glDeleteShader(fShader); + + ASSERT_GL_NO_ERROR(); + } + + void bindProgram() + { + glBindAttribLocation(mProgram, kPositionLocation, "position"); + mBindUniformLocation(mProgram, kViewMatrixLocation, "view_matrix"); + mBindUniformLocation(mProgram, kColorMatrixLocation, "color_matrix"); + mBindUniformLocation(mProgram, kModelTranslateLocation, "model_translate"); + glBindFragmentInputLocationCHROMIUM(mProgram, kColorFragmentInputLocation, "color"); + + ASSERT_GL_NO_ERROR(); + } + + bool linkProgram() + { + glLinkProgram(mProgram); + + GLint linked = 0; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linked); + if (linked) + { + glUseProgram(mProgram); + } + + return (linked == 1); + } + + void drawTestPattern() + { + // This v-shape is used both for DrawArrays and path rendering. + static const GLfloat kVertices[] = {75.0f, 75.0f, 50.0f, 25.5f, 50.0f, 50.0f, 25.0f, 75.0f}; + + GLuint vbo = 0; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(kPositionLocation); + glVertexAttribPointer(kPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); + + // Setup state for drawing the shape with path rendering. + glPathStencilFuncCHROMIUM(GL_ALWAYS, 0, 0x7F); + glStencilFunc(GL_LESS, 0, 0x7F); + glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); + glMatrixLoadfCHROMIUM(GL_PATH_PROJECTION_CHROMIUM, kProjectionMatrix); + glMatrixLoadIdentityCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM); + + static const GLubyte kCommands[] = {GL_MOVE_TO_CHROMIUM, GL_LINE_TO_CHROMIUM, + GL_LINE_TO_CHROMIUM, GL_LINE_TO_CHROMIUM, + GL_CLOSE_PATH_CHROMIUM}; + + static const GLfloat kCoords[] = { + kVertices[0], kVertices[1], kVertices[2], kVertices[3], + kVertices[6], kVertices[7], kVertices[4], kVertices[5], + }; + + GLuint path = glGenPathsCHROMIUM(1); + glPathCommandsCHROMIUM(path, static_cast<GLsizei>(ArraySize(kCommands)), kCommands, + static_cast<GLsizei>(ArraySize(kCoords)), GL_FLOAT, kCoords); + ASSERT_GL_NO_ERROR(); + + GLfloat path_model_translate[16] = { + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + }; + + // Draws the shapes. Every even row from the bottom is drawn with + // DrawArrays, odd row with path rendering. The shader program is + // the same for the both draws. + for (int j = 0; j < kTestRows; ++j) + { + for (int i = 0; i < kTestColumns; ++i) + { + if (j % 2 == 0) + { + glDisable(GL_STENCIL_TEST); + glUniform2f(kModelTranslateLocation, static_cast<GLfloat>(i * kShapeWidth), + static_cast<GLfloat>(j * kShapeHeight)); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + else + { + glEnable(GL_STENCIL_TEST); + path_model_translate[12] = static_cast<GLfloat>(i * kShapeWidth); + path_model_translate[13] = static_cast<GLfloat>(j * kShapeHeight); + glMatrixLoadfCHROMIUM(GL_PATH_MODELVIEW_CHROMIUM, path_model_translate); + glStencilThenCoverFillPathCHROMIUM(path, GL_COUNT_UP_CHROMIUM, 0x7F, + GL_BOUNDING_BOX_CHROMIUM); + } + } + } + ASSERT_GL_NO_ERROR(); + + glDisableVertexAttribArray(kPositionLocation); + glDeleteBuffers(1, &vbo); + glDeletePathsCHROMIUM(path, 1); + ASSERT_GL_NO_ERROR(); + } + + enum + { + kShapeWidth = 75, + kShapeHeight = 75, + kTestRows = kResolution / kShapeHeight, + kTestColumns = kResolution / kShapeWidth, + }; + + typedef void(GL_APIENTRYP PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC)(GLuint mProgram, + GLint location, + const GLchar *name); + PFNGLBINDUNIFORMLOCATIONCHROMIUMPROC mBindUniformLocation = nullptr; + + GLuint mProgram; + + // This uniform be can set by the test. It should be used to set the color for + // drawing with DrawArrays. + static const GLint kColorMatrixLocation = 4; + + // This fragment input can be set by the test. It should be used to set the + // color for drawing with path rendering. + static const GLint kColorFragmentInputLocation = 7; + + static const GLint kModelTranslateLocation = 3; + static const GLint kPositionLocation = 0; + static const GLint kViewMatrixLocation = 7; +}; + +// Test success and error cases for binding fragment input location. +TEST_P(CHROMIUMPathRenderingWithTexturingTest, TestBindFragmentInputLocation) +{ + if (!isApplicable()) + return; + + // original NV_path_rendering specification doesn't define whether the + // fragment shader input variables should be defined in the vertex shader or + // not. In fact it doesn't even require a vertex shader. + // However the GLES3.1 spec basically says that fragment inputs are + // either built-ins or come from the previous shader stage. + // (§ 14.1, Fragment Shader Variables). + // Additionally there are many places that are based on the assumption of having + // a vertex shader (command buffer, angle) so we're going to stick to the same + // semantics and require a vertex shader and to have the vertex shader define the + // varying fragment shader input. + + // clang-format off + const char* kVertexShaderSource = + "varying vec4 color;\n" + "void main() {}\n"; + + const char* kFragmentShaderSource = + "precision mediump float;\n" + "varying vec4 color;\n" + "void main() {\n" + " gl_FragColor = vec4(1.0);\n" + "}\n"; + + // clang-format on + compileProgram(kVertexShaderSource, kFragmentShaderSource); + + enum kBindLocations + { + kColorLocation = 5, + kFragColorLocation = 6 + }; + + // successful bind. + glBindFragmentInputLocationCHROMIUM(mProgram, kColorLocation, "color"); + ASSERT_GL_NO_ERROR(); + + // any name can be bound and names that do not actually exist in the program after + // linking are ignored. + glBindFragmentInputLocationCHROMIUM(mProgram, kColorLocation, "doesnt_exist"); + ASSERT_GL_NO_ERROR(); + + // illegal program + glBindFragmentInputLocationCHROMIUM(mProgram + 1, kColorLocation, "color"); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // illegal bind (built-in) + glBindFragmentInputLocationCHROMIUM(mProgram, kFragColorLocation, "gl_FragColor"); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBindFragmentInputLocationCHROMIUM(mProgram, kFragColorLocation, NULL); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glBindFragmentInputLocationCHROMIUM(mProgram, 0xffffff, "color"); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + ASSERT_TRUE(linkProgram() == true); + + const GLfloat kCoefficients16[] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f}; + + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorLocation, GL_EYE_LINEAR_CHROMIUM, 4, + kCoefficients16); + ASSERT_GL_NO_ERROR(); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, GL_EYE_LINEAR_CHROMIUM, 4, kCoefficients16); + ASSERT_GL_NO_ERROR(); +} + +// Test fragment input interpolation in CHROMIUM_EYE coordinates. +TEST_P(CHROMIUMPathRenderingWithTexturingTest, TestProgramPathFragmentInputGenCHROMIUM_EYE) +{ + if (!isApplicable()) + return; + + // clang-format off + const char *kVertexShaderSource = + "uniform mat4 view_matrix;\n" + "uniform mat4 color_matrix;\n" + "uniform vec2 model_translate;\n" + "attribute vec2 position;\n" + "varying vec3 color;\n" + "void main() {\n" + " vec4 p = vec4(model_translate + position, 1.0, 1.0);\n" + " color = (color_matrix * p).rgb;\n" + " gl_Position = view_matrix * p;\n" + "}\n"; + + const char *kFragmentShaderSource = + "precision mediump float;\n" + "varying vec3 color;\n" + "void main() {\n" + " gl_FragColor = vec4(color, 1.0);\n" + "}\n"; + // clang-format on + + compileProgram(kVertexShaderSource, kFragmentShaderSource); + bindProgram(); + ASSERT_TRUE(linkProgram() == true); + + glUniformMatrix4fv(kViewMatrixLocation, 1, GL_FALSE, kProjectionMatrix); + + static const GLfloat kColorMatrix[16] = { + 1.0f / kResolution, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f / kResolution, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f}; + + glUniformMatrix4fv(kColorMatrixLocation, 1, GL_FALSE, kColorMatrix); + + // This is the functionality we are testing: ProgramPathFragmentInputGen + // does the same work as the color transform in vertex shader. + static const GLfloat kColorCoefficients[12] = { + 1.0f / kResolution, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f / kResolution, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f}; + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorFragmentInputLocation, + GL_EYE_LINEAR_CHROMIUM, 3, kColorCoefficients); + ASSERT_GL_NO_ERROR(); + + drawTestPattern(); + + const GLfloat kFillCoords[6] = {59.0f, 50.0f, 50.0f, 28.0f, 66.0f, 63.0f}; + + for (int j = 0; j < kTestRows; ++j) + { + for (int i = 0; i < kTestColumns; ++i) + { + for (size_t k = 0; k < ArraySize(kFillCoords); k += 2) + { + const float fx = kFillCoords[k]; + const float fy = kFillCoords[k + 1]; + const float px = static_cast<float>(i * kShapeWidth); + const float py = static_cast<float>(j * kShapeHeight); + + angle::GLColor color; + color.R = static_cast<GLubyte>(std::roundf((px + fx) / kResolution * 255.0f)); + color.G = static_cast<GLubyte>(std::roundf((py + fy) / kResolution * 255.0f)); + color.B = 0; + color.A = 255; + CheckPixels(static_cast<GLint>(px + fx), static_cast<GLint>(py + fy), 1, 1, 2, + color); + } + } + } +} + +// Test fragment input interpolation in CHROMIUM_OBJECT coordinates. +TEST_P(CHROMIUMPathRenderingWithTexturingTest, TestProgramPathFragmentInputGenCHROMIUM_OBJECT) +{ + if (!isApplicable()) + return; + + // clang-format off + const char *kVertexShaderSource = + "uniform mat4 view_matrix;\n" + "uniform mat4 color_matrix;\n" + "uniform vec2 model_translate;\n" + "attribute vec2 position;\n" + "varying vec3 color;\n" + "void main() {\n" + " color = (color_matrix * vec4(position, 1.0, 1.0)).rgb;\n" + " vec4 p = vec4(model_translate + position, 1.0, 1.0);\n" + " gl_Position = view_matrix * p;\n" + "}"; + + const char *kFragmentShaderSource = + "precision mediump float;\n" + "varying vec3 color;\n" + "void main() {\n" + " gl_FragColor = vec4(color.rgb, 1.0);\n" + "}"; + // clang-format on + + compileProgram(kVertexShaderSource, kFragmentShaderSource); + bindProgram(); + ASSERT_TRUE(linkProgram() == true); + + glUniformMatrix4fv(kViewMatrixLocation, 1, GL_FALSE, kProjectionMatrix); + + static const GLfloat kColorMatrix[16] = { + 1.0f / kShapeWidth, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f / kShapeHeight, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f }; + glUniformMatrix4fv(kColorMatrixLocation, 1, GL_FALSE, kColorMatrix); + + // This is the functionality we are testing: ProgramPathFragmentInputGen + // does the same work as the color transform in vertex shader. + static const GLfloat kColorCoefficients[9] = { + 1.0f / kShapeWidth, 0.0f, 0.0f, 0.0f, 1.0f / kShapeHeight, 0.0f, 0.0f, 0.0f, 0.0f}; + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorFragmentInputLocation, + GL_OBJECT_LINEAR_CHROMIUM, 3, kColorCoefficients); + + ASSERT_GL_NO_ERROR(); + + drawTestPattern(); + + const GLfloat kFillCoords[6] = {59.0f, 50.0f, 50.0f, 28.0f, 66.0f, 63.0f}; + + for (int j = 0; j < kTestRows; ++j) + { + for (int i = 0; i < kTestColumns; ++i) + { + for (size_t k = 0; k < ArraySize(kFillCoords); k += 2) + { + const float fx = kFillCoords[k]; + const float fy = kFillCoords[k + 1]; + const float px = static_cast<float>(i * kShapeWidth); + const float py = static_cast<float>(j * kShapeHeight); + + angle::GLColor color; + color.R = static_cast<GLubyte>(std::roundf(fx / kShapeWidth * 255.0f)); + color.G = static_cast<GLubyte>(std::roundf(fy / kShapeHeight * 255.0f)); + color.B = 0; + color.A = 255; + CheckPixels(static_cast<GLint>(px + fx), static_cast<GLint>(py + fy), 1, 1, 2, + color); + } + } + } +} + +// Test success and error cases for setting interpolation parameters. +TEST_P(CHROMIUMPathRenderingWithTexturingTest, TestProgramPathFragmentInputGenArgs) +{ + if (!isApplicable()) + return; + + // clang-format off + const char *kVertexShaderSource = + "varying vec2 vec2_var;\n" + "varying vec3 vec3_var;\n" + "varying vec4 vec4_var;\n" + "varying float float_var;\n" + "varying mat2 mat2_var;\n" + "varying mat3 mat3_var;\n" + "varying mat4 mat4_var;\n" + "attribute float avoid_opt;\n" + "void main() {\n" + " vec2_var = vec2(1.0, 2.0 + avoid_opt);\n" + " vec3_var = vec3(1.0, 2.0, 3.0 + avoid_opt);\n" + " vec4_var = vec4(1.0, 2.0, 3.0, 4.0 + avoid_opt);\n" + " float_var = 5.0 + avoid_opt;\n" + " mat2_var = mat2(2.0 + avoid_opt);\n" + " mat3_var = mat3(3.0 + avoid_opt);\n" + " mat4_var = mat4(4.0 + avoid_opt);\n" + " gl_Position = vec4(1.0);\n" + "}"; + + const char* kFragmentShaderSource = + "precision mediump float;\n" + "varying vec2 vec2_var;\n" + "varying vec3 vec3_var;\n" + "varying vec4 vec4_var;\n" + "varying float float_var;\n" + "varying mat2 mat2_var;\n" + "varying mat3 mat3_var;\n" + "varying mat4 mat4_var;\n" + "void main() {\n" + " gl_FragColor = vec4(vec2_var, 0, 0) + vec4(vec3_var, 0) + vec4_var + " + " vec4(float_var) + " + " vec4(mat2_var[0][0], mat3_var[1][1], mat4_var[2][2], 1);\n" + "}"; + // clang-format on + + enum + { + kVec2Location = 0, + kVec3Location, + kVec4Location, + kFloatLocation, + kMat2Location, + kMat3Location, + kMat4Location, + }; + struct + { + GLint location; + const char *name; + GLint components; + } variables[] = { + {kVec2Location, "vec2_var", 2}, + {kVec3Location, "vec3_var", 3}, + {kVec4Location, "vec4_var", 4}, + {kFloatLocation, "float_var", 1}, + // If a varying is not single-precision floating-point scalar or + // vector, it always causes an invalid operation. + {kMat2Location, "mat2_var", -1}, + {kMat3Location, "mat3_var", -1}, + {kMat4Location, "mat4_var", -1}, + }; + + compileProgram(kVertexShaderSource, kFragmentShaderSource); + + for (size_t i = 0; i < ArraySize(variables); ++i) + { + glBindFragmentInputLocationCHROMIUM(mProgram, variables[i].location, variables[i].name); + } + + // test that using invalid (not linked) program is an invalid operation. + // See similar calls at the end of the test for discussion about the arguments. + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, GL_NONE, 0, NULL); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + ASSERT_TRUE(linkProgram() == true); + + const GLfloat kCoefficients16[] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f}; + const GLenum kGenModes[] = {GL_NONE, GL_EYE_LINEAR_CHROMIUM, GL_OBJECT_LINEAR_CHROMIUM, + GL_CONSTANT_CHROMIUM}; + + for (size_t variable = 0; variable < ArraySize(variables); ++variable) + { + for (GLint components = 0; components <= 4; ++components) + { + for (size_t genmode = 0; genmode < ArraySize(kGenModes); ++genmode) + { + glProgramPathFragmentInputGenCHROMIUM(mProgram, variables[variable].location, + kGenModes[genmode], components, + kCoefficients16); + + if (components == 0 && kGenModes[genmode] == GL_NONE) + { + if (variables[variable].components == -1) + { + // Clearing a fragment input that is not single-precision floating + // point scalar or vector is an invalid operation. + ASSERT_GL_ERROR(GL_INVALID_OPERATION); + } + else + { + // Clearing a valid fragment input is ok. + ASSERT_GL_NO_ERROR(); + } + } + else if (components == 0 || kGenModes[genmode] == GL_NONE) + { + ASSERT_GL_ERROR(GL_INVALID_VALUE); + } + else + { + if (components == variables[variable].components) + { + // Setting a generator for a single-precision floating point + // scalar or vector fragment input is ok. + ASSERT_GL_NO_ERROR(); + } + else + { + // Setting a generator when components do not match is an invalid operation. + ASSERT_GL_ERROR(GL_INVALID_OPERATION); + } + } + } + } + } + + enum + { + kValidGenMode = GL_CONSTANT_CHROMIUM, + kValidComponents = 3, + kInvalidGenMode = 0xAB, + kInvalidComponents = 5, + }; + + // The location == -1 would mean fragment input was optimized away. At the + // time of writing, -1 can not happen because the only way to obtain the + // location numbers is through bind. Test just to be consistent. + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kValidGenMode, kValidComponents, + kCoefficients16); + ASSERT_GL_NO_ERROR(); + + // Test that even though the spec says location == -1 causes the operation to + // be skipped, the verification of other parameters is still done. This is a + // GL policy. + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kInvalidGenMode, kValidComponents, + kCoefficients16); + ASSERT_GL_ERROR(GL_INVALID_ENUM); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kInvalidGenMode, kInvalidComponents, + kCoefficients16); + ASSERT_GL_ERROR(GL_INVALID_ENUM); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kValidGenMode, kInvalidComponents, + kCoefficients16); + ASSERT_GL_ERROR(GL_INVALID_VALUE); + + glDeleteProgram(mProgram); + + // Test that using invalid (deleted) program is an invalid operation. + EXPECT_FALSE(glIsProgram(mProgram) == GL_FALSE); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kValidGenMode, kValidComponents, + kCoefficients16); + ASSERT_GL_ERROR(GL_INVALID_OPERATION); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kInvalidGenMode, kValidComponents, + kCoefficients16); + ASSERT_GL_ERROR(GL_INVALID_OPERATION); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kInvalidGenMode, kInvalidComponents, + kCoefficients16); + ASSERT_GL_ERROR(GL_INVALID_OPERATION); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, kValidGenMode, kInvalidComponents, + kCoefficients16); + ASSERT_GL_ERROR(GL_INVALID_OPERATION); + + mProgram = 0u; +} + +// Test that having input statically aliased fragment inputs the linking fails +// and then succeeds when the conflict is resolved. +TEST_P(CHROMIUMPathRenderingWithTexturingTest, TestConflictingBind) +{ + if (!isApplicable()) + return; + + // clang-format off + const char* kVertexShaderSource = + "attribute vec4 position;\n" + "varying vec4 colorA;\n" + "varying vec4 colorB;\n" + "void main() {\n" + " gl_Position = position;\n" + " colorA = position + vec4(1);\n" + " colorB = position + vec4(2);\n" + "}"; + + const char* kFragmentShaderSource = + "precision mediump float;\n" + "varying vec4 colorA;\n" + "varying vec4 colorB;\n" + "void main() {\n" + " gl_FragColor = colorA + colorB;\n" + "}"; + // clang-format on + + const GLint kColorALocation = 3; + const GLint kColorBLocation = 4; + + compileProgram(kVertexShaderSource, kFragmentShaderSource); + + glBindFragmentInputLocationCHROMIUM(mProgram, kColorALocation, "colorA"); + // Bind colorB to location a, causing conflicts. Linking should fail. + glBindFragmentInputLocationCHROMIUM(mProgram, kColorALocation, "colorB"); + + // Should fail now. + ASSERT_TRUE(linkProgram() == false); + ASSERT_GL_NO_ERROR(); + + // Resolve the bind conflict. + glBindFragmentInputLocationCHROMIUM(mProgram, kColorBLocation, "colorB"); + + ASSERT_TRUE(linkProgram() == true); + ASSERT_GL_NO_ERROR(); +} + +// Test binding with array variables, using zero indices. Tests that +// binding colorA[0] with explicit "colorA[0]" as well as "colorA" produces +// a correct location that can be used with PathProgramFragmentInputGen. +// For path rendering, colorA[0] is bound to a location. The input generator for +// the location is set to produce vec4(0, 0.1, 0, 0.1). +// The default varying, color, is bound to a location and its generator +// will produce vec4(10.0). The shader program produces green pixels. +// For vertex-based rendering, the vertex shader produces the same effect as +// the input generator for path rendering. +TEST_P(CHROMIUMPathRenderingWithTexturingTest, BindFragmentInputArray) +{ + if (!isApplicable()) + return; + + //clang-format off + const char* kVertexShaderSource = + "uniform mat4 view_matrix;\n" + "uniform mat4 color_matrix;\n" + "uniform vec2 model_translate;\n" + "attribute vec2 position;\n" + "varying vec4 color;\n" + "varying vec4 colorA[4];\n" + "void main() {\n" + " vec4 p = vec4(model_translate + position, 1, 1);\n" + " gl_Position = view_matrix * p;\n" + " colorA[0] = vec4(0.0, 0.1, 0, 0.1);\n" + " colorA[1] = vec4(0.2);\n" + " colorA[2] = vec4(0.3);\n" + " colorA[3] = vec4(0.4);\n" + " color = vec4(10.0);\n" + "}"; + + const char* kFragmentShaderSource = + "precision mediump float;\n" + "varying vec4 color;\n" + "varying vec4 colorA[4];\n" + "void main() {\n" + " gl_FragColor = colorA[0] * color;\n" + "}"; + // clang-format on + + const GLint kColorA0Location = 4; + const GLint kUnusedLocation = 5; + const GLfloat kColorA0[] = {0.0f, 0.1f, 0.0f, 0.1f}; + const GLfloat kColor[] = {10.0f, 10.0f, 10.0f, 10.0f}; + const GLfloat kFillCoords[6] = {59.0f, 50.0f, 50.0f, 28.0f, 66.0f, 63.0f}; + + for (int pass = 0; pass < 2; ++pass) + { + compileProgram(kVertexShaderSource, kFragmentShaderSource); + if (pass == 0) + { + glBindFragmentInputLocationCHROMIUM(mProgram, kUnusedLocation, "colorA[0]"); + glBindFragmentInputLocationCHROMIUM(mProgram, kColorA0Location, "colorA"); + } + else + { + glBindFragmentInputLocationCHROMIUM(mProgram, kUnusedLocation, "colorA"); + glBindFragmentInputLocationCHROMIUM(mProgram, kColorA0Location, "colorA[0]"); + } + + bindProgram(); + + ASSERT_TRUE(linkProgram() == true); + + glUniformMatrix4fv(kViewMatrixLocation, 1, GL_FALSE, kProjectionMatrix); + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorA0Location, GL_CONSTANT_CHROMIUM, 4, kColorA0); + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorFragmentInputLocation, GL_CONSTANT_CHROMIUM, 4, kColor); + ASSERT_GL_NO_ERROR(); + + drawTestPattern(); + + for (int j = 0; j < kTestRows; ++j) + { + for (int i = 0; i < kTestColumns; ++i) + { + for (size_t k = 0; k < ArraySize(kFillCoords); k += 2) + { + const float fx = kFillCoords[k]; + const float fy = kFillCoords[k + 1]; + const float px = static_cast<float>(i * kShapeWidth); + const float py = static_cast<float>(j * kShapeHeight); + + angle::GLColor color; + color.R = 0; + color.G = 255; + color.B = 0; + color.A = 255; + CheckPixels(static_cast<GLint>(px + fx), static_cast<GLint>(py + fy), 1, 1, 2, + color); + } + } + } + } +} + +// Test binding array variables. This is like BindFragmentInputArray. +// Currently disabled since it seems there's a driver bug with the +// older drivers. This should work with driver >= 364.12 +TEST_P(CHROMIUMPathRenderingWithTexturingTest, + DISABLED_BindFragmentInputArrayNonZeroIndex) +{ + if (!isApplicable()) + return; + + // clang-format off + const char* kVertexShaderSource = + "uniform mat4 view_matrix;\n" + "uniform mat4 color_matrix;\n" + "uniform vec2 model_translate;\n" + "attribute vec2 position;\n" + "varying vec4 color;\n" + "varying vec4 colorA[4];\n" + "void main() {\n" + " vec4 p = vec4(model_translate + position, 1, 1);\n" + " gl_Position = view_matrix * p;\n" + " colorA[0] = vec4(0, 0.1, 0, 0.1);\n" + " colorA[1] = vec4(0, 1, 0, 1);\n" + " colorA[2] = vec4(0, 0.8, 0, 0.8);\n" + " colorA[3] = vec4(0, 0.5, 0, 0.5);\n" + " color = vec4(0.2);\n" + "}\n"; + + const char* kFragmentShaderSource = + "precision mediump float;\n" + "varying vec4 colorA[4];\n" + "varying vec4 color;\n" + "void main() {\n" + " gl_FragColor = (colorA[0] * colorA[1]) +\n" + " colorA[2] + (colorA[3] * color);\n" + "}\n"; + // clang-format on + + const GLint kColorA0Location = 4; + const GLint kColorA1Location = 1; + const GLint kColorA2Location = 2; + const GLint kColorA3Location = 3; + const GLint kUnusedLocation = 5; + const GLfloat kColorA0[] = {0.0f, 0.1f, 0.0f, 0.1f}; + const GLfloat kColorA1[] = {0.0f, 1.0f, 0.0f, 1.0f}; + const GLfloat kColorA2[] = {0.0f, 0.8f, 0.0f, 0.8f}; + const GLfloat kColorA3[] = {0.0f, 0.5f, 0.0f, 0.5f}; + const GLfloat kColor[] = {0.2f, 0.2f, 0.2f, 0.2f}; + const GLfloat kFillCoords[6] = {59.0f, 50.0f, 50.0f, 28.0f, 66.0f, 63.0f}; + + compileProgram(kVertexShaderSource, kFragmentShaderSource); + + glBindFragmentInputLocationCHROMIUM(mProgram, kUnusedLocation, "colorA[0]"); + glBindFragmentInputLocationCHROMIUM(mProgram, kColorA1Location, "colorA[1]"); + glBindFragmentInputLocationCHROMIUM(mProgram, kColorA2Location, "colorA[2]"); + glBindFragmentInputLocationCHROMIUM(mProgram, kColorA3Location, "colorA[3]"); + glBindFragmentInputLocationCHROMIUM(mProgram, kColorA0Location, "colorA"); + ASSERT_GL_NO_ERROR(); + + bindProgram(); + ASSERT_TRUE(linkProgram() == true); + + glUniformMatrix4fv(kViewMatrixLocation, 1, GL_FALSE, kProjectionMatrix); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorA0Location, GL_CONSTANT_CHROMIUM, 4, kColorA0); + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorA1Location, GL_CONSTANT_CHROMIUM, 4, kColorA1); + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorA2Location, GL_CONSTANT_CHROMIUM, 4, kColorA2); + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorA3Location, GL_CONSTANT_CHROMIUM, 4, kColorA3); + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorFragmentInputLocation, + GL_CONSTANT_CHROMIUM, 4, kColor); + ASSERT_GL_NO_ERROR(); + + drawTestPattern(); + + for (int j = 0; j < kTestRows; ++j) + { + for (int i = 0; i < kTestColumns; ++i) + { + for (size_t k = 0; k < ArraySize(kFillCoords); k += 2) + { + const float fx = kFillCoords[k]; + const float fy = kFillCoords[k + 1]; + const float px = static_cast<float>(i * kShapeWidth); + const float py = static_cast<float>(j * kShapeHeight); + + angle::GLColor color; + color.R = 0; + color.G = 255; + color.B = 0; + color.A = 255; + CheckPixels(static_cast<GLint>(px + fx), static_cast<GLint>(py + fy), 1, 1, 2, + color); + } + } + } +} + +TEST_P(CHROMIUMPathRenderingWithTexturingTest, UnusedFragmentInputUpdate) +{ + if (!isApplicable()) + return; + + // clang-format off + const char* kVertexShaderString = + "attribute vec4 a_position;\n" + "void main() {\n" + " gl_Position = a_position;\n" + "}"; + + const char* kFragmentShaderString = + "precision mediump float;\n" + "uniform vec4 u_colorA;\n" + "uniform float u_colorU;\n" + "uniform vec4 u_colorC;\n" + "void main() {\n" + " gl_FragColor = u_colorA + u_colorC;\n" + "}"; + // clang-format on + + const GLint kColorULocation = 1; + const GLint kNonexistingLocation = 5; + const GLint kUnboundLocation = 6; + + compileProgram(kVertexShaderString, kFragmentShaderString); + + glBindFragmentInputLocationCHROMIUM(mProgram, kColorULocation, "u_colorU"); + + // The non-existing input should behave like existing but optimized away input. + glBindFragmentInputLocationCHROMIUM(mProgram, kNonexistingLocation, "nonexisting"); + + // Let A and C be assigned automatic locations. + ASSERT_TRUE(linkProgram() == true); + + const GLfloat kColor[16] = {}; + + // No errors on bound locations, since caller does not know + // if the driver optimizes them away or not. + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorULocation, GL_CONSTANT_CHROMIUM, 1, kColor); + ASSERT_GL_NO_ERROR(); + + // No errors on bound locations of names that do not exist + // in the shader. Otherwise it would be inconsistent wrt the + // optimization case. + glProgramPathFragmentInputGenCHROMIUM(mProgram, kNonexistingLocation, GL_CONSTANT_CHROMIUM, 1, kColor); + ASSERT_GL_NO_ERROR(); + + // The above are equal to updating -1. + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, GL_CONSTANT_CHROMIUM, 1, kColor); + ASSERT_GL_NO_ERROR(); + + // No errors when updating with other type either. + // The type can not be known with the non-existing case. + glProgramPathFragmentInputGenCHROMIUM(mProgram, kColorULocation, GL_CONSTANT_CHROMIUM, 4, kColor); + ASSERT_GL_NO_ERROR(); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, kNonexistingLocation, GL_CONSTANT_CHROMIUM, 4, kColor); + ASSERT_GL_NO_ERROR(); + + glProgramPathFragmentInputGenCHROMIUM(mProgram, -1, GL_CONSTANT_CHROMIUM, 4, kColor); + ASSERT_GL_NO_ERROR(); + + // Updating an unbound, non-existing location still causes an error. + glProgramPathFragmentInputGenCHROMIUM(mProgram, kUnboundLocation, GL_CONSTANT_CHROMIUM, 4, kColor); + ASSERT_GL_ERROR(GL_INVALID_OPERATION); +} + + +} // namespace + +ANGLE_INSTANTIATE_TEST(CHROMIUMPathRenderingTest, + ES2_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGL(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(CHROMIUMPathRenderingDrawTest, + ES2_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGL(), + ES3_OPENGLES()); + +ANGLE_INSTANTIATE_TEST(CHROMIUMPathRenderingWithTexturingTest, + ES2_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGL(), + ES3_OPENGLES());
\ No newline at end of file diff --git a/gfx/angle/src/tests/gl_tests/PbufferTest.cpp b/gfx/angle/src/tests/gl_tests/PbufferTest.cpp new file mode 100755 index 000000000..fb381e143 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/PbufferTest.cpp @@ -0,0 +1,343 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +class PbufferTest : public ANGLETest +{ + protected: + PbufferTest() + { + setWindowWidth(512); + setWindowHeight(512); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string vsSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = position; + texcoord = (position.xy * 0.5) + 0.5; + texcoord.y = 1.0 - texcoord.y; + } + ); + + const std::string textureFSSource = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + mTextureProgram = CompileProgram(vsSource, textureFSSource); + if (mTextureProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); + + EGLWindow *window = getEGLWindow(); + + EGLint surfaceType = 0; + eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_SURFACE_TYPE, &surfaceType); + mSupportsPbuffers = (surfaceType & EGL_PBUFFER_BIT) != 0; + + EGLint bindToTextureRGBA = 0; + eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBA); + mSupportsBindTexImage = (bindToTextureRGBA == EGL_TRUE); + + const EGLint pBufferAttributes[] = + { + EGL_WIDTH, static_cast<EGLint>(mPbufferSize), + EGL_HEIGHT, static_cast<EGLint>(mPbufferSize), + EGL_TEXTURE_FORMAT, mSupportsBindTexImage ? EGL_TEXTURE_RGBA : EGL_NO_TEXTURE, + EGL_TEXTURE_TARGET, mSupportsBindTexImage ? EGL_TEXTURE_2D : EGL_NO_TEXTURE, + EGL_NONE, EGL_NONE, + }; + + mPbuffer = eglCreatePbufferSurface(window->getDisplay(), window->getConfig(), pBufferAttributes); + if (mSupportsPbuffers) + { + ASSERT_NE(mPbuffer, EGL_NO_SURFACE); + ASSERT_EGL_SUCCESS(); + } + else + { + ASSERT_EQ(mPbuffer, EGL_NO_SURFACE); + ASSERT_EGL_ERROR(EGL_BAD_MATCH); + } + + ASSERT_GL_NO_ERROR(); + } + + virtual void TearDown() + { + glDeleteProgram(mTextureProgram); + + EGLWindow *window = getEGLWindow(); + eglDestroySurface(window->getDisplay(), mPbuffer); + + ANGLETest::TearDown(); + } + + GLuint mTextureProgram; + GLint mTextureUniformLocation; + + const size_t mPbufferSize = 32; + EGLSurface mPbuffer; + bool mSupportsPbuffers; + bool mSupportsBindTexImage; +}; + +// Test clearing a Pbuffer and checking the color is correct +TEST_P(PbufferTest, Clearing) +{ + if (!mSupportsPbuffers) + { + std::cout << "Test skipped because Pbuffers are not supported." << std::endl; + return; + } + + EGLWindow *window = getEGLWindow(); + + // Clear the window surface to blue and verify + eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext()); + ASSERT_EGL_SUCCESS(); + + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 255, 255); + + // Apply the Pbuffer and clear it to purple and verify + eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext()); + ASSERT_EGL_SUCCESS(); + + glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize)); + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2, 255, + 0, 255, 255); + + // Rebind the window surface and verify that it is still blue + eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext()); + ASSERT_EGL_SUCCESS(); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 255, 255); +} + +// Bind the Pbuffer to a texture and verify it renders correctly +TEST_P(PbufferTest, BindTexImage) +{ + if (!mSupportsPbuffers) + { + std::cout << "Test skipped because Pbuffers are not supported." << std::endl; + return; + } + + if (!mSupportsBindTexImage) + { + std::cout << "Test skipped because Pbuffer does not support binding to RGBA textures." << std::endl; + return; + } + + EGLWindow *window = getEGLWindow(); + + // Apply the Pbuffer and clear it to purple + eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext()); + ASSERT_EGL_SUCCESS(); + + glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize)); + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_EQ(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2, 255, + 0, 255, 255); + + // Apply the window surface + eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext()); + + // Create a texture and bind the Pbuffer to it + GLuint texture = 0; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + EXPECT_GL_NO_ERROR(); + + eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER); + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + ASSERT_EGL_SUCCESS(); + + // Draw a quad and verify that it is purple + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + // Unbind the texture + eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER); + ASSERT_EGL_SUCCESS(); + + // Verify that purple was drawn + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255); + + glDeleteTextures(1, &texture); +} + +// Verify that when eglBind/ReleaseTexImage are called, the texture images are freed and their +// size information is correctly updated. +TEST_P(PbufferTest, TextureSizeReset) +{ + if (!mSupportsPbuffers) + { + std::cout << "Test skipped because Pbuffers are not supported." << std::endl; + return; + } + + if (!mSupportsBindTexImage) + { + std::cout << "Test skipped because Pbuffer does not support binding to RGBA textures." << std::endl; + return; + } + + GLuint texture = 0; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + EXPECT_GL_NO_ERROR(); + + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + // Fill the texture with white pixels + std::vector<GLubyte> whitePixels(mPbufferSize * mPbufferSize * 4, 255); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, static_cast<GLsizei>(mPbufferSize), + static_cast<GLsizei>(mPbufferSize), 0, GL_RGBA, GL_UNSIGNED_BYTE, &whitePixels[0]); + EXPECT_GL_NO_ERROR(); + + // Draw the white texture and verify that the pixels are correct + drawQuad(mTextureProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255); + + // Bind the EGL surface and draw with it, results are undefined since nothing has + // been written to it + EGLWindow *window = getEGLWindow(); + eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER); + drawQuad(mTextureProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + // Clear the back buffer to a unique color (green) + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + // Unbind the EGL surface and try to draw with the texture again, the texture's size should + // now be zero and incomplete so the back buffer should be black + eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER); + drawQuad(mTextureProgram, "position", 0.5f); + EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 255); +} + +// Bind a Pbuffer, redefine the texture, and verify it renders correctly +TEST_P(PbufferTest, BindTexImageAndRedefineTexture) +{ + if (!mSupportsPbuffers) + { + std::cout << "Test skipped because Pbuffers are not supported." << std::endl; + return; + } + + if (!mSupportsBindTexImage) + { + std::cout << "Test skipped because Pbuffer does not support binding to RGBA textures." << std::endl; + return; + } + + EGLWindow *window = getEGLWindow(); + + // Apply the Pbuffer and clear it to purple + eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext()); + ASSERT_EGL_SUCCESS(); + + glViewport(0, 0, static_cast<GLsizei>(mPbufferSize), static_cast<GLsizei>(mPbufferSize)); + glClearColor(1.0f, 0.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_EQ(static_cast<GLint>(mPbufferSize) / 2, static_cast<GLint>(mPbufferSize) / 2, 255, + 0, 255, 255); + + // Apply the window surface + eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext()); + + // Create a texture and bind the Pbuffer to it + GLuint texture = 0; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + EXPECT_GL_NO_ERROR(); + + eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER); + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + ASSERT_EGL_SUCCESS(); + + // Redefine the texture + unsigned int pixelValue = 0xFFFF00FF; + std::vector<unsigned int> pixelData(getWindowWidth() * getWindowHeight(), pixelValue); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixelData[0]); + + // Draw a quad and verify that it is magenta + glUseProgram(mTextureProgram); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + // Verify that magenta was drawn + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255); + + glDeleteTextures(1, &texture); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(PbufferTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_OPENGL(), + ES2_D3D11_WARP(), + ES2_D3D11_REFERENCE(), + ES2_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/PointSpritesTest.cpp b/gfx/angle/src/tests/gl_tests/PointSpritesTest.cpp new file mode 100755 index 000000000..2045e48cc --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/PointSpritesTest.cpp @@ -0,0 +1,526 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Some of the pointsprite tests below were ported from Khronos WebGL +// conformance test suite. + +#include "test_utils/ANGLETest.h" + +#include <cmath> + +using namespace angle; + +class PointSpritesTest : public ANGLETest +{ + protected: + const int windowWidth = 256; + const int windowHeight = 256; + PointSpritesTest() + { + setWindowWidth(windowWidth); + setWindowHeight(windowHeight); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + } + + float s2p(float s) + { + return (s + 1.0f) * 0.5f * (GLfloat)windowWidth; + } +}; + +// Checks gl_PointCoord and gl_PointSize +// https://www.khronos.org/registry/webgl/sdk/tests/conformance/glsl/variables/gl-pointcoord.html +TEST_P(PointSpritesTest, PointCoordAndPointSizeCompliance) +{ + // TODO(jmadill): figure out why this fails + if (IsIntel() && GetParam() == ES2_D3D9()) + { + std::cout << "Test skipped on Intel due to failures." << std::endl; + return; + } + + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + void main() + { + gl_FragColor = vec4( + gl_PointCoord.x, + gl_PointCoord.y, + 0, + 1); + } + ); + + const std::string vs = SHADER_SOURCE + ( + attribute vec4 vPosition; + uniform float uPointSize; + void main() + { + gl_PointSize = uPointSize; + gl_Position = vPosition; + } + ); + + GLuint program = CompileProgram(vs, fs); + ASSERT_NE(program, 0u); + ASSERT_GL_NO_ERROR(); + + glUseProgram(program); + + GLfloat pointSizeRange[2] = {}; + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); + + GLfloat maxPointSize = pointSizeRange[1]; + + ASSERT_TRUE(maxPointSize >= 1); + maxPointSize = floorf(maxPointSize); + ASSERT_TRUE((int)maxPointSize % 1 == 0); + + maxPointSize = std::min(maxPointSize, 64.0f); + GLfloat pointWidth = maxPointSize / windowWidth; + GLint step = static_cast<GLint>(floorf(maxPointSize / 4)); + GLint pointStep = std::max<GLint>(1, step); + + GLint pointSizeLoc = glGetUniformLocation(program, "uPointSize"); + ASSERT_GL_NO_ERROR(); + + glUniform1f(pointSizeLoc, maxPointSize); + ASSERT_GL_NO_ERROR(); + + GLfloat pixelOffset = ((int)maxPointSize % 2) ? (1.0f / (GLfloat)windowWidth) : 0; + GLuint vertexObject = 0; + glGenBuffers(1, &vertexObject); + ASSERT_NE(vertexObject, 0U); + ASSERT_GL_NO_ERROR(); + + glBindBuffer(GL_ARRAY_BUFFER, vertexObject); + ASSERT_GL_NO_ERROR(); + + GLfloat thePoints[] = { -0.5f + pixelOffset, -0.5f + pixelOffset, + 0.5f + pixelOffset, -0.5f + pixelOffset, + -0.5f + pixelOffset, 0.5f + pixelOffset, + 0.5f + pixelOffset, 0.5f + pixelOffset }; + + glBufferData(GL_ARRAY_BUFFER, sizeof(thePoints), thePoints, GL_STATIC_DRAW); + ASSERT_GL_NO_ERROR(); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glDrawArrays(GL_POINTS, 0, 4); + ASSERT_GL_NO_ERROR(); + + glDeleteBuffers(1, &vertexObject); + + std::string debugText; + for (float py = 0; py < 2; ++py) { + for (float px = 0; px < 2; ++px) { + float pointX = -0.5f + px + pixelOffset; + float pointY = -0.5f + py + pixelOffset; + for (int yy = 0; yy < maxPointSize; yy += pointStep) { + for (int xx = 0; xx < maxPointSize; xx += pointStep) { + // formula for s and t from OpenGL ES 2.0 spec section 3.3 + float xw = s2p(pointX); + float yw = s2p(pointY); + float u = xx / maxPointSize * 2 - 1; + float v = yy / maxPointSize * 2 - 1; + int xf = static_cast<int>(floorf(s2p(pointX + u * pointWidth))); + int yf = static_cast<int>(floorf(s2p(pointY + v * pointWidth))); + float s = 0.5f + (xf + 0.5f - xw) / maxPointSize; + float t = 0.5f + (yf + 0.5f - yw) / maxPointSize; + GLubyte color[4] = { static_cast<GLubyte>(floorf(s * 255)), static_cast<GLubyte>(floorf((1 - t) * 255)), 0, 255 }; + EXPECT_PIXEL_NEAR(xf, yf, color[0], color[1], color[2], color[3], 4); + } + } + } + } +} + +// Verify that drawing a point without enabling any attributes succeeds +// https://www.khronos.org/registry/webgl/sdk/tests/conformance/rendering/point-no-attributes.html +TEST_P(PointSpritesTest, PointWithoutAttributesCompliance) +{ + // clang-format off + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + void main() + { + gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); + } + ); + + const std::string vs = SHADER_SOURCE + ( + void main() + { + gl_PointSize = 2.0; + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + } + ); + // clang-format on + + GLuint program = CompileProgram(vs, fs); + ASSERT_NE(program, 0u); + ASSERT_GL_NO_ERROR(); + + glUseProgram(program); + + glDrawArrays(GL_POINTS, 0, 1); + ASSERT_GL_NO_ERROR(); + + // expect the center pixel to be green + EXPECT_PIXEL_EQ((windowWidth - 1) / 2, (windowHeight - 1) / 2, 0, 255, 0, 255); +} + +// This is a regression test for a graphics driver bug affecting end caps on roads in MapsGL +// https://www.khronos.org/registry/webgl/sdk/tests/conformance/rendering/point-with-gl-pointcoord-in-fragment-shader.html +TEST_P(PointSpritesTest, PointCoordRegressionTest) +{ + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + varying vec4 v_color; + void main() + { + // It seems as long as this mathematical expression references + // gl_PointCoord, the fragment's color is incorrect. + vec2 diff = gl_PointCoord - vec2(.5, .5); + if (length(diff) > 0.5) + discard; + + // The point should be a solid color. + gl_FragColor = v_color; + } + ); + + const std::string vs = SHADER_SOURCE + ( + varying vec4 v_color; + // The X and Y coordinates of the center of the point. + attribute vec2 a_vertex; + uniform float u_pointSize; + void main() + { + gl_PointSize = u_pointSize; + gl_Position = vec4(a_vertex, 0.0, 1.0); + // The color of the point. + v_color = vec4(0.0, 1.0, 0.0, 1.0); + } + ); + + GLuint program = CompileProgram(vs, fs); + ASSERT_NE(program, 0u); + ASSERT_GL_NO_ERROR(); + + glUseProgram(program); + + GLfloat pointSizeRange[2] = {}; + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); + + GLfloat maxPointSize = pointSizeRange[1]; + + ASSERT_TRUE(maxPointSize > 2); + + glClearColor(0, 0, 0, 1); + glDisable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT); + + GLint pointSizeLoc = glGetUniformLocation(program, "u_pointSize"); + ASSERT_GL_NO_ERROR(); + + GLfloat pointSize = std::min<GLfloat>(20.0f, maxPointSize); + glUniform1f(pointSizeLoc, pointSize); + ASSERT_GL_NO_ERROR(); + + GLuint vertexObject = 0; + glGenBuffers(1, &vertexObject); + ASSERT_NE(vertexObject, 0U); + ASSERT_GL_NO_ERROR(); + + glBindBuffer(GL_ARRAY_BUFFER, vertexObject); + ASSERT_GL_NO_ERROR(); + + GLfloat thePoints[] = { 0.0f, 0.0f }; + + glBufferData(GL_ARRAY_BUFFER, sizeof(thePoints), thePoints, GL_STATIC_DRAW); + ASSERT_GL_NO_ERROR(); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); + + glDrawArrays(GL_POINTS, 0, 1); + ASSERT_GL_NO_ERROR(); + + // expect the center pixel to be green + EXPECT_PIXEL_EQ((windowWidth - 1) / 2, (windowHeight - 1) / 2, 0, 255, 0, 255); + + glDeleteBuffers(1, &vertexObject); +} + +// Verify GL_VERTEX_PROGRAM_POINT_SIZE is enabled +// https://www.khronos.org/registry/webgl/sdk/tests/conformance/rendering/point-size.html +TEST_P(PointSpritesTest, PointSizeEnabledCompliance) +{ + const std::string fs = SHADER_SOURCE + ( + precision mediump float; + varying vec4 color; + + void main() + { + gl_FragColor = color; + } + ); + + const std::string vs = SHADER_SOURCE + ( + attribute vec3 pos; + attribute vec4 colorIn; + uniform float pointSize; + varying vec4 color; + + void main() + { + gl_PointSize = pointSize; + color = colorIn; + gl_Position = vec4(pos, 1.0); + } + ); + + // The WebGL test is drawn on a 2x2 canvas. Emulate this by setting a 2x2 viewport. + glViewport(0, 0, 2, 2); + + GLuint program = CompileProgram(vs, fs); + ASSERT_NE(program, 0u); + ASSERT_GL_NO_ERROR(); + + glUseProgram(program); + + glDisable(GL_BLEND); + + // The choice of (0.4, 0.4) ensures that the centers of the surrounding + // pixels are not contained within the point when it is of size 1, but + // that they definitely are when it is of size 2. + GLfloat vertices[] = { 0.4f, 0.4f, 0.0f }; + GLubyte colors[] = { 255, 0, 0, 255 }; + + GLuint vertexObject = 0; + glGenBuffers(1, &vertexObject); + ASSERT_NE(vertexObject, 0U); + ASSERT_GL_NO_ERROR(); + + glBindBuffer(GL_ARRAY_BUFFER, vertexObject); + ASSERT_GL_NO_ERROR(); + + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), NULL, GL_STATIC_DRAW); + ASSERT_GL_NO_ERROR(); + + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); + ASSERT_GL_NO_ERROR(); + + glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors); + ASSERT_GL_NO_ERROR(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (GLvoid*)sizeof(vertices)); + glEnableVertexAttribArray(1); + + GLint pointSizeLoc = glGetUniformLocation(program, "pointSize"); + ASSERT_GL_NO_ERROR(); + + glUniform1f(pointSizeLoc, 1.0f); + ASSERT_GL_NO_ERROR(); + + glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(ArraySize(vertices)) / 3); + ASSERT_GL_NO_ERROR(); + + // Test the pixels around the target Red pixel to ensure + // they are the expected color values + for (GLint y = 0; y < 2; ++y) + { + for (GLint x = 0; x < 2; ++x) + { + // 1x1 is expected to be a red pixel + // All others are black + GLubyte expectedColor[4] = { 0, 0, 0, 0 }; + if (x == 1 && y == 1) + { + expectedColor[0] = 255; + expectedColor[3] = 255; + } + EXPECT_PIXEL_EQ(x, y, expectedColor[0], expectedColor[1], expectedColor[2], expectedColor[3]); + } + } + + GLfloat pointSizeRange[2] = {}; + glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, pointSizeRange); + + if (pointSizeRange[1] >= 2.0) + { + // Draw a point of size 2 and verify it fills the appropriate region. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUniform1f(pointSizeLoc, 2.0f); + ASSERT_GL_NO_ERROR(); + + glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(ArraySize(vertices)) / 3); + ASSERT_GL_NO_ERROR(); + + // Test the pixels to ensure the target is ALL Red pixels + for (GLint y = 0; y < 2; ++y) + { + for (GLint x = 0; x < 2; ++x) + { + EXPECT_PIXEL_EQ(x, y, 255, 0, 0, 255); + } + } + } + + glDeleteBuffers(1, &vertexObject); +} + +// Verify that rendering works correctly when gl_PointSize is declared in a shader but isn't used +TEST_P(PointSpritesTest, PointSizeDeclaredButUnused) +{ + const std::string vs = SHADER_SOURCE + ( + attribute highp vec4 position; + + void main(void) + { + gl_PointSize = 1.0; + gl_Position = position; + } + ); + + const std::string fs = SHADER_SOURCE + ( + void main(void) + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + GLuint program = CompileProgram(vs, fs); + ASSERT_NE(program, 0u); + ASSERT_GL_NO_ERROR(); + + glUseProgram(program); + drawQuad(program, "position", 0.5f, 1.0f); + ASSERT_GL_NO_ERROR(); + + // expect the center pixel to be red + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 0, 255); + + glDeleteProgram(program); +} + +// Test to cover a bug where the D3D11 rasterizer state would not be update when switching between +// draw types. This causes the cull face to potentially be incorrect when drawing emulated point +// spites. +TEST_P(PointSpritesTest, PointSpriteAlternatingDrawTypes) +{ + // clang-format off + const std::string pointFS = SHADER_SOURCE + ( + precision mediump float; + void main() + { + gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); + } + ); + + const std::string pointVS = SHADER_SOURCE + ( + void main() + { + gl_PointSize = 16.0; + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + } + ); + + const std::string quadFS = SHADER_SOURCE + ( + precision mediump float; + void main() + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + const std::string quadVS = SHADER_SOURCE + ( + precision mediump float; + attribute vec4 pos; + void main() + { + gl_Position = pos; + } + ); + // clang-format on + + GLuint pointProgram = CompileProgram(pointVS, pointFS); + ASSERT_NE(pointProgram, 0u); + ASSERT_GL_NO_ERROR(); + + GLuint quadProgram = CompileProgram(quadVS, quadFS); + ASSERT_NE(pointProgram, 0u); + ASSERT_GL_NO_ERROR(); + + glEnable(GL_CULL_FACE); + glCullFace(GL_FRONT); + + const GLfloat quadVertices[] = { + -1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, -1.0f, -1.0f, 0.5f, + + -1.0f, 1.0f, 0.5f, 1.0f, 1.0f, 0.5f, 1.0f, -1.0f, 0.5f, + }; + + glUseProgram(quadProgram); + GLint positionLocation = glGetAttribLocation(quadProgram, "pos"); + glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, quadVertices); + glEnableVertexAttribArray(positionLocation); + glDrawArrays(GL_TRIANGLES, 0, 6); + + glUseProgram(pointProgram); + glDrawArrays(GL_POINTS, 0, 1); + ASSERT_GL_NO_ERROR(); + + // expect the center pixel to be green + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 255, 0, 255); + + glDeleteProgram(pointProgram); + glDeleteProgram(quadProgram); +} + +// Use this to select which configurations (e.g. which renderer, which GLES +// major version) these tests should be run against. +// +// We test on D3D11 9_3 because the existing D3D11 PointSprite implementation +// uses Geometry Shaders which are not supported for 9_3. +// D3D9 and D3D11 are also tested to ensure no regressions. +ANGLE_INSTANTIATE_TEST(PointSpritesTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/ProgramBinaryTest.cpp b/gfx/angle/src/tests/gl_tests/ProgramBinaryTest.cpp new file mode 100755 index 000000000..011725fc5 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ProgramBinaryTest.cpp @@ -0,0 +1,639 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include <memory> +#include <stdint.h> + +#include "EGLWindow.h" +#include "OSWindow.h" +#include "test_utils/angle_test_configs.h" + +using namespace angle; + +class ProgramBinaryTest : public ANGLETest +{ + protected: + ProgramBinaryTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + attribute vec4 inputAttribute; + void main() + { + gl_Position = inputAttribute; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + void main() + { + gl_FragColor = vec4(1,0,0,1); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + glGenBuffers(1, &mBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + glDeleteBuffers(1, &mBuffer); + + ANGLETest::TearDown(); + } + + GLint getAvailableProgramBinaryFormatCount() const + { + GLint formatCount; + glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &formatCount); + return formatCount; + } + + GLuint mProgram; + GLuint mBuffer; +}; + +// This tests the assumption that float attribs of different size +// should not internally cause a vertex shader recompile (for conversion). +TEST_P(ProgramBinaryTest, FloatDynamicShaderSize) +{ + if (!extensionEnabled("GL_OES_get_program_binary")) + { + std::cout << "Test skipped because GL_OES_get_program_binary is not available." + << std::endl; + return; + } + + if (getAvailableProgramBinaryFormatCount() == 0) + { + std::cout << "Test skipped because no program binary formats are available." << std::endl; + return; + } + + glUseProgram(mProgram); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8, NULL); + glEnableVertexAttribArray(0); + glDrawArrays(GL_POINTS, 0, 1); + + GLint programLength; + glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &programLength); + + EXPECT_GL_NO_ERROR(); + + for (GLsizei size = 1; size <= 3; size++) + { + glVertexAttribPointer(0, size, GL_FLOAT, GL_FALSE, 8, NULL); + glEnableVertexAttribArray(0); + glDrawArrays(GL_POINTS, 0, 1); + + GLint newProgramLength; + glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &newProgramLength); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(programLength, newProgramLength); + } +} + +// Tests that switching between signed and unsigned un-normalized data doesn't trigger a bug +// in the D3D11 back-end. +TEST_P(ProgramBinaryTest, DynamicShadersSignatureBug) +{ + glUseProgram(mProgram); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + + GLint attribLocation = glGetAttribLocation(mProgram, "inputAttribute"); + ASSERT_NE(-1, attribLocation); + glEnableVertexAttribArray(attribLocation); + + glVertexAttribPointer(attribLocation, 2, GL_BYTE, GL_FALSE, 0, nullptr); + glDrawArrays(GL_POINTS, 0, 1); + + glVertexAttribPointer(attribLocation, 2, GL_UNSIGNED_BYTE, GL_FALSE, 0, nullptr); + glDrawArrays(GL_POINTS, 0, 1); +} + +// This tests the ability to successfully save and load a program binary. +TEST_P(ProgramBinaryTest, SaveAndLoadBinary) +{ + if (!extensionEnabled("GL_OES_get_program_binary")) + { + std::cout << "Test skipped because GL_OES_get_program_binary is not available." + << std::endl; + return; + } + + if (getAvailableProgramBinaryFormatCount() == 0) + { + std::cout << "Test skipped because no program binary formats are available." << std::endl; + return; + } + + GLint programLength = 0; + GLint writtenLength = 0; + GLenum binaryFormat = 0; + + glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &programLength); + EXPECT_GL_NO_ERROR(); + + std::vector<uint8_t> binary(programLength); + glGetProgramBinaryOES(mProgram, programLength, &writtenLength, &binaryFormat, binary.data()); + EXPECT_GL_NO_ERROR(); + + // The lengths reported by glGetProgramiv and glGetProgramBinaryOES should match + EXPECT_EQ(programLength, writtenLength); + + if (writtenLength) + { + GLuint program2 = glCreateProgram(); + glProgramBinaryOES(program2, binaryFormat, binary.data(), writtenLength); + + EXPECT_GL_NO_ERROR(); + + GLint linkStatus; + glGetProgramiv(program2, GL_LINK_STATUS, &linkStatus); + if (linkStatus == 0) + { + GLint infoLogLength; + glGetProgramiv(program2, GL_INFO_LOG_LENGTH, &infoLogLength); + + if (infoLogLength > 0) + { + std::vector<GLchar> infoLog(infoLogLength); + glGetProgramInfoLog(program2, static_cast<GLsizei>(infoLog.size()), NULL, + &infoLog[0]); + FAIL() << "program link failed: " << &infoLog[0]; + } + else + { + FAIL() << "program link failed."; + } + } + else + { + glUseProgram(program2); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 8, NULL); + glEnableVertexAttribArray(0); + glDrawArrays(GL_POINTS, 0, 1); + + EXPECT_GL_NO_ERROR(); + } + + glDeleteProgram(program2); + } +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(ProgramBinaryTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL()); + +class ProgramBinaryTransformFeedbackTest : public ANGLETest +{ + protected: + ProgramBinaryTransformFeedbackTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( #version 300 es\n + in vec4 inputAttribute; + out vec4 outputVarying; + void main() + { + outputVarying = inputAttribute; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( #version 300 es\n + precision highp float; + out vec4 outputColor; + void main() + { + outputColor = vec4(1,0,0,1); + } + ); + + std::vector<std::string> transformFeedbackVaryings; + transformFeedbackVaryings.push_back("outputVarying"); + + mProgram = CompileProgramWithTransformFeedback( + vertexShaderSource, fragmentShaderSource, transformFeedbackVaryings, + GL_SEPARATE_ATTRIBS); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLint getAvailableProgramBinaryFormatCount() const + { + GLint formatCount; + glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &formatCount); + return formatCount; + } + + GLuint mProgram; +}; + +// This tests the assumption that float attribs of different size +// should not internally cause a vertex shader recompile (for conversion). +TEST_P(ProgramBinaryTransformFeedbackTest, GetTransformFeedbackVarying) +{ + if (!extensionEnabled("GL_OES_get_program_binary")) + { + std::cout << "Test skipped because GL_OES_get_program_binary is not available." + << std::endl; + return; + } + + if (getAvailableProgramBinaryFormatCount() == 0) + { + std::cout << "Test skipped because no program binary formats are available." << std::endl; + return; + } + + std::vector<uint8_t> binary(0); + GLint programLength = 0; + GLint writtenLength = 0; + GLenum binaryFormat = 0; + + // Save the program binary out + glGetProgramiv(mProgram, GL_PROGRAM_BINARY_LENGTH_OES, &programLength); + ASSERT_GL_NO_ERROR(); + binary.resize(programLength); + glGetProgramBinaryOES(mProgram, programLength, &writtenLength, &binaryFormat, binary.data()); + ASSERT_GL_NO_ERROR(); + + glDeleteProgram(mProgram); + + // Load program binary + mProgram = glCreateProgram(); + glProgramBinaryOES(mProgram, binaryFormat, binary.data(), writtenLength); + + // Ensure the loaded binary is linked + GLint linkStatus; + glGetProgramiv(mProgram, GL_LINK_STATUS, &linkStatus); + EXPECT_TRUE(linkStatus != 0); + + // Query information about the transform feedback varying + char varyingName[64]; + GLsizei varyingSize = 0; + GLenum varyingType = GL_NONE; + + glGetTransformFeedbackVarying(mProgram, 0, 64, &writtenLength, &varyingSize, &varyingType, varyingName); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(13, writtenLength); + EXPECT_STREQ("outputVarying", varyingName); + EXPECT_EQ(1, varyingSize); + EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, varyingType); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(ProgramBinaryTransformFeedbackTest, + ES3_D3D11(), + ES3_OPENGL()); + +// For the ProgramBinariesAcrossPlatforms tests, we need two sets of params: +// - a set to save the program binary +// - a set to load the program binary +// We combine these into one struct extending PlatformParameters so we can reuse existing ANGLE test macros +struct PlatformsWithLinkResult : PlatformParameters +{ + PlatformsWithLinkResult(PlatformParameters saveParams, PlatformParameters loadParamsIn, bool expectedLinkResultIn) + { + majorVersion = saveParams.majorVersion; + minorVersion = saveParams.minorVersion; + eglParameters = saveParams.eglParameters; + loadParams = loadParamsIn; + expectedLinkResult = expectedLinkResultIn; + } + + PlatformParameters loadParams; + bool expectedLinkResult; +}; + +// Provide a custom gtest parameter name function for PlatformsWithLinkResult +// to avoid returning the same parameter name twice. Such a conflict would happen +// between ES2_D3D11_to_ES2D3D11 and ES2_D3D11_to_ES3D3D11 as they were both +// named ES2_D3D11 +std::ostream &operator<<(std::ostream& stream, const PlatformsWithLinkResult &platform) +{ + const PlatformParameters &platform1 = platform; + const PlatformParameters &platform2 = platform.loadParams; + stream << platform1 << "_to_" << platform2; + return stream; +} + +class ProgramBinariesAcrossPlatforms : public testing::TestWithParam<PlatformsWithLinkResult> +{ + public: + void SetUp() override + { + mOSWindow = CreateOSWindow(); + bool result = mOSWindow->initialize("ProgramBinariesAcrossRenderersTests", 100, 100); + + if (result == false) + { + FAIL() << "Failed to create OS window"; + } + } + + EGLWindow *createAndInitEGLWindow(angle::PlatformParameters ¶m) + { + EGLWindow *eglWindow = + new EGLWindow(param.majorVersion, param.minorVersion, param.eglParameters); + bool result = eglWindow->initializeGL(mOSWindow); + if (result == false) + { + SafeDelete(eglWindow); + eglWindow = nullptr; + } + + return eglWindow; + } + + void destroyEGLWindow(EGLWindow **eglWindow) + { + ASSERT(*eglWindow != nullptr); + (*eglWindow)->destroyGL(); + SafeDelete(*eglWindow); + *eglWindow = nullptr; + } + + GLuint createES2ProgramFromSource() + { + const std::string testVertexShaderSource = SHADER_SOURCE + ( + attribute highp vec4 position; + + void main(void) + { + gl_Position = position; + } + ); + + const std::string testFragmentShaderSource = SHADER_SOURCE + ( + void main(void) + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + return CompileProgram(testVertexShaderSource, testFragmentShaderSource); + } + + GLuint createES3ProgramFromSource() + { + const std::string testVertexShaderSource = SHADER_SOURCE + ( #version 300 es\n + precision highp float; + in highp vec4 position; + + void main(void) + { + gl_Position = position; + } + ); + + const std::string testFragmentShaderSource = SHADER_SOURCE + ( #version 300 es \n + precision highp float; + out vec4 out_FragColor; + + void main(void) + { + out_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + return CompileProgram(testVertexShaderSource, testFragmentShaderSource); + } + + void drawWithProgram(GLuint program) + { + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + GLint positionLocation = glGetAttribLocation(program, "position"); + + glUseProgram(program); + + const GLfloat vertices[] = + { + -1.0f, 1.0f, 0.5f, + -1.0f, -1.0f, 0.5f, + 1.0f, -1.0f, 0.5f, + + -1.0f, 1.0f, 0.5f, + 1.0f, -1.0f, 0.5f, + 1.0f, 1.0f, 0.5f, + }; + + glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(positionLocation); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + glDisableVertexAttribArray(positionLocation); + glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL); + + EXPECT_PIXEL_EQ(mOSWindow->getWidth() / 2, mOSWindow->getHeight() / 2, 255, 0, 0, 255); + } + + void TearDown() override + { + mOSWindow->destroy(); + SafeDelete(mOSWindow); + } + + OSWindow *mOSWindow; +}; + +// Tries to create a program binary using one set of platform params, then load it using a different sent of params +TEST_P(ProgramBinariesAcrossPlatforms, CreateAndReloadBinary) +{ + angle::PlatformParameters firstRenderer = GetParam(); + angle::PlatformParameters secondRenderer = GetParam().loadParams; + bool expectedLinkResult = GetParam().expectedLinkResult; + + if (!(IsPlatformAvailable(firstRenderer))) + { + std::cout << "First renderer not supported, skipping test"; + return; + } + + if (!(IsPlatformAvailable(secondRenderer))) + { + std::cout << "Second renderer not supported, skipping test"; + return; + } + + EGLWindow *eglWindow = nullptr; + std::vector<uint8_t> binary(0); + GLuint program = 0; + + GLint programLength = 0; + GLint writtenLength = 0; + GLenum binaryFormat = 0; + + // Create a EGL window with the first renderer + eglWindow = createAndInitEGLWindow(firstRenderer); + if (eglWindow == nullptr) + { + FAIL() << "Failed to create EGL window"; + return; + } + + // If the test is trying to use both the default GPU and WARP, but the default GPU *IS* WARP, + // then our expectations for the test results will be invalid. + if (firstRenderer.eglParameters.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE && + secondRenderer.eglParameters.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE) + { + std::string rendererString = std::string(reinterpret_cast<const char*>(glGetString(GL_RENDERER))); + std::transform(rendererString.begin(), rendererString.end(), rendererString.begin(), ::tolower); + + auto basicRenderPos = rendererString.find(std::string("microsoft basic render")); + auto softwareAdapterPos = rendererString.find(std::string("software adapter")); + + if (basicRenderPos != std::string::npos || softwareAdapterPos != std::string::npos) + { + // The first renderer is using WARP, even though we didn't explictly request it + // We should skip this test + std::cout << "Test skipped on when default GPU is WARP." << std::endl; + return; + } + } + + // Create a program + if (firstRenderer.majorVersion == 3) + { + program = createES3ProgramFromSource(); + } + else + { + program = createES2ProgramFromSource(); + } + + if (program == 0) + { + destroyEGLWindow(&eglWindow); + FAIL() << "Failed to create program from source"; + } + + // Draw using the program to ensure it works as expected + drawWithProgram(program); + EXPECT_GL_NO_ERROR(); + + // Save the program binary out from this renderer + glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &programLength); + EXPECT_GL_NO_ERROR(); + binary.resize(programLength); + glGetProgramBinaryOES(program, programLength, &writtenLength, &binaryFormat, binary.data()); + EXPECT_GL_NO_ERROR(); + + // Destroy the first renderer + glDeleteProgram(program); + destroyEGLWindow(&eglWindow); + + // Create an EGL window with the second renderer + eglWindow = createAndInitEGLWindow(secondRenderer); + if (eglWindow == nullptr) + { + FAIL() << "Failed to create EGL window"; + return; + } + + program = glCreateProgram(); + glProgramBinaryOES(program, binaryFormat, binary.data(), writtenLength); + + GLint linkStatus; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + EXPECT_EQ(expectedLinkResult, (linkStatus != 0)); + + if (linkStatus != 0) + { + // If the link was successful, then we should try to draw using the program to ensure it works as expected + drawWithProgram(program); + EXPECT_GL_NO_ERROR(); + } + + // Destroy the second renderer + glDeleteProgram(program); + destroyEGLWindow(&eglWindow); +} + +ANGLE_INSTANTIATE_TEST(ProgramBinariesAcrossPlatforms, + // | Save the program | Load the program | Expected + // | using these params | using these params | link result + PlatformsWithLinkResult(ES2_D3D11(), ES2_D3D11(), true ), // Loading + reloading binary should work + PlatformsWithLinkResult(ES3_D3D11(), ES3_D3D11(), true ), // Loading + reloading binary should work + PlatformsWithLinkResult(ES2_D3D11_FL11_0(), ES2_D3D11_FL9_3(), false ), // Switching feature level shouldn't work + PlatformsWithLinkResult(ES2_D3D11(), ES2_D3D11_WARP(), false ), // Switching from hardware to software shouldn't work + PlatformsWithLinkResult(ES2_D3D11_FL9_3(), ES2_D3D11_FL9_3_WARP(), false ), // Switching from hardware to software shouldn't work for FL9 either + PlatformsWithLinkResult(ES2_D3D11(), ES2_D3D9(), false ), // Switching from D3D11 to D3D9 shouldn't work + PlatformsWithLinkResult(ES2_D3D9(), ES2_D3D11(), false ), // Switching from D3D9 to D3D11 shouldn't work + PlatformsWithLinkResult(ES2_D3D11(), ES3_D3D11(), true ) // Switching to newer client version should work + + // TODO: ANGLE issue 523 + // Compiling a program with client version 3, saving the binary, then loading it with client version 2 should not work + // PlatformsWithLinkResult(ES3_D3D11(), ES2_D3D11(), false ) + ); diff --git a/gfx/angle/src/tests/gl_tests/ProvokingVertexTest.cpp b/gfx/angle/src/tests/gl_tests/ProvokingVertexTest.cpp new file mode 100755 index 000000000..adf0b1a6e --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ProvokingVertexTest.cpp @@ -0,0 +1,316 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProvkingVertexTest: +// Tests on the conformance of the provoking vertex, which applies to flat +// shading and compatibility with D3D. See the section on 'flatshading' +// in the ES 3 specs. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class ProvokingVertexTest : public ANGLETest +{ + protected: + ProvokingVertexTest() + : mProgram(0), + mFramebuffer(0), + mTexture(0), + mTransformFeedback(0), + mBuffer(0), + mIntAttribLocation(-1) + { + setWindowWidth(64); + setWindowHeight(64); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string &vertexShader = + "#version 300 es\n" + "in int intAttrib;\n" + "in vec2 position;\n" + "flat out int attrib;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + " attrib = intAttrib;\n" + "}"; + + const std::string &fragmentShader = + "#version 300 es\n" + "flat in int attrib;\n" + "out int fragColor;\n" + "void main() {\n" + " fragColor = attrib;\n" + "}"; + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("attrib"); + mProgram = CompileProgramWithTransformFeedback(vertexShader, fragmentShader, tfVaryings, + GL_SEPARATE_ATTRIBS); + ASSERT_NE(0u, mProgram); + + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32I, getWindowWidth(), getWindowHeight()); + + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0); + + mIntAttribLocation = glGetAttribLocation(mProgram, "intAttrib"); + ASSERT_NE(-1, mIntAttribLocation); + glEnableVertexAttribArray(mIntAttribLocation); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + if (mProgram != 0) + { + glDeleteProgram(mProgram); + mProgram = 0; + } + + if (mFramebuffer != 0) + { + glDeleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + + if (mTexture != 0) + { + glDeleteTextures(1, &mTexture); + mTexture = 0; + } + + if (mTransformFeedback != 0) + { + glDeleteTransformFeedbacks(1, &mTransformFeedback); + mTransformFeedback = 0; + } + + if (mBuffer != 0) + { + glDeleteBuffers(1, &mBuffer); + mBuffer = 0; + } + + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLuint mFramebuffer; + GLuint mTexture; + GLuint mTransformFeedback; + GLuint mBuffer; + GLint mIntAttribLocation; +}; + +// Test drawing a simple triangle with flat shading, and different valued vertices. +TEST_P(ProvokingVertexTest, FlatTriangle) +{ + GLint vertexData[] = {1, 2, 3, 1, 2, 3}; + glVertexAttribIPointer(mIntAttribLocation, 1, GL_INT, 0, vertexData); + + drawQuad(mProgram, "position", 0.5f); + + GLint pixelValue = 0; + glReadPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_INT, &pixelValue); + + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(vertexData[2], pixelValue); +} + +// Ensure that any provoking vertex shenanigans still gives correct vertex streams. +TEST_P(ProvokingVertexTest, FlatTriWithTransformFeedback) +{ + // TODO(cwallez) figure out why it is broken on AMD on Mac +#if defined(ANGLE_PLATFORM_APPLE) + if (IsAMD()) + { + std::cout << "Test skipped on AMD on Mac." << std::endl; + return; + } +#endif + + glGenTransformFeedbacks(1, &mTransformFeedback); + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); + + glGenBuffers(1, &mBuffer); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mBuffer); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 128, nullptr, GL_STREAM_DRAW); + + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mBuffer); + + GLint vertexData[] = {1, 2, 3, 1, 2, 3}; + glVertexAttribIPointer(mIntAttribLocation, 1, GL_INT, 0, vertexData); + + glUseProgram(mProgram); + glBeginTransformFeedback(GL_TRIANGLES); + drawQuad(mProgram, "position", 0.5f); + glEndTransformFeedback(); + glUseProgram(0); + + GLint pixelValue = 0; + glReadPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_INT, &pixelValue); + + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(vertexData[2], pixelValue); + + GLvoid *mapPointer = + glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(int) * 6, GL_MAP_READ_BIT); + ASSERT_NE(nullptr, mapPointer); + + int *mappedInts = static_cast<int *>(mapPointer); + for (unsigned int cnt = 0; cnt < 6; ++cnt) + { + EXPECT_EQ(vertexData[cnt], mappedInts[cnt]); + } +} + +// Test drawing a simple line with flat shading, and different valued vertices. +TEST_P(ProvokingVertexTest, FlatLine) +{ + GLfloat halfPixel = 1.0f / static_cast<GLfloat>(getWindowWidth()); + + GLint vertexData[] = {1, 2}; + GLfloat positionData[] = {-1.0f + halfPixel, -1.0f, -1.0f + halfPixel, 1.0f}; + + glVertexAttribIPointer(mIntAttribLocation, 1, GL_INT, 0, vertexData); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + glEnableVertexAttribArray(positionLocation); + glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, positionData); + + glUseProgram(mProgram); + glDrawArrays(GL_LINES, 0, 2); + + GLint pixelValue = 0; + glReadPixels(0, 0, 1, 1, GL_RED_INTEGER, GL_INT, &pixelValue); + + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(vertexData[1], pixelValue); +} + +// Test drawing a simple triangle strip with flat shading, and different valued vertices. +TEST_P(ProvokingVertexTest, FlatTriStrip) +{ + GLint vertexData[] = {1, 2, 3, 4, 5, 6}; + GLfloat positionData[] = {-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, + 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f}; + + glVertexAttribIPointer(mIntAttribLocation, 1, GL_INT, 0, vertexData); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + glEnableVertexAttribArray(positionLocation); + glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, positionData); + + glUseProgram(mProgram); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 6); + + std::vector<GLint> pixelBuffer(getWindowWidth() * getWindowHeight(), 0); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RED_INTEGER, GL_INT, + &pixelBuffer[0]); + + ASSERT_GL_NO_ERROR(); + + for (unsigned int triIndex = 0; triIndex < 4; ++triIndex) + { + GLfloat sumX = positionData[triIndex * 2 + 0] + positionData[triIndex * 2 + 2] + + positionData[triIndex * 2 + 4]; + GLfloat sumY = positionData[triIndex * 2 + 1] + positionData[triIndex * 2 + 3] + + positionData[triIndex * 2 + 5]; + + float centerX = sumX / 3.0f * 0.5f + 0.5f; + float centerY = sumY / 3.0f * 0.5f + 0.5f; + unsigned int pixelX = + static_cast<unsigned int>(centerX * static_cast<GLfloat>(getWindowWidth())); + unsigned int pixelY = + static_cast<unsigned int>(centerY * static_cast<GLfloat>(getWindowHeight())); + unsigned int pixelIndex = pixelY * getWindowWidth() + pixelX; + + unsigned int provokingVertexIndex = triIndex + 2; + + EXPECT_EQ(vertexData[provokingVertexIndex], pixelBuffer[pixelIndex]); + } +} + +// Test drawing an indexed triangle strip with flat shading and primitive restart. +TEST_P(ProvokingVertexTest, FlatTriStripPrimitiveRestart) +{ + // TODO(jmadill): Implement on the D3D back-end. + if (IsD3D11()) + { + std::cout << "Test disabled on D3D11." << std::endl; + return; + } + + GLint indexData[] = {0, 1, 2, -1, 1, 2, 3, 4, -1, 3, 4, 5}; + GLint vertexData[] = {1, 2, 3, 4, 5, 6}; + GLfloat positionData[] = {-1.0f, -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, + 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f}; + + glVertexAttribIPointer(mIntAttribLocation, 1, GL_INT, 0, vertexData); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + glEnableVertexAttribArray(positionLocation); + glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, positionData); + + glDisable(GL_CULL_FACE); + glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); + glUseProgram(mProgram); + glDrawElements(GL_TRIANGLE_STRIP, 12, GL_UNSIGNED_INT, indexData); + + std::vector<GLint> pixelBuffer(getWindowWidth() * getWindowHeight(), 0); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RED_INTEGER, GL_INT, + &pixelBuffer[0]); + + ASSERT_GL_NO_ERROR(); + + // Account for primitive restart when checking the tris. + GLint triOffsets[] = {0, 4, 5, 9}; + + for (unsigned int triIndex = 0; triIndex < 4; ++triIndex) + { + GLint vertexA = indexData[triOffsets[triIndex] + 0]; + GLint vertexB = indexData[triOffsets[triIndex] + 1]; + GLint vertexC = indexData[triOffsets[triIndex] + 2]; + + GLfloat sumX = + positionData[vertexA * 2] + positionData[vertexB * 2] + positionData[vertexC * 2]; + GLfloat sumY = positionData[vertexA * 2 + 1] + positionData[vertexB * 2 + 1] + + positionData[vertexC * 2 + 1]; + + float centerX = sumX / 3.0f * 0.5f + 0.5f; + float centerY = sumY / 3.0f * 0.5f + 0.5f; + unsigned int pixelX = + static_cast<unsigned int>(centerX * static_cast<GLfloat>(getWindowWidth())); + unsigned int pixelY = + static_cast<unsigned int>(centerY * static_cast<GLfloat>(getWindowHeight())); + unsigned int pixelIndex = pixelY * getWindowWidth() + pixelX; + + unsigned int provokingVertexIndex = triIndex + 2; + + EXPECT_EQ(vertexData[provokingVertexIndex], pixelBuffer[pixelIndex]); + } +} + +ANGLE_INSTANTIATE_TEST(ProvokingVertexTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/ReadPixelsTest.cpp b/gfx/angle/src/tests/gl_tests/ReadPixelsTest.cpp new file mode 100755 index 000000000..47d2e3dba --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ReadPixelsTest.cpp @@ -0,0 +1,722 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ReadPixelsTest: +// Tests calls related to glReadPixels. +// + +#include "test_utils/ANGLETest.h" + +#include <array> + +#include "random_utils.h" + +using namespace angle; + +namespace +{ + +class ReadPixelsTest : public ANGLETest +{ + protected: + ReadPixelsTest() + { + setWindowWidth(32); + setWindowHeight(32); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } +}; + +// Test out of bounds framebuffer reads. +TEST_P(ReadPixelsTest, OutOfBounds) +{ + // TODO: re-enable once root cause of http://anglebug.com/1413 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + GLsizei pixelsWidth = 32; + GLsizei pixelsHeight = 32; + GLint offset = 16; + std::vector<GLColor> pixels((pixelsWidth + offset) * (pixelsHeight + offset)); + + glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]); + EXPECT_GL_NO_ERROR(); + + // Expect that all pixels which fell within the framebuffer are red + for (int y = pixelsHeight / 2; y < pixelsHeight; y++) + { + for (int x = pixelsWidth / 2; x < pixelsWidth; x++) + { + EXPECT_EQ(GLColor::red, pixels[y * (pixelsWidth + offset) + x]); + } + } +} + +class ReadPixelsPBOTest : public ReadPixelsTest +{ + protected: + ReadPixelsPBOTest() : mPBO(0), mTexture(0), mFBO(0) {} + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenBuffers(1, &mPBO); + glGenFramebuffers(1, &mFBO); + + Reset(4 * getWindowWidth() * getWindowHeight(), 4, 1); + } + + void Reset(GLuint bufferSize, GLuint fboWidth, GLuint fboHeight) + { + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glBufferData(GL_PIXEL_PACK_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + glDeleteTextures(1, &mTexture); + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteBuffers(1, &mPBO); + glDeleteTextures(1, &mTexture); + glDeleteFramebuffers(1, &mFBO); + + ANGLETest::TearDown(); + } + + GLuint mPBO = 0; + GLuint mTexture = 0; + GLuint mFBO = 0; +}; + +// Test basic usage of PBOs. +TEST_P(ReadPixelsPBOTest, Basic) +{ + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + GLvoid *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT); + GLColor *dataColor = static_cast<GLColor *>(mappedPtr); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GLColor::red, dataColor[0]); + + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + EXPECT_GL_NO_ERROR(); +} + +// Test an error is generated when the PBO is too small. +TEST_P(ReadPixelsPBOTest, PBOTooSmall) +{ + Reset(4 * 16 * 16 - 1, 16, 16); + + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test an error is generated when the PBO is mapped. +TEST_P(ReadPixelsPBOTest, PBOMapped) +{ + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test that binding a PBO to ARRAY_BUFFER works as expected. +TEST_P(ReadPixelsPBOTest, ArrayBufferTarget) +{ + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, mPBO); + + GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT); + GLColor *dataColor = static_cast<GLColor *>(mappedPtr); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GLColor::red, dataColor[0]); + + glUnmapBuffer(GL_ARRAY_BUFFER); + EXPECT_GL_NO_ERROR(); +} + +// Test that using a PBO does not overwrite existing data. +TEST_P(ReadPixelsPBOTest, ExistingDataPreserved) +{ + // TODO(geofflang): Figure out why this fails on AMD OpenGL (http://anglebug.com/1291) + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test disabled on AMD OpenGL." << std::endl; + return; + } + + // Clear backbuffer to red + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + // Read 16x16 region from red backbuffer to PBO + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + // Clear backbuffer to green + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + // Read 16x16 region from green backbuffer to PBO at offset 16 + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16)); + GLvoid *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT); + GLColor *dataColor = static_cast<GLColor *>(mappedPtr); + EXPECT_GL_NO_ERROR(); + + // Test pixel 0 is red (existing data) + EXPECT_EQ(GLColor::red, dataColor[0]); + + // Test pixel 16 is green (new data) + EXPECT_EQ(GLColor::green, dataColor[16]); + + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + EXPECT_GL_NO_ERROR(); +} + +// Test that calling SubData preserves PBO data. +TEST_P(ReadPixelsPBOTest, SubDataPreservesContents) +{ + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + unsigned char data[4] = { 1, 2, 3, 4 }; + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, mPBO); + glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data); + + GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT); + GLColor *dataColor = static_cast<GLColor *>(mappedPtr); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]); + + glUnmapBuffer(GL_ARRAY_BUFFER); + EXPECT_GL_NO_ERROR(); +} + +// Same as the prior test, but with an offset. +TEST_P(ReadPixelsPBOTest, SubDataOffsetPreservesContents) +{ + // TODO: re-enable once root cause of http://anglebug.com/1415 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + unsigned char data[4] = { 1, 2, 3, 4 }; + + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, mPBO); + glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data); + + GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT); + GLColor *dataColor = static_cast<GLColor *>(mappedPtr); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GLColor::red, dataColor[0]); + EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[4]); + + glUnmapBuffer(GL_ARRAY_BUFFER); + EXPECT_GL_NO_ERROR(); +} + +class ReadPixelsPBODrawTest : public ReadPixelsPBOTest +{ + protected: + ReadPixelsPBODrawTest() : mProgram(0), mPositionVBO(0) {} + + void SetUp() override + { + ReadPixelsPBOTest::SetUp(); + + const char *vertexShaderSrc = + "attribute vec4 aTest; attribute vec2 aPosition; varying vec4 vTest;\n" + "void main()\n" + "{\n" + " vTest = aTest;\n" + " gl_Position = vec4(aPosition, 0.0, 1.0);\n" + " gl_PointSize = 1.0;\n" + "}"; + + const char *fragmentShaderSrc = + "precision mediump float; varying vec4 vTest;\n" + "void main()\n" + "{\n" + " gl_FragColor = vTest;\n" + "}"; + + mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc); + ASSERT_NE(0u, mProgram); + + glGenBuffers(1, &mPositionVBO); + glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO); + glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + glDeleteBuffers(1, &mPositionVBO); + ReadPixelsPBOTest::TearDown(); + } + + GLuint mProgram; + GLuint mPositionVBO; +}; + +// Test that we can draw with PBO data. +TEST_P(ReadPixelsPBODrawTest, DrawWithPBO) +{ + GLColor color(1, 2, 3, 4); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); + EXPECT_GL_NO_ERROR(); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + EXPECT_GL_NO_ERROR(); + + float positionData[] = { 0.5f, 0.5f }; + + glUseProgram(mProgram); + glViewport(0, 0, 1, 1); + glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO); + glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData); + EXPECT_GL_NO_ERROR(); + + GLint positionLocation = glGetAttribLocation(mProgram, "aPosition"); + EXPECT_NE(-1, positionLocation); + + GLint testLocation = glGetAttribLocation(mProgram, "aTest"); + EXPECT_NE(-1, testLocation); + + glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(positionLocation); + EXPECT_GL_NO_ERROR(); + + glBindBuffer(GL_ARRAY_BUFFER, mPBO); + glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0); + glEnableVertexAttribArray(testLocation); + EXPECT_GL_NO_ERROR(); + + glDrawArrays(GL_POINTS, 0, 1); + EXPECT_GL_NO_ERROR(); + + color = GLColor(0, 0, 0, 0); + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(GLColor(1, 2, 3, 4), color); +} + +class ReadPixelsMultisampleTest : public ReadPixelsTest +{ + protected: + ReadPixelsMultisampleTest() : mFBO(0), mRBO(0), mPBO(0) {} + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenFramebuffers(1, &mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + + glGenRenderbuffers(1, &mRBO); + glBindRenderbuffer(GL_RENDERBUFFER, mRBO); + + glGenBuffers(1, &mPBO); + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr, + GL_STATIC_DRAW); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + ANGLETest::TearDown(); + + glDeleteFramebuffers(1, &mFBO); + glDeleteRenderbuffers(1, &mRBO); + glDeleteBuffers(1, &mPBO); + } + + GLuint mFBO; + GLuint mRBO; + GLuint mPBO; +}; + +// Test ReadPixels from a multisampled framebuffer. +TEST_P(ReadPixelsMultisampleTest, BasicClear) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_ANGLE_framebuffer_multisample")) + { + std::cout << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available." << std::endl; + return; + } + + if (extensionEnabled("GL_ANGLE_framebuffer_multisample")) + { + glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4); + } + else + { + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4); + } + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRBO); + ASSERT_GL_NO_ERROR(); + + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO); + EXPECT_GL_NO_ERROR(); + + glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +class ReadPixelsTextureTest : public ANGLETest +{ + public: + ReadPixelsTextureTest() : mFBO(0), mTexture(0) + { + setWindowWidth(32); + setWindowHeight(32); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenTextures(1, &mTexture); + glGenFramebuffers(1, &mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + } + + void TearDown() override + { + glDeleteFramebuffers(1, &mFBO); + glDeleteTextures(1, &mTexture); + + ANGLETest::TearDown(); + } + + void initTexture(GLenum textureTarget, + GLint levels, + GLint attachmentLevel, + GLint attachmentLayer) + { + glBindTexture(textureTarget, mTexture); + glTexStorage3D(textureTarget, levels, GL_RGBA8, 4, 4, 4); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, attachmentLevel, + attachmentLayer); + initializeTextureData(textureTarget, levels); + } + + void testRead(GLenum textureTarget, GLint levels, GLint attachmentLevel, GLint attachmentLayer) + { + initTexture(textureTarget, levels, attachmentLevel, attachmentLayer); + verifyColor(attachmentLevel, attachmentLayer); + } + + void initPBO() + { + glGenBuffers(1, &mBuffer); + glBindBuffer(GL_PIXEL_PACK_BUFFER, mBuffer); + glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(angle::GLColor), nullptr, GL_STREAM_COPY); + ASSERT_GL_NO_ERROR(); + } + + void testPBORead(GLenum textureTarget, + GLint levels, + GLint attachmentLevel, + GLint attachmentLayer) + { + initPBO(); + initTexture(textureTarget, levels, attachmentLevel, attachmentLayer); + verifyPBO(attachmentLevel, attachmentLayer); + } + + // Give each {level,layer} pair a (probably) unique color via random. + GLuint getColorValue(GLint level, GLint layer) + { + mRNG.reseed(level + layer * 32); + return mRNG.randomUInt(); + } + + void verifyColor(GLint level, GLint layer) + { + angle::GLColor colorValue(getColorValue(level, layer)); + EXPECT_PIXEL_COLOR_EQ(0, 0, colorValue); + } + + void verifyPBO(GLint level, GLint layer) + { + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + angle::GLColor expectedColor(getColorValue(level, layer)); + void *mapPointer = + glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(angle::GLColor), GL_MAP_READ_BIT); + ASSERT_NE(nullptr, mapPointer); + angle::GLColor actualColor; + memcpy(&actualColor, mapPointer, sizeof(angle::GLColor)); + glUnmapBuffer(GL_PIXEL_PACK_BUFFER); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(expectedColor, actualColor); + } + + void initializeTextureData(GLenum textureTarget, GLint levels) + { + for (GLint level = 0; level < levels; ++level) + { + GLint mipSize = 4 >> level; + GLint layers = (textureTarget == GL_TEXTURE_3D ? mipSize : 4); + + size_t layerSize = mipSize * mipSize; + std::vector<GLuint> textureData(layers * layerSize); + + for (GLint layer = 0; layer < layers; ++layer) + { + GLuint colorValue = getColorValue(level, layer); + size_t offset = (layer * layerSize); + std::fill(textureData.begin() + offset, textureData.begin() + offset + layerSize, + colorValue); + } + + glTexSubImage3D(textureTarget, level, 0, 0, 0, mipSize, mipSize, layers, GL_RGBA, + GL_UNSIGNED_BYTE, textureData.data()); + } + } + + angle::RNG mRNG; + GLuint mFBO; + GLuint mTexture; + GLuint mBuffer; +}; + +// Test 3D attachment readback. +TEST_P(ReadPixelsTextureTest, BasicAttachment3D) +{ + testRead(GL_TEXTURE_3D, 1, 0, 0); +} + +// Test 3D attachment readback, non-zero mip. +TEST_P(ReadPixelsTextureTest, MipAttachment3D) +{ + testRead(GL_TEXTURE_3D, 2, 1, 0); +} + +// Test 3D attachment readback, non-zero layer. +TEST_P(ReadPixelsTextureTest, LayerAttachment3D) +{ + testRead(GL_TEXTURE_3D, 1, 0, 1); +} + +// Test 3D attachment readback, non-zero mip and layer. +TEST_P(ReadPixelsTextureTest, MipLayerAttachment3D) +{ + testRead(GL_TEXTURE_3D, 2, 1, 1); +} + +// Test 2D array attachment readback. +TEST_P(ReadPixelsTextureTest, BasicAttachment2DArray) +{ + testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 0); +} + +// Test 3D attachment readback, non-zero mip. +TEST_P(ReadPixelsTextureTest, MipAttachment2DArray) +{ + testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 0); +} + +// Test 3D attachment readback, non-zero layer. +TEST_P(ReadPixelsTextureTest, LayerAttachment2DArray) +{ + testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 1); +} + +// Test 3D attachment readback, non-zero mip and layer. +TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArray) +{ + testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 1); +} + +// Test 3D attachment PBO readback. +TEST_P(ReadPixelsTextureTest, BasicAttachment3DPBO) +{ + testPBORead(GL_TEXTURE_3D, 1, 0, 0); +} + +// Test 3D attachment readback, non-zero mip. +TEST_P(ReadPixelsTextureTest, MipAttachment3DPBO) +{ + testPBORead(GL_TEXTURE_3D, 2, 1, 0); +} + +// Test 3D attachment readback, non-zero layer. +TEST_P(ReadPixelsTextureTest, LayerAttachment3DPBO) +{ + testPBORead(GL_TEXTURE_3D, 1, 0, 1); +} + +// Test 3D attachment readback, non-zero mip and layer. +TEST_P(ReadPixelsTextureTest, MipLayerAttachment3DPBO) +{ + testPBORead(GL_TEXTURE_3D, 2, 1, 1); +} + +// Test 2D array attachment readback. +TEST_P(ReadPixelsTextureTest, BasicAttachment2DArrayPBO) +{ + testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 0); +} + +// Test 3D attachment readback, non-zero mip. +TEST_P(ReadPixelsTextureTest, MipAttachment2DArrayPBO) +{ + testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 0); +} + +// Test 3D attachment readback, non-zero layer. +TEST_P(ReadPixelsTextureTest, LayerAttachment2DArrayPBO) +{ + testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 1); +} + +// Test 3D attachment readback, non-zero mip and layer. +TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArrayPBO) +{ + testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 1); +} + +// a test class to be used for error checking of glReadPixels +class ReadPixelsErrorTest : public ReadPixelsTest +{ + protected: + ReadPixelsErrorTest() : mTexture(0), mFBO(0) {} + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1); + + glGenFramebuffers(1, &mFBO); + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + ANGLETest::TearDown(); + + glDeleteTextures(1, &mTexture); + glDeleteFramebuffers(1, &mFBO); + } + + GLuint mTexture; + GLuint mFBO; +}; + +// The test verifies that glReadPixels generates a GL_INVALID_OPERATION error +// when the read buffer is GL_NONE. +// Reference: GLES 3.0.4, Section 4.3.2 Reading Pixels +TEST_P(ReadPixelsErrorTest, ReadBufferIsNone) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glReadBuffer(GL_NONE); + std::vector<GLubyte> pixels(4); + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +} // anonymous namespace + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(ReadPixelsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ReadPixelsPBOTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ReadPixelsPBODrawTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ReadPixelsMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ReadPixelsTextureTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ReadPixelsErrorTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); diff --git a/gfx/angle/src/tests/gl_tests/RendererTest.cpp b/gfx/angle/src/tests/gl_tests/RendererTest.cpp new file mode 100755 index 000000000..1b07acbf7 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/RendererTest.cpp @@ -0,0 +1,210 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RendererTest: +// These tests are designed to ensure that the various configurations of the test fixtures work as expected. +// If one of these tests fails, then it is likely that some of the other tests are being configured incorrectly. +// For example, they might be using the D3D11 renderer when the test is meant to be using the D3D9 renderer. + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class RendererTest : public ANGLETest +{ + protected: + RendererTest() + { + setWindowWidth(128); + setWindowHeight(128); + } +}; + +TEST_P(RendererTest, RequestedRendererCreated) +{ + std::string rendererString = std::string(reinterpret_cast<const char*>(glGetString(GL_RENDERER))); + std::transform(rendererString.begin(), rendererString.end(), rendererString.begin(), ::tolower); + + std::string versionString = std::string(reinterpret_cast<const char*>(glGetString(GL_VERSION))); + std::transform(versionString.begin(), versionString.end(), versionString.begin(), ::tolower); + + const EGLPlatformParameters &platform = GetParam().eglParameters; + + // Ensure that the renderer string contains D3D11, if we requested a D3D11 renderer. + if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + ASSERT_NE(rendererString.find(std::string("direct3d11")), std::string::npos); + } + + // Ensure that the renderer string contains D3D9, if we requested a D3D9 renderer. + if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE) + { + ASSERT_NE(rendererString.find(std::string("direct3d9")), std::string::npos); + } + + // Ensure that the major and minor versions trigger expected behavior in D3D11 + if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + // Ensure that the renderer uses WARP, if we requested it. + if (platform.deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE) + { + auto basicRenderPos = rendererString.find(std::string("microsoft basic render")); + auto softwareAdapterPos = rendererString.find(std::string("software adapter")); + ASSERT_TRUE(basicRenderPos != std::string::npos || softwareAdapterPos != std::string::npos); + } + + std::vector<std::string> acceptableShaderModels; + + // When no specific major/minor version is requested, then ANGLE should return the highest possible feature level by default. + // The current hardware driver might not support Feature Level 11_0, but WARP always does. + // Therefore if WARP is specified but no major/minor version is specified, then we test to check that ANGLE returns FL11_0. + if (platform.majorVersion >= 11 || platform.majorVersion == EGL_DONT_CARE) + { + // Feature Level 10_0 corresponds to shader model 5_0 + acceptableShaderModels.push_back("ps_5_0"); + } + + if (platform.majorVersion >= 10 || platform.majorVersion == EGL_DONT_CARE) + { + if (platform.minorVersion >= 1 || platform.minorVersion == EGL_DONT_CARE) + { + // Feature Level 10_1 corresponds to shader model 4_1 + acceptableShaderModels.push_back("ps_4_1"); + } + + if (platform.minorVersion >= 0 || platform.minorVersion == EGL_DONT_CARE) + { + // Feature Level 10_0 corresponds to shader model 4_0 + acceptableShaderModels.push_back("ps_4_0"); + } + } + + if (platform.majorVersion == 9 && platform.minorVersion == 3) + { + acceptableShaderModels.push_back("ps_4_0_level_9_3"); + } + + bool found = false; + for (size_t i = 0; i < acceptableShaderModels.size(); i++) + { + if (rendererString.find(acceptableShaderModels[i]) != std::string::npos) + { + found = true; + } + } + + ASSERT_TRUE(found); + } + + EGLint glesMajorVersion = GetParam().majorVersion; + + // Ensure that the renderer string contains GL ES 3.0, if we requested a GL ES 3.0 + if (glesMajorVersion == 3) + { + ASSERT_NE(versionString.find(std::string("es 3.0")), std::string::npos); + } + + // Ensure that the version string contains GL ES 2.0, if we requested GL ES 2.0 + if (glesMajorVersion == 2) + { + ASSERT_NE(versionString.find(std::string("es 2.0")), std::string::npos); + } +} + +// Perform a simple operation (clear and read pixels) to verify the device is working +TEST_P(RendererTest, SimpleOperation) +{ + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); +} + +// Select configurations (e.g. which renderer, which GLES major version) these tests should be run against. + +ANGLE_INSTANTIATE_TEST(RendererTest, + // ES2 on top of D3D9 + ES2_D3D9(), + ES2_D3D9_REFERENCE(), + + // ES2 on top of D3D11 feature level 9.3 to 11.0 + ES2_D3D11(), + ES2_D3D11_FL11_0(), + ES2_D3D11_FL10_1(), + ES2_D3D11_FL10_0(), + ES2_D3D11_FL9_3(), + + // ES2 on top of D3D11 WARP feature level 9.3 to 11.0 + ES2_D3D11_WARP(), + ES2_D3D11_FL11_0_WARP(), + ES2_D3D11_FL10_1_WARP(), + ES2_D3D11_FL10_0_WARP(), + ES2_D3D11_FL9_3_WARP(), + + // ES2 on top of D3D11 reference feature level 9.3 to 11.0 + ES2_D3D11_REFERENCE(), + ES2_D3D11_FL11_0_REFERENCE(), + ES2_D3D11_FL10_1_REFERENCE(), + ES2_D3D11_FL10_0_REFERENCE(), + ES2_D3D11_FL9_3_REFERENCE(), + + // ES3 on top of D3D11 feature level 9.3 to 11.0 + ES3_D3D11(), + ES3_D3D11_FL11_0(), + ES3_D3D11_FL10_1(), + ES3_D3D11_FL10_0(), + + // ES3 on top of D3D11 WARP feature level 9.3 to 11.0 + ES3_D3D11_WARP(), + ES3_D3D11_FL11_0_WARP(), + ES3_D3D11_FL10_1_WARP(), + ES3_D3D11_FL10_0_WARP(), + + // ES3 on top of D3D11 reference feature level 9.3 to 11.0 + ES3_D3D11_REFERENCE(), + ES3_D3D11_FL11_0_REFERENCE(), + ES3_D3D11_FL10_1_REFERENCE(), + ES3_D3D11_FL10_0_REFERENCE(), + + // ES2 on top of desktop OpenGL versions 2.1 to 4.5 + ES2_OPENGL(), + ES2_OPENGL(2, 1), + ES2_OPENGL(3, 0), + ES2_OPENGL(3, 1), + ES2_OPENGL(3, 2), + ES2_OPENGL(3, 3), + ES2_OPENGL(4, 0), + ES2_OPENGL(4, 1), + ES2_OPENGL(4, 2), + ES2_OPENGL(4, 3), + ES2_OPENGL(4, 4), + ES2_OPENGL(4, 5), + + // ES2 on top of desktop OpenGL versions 3.2 to 4.5 + ES3_OPENGL(), + ES3_OPENGL(3, 2), + ES3_OPENGL(3, 3), + ES3_OPENGL(4, 0), + ES3_OPENGL(4, 1), + ES3_OPENGL(4, 2), + ES3_OPENGL(4, 3), + ES3_OPENGL(4, 4), + ES3_OPENGL(4, 5), + + // ES2 on top of OpenGL ES 2.0 to 3.2 + ES2_OPENGLES(), + ES2_OPENGLES(2, 0), + ES2_OPENGLES(3, 0), + ES2_OPENGLES(3, 1), + ES2_OPENGLES(3, 2), + + // ES2 on top of OpenGL ES 3.0 to 3.2 + ES3_OPENGLES(), + ES3_OPENGLES(3, 0), + ES3_OPENGLES(3, 1), + ES3_OPENGLES(3, 2)); +} diff --git a/gfx/angle/src/tests/gl_tests/RobustClientMemoryTest.cpp b/gfx/angle/src/tests/gl_tests/RobustClientMemoryTest.cpp new file mode 100644 index 000000000..b5f89e904 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/RobustClientMemoryTest.cpp @@ -0,0 +1,385 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RobustClientMemoryTest.cpp : Tests of the GL_ANGLE_robust_client_memory extension. + +#include "test_utils/ANGLETest.h" + +#include "test_utils/gl_raii.h" + +namespace angle +{ +class RobustClientMemoryTest : public ANGLETest +{ + protected: + RobustClientMemoryTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGetBooleanvRobustANGLE = reinterpret_cast<PFNGLGETBOOLEANVROBUSTANGLE>( + eglGetProcAddress("glGetBooleanvRobustANGLE")); + glGetBufferParameterivRobustANGLE = reinterpret_cast<PFNGLGETBUFFERPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glGetBufferParameterivRobustANGLE")); + glGetFloatvRobustANGLE = reinterpret_cast<PFNGLGETFLOATVROBUSTANGLE>( + eglGetProcAddress("glGetFloatvRobustANGLE")); + glGetFramebufferAttachmentParameterivRobustANGLE = + reinterpret_cast<PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glGetFramebufferAttachmentParameterivRobustANGLE")); + glGetIntegervRobustANGLE = reinterpret_cast<PFNGLGETINTEGERVROBUSTANGLE>( + eglGetProcAddress("glGetIntegervRobustANGLE")); + glGetProgramivRobustANGLE = reinterpret_cast<PFNGLGETPROGRAMIVROBUSTANGLE>( + eglGetProcAddress("glGetProgramivRobustANGLE")); + glGetRenderbufferParameterivRobustANGLE = + reinterpret_cast<PFNGLGETRENDERBUFFERPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glGetRenderbufferParameterivRobustANGLE")); + glGetShaderivRobustANGLE = reinterpret_cast<PFNGLGETSHADERIVROBUSTANGLE>( + eglGetProcAddress("glGetShaderivRobustANGLE")); + glGetTexParameterfvRobustANGLE = reinterpret_cast<PFNGLGETTEXPARAMETERFVROBUSTANGLE>( + eglGetProcAddress("glGetTexParameterfvRobustANGLE")); + glGetTexParameterivRobustANGLE = reinterpret_cast<PFNGLGETTEXPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glGetTexParameterivRobustANGLE")); + glGetUniformfvRobustANGLE = reinterpret_cast<PFNGLGETUNIFORMFVROBUSTANGLE>( + eglGetProcAddress("glGetUniformfvRobustANGLE")); + glGetUniformivRobustANGLE = reinterpret_cast<PFNGLGETUNIFORMIVROBUSTANGLE>( + eglGetProcAddress("glGetUniformivRobustANGLE")); + glGetVertexAttribfvRobustANGLE = reinterpret_cast<PFNGLGETVERTEXATTRIBFVROBUSTANGLE>( + eglGetProcAddress("glGetVertexAttribfvRobustANGLE")); + glGetVertexAttribivRobustANGLE = reinterpret_cast<PFNGLGETVERTEXATTRIBIVROBUSTANGLE>( + eglGetProcAddress("glGetVertexAttribivRobustANGLE")); + glGetVertexAttribPointervRobustANGLE = + reinterpret_cast<PFNGLGETVERTEXATTRIBPOINTERVROBUSTANGLE>( + eglGetProcAddress("glGetVertexAttribPointervRobustANGLE")); + glReadPixelsRobustANGLE = reinterpret_cast<PFNGLREADPIXELSROBUSTANGLE>( + eglGetProcAddress("glReadPixelsRobustANGLE")); + glTexImage2DRobustANGLE = reinterpret_cast<PFNGLTEXIMAGE2DROBUSTANGLE>( + eglGetProcAddress("glTexImage2DRobustANGLE")); + glTexParameterfvRobustANGLE = reinterpret_cast<PFNGLTEXPARAMETERFVROBUSTANGLE>( + eglGetProcAddress("glTexParameterfvRobustANGLE")); + glTexParameterivRobustANGLE = reinterpret_cast<PFNGLTEXPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glTexParameterivRobustANGLE")); + glTexSubImage2DRobustANGLE = reinterpret_cast<PFNGLTEXSUBIMAGE2DROBUSTANGLE>( + eglGetProcAddress("glTexSubImage2DRobustANGLE")); + glTexImage3DRobustANGLE = reinterpret_cast<PFNGLTEXIMAGE3DROBUSTANGLE>( + eglGetProcAddress("glTexImage3DRobustANGLE")); + glTexSubImage3DRobustANGLE = reinterpret_cast<PFNGLTEXSUBIMAGE3DROBUSTANGLE>( + eglGetProcAddress("glTexSubImage3DRobustANGLE")); + glGetQueryivRobustANGLE = reinterpret_cast<PFNGLGETQUERYIVROBUSTANGLE>( + eglGetProcAddress("glGetQueryivRobustANGLE")); + glGetQueryObjectuivRobustANGLE = reinterpret_cast<PFNGLGETQUERYOBJECTUIVROBUSTANGLE>( + eglGetProcAddress("glGetQueryObjectuivRobustANGLE")); + glGetBufferPointervRobustANGLE = reinterpret_cast<PFNGLGETBUFFERPOINTERVROBUSTANGLE>( + eglGetProcAddress("glGetBufferPointervRobustANGLE")); + glGetIntegeri_vRobustANGLE = reinterpret_cast<PFNGLGETINTEGERI_VROBUSTANGLE>( + eglGetProcAddress("glGetIntegeri_vRobustANGLE")); + glGetInternalformativRobustANGLE = reinterpret_cast<PFNGETINTERNALFORMATIVROBUSTANGLE>( + eglGetProcAddress("glGetInternalformativRobustANGLE")); + glGetVertexAttribIivRobustANGLE = reinterpret_cast<PFNGLGETVERTEXATTRIBIIVROBUSTANGLE>( + eglGetProcAddress("glGetVertexAttribIivRobustANGLE")); + glGetVertexAttribIuivRobustANGLE = reinterpret_cast<PFNGLGETVERTEXATTRIBIUIVROBUSTANGLE>( + eglGetProcAddress("glGetVertexAttribIuivRobustANGLE")); + glGetUniformuivRobustANGLE = reinterpret_cast<PFNGLGETUNIFORMUIVROBUSTANGLE>( + eglGetProcAddress("glGetUniformuivRobustANGLE")); + glGetActiveUniformBlockivRobustANGLE = + reinterpret_cast<PFNGLGETACTIVEUNIFORMBLOCKIVROBUSTANGLE>( + eglGetProcAddress("glGetActiveUniformBlockivRobustANGLE")); + glGetInteger64vRobustANGLE = reinterpret_cast<PFNGLGETINTEGER64VROBUSTANGLE>( + eglGetProcAddress("glGetInteger64vRobustANGLE")); + glGetInteger64i_vRobustANGLE = reinterpret_cast<PFNGLGETINTEGER64I_VROBUSTANGLE>( + eglGetProcAddress("glGetInteger64i_vRobustANGLE")); + glGetBufferParameteri64vRobustANGLE = + reinterpret_cast<PFNGLGETBUFFERPARAMETERI64VROBUSTANGLE>( + eglGetProcAddress("glGetBufferParameteri64vRobustANGLE")); + glSamplerParameterivRobustANGLE = reinterpret_cast<PFNGLSAMPLERPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glSamplerParameterivRobustANGLE")); + glSamplerParameterfvRobustANGLE = reinterpret_cast<PFNGLSAMPLERPARAMETERFVROBUSTANGLE>( + eglGetProcAddress("glSamplerParameterfvRobustANGLE")); + glGetSamplerParameterivRobustANGLE = + reinterpret_cast<PFNGLGETSAMPLERPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glGetSamplerParameterivRobustANGLE")); + glGetSamplerParameterfvRobustANGLE = + reinterpret_cast<PFNGLGETSAMPLERPARAMETERFVROBUSTANGLE>( + eglGetProcAddress("glGetSamplerParameterfvRobustANGLE")); + glGetFramebufferParameterivRobustANGLE = + reinterpret_cast<PFNGLGETFRAMEBUFFERPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glGetFramebufferParameterivRobustANGLE")); + glGetProgramInterfaceivRobustANGLE = + reinterpret_cast<PFNGLGETPROGRAMINTERFACEIVROBUSTANGLE>( + eglGetProcAddress("glGetProgramInterfaceivRobustANGLE")); + glGetBooleani_vRobustANGLE = reinterpret_cast<PFNGLGETBOOLEANI_VROBUSTANGLE>( + eglGetProcAddress("glGetBooleani_vRobustANGLE")); + glGetMultisamplefvRobustANGLE = reinterpret_cast<PFNGLGETMULTISAMPLEFVROBUSTANGLE>( + eglGetProcAddress("glGetMultisamplefvRobustANGLE")); + glGetTexLevelParameterivRobustANGLE = + reinterpret_cast<PFNGLGETTEXLEVELPARAMETERIVROBUSTANGLE>( + eglGetProcAddress("glGetTexLevelParameterivRobustANGLE")); + glGetTexLevelParameterfvRobustANGLE = + reinterpret_cast<PFNGLGETTEXLEVELPARAMETERFVROBUSTANGLE>( + eglGetProcAddress("glGetTexLevelParameterfvRobustANGLE")); + glGetPointervRobustANGLERobustANGLE = + reinterpret_cast<PFNGLGETPOINTERVROBUSTANGLEROBUSTANGLE>( + eglGetProcAddress("glGetPointervRobustANGLERobustANGLE")); + glReadnPixelsRobustANGLE = reinterpret_cast<PFNGLREADNPIXELSROBUSTANGLE>( + eglGetProcAddress("glReadnPixelsRobustANGLE")); + glGetnUniformfvRobustANGLE = reinterpret_cast<PFNGLGETNUNIFORMFVROBUSTANGLE>( + eglGetProcAddress("glGetnUniformfvRobustANGLE")); + glGetnUniformivRobustANGLE = reinterpret_cast<PFNGLGETNUNIFORMIVROBUSTANGLE>( + eglGetProcAddress("glGetnUniformivRobustANGLE")); + glGetnUniformuivRobustANGLE = reinterpret_cast<PFNGLGETNUNIFORMUIVROBUSTANGLE>( + eglGetProcAddress("glGetnUniformuivRobustANGLE")); + glTexParameterIivRobustANGLE = reinterpret_cast<PFNGLTEXPARAMETERIIVROBUSTANGLE>( + eglGetProcAddress("glTexParameterIivRobustANGLE")); + glTexParameterIuivRobustANGLE = reinterpret_cast<PFNGLTEXPARAMETERIUIVROBUSTANGLE>( + eglGetProcAddress("glTexParameterIuivRobustANGLE")); + glGetTexParameterIivRobustANGLE = reinterpret_cast<PFNGLGETTEXPARAMETERIIVROBUSTANGLE>( + eglGetProcAddress("glGetTexParameterIivRobustANGLE")); + glGetTexParameterIuivRobustANGLE = reinterpret_cast<PFNGLGETTEXPARAMETERIUIVROBUSTANGLE>( + eglGetProcAddress("glGetTexParameterIuivRobustANGLE")); + glSamplerParameterIivRobustANGLE = reinterpret_cast<PFNGLSAMPLERPARAMETERIIVROBUSTANGLE>( + eglGetProcAddress("glSamplerParameterIivRobustANGLE")); + glSamplerParameterIuivRobustANGLE = reinterpret_cast<PFNGLSAMPLERPARAMETERIUIVROBUSTANGLE>( + eglGetProcAddress("glSamplerParameterIuivRobustANGLE")); + glGetSamplerParameterIivRobustANGLE = + reinterpret_cast<PFNGLGETSAMPLERPARAMETERIIVROBUSTANGLE>( + eglGetProcAddress("glGetSamplerParameterIivRobustANGLE")); + glGetSamplerParameterIuivRobustANGLE = + reinterpret_cast<PFNGLGETSAMPLERPARAMETERIUIVROBUSTANGLE>( + eglGetProcAddress("glGetSamplerParameterIuivRobustANGLE")); + glGetQueryObjectivRobustANGLE = reinterpret_cast<PFNGLGETQUERYOBJECTIVROBUSTANGLE>( + eglGetProcAddress("glGetQueryObjectivRobustANGLE")); + glGetQueryObjecti64vRobustANGLE = reinterpret_cast<PFNGLGETQUERYOBJECTI64VROBUSTANGLE>( + eglGetProcAddress("glGetQueryObjecti64vRobustANGLE")); + glGetQueryObjectui64vRobustANGLE = reinterpret_cast<PFNGLGETQUERYOBJECTUI64VROBUSTANGLE>( + eglGetProcAddress("glGetQueryObjectui64vRobustANGLE")); + } + + void TearDown() override { ANGLETest::TearDown(); } + + bool extensionsPresent() const + { + if (!extensionEnabled("GL_ANGLE_robust_client_memory")) + { + std::cout << "Test skipped because GL_ANGLE_robust_client_memory is not available."; + return false; + } + + return true; + } + + PFNGLGETBOOLEANVROBUSTANGLE glGetBooleanvRobustANGLE = nullptr; + PFNGLGETBUFFERPARAMETERIVROBUSTANGLE glGetBufferParameterivRobustANGLE = nullptr; + PFNGLGETFLOATVROBUSTANGLE glGetFloatvRobustANGLE = nullptr; + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVROBUSTANGLE + glGetFramebufferAttachmentParameterivRobustANGLE = nullptr; + PFNGLGETINTEGERVROBUSTANGLE glGetIntegervRobustANGLE = nullptr; + PFNGLGETPROGRAMIVROBUSTANGLE glGetProgramivRobustANGLE = nullptr; + PFNGLGETRENDERBUFFERPARAMETERIVROBUSTANGLE glGetRenderbufferParameterivRobustANGLE = nullptr; + PFNGLGETSHADERIVROBUSTANGLE glGetShaderivRobustANGLE = nullptr; + PFNGLGETTEXPARAMETERFVROBUSTANGLE glGetTexParameterfvRobustANGLE = nullptr; + PFNGLGETTEXPARAMETERIVROBUSTANGLE glGetTexParameterivRobustANGLE = nullptr; + PFNGLGETUNIFORMFVROBUSTANGLE glGetUniformfvRobustANGLE = nullptr; + PFNGLGETUNIFORMIVROBUSTANGLE glGetUniformivRobustANGLE = nullptr; + PFNGLGETVERTEXATTRIBFVROBUSTANGLE glGetVertexAttribfvRobustANGLE = nullptr; + PFNGLGETVERTEXATTRIBIVROBUSTANGLE glGetVertexAttribivRobustANGLE = nullptr; + PFNGLGETVERTEXATTRIBPOINTERVROBUSTANGLE glGetVertexAttribPointervRobustANGLE = nullptr; + PFNGLREADPIXELSROBUSTANGLE glReadPixelsRobustANGLE = nullptr; + PFNGLTEXIMAGE2DROBUSTANGLE glTexImage2DRobustANGLE = nullptr; + PFNGLTEXPARAMETERFVROBUSTANGLE glTexParameterfvRobustANGLE = nullptr; + PFNGLTEXPARAMETERIVROBUSTANGLE glTexParameterivRobustANGLE = nullptr; + PFNGLTEXSUBIMAGE2DROBUSTANGLE glTexSubImage2DRobustANGLE = nullptr; + PFNGLTEXIMAGE3DROBUSTANGLE glTexImage3DRobustANGLE = nullptr; + PFNGLTEXSUBIMAGE3DROBUSTANGLE glTexSubImage3DRobustANGLE = nullptr; + PFNGLGETQUERYIVROBUSTANGLE glGetQueryivRobustANGLE = nullptr; + PFNGLGETQUERYOBJECTUIVROBUSTANGLE glGetQueryObjectuivRobustANGLE = nullptr; + PFNGLGETBUFFERPOINTERVROBUSTANGLE glGetBufferPointervRobustANGLE = nullptr; + PFNGLGETINTEGERI_VROBUSTANGLE glGetIntegeri_vRobustANGLE = nullptr; + PFNGETINTERNALFORMATIVROBUSTANGLE glGetInternalformativRobustANGLE = nullptr; + PFNGLGETVERTEXATTRIBIIVROBUSTANGLE glGetVertexAttribIivRobustANGLE = nullptr; + PFNGLGETVERTEXATTRIBIUIVROBUSTANGLE glGetVertexAttribIuivRobustANGLE = nullptr; + PFNGLGETUNIFORMUIVROBUSTANGLE glGetUniformuivRobustANGLE = nullptr; + PFNGLGETACTIVEUNIFORMBLOCKIVROBUSTANGLE glGetActiveUniformBlockivRobustANGLE = nullptr; + PFNGLGETINTEGER64VROBUSTANGLE glGetInteger64vRobustANGLE = nullptr; + PFNGLGETINTEGER64I_VROBUSTANGLE glGetInteger64i_vRobustANGLE = nullptr; + PFNGLGETBUFFERPARAMETERI64VROBUSTANGLE glGetBufferParameteri64vRobustANGLE = nullptr; + PFNGLSAMPLERPARAMETERIVROBUSTANGLE glSamplerParameterivRobustANGLE = nullptr; + PFNGLSAMPLERPARAMETERFVROBUSTANGLE glSamplerParameterfvRobustANGLE = nullptr; + PFNGLGETSAMPLERPARAMETERIVROBUSTANGLE glGetSamplerParameterivRobustANGLE = nullptr; + PFNGLGETSAMPLERPARAMETERFVROBUSTANGLE glGetSamplerParameterfvRobustANGLE = nullptr; + PFNGLGETFRAMEBUFFERPARAMETERIVROBUSTANGLE glGetFramebufferParameterivRobustANGLE = nullptr; + PFNGLGETPROGRAMINTERFACEIVROBUSTANGLE glGetProgramInterfaceivRobustANGLE = nullptr; + PFNGLGETBOOLEANI_VROBUSTANGLE glGetBooleani_vRobustANGLE = nullptr; + PFNGLGETMULTISAMPLEFVROBUSTANGLE glGetMultisamplefvRobustANGLE = nullptr; + PFNGLGETTEXLEVELPARAMETERIVROBUSTANGLE glGetTexLevelParameterivRobustANGLE = nullptr; + PFNGLGETTEXLEVELPARAMETERFVROBUSTANGLE glGetTexLevelParameterfvRobustANGLE = nullptr; + PFNGLGETPOINTERVROBUSTANGLEROBUSTANGLE glGetPointervRobustANGLERobustANGLE = nullptr; + PFNGLREADNPIXELSROBUSTANGLE glReadnPixelsRobustANGLE = nullptr; + PFNGLGETNUNIFORMFVROBUSTANGLE glGetnUniformfvRobustANGLE = nullptr; + PFNGLGETNUNIFORMIVROBUSTANGLE glGetnUniformivRobustANGLE = nullptr; + PFNGLGETNUNIFORMUIVROBUSTANGLE glGetnUniformuivRobustANGLE = nullptr; + PFNGLTEXPARAMETERIIVROBUSTANGLE glTexParameterIivRobustANGLE = nullptr; + PFNGLTEXPARAMETERIUIVROBUSTANGLE glTexParameterIuivRobustANGLE = nullptr; + PFNGLGETTEXPARAMETERIIVROBUSTANGLE glGetTexParameterIivRobustANGLE = nullptr; + PFNGLGETTEXPARAMETERIUIVROBUSTANGLE glGetTexParameterIuivRobustANGLE = nullptr; + PFNGLSAMPLERPARAMETERIIVROBUSTANGLE glSamplerParameterIivRobustANGLE = nullptr; + PFNGLSAMPLERPARAMETERIUIVROBUSTANGLE glSamplerParameterIuivRobustANGLE = nullptr; + PFNGLGETSAMPLERPARAMETERIIVROBUSTANGLE glGetSamplerParameterIivRobustANGLE = nullptr; + PFNGLGETSAMPLERPARAMETERIUIVROBUSTANGLE glGetSamplerParameterIuivRobustANGLE = nullptr; + PFNGLGETQUERYOBJECTIVROBUSTANGLE glGetQueryObjectivRobustANGLE = nullptr; + PFNGLGETQUERYOBJECTI64VROBUSTANGLE glGetQueryObjecti64vRobustANGLE = nullptr; + PFNGLGETQUERYOBJECTUI64VROBUSTANGLE glGetQueryObjectui64vRobustANGLE = nullptr; +}; + +// Test basic usage and validation of glGetIntegervRobustANGLE +TEST_P(RobustClientMemoryTest, GetInteger) +{ + if (!extensionsPresent()) + { + return; + } + + // Verify that the robust and regular entry points return the same values + GLint resultRobust; + GLsizei length; + glGetIntegervRobustANGLE(GL_MAX_VERTEX_ATTRIBS, 1, &length, &resultRobust); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(1, length); + + GLint resultRegular; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &resultRegular); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(resultRegular, resultRobust); + + // Query a dynamic value + GLint numCompressedFormats; + glGetIntegervRobustANGLE(GL_NUM_COMPRESSED_TEXTURE_FORMATS, 1, &length, &numCompressedFormats); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, length); + + if (numCompressedFormats > 0) + { + std::vector<GLint> resultBuf(numCompressedFormats * 2, 0); + + // Test when the bufSize is too low + glGetIntegervRobustANGLE(GL_COMPRESSED_TEXTURE_FORMATS, numCompressedFormats - 1, &length, + resultBuf.data()); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + EXPECT_TRUE(std::all_of(resultBuf.begin(), resultBuf.end(), + [](GLint value) { return value == 0; })); + + // Make sure the GL doesn't touch the end of the buffer + glGetIntegervRobustANGLE(GL_COMPRESSED_TEXTURE_FORMATS, + static_cast<GLsizei>(resultBuf.size()), &length, resultBuf.data()); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(numCompressedFormats, length); + EXPECT_TRUE(std::none_of(resultBuf.begin(), resultBuf.begin() + length, + [](GLint value) { return value == 0; })); + EXPECT_TRUE(std::all_of(resultBuf.begin() + length, resultBuf.end(), + [](GLint value) { return value == 0; })); + } + + // Test with null length + glGetIntegervRobustANGLE(GL_MAX_VARYING_VECTORS, 1, nullptr, &resultRobust); + EXPECT_GL_NO_ERROR(); + + glGetIntegervRobustANGLE(GL_MAX_VIEWPORT_DIMS, 1, nullptr, &resultRobust); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + GLint maxViewportDims[2]; + glGetIntegervRobustANGLE(GL_MAX_VIEWPORT_DIMS, 2, nullptr, maxViewportDims); + EXPECT_GL_NO_ERROR(); +} + +// Test basic usage and validation of glTexImage2DRobustANGLE +TEST_P(RobustClientMemoryTest, TexImage2D) +{ + if (!extensionsPresent()) + { + return; + } + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + + GLsizei dataDimension = 1024; + std::vector<GLubyte> rgbaData(dataDimension * dataDimension * 4); + + // Test the regular case + glTexImage2DRobustANGLE(GL_TEXTURE_2D, 0, GL_RGBA, dataDimension, dataDimension, 0, GL_RGBA, + GL_UNSIGNED_BYTE, static_cast<GLsizei>(rgbaData.size()), + rgbaData.data()); + EXPECT_GL_NO_ERROR(); + + // Test with a data size that is too small + glTexImage2DRobustANGLE(GL_TEXTURE_2D, 0, GL_RGBA, dataDimension, dataDimension, 0, GL_RGBA, + GL_UNSIGNED_BYTE, static_cast<GLsizei>(rgbaData.size()) / 2, + rgbaData.data()); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + if (getClientMajorVersion() >= 3) + { + // Set an unpack parameter that would cause the driver to read past the end of the buffer + glPixelStorei(GL_UNPACK_ROW_LENGTH, dataDimension + 1); + glTexImage2DRobustANGLE(GL_TEXTURE_2D, 0, GL_RGBA, dataDimension, dataDimension, 0, GL_RGBA, + GL_UNSIGNED_BYTE, static_cast<GLsizei>(rgbaData.size()), + rgbaData.data()); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } +} + +// Test basic usage and validation of glReadPixelsRobustANGLE +TEST_P(RobustClientMemoryTest, ReadPixels) +{ + if (!extensionsPresent()) + { + return; + } + + GLsizei dataDimension = 16; + std::vector<GLubyte> rgbaData(dataDimension * dataDimension * 4); + + // Test the regular case + GLsizei length = 0; + glReadPixelsRobustANGLE(0, 0, dataDimension, dataDimension, GL_RGBA, GL_UNSIGNED_BYTE, + static_cast<GLsizei>(rgbaData.size()), &length, rgbaData.data()); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(static_cast<GLsizei>(rgbaData.size()), length); + + // Test with a data size that is too small + glReadPixelsRobustANGLE(0, 0, dataDimension, dataDimension, GL_RGBA, GL_UNSIGNED_BYTE, + static_cast<GLsizei>(rgbaData.size()) - 1, &length, rgbaData.data()); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + if (getClientMajorVersion() >= 3) + { + // Set a pack parameter that would cause the driver to write past the end of the buffer + glPixelStorei(GL_PACK_ROW_LENGTH, dataDimension + 1); + glReadPixelsRobustANGLE(0, 0, dataDimension, dataDimension, GL_RGBA, GL_UNSIGNED_BYTE, + static_cast<GLsizei>(rgbaData.size()), &length, rgbaData.data()); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(RobustClientMemoryTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/SRGBFramebufferTest.cpp b/gfx/angle/src/tests/gl_tests/SRGBFramebufferTest.cpp new file mode 100644 index 000000000..47ff2f3e0 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/SRGBFramebufferTest.cpp @@ -0,0 +1,141 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SRGBFramebufferTest.cpp: Tests of sRGB framebuffer functionality. + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +namespace angle +{ + +class SRGBFramebufferTest : public ANGLETest +{ + protected: + SRGBFramebufferTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vs = + "precision highp float;\n" + "attribute vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + "}\n"; + + const std::string fs = + "precision highp float;\n" + "uniform vec4 color;\n" + "void main()\n" + "{\n" + " gl_FragColor = color;\n" + "}\n"; + + mProgram = CompileProgram(vs, fs); + ASSERT_NE(0u, mProgram); + + mColorLocation = glGetUniformLocation(mProgram, "color"); + ASSERT_NE(-1, mColorLocation); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram = 0; + GLint mColorLocation = -1; +}; + +// Test basic validation of GL_EXT_sRGB_write_control +TEST_P(SRGBFramebufferTest, Validation) +{ + GLenum expectedError = + extensionEnabled("GL_EXT_sRGB_write_control") ? GL_NO_ERROR : GL_INVALID_ENUM; + + GLboolean value = GL_FALSE; + glEnable(GL_FRAMEBUFFER_SRGB_EXT); + EXPECT_GL_ERROR(expectedError); + + glGetBooleanv(GL_FRAMEBUFFER_SRGB_EXT, &value); + EXPECT_GL_ERROR(expectedError); + if (expectedError == GL_NO_ERROR) + { + EXPECT_EQ(GL_TRUE, value); + } + + glDisable(GL_FRAMEBUFFER_SRGB_EXT); + EXPECT_GL_ERROR(expectedError); + + glGetBooleanv(GL_FRAMEBUFFER_SRGB_EXT, &value); + EXPECT_GL_ERROR(expectedError); + if (expectedError == GL_NO_ERROR) + { + EXPECT_EQ(GL_FALSE, value); + } +} + +// Test basic functionality of GL_EXT_sRGB_write_control +TEST_P(SRGBFramebufferTest, BasicUsage) +{ + if (!extensionEnabled("GL_EXT_sRGB_write_control") || + (!extensionEnabled("GL_EXT_sRGB") && getClientMajorVersion() < 3)) + { + std::cout + << "Test skipped because GL_EXT_sRGB_write_control and GL_EXT_sRGB are not available." + << std::endl; + return; + } + + GLColor linearColor(64, 127, 191, 255); + GLColor srgbColor(13, 54, 133, 255); + + GLTexture texture; + glBindTexture(GL_TEXTURE_2D, texture.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, + nullptr); + + GLFramebuffer framebuffer; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get()); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.get(), 0); + + glUseProgram(mProgram); + glUniform4fv(mColorLocation, 1, srgbColor.toNormalizedVector().data()); + + glEnable(GL_FRAMEBUFFER_SRGB_EXT); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0); + + glDisable(GL_FRAMEBUFFER_SRGB_EXT); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(SRGBFramebufferTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace angle diff --git a/gfx/angle/src/tests/gl_tests/SRGBTextureTest.cpp b/gfx/angle/src/tests/gl_tests/SRGBTextureTest.cpp new file mode 100755 index 000000000..f379f429f --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/SRGBTextureTest.cpp @@ -0,0 +1,268 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +namespace angle +{ + +class SRGBTextureTest : public ANGLETest +{ + protected: + SRGBTextureTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vs = + "precision highp float;\n" + "attribute vec4 position;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"; + + const std::string fs = + "precision highp float;\n" + "uniform sampler2D tex;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(tex, texcoord);\n" + "}\n"; + + mProgram = CompileProgram(vs, fs); + ASSERT_NE(0u, mProgram); + + mTextureLocation = glGetUniformLocation(mProgram, "tex"); + ASSERT_NE(-1, mTextureLocation); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram = 0; + GLint mTextureLocation = -1; +}; + +TEST_P(SRGBTextureTest, SRGBValidation) +{ + bool supported = extensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3; + + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + GLubyte pixel[3] = { 0 }; + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, 1, 1, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel); + if (supported) + { + EXPECT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB, GL_UNSIGNED_BYTE, pixel); + EXPECT_GL_NO_ERROR(); + + glGenerateMipmap(GL_TEXTURE_2D); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } + + glDeleteTextures(1, &tex); +} + +TEST_P(SRGBTextureTest, SRGBAValidation) +{ + bool supported = extensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3; + + GLuint tex = 0; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + GLubyte pixel[4] = { 0 }; + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel); + if (supported) + { + EXPECT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel); + EXPECT_GL_NO_ERROR(); + + glGenerateMipmap(GL_TEXTURE_2D); + if (getClientMajorVersion() == 2) + { + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } + else + { + EXPECT_GL_NO_ERROR(); + } + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } + + glDeleteTextures(1, &tex); +} + +TEST_P(SRGBTextureTest, SRGBARenderbuffer) +{ + bool supported = extensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() == 3; + + GLuint rbo = 0; + glGenRenderbuffers(1, &rbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo); + + glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8_EXT, 1, 1); + if (supported) + { + EXPECT_GL_NO_ERROR(); + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + // Make sure the rbo has a size for future tests + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1); + EXPECT_GL_NO_ERROR(); + } + + GLuint fbo = 0; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); + EXPECT_GL_NO_ERROR(); + + GLint colorEncoding = 0; + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT, &colorEncoding); + if (supported) + { + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(GL_SRGB_EXT, colorEncoding); + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } + + glDeleteFramebuffers(1, &fbo); + glDeleteRenderbuffers(1, &rbo); +} + +// Verify that if the srgb decode extension is available, srgb textures are too +TEST_P(SRGBTextureTest, SRGBDecodeExtensionAvailability) +{ + bool hasSRGBDecode = extensionEnabled("GL_EXT_texture_sRGB_decode"); + if (hasSRGBDecode) + { + bool hasSRGBTextures = extensionEnabled("GL_EXT_sRGB") || getClientMajorVersion() >= 3; + EXPECT_TRUE(hasSRGBTextures); + } +} + +// Test basic functionality of SRGB decode using the texture parameter +TEST_P(SRGBTextureTest, SRGBDecodeTextureParameter) +{ + if (!extensionEnabled("GL_EXT_texture_sRGB_decode")) + { + std::cout << "Test skipped because GL_EXT_texture_sRGB_decode is not available." + << std::endl; + return; + } + + GLColor linearColor(64, 127, 191, 255); + GLColor srgbColor(13, 54, 133, 255); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, + &linearColor); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); + ASSERT_GL_NO_ERROR(); + + glUseProgram(mProgram); + glUniform1i(mTextureLocation, 0); + + glDisable(GL_DEPTH_TEST); + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0); +} + +// Test basic functionality of SRGB decode using the sampler parameter +TEST_P(SRGBTextureTest, SRGBDecodeSamplerParameter) +{ + if (!extensionEnabled("GL_EXT_texture_sRGB_decode") || getClientMajorVersion() < 3) + { + std::cout << "Test skipped because GL_EXT_texture_sRGB_decode or ES3 is not available." + << std::endl; + return; + } + + GLColor linearColor(64, 127, 191, 255); + GLColor srgbColor(13, 54, 133, 255); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, + &linearColor); + ASSERT_GL_NO_ERROR(); + + GLSampler sampler; + glBindSampler(0, sampler.get()); + glSamplerParameteri(sampler.get(), GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); + + glUseProgram(mProgram); + glUniform1i(mTextureLocation, 0); + + glDisable(GL_DEPTH_TEST); + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, srgbColor, 1.0); + + glSamplerParameteri(sampler.get(), GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, linearColor, 1.0); +} +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(SRGBTextureTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/SimpleOperationTest.cpp b/gfx/angle/src/tests/gl_tests/SimpleOperationTest.cpp new file mode 100755 index 000000000..b11fb9fe9 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/SimpleOperationTest.cpp @@ -0,0 +1,212 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SimpleOperationTest: +// Basic GL commands such as linking a program, initializing a buffer, etc. + +#include "test_utils/ANGLETest.h" + +#include <vector> + +using namespace angle; + +namespace +{ + +class SimpleOperationTest : public ANGLETest +{ + protected: + SimpleOperationTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } +}; + +TEST_P(SimpleOperationTest, CompileVertexShader) +{ + const std::string source = SHADER_SOURCE + ( + attribute vec4 a_input; + void main() + { + gl_Position = a_input; + } + ); + + GLuint shader = CompileShader(GL_VERTEX_SHADER, source); + EXPECT_NE(shader, 0u); + glDeleteShader(shader); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(SimpleOperationTest, CompileFragmentShader) +{ + const std::string source = SHADER_SOURCE + ( + precision mediump float; + varying vec4 v_input; + void main() + { + gl_FragColor = v_input; + } + ); + + GLuint shader = CompileShader(GL_FRAGMENT_SHADER, source); + EXPECT_NE(shader, 0u); + glDeleteShader(shader); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(SimpleOperationTest, LinkProgram) +{ + const std::string vsSource = SHADER_SOURCE + ( + void main() + { + gl_Position = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + void main() + { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + + GLuint program = CompileProgram(vsSource, fsSource); + EXPECT_NE(program, 0u); + glDeleteProgram(program); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(SimpleOperationTest, LinkProgramWithUniforms) +{ + const std::string vsSource = SHADER_SOURCE + ( + void main() + { + gl_Position = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + precision mediump float; + uniform vec4 u_input; + void main() + { + gl_FragColor = u_input; + } + ); + + GLuint program = CompileProgram(vsSource, fsSource); + EXPECT_NE(program, 0u); + + GLint uniformLoc = glGetUniformLocation(program, "u_input"); + EXPECT_NE(-1, uniformLoc); + + glDeleteProgram(program); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(SimpleOperationTest, LinkProgramWithAttributes) +{ + const std::string vsSource = SHADER_SOURCE + ( + attribute vec4 a_input; + void main() + { + gl_Position = a_input; + } + ); + + const std::string fsSource = SHADER_SOURCE + ( + void main() + { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + + GLuint program = CompileProgram(vsSource, fsSource); + EXPECT_NE(program, 0u); + + GLint attribLoc = glGetAttribLocation(program, "a_input"); + EXPECT_NE(-1, attribLoc); + + glDeleteProgram(program); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(SimpleOperationTest, BufferDataWithData) +{ + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + + std::vector<uint8_t> data(1024); + glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW); + + glDeleteBuffers(1, &buffer); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(SimpleOperationTest, BufferDataWithNoData) +{ + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, 1024, nullptr, GL_STATIC_DRAW); + glDeleteBuffers(1, &buffer); + + EXPECT_GL_NO_ERROR(); +} + +TEST_P(SimpleOperationTest, BufferSubData) +{ + GLuint buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + + const size_t bufferSize = 1024; + glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW); + + const size_t subDataCount = 16; + std::vector<uint8_t> data(bufferSize / subDataCount); + for (size_t i = 0; i < subDataCount; i++) + { + glBufferSubData(GL_ARRAY_BUFFER, data.size() * i, data.size(), &data[0]); + } + + glDeleteBuffers(1, &buffer); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(SimpleOperationTest, + ES2_D3D9(), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/SixteenBppTextureTest.cpp b/gfx/angle/src/tests/gl_tests/SixteenBppTextureTest.cpp new file mode 100755 index 000000000..dfc4111d7 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/SixteenBppTextureTest.cpp @@ -0,0 +1,551 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SixteenBppTextureTest: +// Basic tests using 16bpp texture formats (e.g. GL_RGB565). + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +#include "image_util/imageformats.h" + +using namespace angle; + +namespace +{ + +GLColor Convert565(const R5G6B5 &rgb565) +{ + gl::ColorF colorf; + R5G6B5::readColor(&colorf, &rgb565); + Vector4 vecColor(colorf.red, colorf.green, colorf.blue, colorf.alpha); + return GLColor(vecColor); +} + +R5G6B5 Convert565(const GLColor &glColor) +{ + const Vector4 &vecColor = glColor.toNormalizedVector(); + gl::ColorF colorf(vecColor.x, vecColor.y, vecColor.z, vecColor.w); + R5G6B5 rgb565; + R5G6B5::writeColor(&rgb565, &colorf); + return rgb565; +} + +class SixteenBppTextureTest : public ANGLETest +{ + protected: + SixteenBppTextureTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = vec4(position.xy, 0.0, 1.0); + texcoord = (position.xy * 0.5) + 0.5; + } + ); + + const std::string fragmentShaderSource2D = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + m2DProgram = CompileProgram(vertexShaderSource, fragmentShaderSource2D); + mTexture2DUniformLocation = glGetUniformLocation(m2DProgram, "tex"); + } + + void TearDown() override + { + glDeleteProgram(m2DProgram); + + ANGLETest::TearDown(); + } + + void simpleValidationBase(GLuint tex) + { + // Draw a quad using the texture + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(m2DProgram); + glUniform1i(mTexture2DUniformLocation, 0); + drawQuad(m2DProgram, "position", 0.5f); + ASSERT_GL_NO_ERROR(); + + int w = getWindowWidth() - 1; + int h = getWindowHeight() - 1; + + // Check that it drew as expected + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue); + EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow); + + // Generate mipmaps + glGenerateMipmap(GL_TEXTURE_2D); + + // Draw a quad using the texture + glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(m2DProgram); + glUniform1i(mTexture2DUniformLocation, 0); + drawQuad(m2DProgram, "position", 0.5f); + ASSERT_GL_NO_ERROR(); + + // Check that it drew as expected + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green); + EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue); + EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow); + + // Bind the texture as a framebuffer, render to it, then check the results + GLFramebuffer fbo; + glBindFramebuffer(GL_FRAMEBUFFER, fbo.get()); + glBindTexture(GL_TEXTURE_2D, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_UNSUPPORTED) + { + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(1, 0, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(1, 1, 255, 0, 0, 255); + EXPECT_PIXEL_EQ(0, 1, 255, 0, 0, 255); + } + else + { + std::cout << "Skipping rendering to an unsupported framebuffer format" << std::endl; + } + } + + GLuint m2DProgram; + GLint mTexture2DUniformLocation; +}; + +class SixteenBppTextureTestES3 : public SixteenBppTextureTest +{ +}; + +// Simple validation test for GL_RGB565 textures. +// Samples from the texture, renders to it, generates mipmaps etc. +TEST_P(SixteenBppTextureTest, RGB565Validation) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + GLuint test; + memcpy(&test, &GLColor::black, 4); + + R5G6B5 pixels[4] = {Convert565(GLColor::red), Convert565(GLColor::green), + Convert565(GLColor::blue), Convert565(GLColor::yellow)}; + + glClearColor(0, 0, 0, 0); + + // Create a simple RGB565 texture + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + // Supply the data to it + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); + EXPECT_GL_NO_ERROR(); + + simpleValidationBase(tex.get()); +} + +// Simple validation test for GL_RGBA5551 textures. +// Samples from the texture, renders to it, generates mipmaps etc. +TEST_P(SixteenBppTextureTest, RGBA5551Validation) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + GLushort pixels[4] = + { + 0xF801, // Red + 0x07C1, // Green + 0x003F, // Blue + 0xFFC1 // Red + Green + }; + + // Create a simple 5551 texture + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixels); + EXPECT_GL_NO_ERROR(); + + simpleValidationBase(tex.get()); +} + +// Test to ensure calling Clear() on an RGBA5551 texture does something reasonable +// Based on WebGL test conformance/textures/texture-attachment-formats.html +TEST_P(SixteenBppTextureTest, RGBA5551ClearAlpha) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + GLTexture tex; + GLFramebuffer fbo; + + // Create a simple 5551 texture + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + // Bind the texture as a framebuffer, clear it, then check the results + glBindFramebuffer(GL_FRAMEBUFFER, fbo.get()); + glBindTexture(GL_TEXTURE_2D, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.get(), 0); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_UNSUPPORTED) + { + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0); + + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 255); + } + else + { + std::cout << "Skipping rendering to an unsupported framebuffer format" << std::endl; + } +} + +// Simple validation test for GL_RGBA4444 textures. +// Samples from the texture, renders to it, generates mipmaps etc. +TEST_P(SixteenBppTextureTest, RGBA4444Validation) +{ + // These tests fail on certain Intel machines running an un-updated version of Win7 + // The tests pass after installing the latest updates from Windows Update. + // TODO: reenable these tests once the bots have been updated + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + GLushort pixels[4] = + { + 0xF00F, // Red + 0x0F0F, // Green + 0x00FF, // Blue + 0xFF0F // Red + Green + }; + + glClearColor(0, 0, 0, 0); + + // Generate a RGBA4444 texture, no mipmaps + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + // Provide some data for the texture + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels); + EXPECT_GL_NO_ERROR(); + + simpleValidationBase(tex.get()); +} + +// Test uploading RGBA8 data to RGBA4 textures. +TEST_P(SixteenBppTextureTestES3, RGBA4UploadRGBA8) +{ + std::vector<GLColor> fourColors; + fourColors.push_back(GLColor::red); + fourColors.push_back(GLColor::green); + fourColors.push_back(GLColor::blue); + fourColors.push_back(GLColor::yellow); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, fourColors.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + simpleValidationBase(tex.get()); +} + +// Test uploading RGB8 data to RGB565 textures. +TEST_P(SixteenBppTextureTestES3, RGB565UploadRGB8) +{ + std::vector<GLColorRGB> fourColors; + fourColors.push_back(GLColorRGB::red); + fourColors.push_back(GLColorRGB::green); + fourColors.push_back(GLColorRGB::blue); + fourColors.push_back(GLColorRGB::yellow); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, fourColors.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + + simpleValidationBase(tex.get()); +} + +// Test uploading RGBA8 data to RGB5A41 textures. +TEST_P(SixteenBppTextureTestES3, RGB5A1UploadRGBA8) +{ + std::vector<GLColor> fourColors; + fourColors.push_back(GLColor::red); + fourColors.push_back(GLColor::green); + fourColors.push_back(GLColor::blue); + fourColors.push_back(GLColor::yellow); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + fourColors.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + simpleValidationBase(tex.get()); +} + +// Test uploading RGB10A2 data to RGB5A1 textures. +TEST_P(SixteenBppTextureTestES3, RGB5A1UploadRGB10A2) +{ + struct RGB10A2 + { + RGB10A2(uint32_t r, uint32_t g, uint32_t b, uint32_t a) : R(r), G(g), B(b), A(a) {} + + uint32_t R : 10; + uint32_t G : 10; + uint32_t B : 10; + uint32_t A : 2; + }; + + uint32_t one10 = (1u << 10u) - 1u; + + RGB10A2 red(one10, 0u, 0u, 0x3u); + RGB10A2 green(0u, one10, 0u, 0x3u); + RGB10A2 blue(0u, 0u, one10, 0x3u); + RGB10A2 yellow(one10, one10, 0u, 0x3u); + + std::vector<RGB10A2> fourColors; + fourColors.push_back(red); + fourColors.push_back(green); + fourColors.push_back(blue); + fourColors.push_back(yellow); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 2, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, + fourColors.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + ASSERT_GL_NO_ERROR(); + simpleValidationBase(tex.get()); +} + +// Test reading from RGBA4 textures attached to FBO. +TEST_P(SixteenBppTextureTestES3, RGBA4FramebufferReadback) +{ + // TODO(jmadill): Fix bug with GLES + if (IsOpenGLES()) + { + std::cout << "Test skipped on GLES." << std::endl; + return; + } + + Vector4 rawColor(0.5f, 0.7f, 1.0f, 0.0f); + GLColor expectedColor(rawColor); + + GLFramebuffer fbo; + glBindFramebuffer(GL_FRAMEBUFFER, fbo.get()); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.get(), 0); + + glClearColor(rawColor.x, rawColor.y, rawColor.z, rawColor.w); + glClear(GL_COLOR_BUFFER_BIT); + + ASSERT_GL_NO_ERROR(); + + GLenum colorReadFormat = GL_NONE; + GLenum colorReadType = GL_NONE; + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, reinterpret_cast<GLint *>(&colorReadFormat)); + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, reinterpret_cast<GLint *>(&colorReadType)); + + if (colorReadFormat == GL_RGBA && colorReadType == GL_UNSIGNED_BYTE) + { + GLColor actualColor = GLColor::black; + glReadPixels(0, 0, 1, 1, colorReadFormat, colorReadType, &actualColor); + EXPECT_COLOR_NEAR(expectedColor, actualColor, 20); + } + else + { + ASSERT_GLENUM_EQ(GL_RGBA, colorReadFormat); + ASSERT_TRUE(colorReadType == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT || + colorReadType == GL_UNSIGNED_SHORT_4_4_4_4); + + uint16_t rgba = 0; + glReadPixels(0, 0, 1, 1, colorReadFormat, colorReadType, &rgba); + + GLubyte r8 = static_cast<GLubyte>((rgba & 0xF000) >> 12); + GLubyte g8 = static_cast<GLubyte>((rgba & 0x0F00) >> 8); + GLubyte b8 = static_cast<GLubyte>((rgba & 0x00F0) >> 4); + GLubyte a8 = static_cast<GLubyte>((rgba & 0x000F)); + + GLColor actualColor(r8 << 4, g8 << 4, b8 << 4, a8 << 4); + EXPECT_COLOR_NEAR(expectedColor, actualColor, 20); + } + + ASSERT_GL_NO_ERROR(); +} + +// Test reading from RGB565 textures attached to FBO. +TEST_P(SixteenBppTextureTestES3, RGB565FramebufferReadback) +{ + // TODO(jmadill): Fix bug with GLES + if (IsOpenGLES()) + { + std::cout << "Test skipped on GLES." << std::endl; + return; + } + + GLFramebuffer fbo; + glBindFramebuffer(GL_FRAMEBUFFER, fbo.get()); + + std::vector<GLColor> fourColors; + fourColors.push_back(GLColor::red); + fourColors.push_back(GLColor::green); + fourColors.push_back(GLColor::blue); + fourColors.push_back(GLColor::white); + + const std::string &vertexShader = + "#version 300 es\n" + "in vec4 color;\n" + "in vec2 position;\n" + "out vec4 fcolor;\n" + "void main() {\n" + " fcolor = color;\n" + " gl_Position = vec4(position, 0.5, 1.0);\n" + "}"; + const std::string &fragmentShader = + "#version 300 es\n" + "in mediump vec4 fcolor;\n" + "out mediump vec4 color;\n" + "void main() {\n" + " color = fcolor;\n" + "}"; + + GLuint program = CompileProgram(vertexShader, fragmentShader); + glUseProgram(program); + + GLint colorLocation = glGetAttribLocation(program, "color"); + ASSERT_NE(-1, colorLocation); + glEnableVertexAttribArray(colorLocation); + glVertexAttribPointer(colorLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, fourColors.data()); + + int w = getWindowWidth(); + int h = getWindowHeight(); + + glViewport(0, 0, w, h); + + GLTexture tex; + glBindTexture(GL_TEXTURE_2D, tex.get()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex.get(), 0); + + drawIndexedQuad(program, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + + int t = 12; + EXPECT_PIXEL_COLOR_NEAR(0, h - 1, GLColor::red, t); + EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::green, t); + EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, GLColor::blue, t); + EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, GLColor::white, t); + + GLenum colorReadFormat = GL_NONE; + GLenum colorReadType = GL_NONE; + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, reinterpret_cast<GLint *>(&colorReadFormat)); + glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, reinterpret_cast<GLint *>(&colorReadType)); + + if (colorReadFormat == GL_RGB && colorReadType == GL_UNSIGNED_SHORT_5_6_5) + { + std::vector<R5G6B5> readColors(w * h); + glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, readColors.data()); + + int hoffset = (h - 1) * w; + EXPECT_COLOR_NEAR(GLColor::red, Convert565(readColors[hoffset]), t); + EXPECT_COLOR_NEAR(GLColor::green, Convert565(readColors[0]), t); + EXPECT_COLOR_NEAR(GLColor::blue, Convert565(readColors[w - 1]), t); + EXPECT_COLOR_NEAR(GLColor::white, Convert565(readColors[w - 1 + hoffset]), t); + } + + glDeleteProgram(program); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(SixteenBppTextureTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); + +ANGLE_INSTANTIATE_TEST(SixteenBppTextureTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/StateChangeTest.cpp b/gfx/angle/src/tests/gl_tests/StateChangeTest.cpp new file mode 100755 index 000000000..439a78439 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/StateChangeTest.cpp @@ -0,0 +1,591 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// StateChangeTest: +// Specifically designed for an ANGLE implementation of GL, these tests validate that +// ANGLE's dirty bits systems don't get confused by certain sequences of state changes. +// + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +using namespace angle; + +namespace +{ + +class StateChangeTest : public ANGLETest +{ + protected: + StateChangeTest() + { + setWindowWidth(64); + setWindowHeight(64); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + + // Enable the no error extension to avoid syncing the FBO state on validation. + setNoErrorEnabled(true); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenFramebuffers(1, &mFramebuffer); + glGenTextures(2, mTextures.data()); + glGenRenderbuffers(1, &mRenderbuffer); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + if (mFramebuffer != 0) + { + glDeleteFramebuffers(1, &mFramebuffer); + mFramebuffer = 0; + } + + if (!mTextures.empty()) + { + glDeleteTextures(static_cast<GLsizei>(mTextures.size()), mTextures.data()); + mTextures.clear(); + } + + glDeleteRenderbuffers(1, &mRenderbuffer); + + ANGLETest::TearDown(); + } + + GLuint mFramebuffer = 0; + GLuint mRenderbuffer = 0; + std::vector<GLuint> mTextures = {0, 0}; +}; + +class StateChangeTestES3 : public StateChangeTest +{ + protected: + StateChangeTestES3() {} +}; + +} // anonymous namespace + +// Ensure that CopyTexImage2D syncs framebuffer changes. +TEST_P(StateChangeTest, CopyTexImage2DSync) +{ + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // TODO(geofflang): Fix on Linux AMD drivers (http://anglebug.com/1291) + std::cout << "Test disabled on AMD OpenGL." << std::endl; + return; + } + + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + // Init first texture to red + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + // Init second texture to green + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0); + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + // Copy in the red texture to the green one. + // CopyTexImage should sync the framebuffer attachment change. + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 16, 16, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + ASSERT_GL_NO_ERROR(); +} + +// Ensure that CopyTexSubImage2D syncs framebuffer changes. +TEST_P(StateChangeTest, CopyTexSubImage2DSync) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + // Init first texture to red + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + // Init second texture to green + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0); + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + // Copy in the red texture to the green one. + // CopyTexImage should sync the framebuffer attachment change. + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 16, 16); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + ASSERT_GL_NO_ERROR(); +} + +// Test that Framebuffer completeness caching works when color attachments change. +TEST_P(StateChangeTest, FramebufferIncompleteColorAttachment) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Change the texture at color attachment 0 to be non-color-renderable. + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 16, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + ASSERT_GL_NO_ERROR(); +} + +// Test that caching works when color attachments change with TexStorage. +TEST_P(StateChangeTest, FramebufferIncompleteWithTexStorage) +{ + if (!extensionEnabled("GL_EXT_texture_storage")) + { + std::cout << "Test skipped because TexStorage2DEXT not available." << std::endl; + } + + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Change the texture at color attachment 0 to be non-color-renderable. + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ALPHA8_EXT, 16, 16); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + ASSERT_GL_NO_ERROR(); +} + +// Test that caching works when color attachments change with CompressedTexImage2D. +TEST_P(StateChangeTestES3, FramebufferIncompleteWithCompressedTex) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Change the texture at color attachment 0 to be non-color-renderable. + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 16, 16, 0, 64, nullptr); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + ASSERT_GL_NO_ERROR(); +} + +// Test that caching works when color attachments are deleted. +TEST_P(StateChangeTestES3, FramebufferIncompleteWhenAttachmentDeleted) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Delete the texture at color attachment 0. + glDeleteTextures(1, &mTextures[0]); + mTextures[0] = 0; + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + ASSERT_GL_NO_ERROR(); +} + +// Test that Framebuffer completeness caching works when depth attachments change. +TEST_P(StateChangeTest, FramebufferIncompleteDepthAttachment) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 16, 16); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderbuffer); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Change the texture at color attachment 0 to be non-depth-renderable. + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + ASSERT_GL_NO_ERROR(); +} + +// Test that Framebuffer completeness caching works when stencil attachments change. +TEST_P(StateChangeTest, FramebufferIncompleteStencilAttachment) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 16, 16); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + mRenderbuffer); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Change the texture at the stencil attachment to be non-stencil-renderable. + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + ASSERT_GL_NO_ERROR(); +} + +// Test that Framebuffer completeness caching works when depth-stencil attachments change. +TEST_P(StateChangeTest, FramebufferIncompleteDepthStencilAttachment) +{ + if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_packed_depth_stencil")) + { + std::cout << "Test skipped because packed depth+stencil not availble." << std::endl; + return; + } + + if (IsWindows() && IsIntel() && IsOpenGL()) + { + // TODO(jmadill): Investigate the failure (https://anglebug.com/1388) + std::cout << "Test disabled on Windows Intel OpenGL." << std::endl; + return; + } + + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + mRenderbuffer); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + // Change the texture the depth-stencil attachment to be non-depth-stencil-renderable. + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + ASSERT_GL_NO_ERROR(); +} + +// Ensure that CopyTexSubImage3D syncs framebuffer changes. +TEST_P(StateChangeTestES3, CopyTexSubImage3DSync) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + // Init first texture to red + glBindTexture(GL_TEXTURE_3D, mTextures[0]); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[0], 0, 0); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + // Init second texture to green + glBindTexture(GL_TEXTURE_3D, mTextures[1]); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[1], 0, 0); + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + // Copy in the red texture to the green one. + // CopyTexImage should sync the framebuffer attachment change. + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[0], 0, 0); + glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 16, 16); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[1], 0, 0); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + ASSERT_GL_NO_ERROR(); +} + +// Ensure that BlitFramebuffer syncs framebuffer changes. +TEST_P(StateChangeTestES3, BlitFramebufferSync) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + // Init first texture to red + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + // Init second texture to green + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0); + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + // Change to the red textures and blit. + // BlitFramebuffer should sync the framebuffer attachment change. + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], + 0); + glBlitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + ASSERT_GL_NO_ERROR(); +} + +// Ensure that ReadBuffer and DrawBuffers sync framebuffer changes. +TEST_P(StateChangeTestES3, ReadBufferAndDrawBuffersSync) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + // Initialize two FBO attachments + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[1], 0); + + // Clear first attachment to red + GLenum bufs1[] = {GL_COLOR_ATTACHMENT0, GL_NONE}; + glDrawBuffers(2, bufs1); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Clear second texture to green + GLenum bufs2[] = {GL_NONE, GL_COLOR_ATTACHMENT1}; + glDrawBuffers(2, bufs2); + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Verify first attachment is red and second is green + glReadBuffer(GL_COLOR_ATTACHMENT1); + EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255); + + glReadBuffer(GL_COLOR_ATTACHMENT0); + EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255); + + ASSERT_GL_NO_ERROR(); +} + +// Tests calling invalidate on incomplete framebuffers after switching attachments. +// Adapted partially from WebGL 2 test "renderbuffers/invalidate-framebuffer" +TEST_P(StateChangeTestES3, IncompleteRenderbufferAttachmentInvalidateSync) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + GLint samples = 0; + glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &samples); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRenderbuffer); + ASSERT_GL_NO_ERROR(); + + // invalidate the framebuffer when the attachment is incomplete: no storage allocated to the + // attached renderbuffer + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, + glCheckFramebufferStatus(GL_FRAMEBUFFER)); + GLenum attachments1[] = {GL_COLOR_ATTACHMENT0}; + glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1); + ASSERT_GL_NO_ERROR(); + + glRenderbufferStorageMultisample(GL_RENDERBUFFER, static_cast<GLsizei>(samples), GL_RGBA8, + getWindowWidth(), getWindowHeight()); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + glClear(GL_COLOR_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); + + GLRenderbuffer renderbuf; + + glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get()); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, + renderbuf.get()); + ASSERT_GL_NO_ERROR(); + + // invalidate the framebuffer when the attachment is incomplete: no storage allocated to the + // attached renderbuffer + // Note: the bug will only repro *without* a call to checkStatus before the invalidate. + GLenum attachments2[] = {GL_DEPTH_ATTACHMENT}; + glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments2); + + glRenderbufferStorageMultisample(GL_RENDERBUFFER, static_cast<GLsizei>(samples), + GL_DEPTH_COMPONENT16, getWindowWidth(), getWindowHeight()); + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + glClear(GL_DEPTH_BUFFER_BIT); + ASSERT_GL_NO_ERROR(); +} + +class StateChangeRenderTest : public StateChangeTest +{ + protected: + StateChangeRenderTest() : mProgram(0), mRenderbuffer(0) {} + + void SetUp() override + { + StateChangeTest::SetUp(); + + const std::string vertexShaderSource = + "attribute vec2 position;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + "}"; + const std::string fragmentShaderSource = + "uniform highp vec4 uniformColor;\n" + "void main() {\n" + " gl_FragColor = uniformColor;\n" + "}"; + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + + glGenRenderbuffers(1, &mRenderbuffer); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + glDeleteRenderbuffers(1, &mRenderbuffer); + + StateChangeTest::TearDown(); + } + + void setUniformColor(const GLColor &color) + { + glUseProgram(mProgram); + const Vector4 &normalizedColor = color.toNormalizedVector(); + GLint uniformLocation = glGetUniformLocation(mProgram, "uniformColor"); + ASSERT_NE(-1, uniformLocation); + glUniform4fv(uniformLocation, 1, normalizedColor.data()); + } + + GLuint mProgram; + GLuint mRenderbuffer; +}; + +// Test that re-creating a currently attached texture works as expected. +TEST_P(StateChangeRenderTest, RecreateTexture) +{ + if (IsIntel() && IsLinux()) + { + // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346) + std::cout << "Test disabled on Linux Intel OpenGL." << std::endl; + return; + } + + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + + // Draw with red to the FBO. + GLColor red(255, 0, 0, 255); + setUniformColor(red); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, red); + + // Recreate the texture with green. + GLColor green(0, 255, 0, 255); + std::vector<GLColor> greenPixels(32 * 32, green); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, + greenPixels.data()); + EXPECT_PIXEL_COLOR_EQ(0, 0, green); + + // Verify drawing blue gives blue. This covers the FBO sync with D3D dirty bits. + GLColor blue(0, 0, 255, 255); + setUniformColor(blue); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, blue); + + EXPECT_GL_NO_ERROR(); +} + +// Test that re-creating a currently attached renderbuffer works as expected. +TEST_P(StateChangeRenderTest, RecreateRenderbuffer) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRenderbuffer); + + // Draw with red to the FBO. + GLColor red(255, 0, 0, 255); + setUniformColor(red); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, red); + + // Recreate the renderbuffer and clear to green. + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 32, 32); + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + GLColor green(0, 255, 0, 255); + EXPECT_PIXEL_COLOR_EQ(0, 0, green); + + // Verify drawing blue gives blue. This covers the FBO sync with D3D dirty bits. + GLColor blue(0, 0, 255, 255); + setUniformColor(blue); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, blue); + + EXPECT_GL_NO_ERROR(); +} + +// Test that recreating a texture with GenerateMipmaps signals the FBO is dirty. +TEST_P(StateChangeRenderTest, GenerateMipmap) +{ + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0); + + // Draw once to set the RenderTarget in D3D11 + GLColor red(255, 0, 0, 255); + setUniformColor(red); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, red); + + // This will trigger the texture to be re-created on FL9_3. + glGenerateMipmap(GL_TEXTURE_2D); + + // Now ensure we don't have a stale render target. + GLColor blue(0, 0, 255, 255); + setUniformColor(blue); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, blue); + + EXPECT_GL_NO_ERROR(); +} + +ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL()); +ANGLE_INSTANTIATE_TEST(StateChangeRenderTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_OPENGL(), + ES2_D3D11_FL9_3()); +ANGLE_INSTANTIATE_TEST(StateChangeTestES3, ES3_D3D11(), ES3_OPENGL()); diff --git a/gfx/angle/src/tests/gl_tests/SwizzleTest.cpp b/gfx/angle/src/tests/gl_tests/SwizzleTest.cpp new file mode 100755 index 000000000..b1ad13102 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/SwizzleTest.cpp @@ -0,0 +1,441 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include <vector> + +using namespace angle; + +namespace +{ + +class SwizzleTest : public ANGLETest +{ + protected: + SwizzleTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + + GLenum swizzles[] = + { + GL_RED, + GL_GREEN, + GL_BLUE, + GL_ALPHA, + GL_ZERO, + GL_ONE, + }; + + for (int r = 0; r < 6; r++) + { + for (int g = 0; g < 6; g++) + { + for (int b = 0; b < 6; b++) + { + for (int a = 0; a < 6; a++) + { + swizzlePermutation permutation; + permutation.swizzleRed = swizzles[r]; + permutation.swizzleGreen = swizzles[g]; + permutation.swizzleBlue = swizzles[b]; + permutation.swizzleAlpha = swizzles[a]; + mPermutations.push_back(permutation); + } + } + } + } + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = position; + texcoord = (position.xy * 0.5) + 0.5; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + + mTextureUniformLocation = glGetUniformLocation(mProgram, "tex"); + ASSERT_NE(-1, mTextureUniformLocation); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + glDeleteTextures(1, &mTexture); + + ANGLETest::TearDown(); + } + + template <typename T> + void init2DTexture(GLenum internalFormat, GLenum dataFormat, GLenum dataType, const T* data) + { + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, dataFormat, dataType, data); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + void init2DCompressedTexture(GLenum internalFormat, GLsizei width, GLsizei height, GLsizei dataSize, const GLubyte* data) + { + glGenTextures(1, &mTexture); + glBindTexture(GL_TEXTURE_2D, mTexture); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, width, height, 0, dataSize, data); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + GLubyte getExpectedValue(GLenum swizzle, GLubyte unswizzled[4]) + { + switch (swizzle) + { + case GL_RED: return unswizzled[0]; + case GL_GREEN: return unswizzled[1]; + case GL_BLUE: return unswizzled[2]; + case GL_ALPHA: return unswizzled[3]; + case GL_ZERO: return 0; + case GL_ONE: return 255; + default: return 0; + } + } + + void runTest2D() + { + // TODO(jmadill): Figure out why this fails on Intel. + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + glUseProgram(mProgram); + glBindTexture(GL_TEXTURE_2D, mTexture); + glUniform1i(mTextureUniformLocation, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 0.5f); + + GLubyte unswizzled[4]; + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &unswizzled); + + ASSERT_GL_NO_ERROR(); + + for (size_t i = 0; i < mPermutations.size(); i++) + { + const swizzlePermutation& permutation = mPermutations[i]; + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, permutation.swizzleRed); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, permutation.swizzleGreen); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, permutation.swizzleBlue); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, permutation.swizzleAlpha); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_EQ(0, 0, + getExpectedValue(permutation.swizzleRed, unswizzled), + getExpectedValue(permutation.swizzleGreen, unswizzled), + getExpectedValue(permutation.swizzleBlue, unswizzled), + getExpectedValue(permutation.swizzleAlpha, unswizzled)); + + ASSERT_GL_NO_ERROR(); + } + } + + GLuint mProgram; + GLint mTextureUniformLocation; + + GLuint mTexture; + + struct swizzlePermutation + { + GLenum swizzleRed; + GLenum swizzleGreen; + GLenum swizzleBlue; + GLenum swizzleAlpha; + }; + std::vector<swizzlePermutation> mPermutations; +}; + +class SwizzleIntegerTest : public SwizzleTest +{ + protected: + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "in vec4 position;\n" + "out vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"; + + const std::string fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "precision highp usampler2D;\n" + "uniform usampler2D tex;\n" + "in vec2 texcoord;\n" + "out vec4 my_FragColor;\n" + "\n" + "void main()\n" + "{\n" + " uvec4 s = texture(tex, texcoord);\n" + " if (s[0] == 1u) s[0] = 255u;\n" + " if (s[1] == 1u) s[1] = 255u;\n" + " if (s[2] == 1u) s[2] = 255u;\n" + " if (s[3] == 1u) s[3] = 255u;\n" + " my_FragColor = vec4(s) / 255.0;\n" + "}\n"; + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + + mTextureUniformLocation = glGetUniformLocation(mProgram, "tex"); + ASSERT_NE(-1, mTextureUniformLocation); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + ASSERT_GL_NO_ERROR(); + } +}; + +TEST_P(SwizzleTest, RGBA8_2D) +{ + GLubyte data[] = { 1, 64, 128, 200 }; + init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +TEST_P(SwizzleTest, RGB8_2D) +{ + GLubyte data[] = { 77, 66, 55 }; + init2DTexture(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +TEST_P(SwizzleTest, RG8_2D) +{ + GLubyte data[] = { 11, 99 }; + init2DTexture(GL_RG8, GL_RG, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +TEST_P(SwizzleTest, R8_2D) +{ + GLubyte data[] = { 2 }; + init2DTexture(GL_R8, GL_RED, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +TEST_P(SwizzleTest, RGB10_A2_2D) +{ + GLuint data[] = {20u | (40u << 10) | (60u << 20) | (2u << 30)}; + init2DTexture(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, data); + runTest2D(); +} + +TEST_P(SwizzleTest, RGBA32F_2D) +{ + GLfloat data[] = { 0.25f, 0.5f, 0.75f, 0.8f }; + init2DTexture(GL_RGBA32F, GL_RGBA, GL_FLOAT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, RGB32F_2D) +{ + GLfloat data[] = { 0.1f, 0.2f, 0.3f }; + init2DTexture(GL_RGB32F, GL_RGB, GL_FLOAT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, RG32F_2D) +{ + GLfloat data[] = { 0.9f, 0.1f }; + init2DTexture(GL_RG32F, GL_RG, GL_FLOAT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, R32F_2D) +{ + GLfloat data[] = { 0.5f }; + init2DTexture(GL_R32F, GL_RED, GL_FLOAT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, D32F_2D) +{ + GLfloat data[] = { 0.5f }; + init2DTexture(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, D16_2D) +{ + GLushort data[] = { 0xFF }; + init2DTexture(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, D24_2D) +{ + GLuint data[] = { 0xFFFF }; + init2DTexture(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, L8_2D) +{ + GLubyte data[] = {0x77}; + init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +TEST_P(SwizzleTest, A8_2D) +{ + GLubyte data[] = {0x55}; + init2DTexture(GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +TEST_P(SwizzleTest, LA8_2D) +{ + GLubyte data[] = {0x77, 0x66}; + init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +TEST_P(SwizzleTest, L32F_2D) +{ + GLfloat data[] = {0.7f}; + init2DTexture(GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, A32F_2D) +{ + GLfloat data[] = { + 0.4f, + }; + init2DTexture(GL_ALPHA, GL_ALPHA, GL_FLOAT, data); + runTest2D(); +} + +TEST_P(SwizzleTest, LA32F_2D) +{ + GLfloat data[] = { + 0.5f, 0.6f, + }; + init2DTexture(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT, data); + runTest2D(); +} + +#include "media/pixel.inl" + +TEST_P(SwizzleTest, CompressedDXT_2D) +{ + if (!extensionEnabled("GL_EXT_texture_compression_dxt1")) + { + std::cout << "Test skipped due to missing GL_EXT_texture_compression_dxt1." << std::endl; + return; + } + + init2DCompressedTexture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width, pixel_0_height, pixel_0_size, pixel_0_data); + runTest2D(); +} + +TEST_P(SwizzleIntegerTest, RGB8UI_2D) +{ + GLubyte data[] = {77, 66, 55}; + init2DTexture(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, data); + runTest2D(); +} + +// Test that updating the texture data still generates the correct swizzles +TEST_P(SwizzleTest, SubUpdate) +{ + GLColor data(1, 64, 128, 200); + init2DTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, &data); + + glUseProgram(mProgram); + glBindTexture(GL_TEXTURE_2D, mTexture); + glUniform1i(mTextureUniformLocation, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 0.5f); + + GLColor expectedData(data.R, data.R, data.R, data.R); + EXPECT_PIXEL_COLOR_EQ(0, 0, expectedData); + + GLColor updateData(32, 234, 28, 232); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &updateData); + + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 0.5f); + + GLColor expectedUpdateData(updateData.R, updateData.R, updateData.R, updateData.R); + EXPECT_PIXEL_COLOR_EQ(0, 0, expectedUpdateData); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(SwizzleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGL(3, 3), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SwizzleIntegerTest, + ES3_D3D11(), + ES3_OPENGL(), + ES3_OPENGL(3, 3), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/SyncQueriesTest.cpp b/gfx/angle/src/tests/gl_tests/SyncQueriesTest.cpp new file mode 100755 index 000000000..b36311254 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/SyncQueriesTest.cpp @@ -0,0 +1,108 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SyncQueriesTest.cpp: Tests of the GL_CHROMIUM_sync_query extension + +#include "test_utils/ANGLETest.h" + +namespace angle +{ + +class SyncQueriesTest : public ANGLETest +{ + protected: + SyncQueriesTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + void TearDown() override + { + if (mQuery != 0) + { + glDeleteQueriesEXT(1, &mQuery); + mQuery = 0; + } + + ANGLETest::TearDown(); + } + + GLuint mQuery = 0; +}; + +// Test basic usage of sync queries +TEST_P(SyncQueriesTest, Basic) +{ + if (!extensionEnabled("GL_CHROMIUM_sync_query")) + { + std::cout << "Test skipped because GL_CHROMIUM_sync_query is not available." << std::endl; + return; + } + + glGenQueriesEXT(1, &mQuery); + glBeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, mQuery); + EXPECT_GL_NO_ERROR(); + + glClearColor(0.0, 0.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glEndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM); + + glFlush(); + GLuint result = 0; + glGetQueryObjectuivEXT(mQuery, GL_QUERY_RESULT_EXT, &result); + EXPECT_EQ(static_cast<GLuint>(GL_TRUE), result); + EXPECT_GL_NO_ERROR(); +} + +// Test that the sync query enums are not accepted unless the extension is available +TEST_P(SyncQueriesTest, Validation) +{ + // Need the GL_EXT_occlusion_query_boolean extension for the entry points + if (!extensionEnabled("GL_EXT_occlusion_query_boolean")) + { + std::cout << "Test skipped because GL_EXT_occlusion_query_boolean is not available." + << std::endl; + return; + } + + bool extensionAvailable = extensionEnabled("GL_CHROMIUM_sync_query"); + + glGenQueriesEXT(1, &mQuery); + + glBeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, mQuery); + if (extensionAvailable) + { + EXPECT_GL_NO_ERROR(); + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } + + glDeleteQueriesEXT(1, &mQuery); + + EXPECT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(SyncQueriesTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace angle diff --git a/gfx/angle/src/tests/gl_tests/TextureTest.cpp b/gfx/angle/src/tests/gl_tests/TextureTest.cpp new file mode 100755 index 000000000..ee2fc7ca9 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/TextureTest.cpp @@ -0,0 +1,3772 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "common/mathutil.h" +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +using namespace angle; + +namespace +{ + +// Take a pixel, and reset the components not covered by the format to default +// values. In particular, the default value for the alpha component is 255 +// (1.0 as unsigned normalized fixed point value). +GLColor SliceFormatColor(GLenum format, GLColor full) +{ + switch (format) + { + case GL_RED: + return GLColor(full.R, 0, 0, 255u); + case GL_RG: + return GLColor(full.R, full.G, 0, 255u); + case GL_RGB: + return GLColor(full.R, full.G, full.B, 255u); + case GL_RGBA: + return full; + default: + UNREACHABLE(); + return GLColor::white; + } +} + +class TexCoordDrawTest : public ANGLETest +{ + protected: + TexCoordDrawTest() : ANGLETest(), mProgram(0), mFramebuffer(0), mFramebufferColorTexture(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + virtual std::string getVertexShaderSource() + { + return std::string(SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + void main() + { + gl_Position = vec4(position.xy, 0.0, 1.0); + texcoord = (position.xy * 0.5) + 0.5; + } + ) + ); + } + + virtual std::string getFragmentShaderSource() = 0; + + virtual void setUpProgram() + { + const std::string vertexShaderSource = getVertexShaderSource(); + const std::string fragmentShaderSource = getFragmentShaderSource(); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, mProgram); + ASSERT_GL_NO_ERROR(); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + setUpFramebuffer(); + } + + void TearDown() override + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &mFramebuffer); + glDeleteTextures(1, &mFramebufferColorTexture); + glDeleteProgram(mProgram); + ANGLETest::TearDown(); + } + + void setUpFramebuffer() + { + // We use an FBO to work around an issue where the default framebuffer applies SRGB + // conversion (particularly known to happen incorrectly on Intel GL drivers). It's not + // clear whether this issue can even be fixed on all backends. For example GLES 3.0.4 spec + // section 4.4 says that the format of the default framebuffer is entirely up to the window + // system, so it might be SRGB, and GLES 3.0 doesn't have a "FRAMEBUFFER_SRGB" to turn off + // SRGB conversion like desktop GL does. + // TODO(oetuaho): Get rid of this if the underlying issue is fixed. + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glGenTextures(1, &mFramebufferColorTexture); + glBindTexture(GL_TEXTURE_2D, mFramebufferColorTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + mFramebufferColorTexture, 0); + ASSERT_GL_NO_ERROR(); + ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + glBindTexture(GL_TEXTURE_2D, 0); + } + + // Returns the created texture ID. + GLuint create2DTexture() + { + GLuint texture2D; + glGenTextures(1, &texture2D); + glBindTexture(GL_TEXTURE_2D, texture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + EXPECT_GL_NO_ERROR(); + return texture2D; + } + + GLuint mProgram; + GLuint mFramebuffer; + + private: + GLuint mFramebufferColorTexture; +}; + +class Texture2DTest : public TexCoordDrawTest +{ + protected: + Texture2DTest() : TexCoordDrawTest(), mTexture2D(0), mTexture2DUniformLocation(-1) {} + + std::string getFragmentShaderSource() override + { + return std::string(SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex, texcoord); + } + ) + ); + } + + virtual const char *getTextureUniformName() { return "tex"; } + + void setUpProgram() override + { + TexCoordDrawTest::setUpProgram(); + mTexture2DUniformLocation = glGetUniformLocation(mProgram, getTextureUniformName()); + ASSERT_NE(-1, mTexture2DUniformLocation); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + mTexture2D = create2DTexture(); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteTextures(1, &mTexture2D); + TexCoordDrawTest::TearDown(); + } + + // Tests CopyTexSubImage with floating point textures of various formats. + void testFloatCopySubImage(int sourceImageChannels, int destImageChannels) + { + // TODO(jmadill): Figure out why this is broken on Intel D3D11 + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel D3D11." << std::endl; + return; + } + + setUpProgram(); + + if (getClientMajorVersion() < 3) + { + if (!extensionEnabled("GL_OES_texture_float")) + { + std::cout << "Test skipped due to missing GL_OES_texture_float." << std::endl; + return; + } + + if ((sourceImageChannels < 3 || destImageChannels < 3) && !extensionEnabled("GL_EXT_texture_rg")) + { + std::cout << "Test skipped due to missing GL_EXT_texture_rg." << std::endl; + return; + } + } + + GLfloat sourceImageData[4][16] = + { + { // R + 1.0f, + 0.0f, + 0.0f, + 1.0f + }, + { // RG + 1.0f, 0.0f, + 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f + }, + { // RGB + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f + }, + { // RGBA + 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 1.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f + }, + }; + + GLenum imageFormats[] = + { + GL_R32F, + GL_RG32F, + GL_RGB32F, + GL_RGBA32F, + }; + + GLenum sourceUnsizedFormats[] = + { + GL_RED, + GL_RG, + GL_RGB, + GL_RGBA, + }; + + GLuint textures[2]; + + glGenTextures(2, textures); + + GLfloat *imageData = sourceImageData[sourceImageChannels - 1]; + GLenum sourceImageFormat = imageFormats[sourceImageChannels - 1]; + GLenum sourceUnsizedFormat = sourceUnsizedFormats[sourceImageChannels - 1]; + GLenum destImageFormat = imageFormats[destImageChannels - 1]; + + glBindTexture(GL_TEXTURE_2D, textures[0]); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, sourceImageFormat, 2, 2); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, sourceUnsizedFormat, GL_FLOAT, imageData); + + if (sourceImageChannels < 3 && !extensionEnabled("GL_EXT_texture_rg")) + { + // This is not supported + ASSERT_GL_ERROR(GL_INVALID_OPERATION); + } + else + { + ASSERT_GL_NO_ERROR(); + } + + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0); + + glBindTexture(GL_TEXTURE_2D, textures[1]); + glTexStorage2DEXT(GL_TEXTURE_2D, 1, destImageFormat, 2, 2); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2, 2); + ASSERT_GL_NO_ERROR(); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + drawQuad(mProgram, "position", 0.5f); + + int testImageChannels = std::min(sourceImageChannels, destImageChannels); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + if (testImageChannels > 1) + { + EXPECT_PIXEL_EQ(getWindowHeight() - 1, 0, 0, 255, 0, 255); + EXPECT_PIXEL_EQ(getWindowHeight() - 1, getWindowWidth() - 1, 255, 255, 0, 255); + if (testImageChannels > 2) + { + EXPECT_PIXEL_EQ(0, getWindowWidth() - 1, 0, 0, 255, 255); + } + } + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(2, textures); + + ASSERT_GL_NO_ERROR(); + } + + GLuint mTexture2D; + GLint mTexture2DUniformLocation; +}; + +class Texture2DTestES3 : public Texture2DTest +{ + protected: + Texture2DTestES3() : Texture2DTest() {} + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "out vec2 texcoord;\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp sampler2D tex;\n" + "in vec2 texcoord;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " fragColor = texture(tex, texcoord);\n" + "}\n"); + } + + void SetUp() override + { + Texture2DTest::SetUp(); + setUpProgram(); + } +}; + +class Texture2DIntegerAlpha1TestES3 : public Texture2DTest +{ + protected: + Texture2DIntegerAlpha1TestES3() : Texture2DTest() {} + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "out vec2 texcoord;\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp isampler2D tex;\n" + "in vec2 texcoord;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " vec4 green = vec4(0, 1, 0, 1);\n" + " vec4 black = vec4(0, 0, 0, 0);\n" + " fragColor = (texture(tex, texcoord).a == 1) ? green : black;\n" + "}\n"); + } + + void SetUp() override + { + Texture2DTest::SetUp(); + setUpProgram(); + } +}; + +class Texture2DUnsignedIntegerAlpha1TestES3 : public Texture2DTest +{ + protected: + Texture2DUnsignedIntegerAlpha1TestES3() : Texture2DTest() {} + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "out vec2 texcoord;\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp usampler2D tex;\n" + "in vec2 texcoord;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " vec4 green = vec4(0, 1, 0, 1);\n" + " vec4 black = vec4(0, 0, 0, 0);\n" + " fragColor = (texture(tex, texcoord).a == 1u) ? green : black;\n" + "}\n"); + } + + void SetUp() override + { + Texture2DTest::SetUp(); + setUpProgram(); + } +}; + +class Texture2DTestWithDrawScale : public Texture2DTest +{ + protected: + Texture2DTestWithDrawScale() : Texture2DTest(), mDrawScaleUniformLocation(-1) {} + + std::string getVertexShaderSource() override + { + return std::string(SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + varying vec2 texcoord; + + uniform vec2 drawScale; + + void main() + { + gl_Position = vec4(position.xy * drawScale, 0.0, 1.0); + texcoord = (position.xy * 0.5) + 0.5; + } + ) + ); + } + + void SetUp() override + { + Texture2DTest::SetUp(); + + setUpProgram(); + + mDrawScaleUniformLocation = glGetUniformLocation(mProgram, "drawScale"); + ASSERT_NE(-1, mDrawScaleUniformLocation); + + glUseProgram(mProgram); + glUniform2f(mDrawScaleUniformLocation, 1.0f, 1.0f); + glUseProgram(0); + ASSERT_GL_NO_ERROR(); + } + + GLint mDrawScaleUniformLocation; +}; + +class Sampler2DAsFunctionParameterTest : public Texture2DTest +{ + protected: + Sampler2DAsFunctionParameterTest() : Texture2DTest() {} + + std::string getFragmentShaderSource() override + { + return std::string(SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex; + varying vec2 texcoord; + + vec4 computeFragColor(sampler2D aTex) + { + return texture2D(aTex, texcoord); + } + + void main() + { + gl_FragColor = computeFragColor(tex); + } + ) + ); + } + + void SetUp() override + { + Texture2DTest::SetUp(); + setUpProgram(); + } +}; + +class TextureCubeTest : public TexCoordDrawTest +{ + protected: + TextureCubeTest() + : TexCoordDrawTest(), + mTexture2D(0), + mTextureCube(0), + mTexture2DUniformLocation(-1), + mTextureCubeUniformLocation(-1) + { + } + + std::string getFragmentShaderSource() override + { + return std::string(SHADER_SOURCE + ( + precision highp float; + uniform sampler2D tex2D; + uniform samplerCube texCube; + varying vec2 texcoord; + + void main() + { + gl_FragColor = texture2D(tex2D, texcoord); + gl_FragColor += textureCube(texCube, vec3(texcoord, 0)); + } + ) + ); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + + glGenTextures(1, &mTextureCube); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1); + EXPECT_GL_NO_ERROR(); + + mTexture2D = create2DTexture(); + + setUpProgram(); + + mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D"); + ASSERT_NE(-1, mTexture2DUniformLocation); + mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube"); + ASSERT_NE(-1, mTextureCubeUniformLocation); + } + + void TearDown() override + { + glDeleteTextures(1, &mTextureCube); + TexCoordDrawTest::TearDown(); + } + + GLuint mTexture2D; + GLuint mTextureCube; + GLint mTexture2DUniformLocation; + GLint mTextureCubeUniformLocation; +}; + +class SamplerArrayTest : public TexCoordDrawTest +{ + protected: + SamplerArrayTest() + : TexCoordDrawTest(), + mTexture2DA(0), + mTexture2DB(0), + mTexture0UniformLocation(-1), + mTexture1UniformLocation(-1) + { + } + + std::string getFragmentShaderSource() override + { + return std::string(SHADER_SOURCE + ( + precision mediump float; + uniform highp sampler2D tex2DArray[2]; + varying vec2 texcoord; + void main() + { + gl_FragColor = texture2D(tex2DArray[0], texcoord); + gl_FragColor += texture2D(tex2DArray[1], texcoord); + } + ) + ); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + + setUpProgram(); + + mTexture0UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[0]"); + ASSERT_NE(-1, mTexture0UniformLocation); + mTexture1UniformLocation = glGetUniformLocation(mProgram, "tex2DArray[1]"); + ASSERT_NE(-1, mTexture1UniformLocation); + + mTexture2DA = create2DTexture(); + mTexture2DB = create2DTexture(); + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteTextures(1, &mTexture2DA); + glDeleteTextures(1, &mTexture2DB); + TexCoordDrawTest::TearDown(); + } + + void testSamplerArrayDraw() + { + GLubyte texData[4]; + texData[0] = 0; + texData[1] = 60; + texData[2] = 0; + texData[3] = 255; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2DA); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData); + + texData[1] = 120; + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, mTexture2DB); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData); + EXPECT_GL_ERROR(GL_NO_ERROR); + + glUseProgram(mProgram); + glUniform1i(mTexture0UniformLocation, 0); + glUniform1i(mTexture1UniformLocation, 1); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + EXPECT_PIXEL_NEAR(0, 0, 0, 180, 0, 255, 2); + } + + GLuint mTexture2DA; + GLuint mTexture2DB; + GLint mTexture0UniformLocation; + GLint mTexture1UniformLocation; +}; + + +class SamplerArrayAsFunctionParameterTest : public SamplerArrayTest +{ + protected: + SamplerArrayAsFunctionParameterTest() : SamplerArrayTest() {} + + std::string getFragmentShaderSource() override + { + return std::string(SHADER_SOURCE + ( + precision mediump float; + uniform highp sampler2D tex2DArray[2]; + varying vec2 texcoord; + + vec4 computeFragColor(highp sampler2D aTex2DArray[2]) + { + return texture2D(aTex2DArray[0], texcoord) + texture2D(aTex2DArray[1], texcoord); + } + + void main() + { + gl_FragColor = computeFragColor(tex2DArray); + } + ) + ); + } +}; + +class Texture2DArrayTestES3 : public TexCoordDrawTest +{ + protected: + Texture2DArrayTestES3() : TexCoordDrawTest(), m2DArrayTexture(0), mTextureArrayLocation(-1) {} + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "out vec2 texcoord;\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp sampler2DArray tex2DArray;\n" + "in vec2 texcoord;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " fragColor = texture(tex2DArray, vec3(texcoord.x, texcoord.y, 0.0));\n" + "}\n"); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + + setUpProgram(); + + mTextureArrayLocation = glGetUniformLocation(mProgram, "tex2DArray"); + ASSERT_NE(-1, mTextureArrayLocation); + + glGenTextures(1, &m2DArrayTexture); + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteTextures(1, &m2DArrayTexture); + TexCoordDrawTest::TearDown(); + } + + GLuint m2DArrayTexture; + GLint mTextureArrayLocation; +}; + +class TextureSizeTextureArrayTest : public TexCoordDrawTest +{ + protected: + TextureSizeTextureArrayTest() + : TexCoordDrawTest(), + mTexture2DA(0), + mTexture2DB(0), + mTexture0Location(-1), + mTexture1Location(-1) + { + } + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp sampler2D tex2DArray[2];\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " float red = float(textureSize(tex2DArray[0], 0).x) / 255.0;\n" + " float green = float(textureSize(tex2DArray[1], 0).x) / 255.0;\n" + " fragColor = vec4(red, green, 0.0, 1.0);\n" + "}\n"); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + + setUpProgram(); + + mTexture0Location = glGetUniformLocation(mProgram, "tex2DArray[0]"); + ASSERT_NE(-1, mTexture0Location); + mTexture1Location = glGetUniformLocation(mProgram, "tex2DArray[1]"); + ASSERT_NE(-1, mTexture1Location); + + mTexture2DA = create2DTexture(); + mTexture2DB = create2DTexture(); + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteTextures(1, &mTexture2DA); + glDeleteTextures(1, &mTexture2DB); + TexCoordDrawTest::TearDown(); + } + + GLuint mTexture2DA; + GLuint mTexture2DB; + GLint mTexture0Location; + GLint mTexture1Location; +}; + +class Texture3DTestES3 : public TexCoordDrawTest +{ + protected: + Texture3DTestES3() : TexCoordDrawTest(), mTexture3D(0), mTexture3DUniformLocation(-1) {} + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "out vec2 texcoord;\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp sampler3D tex3D;\n" + "in vec2 texcoord;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " fragColor = texture(tex3D, vec3(texcoord, 0.0));\n" + "}\n"); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + + glGenTextures(1, &mTexture3D); + + setUpProgram(); + + mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D"); + ASSERT_NE(-1, mTexture3DUniformLocation); + } + + void TearDown() override + { + glDeleteTextures(1, &mTexture3D); + TexCoordDrawTest::TearDown(); + } + + GLuint mTexture3D; + GLint mTexture3DUniformLocation; +}; + +class ShadowSamplerPlusSampler3DTestES3 : public TexCoordDrawTest +{ + protected: + ShadowSamplerPlusSampler3DTestES3() + : TexCoordDrawTest(), + mTextureShadow(0), + mTexture3D(0), + mTextureShadowUniformLocation(-1), + mTexture3DUniformLocation(-1), + mDepthRefUniformLocation(-1) + { + } + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "out vec2 texcoord;\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp sampler2DShadow tex2DShadow;\n" + "uniform highp sampler3D tex3D;\n" + "in vec2 texcoord;\n" + "uniform float depthRef;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " fragColor = vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.5);\n" + " fragColor += texture(tex3D, vec3(texcoord, 0.0));\n" + "}\n"); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + + glGenTextures(1, &mTexture3D); + + glGenTextures(1, &mTextureShadow); + glBindTexture(GL_TEXTURE_2D, mTextureShadow); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + + setUpProgram(); + + mTextureShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow"); + ASSERT_NE(-1, mTextureShadowUniformLocation); + mTexture3DUniformLocation = glGetUniformLocation(mProgram, "tex3D"); + ASSERT_NE(-1, mTexture3DUniformLocation); + mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef"); + ASSERT_NE(-1, mDepthRefUniformLocation); + } + + void TearDown() override + { + glDeleteTextures(1, &mTextureShadow); + glDeleteTextures(1, &mTexture3D); + TexCoordDrawTest::TearDown(); + } + + GLuint mTextureShadow; + GLuint mTexture3D; + GLint mTextureShadowUniformLocation; + GLint mTexture3DUniformLocation; + GLint mDepthRefUniformLocation; +}; + +class SamplerTypeMixTestES3 : public TexCoordDrawTest +{ + protected: + SamplerTypeMixTestES3() + : TexCoordDrawTest(), + mTexture2D(0), + mTextureCube(0), + mTexture2DShadow(0), + mTextureCubeShadow(0), + mTexture2DUniformLocation(-1), + mTextureCubeUniformLocation(-1), + mTexture2DShadowUniformLocation(-1), + mTextureCubeShadowUniformLocation(-1), + mDepthRefUniformLocation(-1) + { + } + + std::string getVertexShaderSource() override + { + return std::string( + "#version 300 es\n" + "out vec2 texcoord;\n" + "in vec4 position;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.xy, 0.0, 1.0);\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + "}\n"); + } + + std::string getFragmentShaderSource() override + { + return std::string( + "#version 300 es\n" + "precision highp float;\n" + "uniform highp sampler2D tex2D;\n" + "uniform highp samplerCube texCube;\n" + "uniform highp sampler2DShadow tex2DShadow;\n" + "uniform highp samplerCubeShadow texCubeShadow;\n" + "in vec2 texcoord;\n" + "uniform float depthRef;\n" + "out vec4 fragColor;\n" + "void main()\n" + "{\n" + " fragColor = texture(tex2D, texcoord);\n" + " fragColor += texture(texCube, vec3(1.0, 0.0, 0.0));\n" + " fragColor += vec4(texture(tex2DShadow, vec3(texcoord, depthRef)) * 0.25);\n" + " fragColor += vec4(texture(texCubeShadow, vec4(1.0, 0.0, 0.0, depthRef)) * " + "0.125);\n" + "}\n"); + } + + void SetUp() override + { + TexCoordDrawTest::SetUp(); + + glGenTextures(1, &mTexture2D); + glGenTextures(1, &mTextureCube); + + glGenTextures(1, &mTexture2DShadow); + glBindTexture(GL_TEXTURE_2D, mTexture2DShadow); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + + glGenTextures(1, &mTextureCubeShadow); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + + setUpProgram(); + + mTexture2DUniformLocation = glGetUniformLocation(mProgram, "tex2D"); + ASSERT_NE(-1, mTexture2DUniformLocation); + mTextureCubeUniformLocation = glGetUniformLocation(mProgram, "texCube"); + ASSERT_NE(-1, mTextureCubeUniformLocation); + mTexture2DShadowUniformLocation = glGetUniformLocation(mProgram, "tex2DShadow"); + ASSERT_NE(-1, mTexture2DShadowUniformLocation); + mTextureCubeShadowUniformLocation = glGetUniformLocation(mProgram, "texCubeShadow"); + ASSERT_NE(-1, mTextureCubeShadowUniformLocation); + mDepthRefUniformLocation = glGetUniformLocation(mProgram, "depthRef"); + ASSERT_NE(-1, mDepthRefUniformLocation); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteTextures(1, &mTexture2D); + glDeleteTextures(1, &mTextureCube); + glDeleteTextures(1, &mTexture2DShadow); + glDeleteTextures(1, &mTextureCubeShadow); + TexCoordDrawTest::TearDown(); + } + + GLuint mTexture2D; + GLuint mTextureCube; + GLuint mTexture2DShadow; + GLuint mTextureCubeShadow; + GLint mTexture2DUniformLocation; + GLint mTextureCubeUniformLocation; + GLint mTexture2DShadowUniformLocation; + GLint mTextureCubeShadowUniformLocation; + GLint mDepthRefUniformLocation; +}; + +class SamplerInStructTest : public Texture2DTest +{ + protected: + SamplerInStructTest() : Texture2DTest() {} + + const char *getTextureUniformName() override { return "us.tex"; } + + std::string getFragmentShaderSource() override + { + return std::string( + "precision highp float;\n" + "struct S\n" + "{\n" + " vec4 a;\n" + " highp sampler2D tex;\n" + "};\n" + "uniform S us;\n" + "varying vec2 texcoord;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(us.tex, texcoord + us.a.x);\n" + "}\n"); + } + + void runSamplerInStructTest() + { + setUpProgram(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + &GLColor::green); + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + } +}; + +class SamplerInStructAsFunctionParameterTest : public SamplerInStructTest +{ + protected: + SamplerInStructAsFunctionParameterTest() : SamplerInStructTest() {} + + std::string getFragmentShaderSource() override + { + return std::string( + "precision highp float;\n" + "struct S\n" + "{\n" + " vec4 a;\n" + " highp sampler2D tex;\n" + "};\n" + "uniform S us;\n" + "varying vec2 texcoord;\n" + "vec4 sampleFrom(S s) {\n" + " return texture2D(s.tex, texcoord + s.a.x);\n" + "}\n" + "void main()\n" + "{\n" + " gl_FragColor = sampleFrom(us);\n" + "}\n"); + } +}; + +class SamplerInStructArrayAsFunctionParameterTest : public SamplerInStructTest +{ + protected: + SamplerInStructArrayAsFunctionParameterTest() : SamplerInStructTest() {} + + const char *getTextureUniformName() override { return "us[0].tex"; } + + std::string getFragmentShaderSource() override + { + return std::string( + "precision highp float;\n" + "struct S\n" + "{\n" + " vec4 a;\n" + " highp sampler2D tex;\n" + "};\n" + "uniform S us[1];\n" + "varying vec2 texcoord;\n" + "vec4 sampleFrom(S s) {\n" + " return texture2D(s.tex, texcoord + s.a.x);\n" + "}\n" + "void main()\n" + "{\n" + " gl_FragColor = sampleFrom(us[0]);\n" + "}\n"); + } +}; + +class SamplerInNestedStructAsFunctionParameterTest : public SamplerInStructTest +{ + protected: + SamplerInNestedStructAsFunctionParameterTest() : SamplerInStructTest() {} + + const char *getTextureUniformName() override { return "us[0].sub.tex"; } + + std::string getFragmentShaderSource() override + { + return std::string( + "precision highp float;\n" + "struct SUB\n" + "{\n" + " vec4 a;\n" + " highp sampler2D tex;\n" + "};\n" + "struct S\n" + "{\n" + " SUB sub;\n" + "};\n" + "uniform S us[1];\n" + "varying vec2 texcoord;\n" + "vec4 sampleFrom(SUB s) {\n" + " return texture2D(s.tex, texcoord + s.a.x);\n" + "}\n" + "void main()\n" + "{\n" + " gl_FragColor = sampleFrom(us[0].sub);\n" + "}\n"); + } +}; + +class SamplerInStructAndOtherVariableTest : public SamplerInStructTest +{ + protected: + SamplerInStructAndOtherVariableTest() : SamplerInStructTest() {} + + std::string getFragmentShaderSource() override + { + return std::string( + "precision highp float;\n" + "struct S\n" + "{\n" + " vec4 a;\n" + " highp sampler2D tex;\n" + "};\n" + "uniform S us;\n" + "uniform float us_tex;\n" + "varying vec2 texcoord;\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(us.tex, texcoord + us.a.x + us_tex);\n" + "}\n"); + } +}; + +TEST_P(Texture2DTest, NegativeAPISubImage) +{ + glBindTexture(GL_TEXTURE_2D, mTexture2D); + EXPECT_GL_ERROR(GL_NO_ERROR); + + setUpProgram(); + + const GLubyte *pixels[20] = { 0 }; + glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + if (extensionEnabled("GL_EXT_texture_storage")) + { + // Create a 1-level immutable texture. + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2); + + // Try calling sub image on the second level. + glTexSubImage2D(GL_TEXTURE_2D, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + } +} + +// Test that querying GL_TEXTURE_BINDING* doesn't cause an unexpected error. +TEST_P(Texture2DTest, QueryBinding) +{ + glBindTexture(GL_TEXTURE_2D, 0); + EXPECT_GL_ERROR(GL_NO_ERROR); + + GLint textureBinding; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(0, textureBinding); + + glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &textureBinding); + if (extensionEnabled("GL_OES_EGL_image_external") || + extensionEnabled("GL_NV_EGL_stream_consumer_external")) + { + EXPECT_GL_NO_ERROR(); + EXPECT_EQ(0, textureBinding); + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } +} + +TEST_P(Texture2DTest, ZeroSizedUploads) +{ + glBindTexture(GL_TEXTURE_2D, mTexture2D); + EXPECT_GL_ERROR(GL_NO_ERROR); + + setUpProgram(); + + // Use the texture first to make sure it's in video memory + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + drawQuad(mProgram, "position", 0.5f); + + const GLubyte *pixel[4] = { 0 }; + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel); + EXPECT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); + EXPECT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel); + EXPECT_GL_NO_ERROR(); +} + +// Test drawing with two texture types, to trigger an ANGLE bug in validation +TEST_P(TextureCubeTest, CubeMapBug) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + EXPECT_GL_ERROR(GL_NO_ERROR); + + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + glUniform1i(mTextureCubeUniformLocation, 1); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); +} + +// Test drawing with two texture types accessed from the same shader and check that the result of +// drawing is correct. +TEST_P(TextureCubeTest, CubeMapDraw) +{ + GLubyte texData[4]; + texData[0] = 0; + texData[1] = 60; + texData[2] = 0; + texData[3] = 255; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + texData[1] = 120; + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + texData); + EXPECT_GL_ERROR(GL_NO_ERROR); + + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + glUniform1i(mTextureCubeUniformLocation, 1); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + int px = getWindowWidth() - 1; + int py = 0; + EXPECT_PIXEL_NEAR(px, py, 0, 180, 0, 255, 2); +} + +TEST_P(Sampler2DAsFunctionParameterTest, Sampler2DAsFunctionParameter) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + GLubyte texData[4]; + texData[0] = 0; + texData[1] = 128; + texData[2] = 0; + texData[3] = 255; + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texData); + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + + EXPECT_PIXEL_NEAR(0, 0, 0, 128, 0, 255, 2); +} + +// Test drawing with two textures passed to the shader in a sampler array. +TEST_P(SamplerArrayTest, SamplerArrayDraw) +{ + testSamplerArrayDraw(); +} + +// Test drawing with two textures passed to the shader in a sampler array which is passed to a +// user-defined function in the shader. +TEST_P(SamplerArrayAsFunctionParameterTest, SamplerArrayAsFunctionParameter) +{ + testSamplerArrayDraw(); +} + +// Copy of a test in conformance/textures/texture-mips, to test generate mipmaps +TEST_P(Texture2DTestWithDrawScale, MipmapsTwice) +{ + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + std::vector<GLColor> pixelsRed(16u * 16u, GLColor::red); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelsRed.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + glUniform2f(mDrawScaleUniformLocation, 0.0625f, 0.0625f); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::red); + + std::vector<GLColor> pixelsBlue(16u * 16u, GLColor::blue); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsBlue.data()); + glGenerateMipmap(GL_TEXTURE_2D); + + std::vector<GLColor> pixelsGreen(16u * 16u, GLColor::green); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsGreen.data()); + glGenerateMipmap(GL_TEXTURE_2D); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(px, py, GLColor::green); +} + +// Test creating a FBO with a cube map render target, to test an ANGLE bug +// https://code.google.com/p/angleproject/issues/detail?id=849 +TEST_P(TextureCubeTest, CubeMapFBO) +{ + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, mTextureCube, 0); + + EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); + + glDeleteFramebuffers(1, &fbo); + + EXPECT_GL_NO_ERROR(); +} + +// Test that glTexSubImage2D works properly when glTexStorage2DEXT has initialized the image with a default color. +TEST_P(Texture2DTest, TexStorage) +{ + int width = getWindowWidth(); + int height = getWindowHeight(); + + GLuint tex2D; + glGenTextures(1, &tex2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex2D); + + // Fill with red + std::vector<GLubyte> pixels(3 * 16 * 16); + for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId) + { + pixels[pixelId * 3 + 0] = 255; + pixels[pixelId * 3 + 1] = 0; + pixels[pixelId * 3 + 2] = 0; + } + + // ANGLE internally uses RGBA as the DirectX format for RGB images + // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color. + // The data is kept in a CPU-side image and the image is marked as dirty. + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16); + + // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched. + // glTexSubImage2D should take into account that the image is dirty. + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, pixels.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + setUpProgram(); + + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + drawQuad(mProgram, "position", 0.5f); + glDeleteTextures(1, &tex2D); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255); + + // Validate that the region of the texture without data has an alpha of 1.0 + GLubyte pixel[4]; + glReadPixels(3 * width / 4, 3 * height / 4, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); + EXPECT_EQ(pixel[3], 255); +} + +// Test that glTexSubImage2D combined with a PBO works properly when glTexStorage2DEXT has initialized the image with a default color. +TEST_P(Texture2DTest, TexStorageWithPBO) +{ + if (extensionEnabled("NV_pixel_buffer_object")) + { + int width = getWindowWidth(); + int height = getWindowHeight(); + + GLuint tex2D; + glGenTextures(1, &tex2D); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex2D); + + // Fill with red + std::vector<GLubyte> pixels(3 * 16 * 16); + for (size_t pixelId = 0; pixelId < 16 * 16; ++pixelId) + { + pixels[pixelId * 3 + 0] = 255; + pixels[pixelId * 3 + 1] = 0; + pixels[pixelId * 3 + 2] = 0; + } + + // Read 16x16 region from red backbuffer to PBO + GLuint pbo; + glGenBuffers(1, &pbo); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); + glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * 16 * 16, pixels.data(), GL_STATIC_DRAW); + + // ANGLE internally uses RGBA as the DirectX format for RGB images + // therefore glTexStorage2DEXT initializes the image to a default color to get a consistent alpha color. + // The data is kept in a CPU-side image and the image is marked as dirty. + glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB8, 16, 16); + + // Initializes the color of the upper-left 8x8 pixels, leaves the other pixels untouched. + // glTexSubImage2D should take into account that the image is dirty. + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGB, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + setUpProgram(); + + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + drawQuad(mProgram, "position", 0.5f); + glDeleteTextures(1, &tex2D); + glDeleteBuffers(1, &pbo); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(3 * width / 4, 3 * height / 4, 0, 0, 0, 255); + EXPECT_PIXEL_EQ(width / 4, height / 4, 255, 0, 0, 255); + } +} + +// See description on testFloatCopySubImage +TEST_P(Texture2DTest, CopySubImageFloat_R_R) +{ + testFloatCopySubImage(1, 1); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RG_R) +{ + testFloatCopySubImage(2, 1); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RG_RG) +{ + testFloatCopySubImage(2, 2); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RGB_R) +{ + if (IsIntel() && IsLinux()) + { + // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346) + std::cout << "Test disabled on Linux Intel OpenGL." << std::endl; + return; + } + + testFloatCopySubImage(3, 1); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RGB_RG) +{ + if (IsIntel() && IsLinux()) + { + // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346) + std::cout << "Test disabled on Linux Intel OpenGL." << std::endl; + return; + } + + testFloatCopySubImage(3, 2); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RGB_RGB) +{ + if (IsIntel() && IsLinux()) + { + // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346) + std::cout << "Test disabled on Linux Intel OpenGL." << std::endl; + return; + } + + // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3 + if (IsD3D11_FL93()) + { + std::cout << "Test skipped on Feature Level 9_3." << std::endl; + return; + } + + testFloatCopySubImage(3, 3); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RGBA_R) +{ + testFloatCopySubImage(4, 1); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RG) +{ + testFloatCopySubImage(4, 2); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGB) +{ + // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3 + if (IsD3D11_FL93()) + { + std::cout << "Test skipped on Feature Level 9_3." << std::endl; + return; + } + + testFloatCopySubImage(4, 3); +} + +TEST_P(Texture2DTest, CopySubImageFloat_RGBA_RGBA) +{ + // TODO (bug 1284): Investigate RGBA32f D3D SDK Layers messages on D3D11_FL9_3 + if (IsD3D11_FL93()) + { + std::cout << "Test skipped on Feature Level 9_3." << std::endl; + return; + } + + testFloatCopySubImage(4, 4); +} + +// Port of https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/textures/texture-npot.html +// Run against GL_ALPHA/UNSIGNED_BYTE format, to ensure that D3D11 Feature Level 9_3 correctly handles GL_ALPHA +TEST_P(Texture2DTest, TextureNPOT_GL_ALPHA_UBYTE) +{ + const int npotTexSize = 5; + const int potTexSize = 4; // Should be less than npotTexSize + GLuint tex2D; + + if (extensionEnabled("GL_OES_texture_npot")) + { + // This test isn't applicable if texture_npot is enabled + return; + } + + setUpProgram(); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + // Default unpack alignment is 4. The values of 'pixels' below needs it to be 1. + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &tex2D); + glBindTexture(GL_TEXTURE_2D, tex2D); + + std::vector<GLubyte> pixels(1 * npotTexSize * npotTexSize); + for (size_t pixelId = 0; pixelId < npotTexSize * npotTexSize; ++pixelId) + { + pixels[pixelId] = 64; + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // Check that an NPOT texture not on level 0 generates INVALID_VALUE + glTexImage2D(GL_TEXTURE_2D, 1, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data()); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + // Check that an NPOT texture on level 0 succeeds + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, npotTexSize, npotTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data()); + EXPECT_GL_NO_ERROR(); + + // Check that generateMipmap fails on NPOT + glGenerateMipmap(GL_TEXTURE_2D); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + // Check that nothing is drawn if filtering is not correct for NPOT + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 1.0f); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255); + + // NPOT texture with TEXTURE_MIN_FILTER not NEAREST or LINEAR should draw with 0,0,0,255 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 1.0f); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 255); + + // NPOT texture with TEXTURE_MIN_FILTER set to LINEAR should draw + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 1.0f); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64); + + // Check that glTexImage2D for POT texture succeeds + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, potTexSize, potTexSize, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels.data()); + EXPECT_GL_NO_ERROR(); + + // Check that generateMipmap for an POT texture succeeds + glGenerateMipmap(GL_TEXTURE_2D); + EXPECT_GL_NO_ERROR(); + + // POT texture with TEXTURE_MIN_FILTER set to LINEAR_MIPMAP_LINEAR should draw + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glClear(GL_COLOR_BUFFER_BIT); + drawQuad(mProgram, "position", 1.0f); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 64); + EXPECT_GL_NO_ERROR(); +} + +// Test to ensure that glTexSubImage2D always accepts data for non-power-of-two subregions. +// ANGLE previously rejected this if GL_OES_texture_npot wasn't active, which is incorrect. +TEST_P(Texture2DTest, NPOTSubImageParameters) +{ + // TODO(geofflang): Allow the GL backend to accept SubImage calls with a null data ptr. (bug + // 1278) + if (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE || + getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE) + { + std::cout << "Test disabled on OpenGL." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + // Create an 8x8 (i.e. power-of-two) texture. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glGenerateMipmap(GL_TEXTURE_2D); + + // Supply a 3x3 (i.e. non-power-of-two) subimage to the texture. + // This should always work, even if GL_OES_texture_npot isn't active. + glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + EXPECT_GL_NO_ERROR(); +} + +// Test to check that texture completeness is determined correctly when the texture base level is +// greater than 0, and also that level 0 is not sampled when base level is greater than 0. +TEST_P(Texture2DTestES3, DrawWithBaseLevel1) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + std::vector<GLColor> texDataRed(4u * 4u, GLColor::red); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data()); + std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not +// have images defined. +TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeUndefined) +{ + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array. + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that drawing works correctly when level 0 is undefined and base level is 1. +TEST_P(Texture2DTestES3, DrawWithLevelZeroUndefined) +{ + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Observed crashing on AMD. Oddly the crash only happens with 2D textures, not 3D or array. + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); + + EXPECT_GL_NO_ERROR(); + + // Texture is incomplete. + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); + + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + // Texture is now complete. + drawQuad(mProgram, "position", 0.5f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have +// dimensions that don't fit the images inside the range. +// GLES 3.0.4 section 3.8.13 Texture completeness +TEST_P(Texture2DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions) +{ + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + std::vector<GLColor> texDataRed(8u * 8u, GLColor::red); + std::vector<GLColor> texDataGreen(2u * 2u, GLColor::green); + std::vector<GLColor> texDataCyan(2u * 2u, GLColor::cyan); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + // Two levels that are initially unused. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, texDataRed.data()); + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataCyan.data()); + + // One level that is used - only this level should affect completeness. + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base + // level was changed. + std::cout << "Test partially skipped on Intel OpenGL." << std::endl; + return; + } + + // Switch the level that is being used to the cyan level 2. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan); +} + +// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not +// have images defined. +TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeUndefined) +{ + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_3D, mTexture3D); + std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green); + glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have +// dimensions that don't fit the images inside the range. +// GLES 3.0.4 section 3.8.13 Texture completeness +TEST_P(Texture3DTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions) +{ + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_3D, mTexture3D); + std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red); + std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green); + std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan); + + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + // Two levels that are initially unused. + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataRed.data()); + glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataCyan.data()); + + // One level that is used - only this level should affect completeness. + glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base + // level was changed. + std::cout << "Test partially skipped on Intel OpenGL." << std::endl; + return; + } + + // Switch the level that is being used to the cyan level 2. + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 2); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 2); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan); +} + +// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range do not +// have images defined. +TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeUndefined) +{ + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture); + std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that drawing works correctly when levels outside the BASE_LEVEL/MAX_LEVEL range have +// dimensions that don't fit the images inside the range. +// GLES 3.0.4 section 3.8.13 Texture completeness +TEST_P(Texture2DArrayTestES3, DrawWithLevelsOutsideRangeWithInconsistentDimensions) +{ + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_3D, m2DArrayTexture); + std::vector<GLColor> texDataRed(8u * 8u * 8u, GLColor::red); + std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green); + std::vector<GLColor> texDataCyan(2u * 2u * 2u, GLColor::cyan); + + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + // Two levels that are initially unused. + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataRed.data()); + glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataCyan.data()); + + // One level that is used - only this level should affect completeness. + glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Intel was observed drawing color 0,0,0,0 instead of the texture color after the base + // level was changed. + std::cout << "Test partially skipped on Intel OpenGL." << std::endl; + return; + } + if (IsNVIDIA() && (getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE || + getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) + { + // NVIDIA was observed drawing color 0,0,0,0 instead of the texture color after the base + // level was changed. + std::cout << "Test partially skipped on NVIDIA OpenGL." << std::endl; + return; + } + + // Switch the level that is being used to the cyan level 2. + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 2); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan); +} + +// Test that texture completeness is updated if texture max level changes. +// GLES 3.0.4 section 3.8.13 Texture completeness +TEST_P(Texture2DTestES3, TextureCompletenessChangesWithMaxLevel) +{ + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Intel was observed having wrong behavior after the texture is made incomplete by changing + // the base level. + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + // A level that is initially unused. + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + // One level that is initially used - only this level should affect completeness. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + // Switch the max level to level 1. The levels within the used range now have inconsistent + // dimensions and the texture should be incomplete. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); +} + +// Test that 3D texture completeness is updated if texture max level changes. +// GLES 3.0.4 section 3.8.13 Texture completeness +TEST_P(Texture3DTestES3, Texture3DCompletenessChangesWithMaxLevel) +{ + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Intel was observed having wrong behavior after the texture is made incomplete by changing + // the base level. + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + if (IsOSX()) + { + // Observed incorrect rendering on OSX. + std::cout << "Test skipped on OSX." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_3D, mTexture3D); + std::vector<GLColor> texDataGreen(2u * 2u * 2u, GLColor::green); + + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + // A level that is initially unused. + glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, 1, 1, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + // One level that is initially used - only this level should affect completeness. + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + // Switch the max level to level 1. The levels within the used range now have inconsistent + // dimensions and the texture should be incomplete. + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); +} + +// Test that texture completeness is updated if texture base level changes. +// GLES 3.0.4 section 3.8.13 Texture completeness +TEST_P(Texture2DTestES3, TextureCompletenessChangesWithBaseLevel) +{ + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Intel was observed having wrong behavior after the texture is made incomplete by changing + // the base level. + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + std::vector<GLColor> texDataGreen(8u * 8u, GLColor::green); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + // Two levels that are initially unused. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + // One level that is initially used - only this level should affect completeness. + glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataGreen.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + // Switch the base level to level 1. The levels within the used range now have inconsistent + // dimensions and the texture should be incomplete. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); +} + +// Test that texture is not complete if base level is greater than max level. +// GLES 3.0.4 section 3.8.13 Texture completeness +TEST_P(Texture2DTestES3, TextureBaseLevelGreaterThanMaxLevel) +{ + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + // Intel Windows OpenGL driver crashes if the base level of a non-immutable texture is out + // of range. + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + // Texture should be incomplete. + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black); +} + +// Test that immutable texture base level and max level are clamped. +// GLES 3.0.4 section 3.8.10 subsection Mipmapping +TEST_P(Texture2DTestES3, ImmutableTextureBaseLevelOutOfRange) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green); + + // For immutable-format textures, base level should be clamped to [0, levels - 1], and max level + // should be clamped to [base_level, levels - 1]. + // GLES 3.0.4 section 3.8.10 subsection Mipmapping + // In the case of this test, those rules make the effective base level and max level 0. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + // Texture should be complete. + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that changing base level works when it affects the format of the texture. +TEST_P(Texture2DTestES3, TextureFormatChangesWithBaseLevel) +{ + if (IsNVIDIA() && IsOpenGL()) + { + // Observed rendering corruption on NVIDIA OpenGL. + std::cout << "Test skipped on NVIDIA OpenGL." << std::endl; + return; + } + if (IsIntel() && IsDesktopOpenGL()) + { + // Observed incorrect rendering on Intel OpenGL. + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + if (IsAMD() && IsDesktopOpenGL()) + { + // Observed incorrect rendering on AMD OpenGL. + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + std::vector<GLColor> texDataCyan(4u * 4u, GLColor::cyan); + std::vector<GLColor> texDataGreen(4u * 4u, GLColor::green); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + // RGBA8 level that's initially unused. + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, + texDataCyan.data()); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + + // RG8 level that's initially used, with consistent dimensions with level 0 but a different + // format. It reads green channel data from the green and alpha channels of texDataGreen + // (this is a bit hacky but works). + glTexImage2D(GL_TEXTURE_2D, 1, GL_RG8, 2, 2, 0, GL_RG, GL_UNSIGNED_BYTE, texDataGreen.data()); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + // Switch the texture to use the cyan level 0 with the RGBA format. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan); +} + +// Test that setting a texture image works when base level is out of range. +TEST_P(Texture2DTestES3, SetImageWhenBaseLevelOutOfRange) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 10000); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10000); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green); + + EXPECT_GL_NO_ERROR(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + + drawQuad(mProgram, "position", 0.5f); + + // Texture should be complete. + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// In the D3D11 renderer, we need to initialize some texture formats, to fill empty channels. EG RBA->RGBA8, with 1.0 +// in the alpha channel. This test covers a bug where redefining array textures with these formats does not work as +// expected. +TEST_P(Texture2DArrayTestES3, RedefineInittableArray) +{ + std::vector<GLubyte> pixelData; + for (size_t count = 0; count < 5000; count++) + { + pixelData.push_back(0u); + pixelData.push_back(255u); + pixelData.push_back(0u); + } + + glBindTexture(GL_TEXTURE_2D_ARRAY, m2DArrayTexture); + glUseProgram(mProgram); + glUniform1i(mTextureArrayLocation, 0); + + // The first draw worked correctly. + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]); + + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); + drawQuad(mProgram, "position", 1.0f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + // The dimension of the respecification must match the original exactly to trigger the bug. + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, 4, 4, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixelData[0]); + drawQuad(mProgram, "position", 1.0f); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); + + ASSERT_GL_NO_ERROR(); +} + +// Test shadow sampler and regular non-shadow sampler coexisting in the same shader. +// This test is needed especially to confirm that sampler registers get assigned correctly on +// the HLSL backend even when there's a mix of different HLSL sampler and texture types. +TEST_P(ShadowSamplerPlusSampler3DTestES3, ShadowSamplerPlusSampler3DDraw) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_3D, mTexture3D); + GLubyte texData[4]; + texData[0] = 0; + texData[1] = 60; + texData[2] = 0; + texData[3] = 255; + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, mTextureShadow); + GLfloat depthTexData[1]; + depthTexData[0] = 0.5f; + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT, + depthTexData); + + glUseProgram(mProgram); + glUniform1f(mDepthRefUniformLocation, 0.3f); + glUniform1i(mTexture3DUniformLocation, 0); + glUniform1i(mTextureShadowUniformLocation, 1); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + // The shader writes 0.5 * <comparison result (1.0)> + <texture color> + EXPECT_PIXEL_NEAR(0, 0, 128, 188, 128, 255, 2); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + // The shader writes 0.5 * <comparison result (0.0)> + <texture color> + EXPECT_PIXEL_NEAR(0, 0, 0, 60, 0, 255, 2); +} + +// Test multiple different sampler types in the same shader. +// This test makes sure that even if sampler / texture registers get grouped together based on type +// or otherwise get shuffled around in the HLSL backend of the shader translator, the D3D renderer +// still has the right register index information for each ESSL sampler. +// The tested ESSL samplers have the following types in D3D11 HLSL: +// sampler2D: Texture2D + SamplerState +// samplerCube: TextureCube + SamplerState +// sampler2DShadow: Texture2D + SamplerComparisonState +// samplerCubeShadow: TextureCube + SamplerComparisonState +TEST_P(SamplerTypeMixTestES3, SamplerTypeMixDraw) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + GLubyte texData[4]; + texData[0] = 0; + texData[1] = 0; + texData[2] = 120; + texData[3] = 255; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); + texData[0] = 0; + texData[1] = 90; + texData[2] = 0; + texData[3] = 255; + glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1); + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, + texData); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, mTexture2DShadow); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + GLfloat depthTexData[1]; + depthTexData[0] = 0.5f; + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 1, 1, 0, GL_DEPTH_COMPONENT, GL_FLOAT, + depthTexData); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCubeShadow); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + depthTexData[0] = 0.2f; + glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, GL_DEPTH_COMPONENT32F, 1, 1); + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, + depthTexData); + + EXPECT_GL_NO_ERROR(); + + glUseProgram(mProgram); + glUniform1f(mDepthRefUniformLocation, 0.3f); + glUniform1i(mTexture2DUniformLocation, 0); + glUniform1i(mTextureCubeUniformLocation, 1); + glUniform1i(mTexture2DShadowUniformLocation, 2); + glUniform1i(mTextureCubeShadowUniformLocation, 3); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + // The shader writes: + // <texture 2d color> + + // <cube map color> + + // 0.25 * <comparison result (1.0)> + + // 0.125 * <comparison result (0.0)> + EXPECT_PIXEL_NEAR(0, 0, 64, 154, 184, 255, 2); +} + +// Test different base levels on textures accessed through the same sampler array. +// Calling textureSize() on the samplers hits the D3D sampler metadata workaround. +TEST_P(TextureSizeTextureArrayTest, BaseLevelVariesInTextureArray) +{ + if ((IsAMD() || IsIntel()) && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel and AMD D3D." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2DA); + GLsizei size = 64; + for (GLint level = 0; level < 7; ++level) + { + ASSERT_LT(0, size); + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + size = size / 2; + } + ASSERT_EQ(0, size); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, mTexture2DB); + size = 128; + for (GLint level = 0; level < 8; ++level) + { + ASSERT_LT(0, size); + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, + nullptr); + size = size / 2; + } + ASSERT_EQ(0, size); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 3); + EXPECT_GL_NO_ERROR(); + + glUseProgram(mProgram); + glUniform1i(mTexture0Location, 0); + glUniform1i(mTexture1Location, 1); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + // Red channel: width of level 1 of texture A: 32. + // Green channel: width of level 3 of texture B: 16. + EXPECT_PIXEL_NEAR(0, 0, 32, 16, 0, 255, 2); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureRGBImplicitAlpha1) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureLuminanceImplicitAlpha1) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureLuminance32ImplicitAlpha1) +{ + if (extensionEnabled("GL_OES_texture_float")) + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_FLOAT, nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); + } +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureLuminance16ImplicitAlpha1) +{ + if (extensionEnabled("GL_OES_texture_half_float")) + { + if (IsNVIDIA() && IsOpenGLES()) + { + std::cout << "Test skipped on NVIDIA" << std::endl; + return; + } + // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1420 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, + nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); + } +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB8UIImplicitAlpha1) +{ + if (IsIntel()) + { + std::cout << "Test disabled on Intel." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB8IImplicitAlpha1) +{ + if (IsIntel()) + { + std::cout << "Test disabled on Intel." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8I, 1, 1, 0, GL_RGB_INTEGER, GL_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB16UIImplicitAlpha1) +{ + if (IsIntel()) + { + std::cout << "Test disabled on Intel." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB16IImplicitAlpha1) +{ + if (IsIntel()) + { + std::cout << "Test disabled on Intel." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16I, 1, 1, 0, GL_RGB_INTEGER, GL_SHORT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DUnsignedIntegerAlpha1TestES3, TextureRGB32UIImplicitAlpha1) +{ + if (IsIntel()) + { + std::cout << "Test disabled on Intel." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DIntegerAlpha1TestES3, TextureRGB32IImplicitAlpha1) +{ + if (IsIntel()) + { + std::cout << "Test disabled on Intel." << std::endl; + return; + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32I, 1, 1, 0, GL_RGB_INTEGER, GL_INT, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureRGBSNORMImplicitAlpha1) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 1, 1, 0, GL_RGB, GL_BYTE, nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureRGB9E5ImplicitAlpha1) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB9_E5, 1, 1, 0, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, + nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureCOMPRESSEDRGB8ETC2ImplicitAlpha1) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 1, 1, 0, 8, nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// When sampling a texture without an alpha channel, "1" is returned as the alpha value. +// ES 3.0.4 table 3.24 +TEST_P(Texture2DTestES3, TextureCOMPRESSEDSRGB8ETC2ImplicitAlpha1) +{ + if (IsIntel() && IsLinux()) + { + // TODO(cwallez): Fix on Linux Intel drivers (http://anglebug.com/1346) + std::cout << "Test disabled on Linux Intel OpenGL." << std::endl; + return; + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB8_ETC2, 1, 1, 0, 8, nullptr); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_ALPHA_EQ(0, 0, 255); +} + +// Use a sampler in a uniform struct. +TEST_P(SamplerInStructTest, SamplerInStruct) +{ + runSamplerInStructTest(); +} + +// Use a sampler in a uniform struct that's passed as a function parameter. +TEST_P(SamplerInStructAsFunctionParameterTest, SamplerInStructAsFunctionParameter) +{ + // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + + if (IsWindows() && IsIntel() && IsOpenGL()) + { + std::cout << "Test skipped on Windows OpenGL on Intel." << std::endl; + return; + } + + runSamplerInStructTest(); +} + +// Use a sampler in a uniform struct array with a struct from the array passed as a function +// parameter. +TEST_P(SamplerInStructArrayAsFunctionParameterTest, SamplerInStructArrayAsFunctionParameter) +{ + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + runSamplerInStructTest(); +} + +// Use a sampler in a struct inside a uniform struct with the nested struct passed as a function +// parameter. +TEST_P(SamplerInNestedStructAsFunctionParameterTest, SamplerInNestedStructAsFunctionParameter) +{ + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1427 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + runSamplerInStructTest(); +} + +// Make sure that there isn't a name conflict between sampler extracted from a struct and a +// similarly named uniform. +TEST_P(SamplerInStructAndOtherVariableTest, SamplerInStructAndOtherVariable) +{ + runSamplerInStructTest(); +} + +class TextureLimitsTest : public ANGLETest +{ + protected: + struct RGBA8 + { + uint8_t R, G, B, A; + }; + + TextureLimitsTest() + : mProgram(0), mMaxVertexTextures(0), mMaxFragmentTextures(0), mMaxCombinedTextures(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + ~TextureLimitsTest() + { + if (mProgram != 0) + { + glDeleteProgram(mProgram); + mProgram = 0; + + if (!mTextures.empty()) + { + glDeleteTextures(static_cast<GLsizei>(mTextures.size()), &mTextures[0]); + } + } + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mMaxVertexTextures); + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mMaxFragmentTextures); + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mMaxCombinedTextures); + + ASSERT_GL_NO_ERROR(); + } + + void compileProgramWithTextureCounts(const std::string &vertexPrefix, + GLint vertexTextureCount, + GLint vertexActiveTextureCount, + const std::string &fragPrefix, + GLint fragmentTextureCount, + GLint fragmentActiveTextureCount) + { + std::stringstream vertexShaderStr; + vertexShaderStr << "attribute vec2 position;\n" + << "varying vec4 color;\n" + << "varying vec2 texCoord;\n"; + + for (GLint textureIndex = 0; textureIndex < vertexTextureCount; ++textureIndex) + { + vertexShaderStr << "uniform sampler2D " << vertexPrefix << textureIndex << ";\n"; + } + + vertexShaderStr << "void main() {\n" + << " gl_Position = vec4(position, 0, 1);\n" + << " texCoord = (position * 0.5) + 0.5;\n" + << " color = vec4(0);\n"; + + for (GLint textureIndex = 0; textureIndex < vertexActiveTextureCount; ++textureIndex) + { + vertexShaderStr << " color += texture2D(" << vertexPrefix << textureIndex + << ", texCoord);\n"; + } + + vertexShaderStr << "}"; + + std::stringstream fragmentShaderStr; + fragmentShaderStr << "varying mediump vec4 color;\n" + << "varying mediump vec2 texCoord;\n"; + + for (GLint textureIndex = 0; textureIndex < fragmentTextureCount; ++textureIndex) + { + fragmentShaderStr << "uniform sampler2D " << fragPrefix << textureIndex << ";\n"; + } + + fragmentShaderStr << "void main() {\n" + << " gl_FragColor = color;\n"; + + for (GLint textureIndex = 0; textureIndex < fragmentActiveTextureCount; ++textureIndex) + { + fragmentShaderStr << " gl_FragColor += texture2D(" << fragPrefix << textureIndex + << ", texCoord);\n"; + } + + fragmentShaderStr << "}"; + + const std::string &vertexShaderSource = vertexShaderStr.str(); + const std::string &fragmentShaderSource = fragmentShaderStr.str(); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + } + + RGBA8 getPixel(GLint texIndex) + { + RGBA8 pixel = {static_cast<uint8_t>(texIndex & 0x7u), static_cast<uint8_t>(texIndex >> 3), + 0, 255u}; + return pixel; + } + + void initTextures(GLint tex2DCount, GLint texCubeCount) + { + GLint totalCount = tex2DCount + texCubeCount; + mTextures.assign(totalCount, 0); + glGenTextures(totalCount, &mTextures[0]); + ASSERT_GL_NO_ERROR(); + + std::vector<RGBA8> texData(16 * 16); + + GLint texIndex = 0; + for (; texIndex < tex2DCount; ++texIndex) + { + texData.assign(texData.size(), getPixel(texIndex)); + glActiveTexture(GL_TEXTURE0 + texIndex); + glBindTexture(GL_TEXTURE_2D, mTextures[texIndex]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, + &texData[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + ASSERT_GL_NO_ERROR(); + + for (; texIndex < texCubeCount; ++texIndex) + { + texData.assign(texData.size(), getPixel(texIndex)); + glActiveTexture(GL_TEXTURE0 + texIndex); + glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[texIndex]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, &texData[0]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, &texData[0]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, &texData[0]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, &texData[0]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, &texData[0]); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, &texData[0]); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + ASSERT_GL_NO_ERROR(); + } + + void testWithTextures(GLint vertexTextureCount, + const std::string &vertexTexturePrefix, + GLint fragmentTextureCount, + const std::string &fragmentTexturePrefix) + { + // Generate textures + initTextures(vertexTextureCount + fragmentTextureCount, 0); + + glUseProgram(mProgram); + RGBA8 expectedSum = {0}; + for (GLint texIndex = 0; texIndex < vertexTextureCount; ++texIndex) + { + std::stringstream uniformNameStr; + uniformNameStr << vertexTexturePrefix << texIndex; + const std::string &uniformName = uniformNameStr.str(); + GLint location = glGetUniformLocation(mProgram, uniformName.c_str()); + ASSERT_NE(-1, location); + + glUniform1i(location, texIndex); + RGBA8 contribution = getPixel(texIndex); + expectedSum.R += contribution.R; + expectedSum.G += contribution.G; + } + + for (GLint texIndex = 0; texIndex < fragmentTextureCount; ++texIndex) + { + std::stringstream uniformNameStr; + uniformNameStr << fragmentTexturePrefix << texIndex; + const std::string &uniformName = uniformNameStr.str(); + GLint location = glGetUniformLocation(mProgram, uniformName.c_str()); + ASSERT_NE(-1, location); + + glUniform1i(location, texIndex + vertexTextureCount); + RGBA8 contribution = getPixel(texIndex + vertexTextureCount); + expectedSum.R += contribution.R; + expectedSum.G += contribution.G; + } + + ASSERT_GE(256u, expectedSum.G); + + drawQuad(mProgram, "position", 0.5f); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(0, 0, expectedSum.R, expectedSum.G, 0, 255); + } + + GLuint mProgram; + std::vector<GLuint> mTextures; + GLint mMaxVertexTextures; + GLint mMaxFragmentTextures; + GLint mMaxCombinedTextures; +}; + +// Test rendering with the maximum vertex texture units. +TEST_P(TextureLimitsTest, MaxVertexTextures) +{ + // TODO(jmadill): Figure out why this fails on Intel. + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + compileProgramWithTextureCounts("tex", mMaxVertexTextures, mMaxVertexTextures, "tex", 0, 0); + ASSERT_NE(0u, mProgram); + ASSERT_GL_NO_ERROR(); + + testWithTextures(mMaxVertexTextures, "tex", 0, "tex"); +} + +// Test rendering with the maximum fragment texture units. +TEST_P(TextureLimitsTest, MaxFragmentTextures) +{ + // TODO(jmadill): Figure out why this fails on Intel. + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures, mMaxFragmentTextures); + ASSERT_NE(0u, mProgram); + ASSERT_GL_NO_ERROR(); + + testWithTextures(mMaxFragmentTextures, "tex", 0, "tex"); +} + +// Test rendering with maximum combined texture units. +TEST_P(TextureLimitsTest, MaxCombinedTextures) +{ + // TODO(jmadill): Investigate workaround. + if (IsIntel() && GetParam() == ES2_OPENGL()) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + GLint vertexTextures = mMaxVertexTextures; + + if (vertexTextures + mMaxFragmentTextures > mMaxCombinedTextures) + { + vertexTextures = mMaxCombinedTextures - mMaxFragmentTextures; + } + + compileProgramWithTextureCounts("vtex", vertexTextures, vertexTextures, "ftex", + mMaxFragmentTextures, mMaxFragmentTextures); + ASSERT_NE(0u, mProgram); + ASSERT_GL_NO_ERROR(); + + testWithTextures(vertexTextures, "vtex", mMaxFragmentTextures, "ftex"); +} + +// Negative test for exceeding the number of vertex textures +TEST_P(TextureLimitsTest, ExcessiveVertexTextures) +{ + compileProgramWithTextureCounts("tex", mMaxVertexTextures + 1, mMaxVertexTextures + 1, "tex", 0, + 0); + ASSERT_EQ(0u, mProgram); +} + +// Negative test for exceeding the number of fragment textures +TEST_P(TextureLimitsTest, ExcessiveFragmentTextures) +{ + compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 1, + mMaxFragmentTextures + 1); + ASSERT_EQ(0u, mProgram); +} + +// Test active vertex textures under the limit, but excessive textures specified. +TEST_P(TextureLimitsTest, MaxActiveVertexTextures) +{ + // TODO(jmadill): Figure out why this fails on Intel. + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + compileProgramWithTextureCounts("tex", mMaxVertexTextures + 4, mMaxVertexTextures, "tex", 0, 0); + ASSERT_NE(0u, mProgram); + ASSERT_GL_NO_ERROR(); + + testWithTextures(mMaxVertexTextures, "tex", 0, "tex"); +} + +// Test active fragment textures under the limit, but excessive textures specified. +TEST_P(TextureLimitsTest, MaxActiveFragmentTextures) +{ + // TODO(jmadill): Figure out why this fails on Intel. + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + compileProgramWithTextureCounts("tex", 0, 0, "tex", mMaxFragmentTextures + 4, + mMaxFragmentTextures); + ASSERT_NE(0u, mProgram); + ASSERT_GL_NO_ERROR(); + + testWithTextures(0, "tex", mMaxFragmentTextures, "tex"); +} + +// Negative test for pointing two sampler uniforms of different types to the same texture. +// GLES 2.0.25 section 2.10.4 page 39. +TEST_P(TextureLimitsTest, TextureTypeConflict) +{ + const std::string &vertexShader = + "attribute vec2 position;\n" + "varying float color;\n" + "uniform sampler2D tex2D;\n" + "uniform samplerCube texCube;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + " vec2 texCoord = (position * 0.5) + 0.5;\n" + " color = texture2D(tex2D, texCoord).x;\n" + " color += textureCube(texCube, vec3(texCoord, 0)).x;\n" + "}"; + const std::string &fragmentShader = + "varying mediump float color;\n" + "void main() {\n" + " gl_FragColor = vec4(color, 0, 0, 1);\n" + "}"; + + mProgram = CompileProgram(vertexShader, fragmentShader); + ASSERT_NE(0u, mProgram); + + initTextures(1, 0); + + glUseProgram(mProgram); + GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D"); + ASSERT_NE(-1, tex2DLocation); + GLint texCubeLocation = glGetUniformLocation(mProgram, "texCube"); + ASSERT_NE(-1, texCubeLocation); + + glUniform1i(tex2DLocation, 0); + glUniform1i(texCubeLocation, 0); + ASSERT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Negative test for rendering with texture outside the valid range. +// TODO(jmadill): Possibly adjust the test according to the spec: +// GLES 3.0.4 section 2.12.7 mentions that specifying an out-of-range sampler uniform value +// generates an INVALID_VALUE error - GLES 2.0 doesn't yet have this mention. +TEST_P(TextureLimitsTest, DrawWithTexturePastMaximum) +{ + const std::string &vertexShader = + "attribute vec2 position;\n" + "varying float color;\n" + "uniform sampler2D tex2D;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + " vec2 texCoord = (position * 0.5) + 0.5;\n" + " color = texture2D(tex2D, texCoord).x;\n" + "}"; + const std::string &fragmentShader = + "varying mediump float color;\n" + "void main() {\n" + " gl_FragColor = vec4(color, 0, 0, 1);\n" + "}"; + + mProgram = CompileProgram(vertexShader, fragmentShader); + ASSERT_NE(0u, mProgram); + + glUseProgram(mProgram); + GLint tex2DLocation = glGetUniformLocation(mProgram, "tex2D"); + ASSERT_NE(-1, tex2DLocation); + + glUniform1i(tex2DLocation, mMaxCombinedTextures); + ASSERT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +class Texture2DNorm16TestES3 : public Texture2DTestES3 +{ + protected: + Texture2DNorm16TestES3() : Texture2DTestES3(), mTextures{0, 0, 0}, mFBO(0), mRenderbuffer(0) {} + + void SetUp() override + { + Texture2DTestES3::SetUp(); + + glActiveTexture(GL_TEXTURE0); + glGenTextures(3, mTextures); + glGenFramebuffers(1, &mFBO); + glGenRenderbuffers(1, &mRenderbuffer); + + for (size_t textureIndex = 0; textureIndex < 3; textureIndex++) + { + glBindTexture(GL_TEXTURE_2D, mTextures[textureIndex]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + glBindTexture(GL_TEXTURE_2D, 0); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteTextures(3, mTextures); + glDeleteFramebuffers(1, &mFBO); + glDeleteRenderbuffers(1, &mRenderbuffer); + + Texture2DTestES3::TearDown(); + } + + void testNorm16Texture(GLint internalformat, GLenum format, GLenum type) + { + GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35; + GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue}; + + setUpProgram(); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], + 0); + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8); + + EXPECT_PIXEL_COLOR_EQ( + 0, 0, SliceFormatColor( + format, GLColor(expectedValue, expectedValue, expectedValue, expectedValue))); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + ASSERT_GL_NO_ERROR(); + } + + void testNorm16Render(GLint internalformat, GLenum format, GLenum type) + { + GLushort pixelValue = 0x6A35; + GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue}; + + setUpProgram(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, nullptr); + + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], + 0); + + glBindTexture(GL_TEXTURE_2D, mTextures[2]); + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData); + + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + + GLubyte expectedValue = static_cast<GLubyte>(pixelValue >> 8); + EXPECT_PIXEL_COLOR_EQ( + 0, 0, SliceFormatColor( + format, GLColor(expectedValue, expectedValue, expectedValue, expectedValue))); + + glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, + mRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + EXPECT_GL_NO_ERROR(); + + glClearColor(1.0f, 1.0f, 1.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1); + + EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor::white)); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + ASSERT_GL_NO_ERROR(); + } + + GLuint mTextures[3]; + GLuint mFBO; + GLuint mRenderbuffer; +}; + +// Test texture formats enabled by the GL_EXT_texture_norm16 extension. +TEST_P(Texture2DNorm16TestES3, TextureNorm16Test) +{ + if (!extensionEnabled("GL_EXT_texture_norm16")) + { + std::cout << "Test skipped due to missing GL_EXT_texture_norm16." << std::endl; + return; + } + + testNorm16Texture(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT); + testNorm16Texture(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT); + testNorm16Texture(GL_RGB16_EXT, GL_RGB, GL_UNSIGNED_SHORT); + testNorm16Texture(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT); + testNorm16Texture(GL_R16_SNORM_EXT, GL_RED, GL_SHORT); + testNorm16Texture(GL_RG16_SNORM_EXT, GL_RG, GL_SHORT); + testNorm16Texture(GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT); + testNorm16Texture(GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT); + + testNorm16Render(GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT); + testNorm16Render(GL_RG16_EXT, GL_RG, GL_UNSIGNED_SHORT); + testNorm16Render(GL_RGBA16_EXT, GL_RGBA, GL_UNSIGNED_SHORT); +} + +// Test that UNPACK_SKIP_IMAGES doesn't have an effect on 2D texture uploads. +// GLES 3.0.4 section 3.8.3. +TEST_P(Texture2DTestES3, UnpackSkipImages2D) +{ + if (IsIntel() && IsDesktopOpenGL()) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + // TODO(ynovikov): re-enable once root cause of http://anglebug.com/1429 is fixed + if (IsAndroid() && IsAdreno() && IsOpenGLES()) + { + std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl; + return; + } + + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ASSERT_GL_NO_ERROR(); + + // SKIP_IMAGES should not have an effect on uploading 2D textures + glPixelStorei(GL_UNPACK_SKIP_IMAGES, 1000); + ASSERT_GL_NO_ERROR(); + + std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsGreen.data()); + ASSERT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, + pixelsGreen.data()); + ASSERT_GL_NO_ERROR(); + + glUseProgram(mProgram); + drawQuad(mProgram, "position", 0.5f); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// Test that skip defined in unpack parameters is taken into account when determining whether +// unpacking source extends outside unpack buffer bounds. +TEST_P(Texture2DTestES3, UnpackSkipPixelsOutOfBounds) +{ + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ASSERT_GL_NO_ERROR(); + + GLBuffer buf; + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get()); + std::vector<GLColor> pixelsGreen(128u * 128u, GLColor::green); + glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(), + GL_DYNAMIC_COPY); + ASSERT_GL_NO_ERROR(); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + ASSERT_GL_NO_ERROR(); + + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 1); + ASSERT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 1); + ASSERT_GL_NO_ERROR(); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, 0); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test that unpacking rows that overlap in a pixel unpack buffer works as expected. +TEST_P(Texture2DTestES3, UnpackOverlappingRowsFromUnpackBuffer) +{ + if (IsD3D11()) + { + std::cout << "Test skipped on D3D." << std::endl; + return; + } + if (IsOSX() && IsAMD()) + { + // Incorrect rendering results seen on OSX AMD. + std::cout << "Test skipped on OSX AMD." << std::endl; + return; + } + + const GLuint width = 8u; + const GLuint height = 8u; + const GLuint unpackRowLength = 5u; + const GLuint unpackSkipPixels = 1u; + + setWindowWidth(width); + setWindowHeight(height); + + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ASSERT_GL_NO_ERROR(); + + GLBuffer buf; + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf.get()); + std::vector<GLColor> pixelsGreen((height - 1u) * unpackRowLength + width + unpackSkipPixels, + GLColor::green); + + for (GLuint skippedPixel = 0u; skippedPixel < unpackSkipPixels; ++skippedPixel) + { + pixelsGreen[skippedPixel] = GLColor(255, 0, 0, 255); + } + + glBufferData(GL_PIXEL_UNPACK_BUFFER, pixelsGreen.size() * 4u, pixelsGreen.data(), + GL_DYNAMIC_COPY); + ASSERT_GL_NO_ERROR(); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackRowLength); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels); + ASSERT_GL_NO_ERROR(); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + ASSERT_GL_NO_ERROR(); + + glUseProgram(mProgram); + drawQuad(mProgram, "position", 0.5f); + ASSERT_GL_NO_ERROR(); + + GLuint windowPixelCount = getWindowWidth() * getWindowHeight(); + std::vector<GLColor> actual(windowPixelCount, GLColor::black); + glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, + actual.data()); + std::vector<GLColor> expected(windowPixelCount, GLColor::green); + EXPECT_EQ(expected, actual); +} + +template <typename T> +T UNorm(double value) +{ + return static_cast<T>(value * static_cast<double>(std::numeric_limits<T>::max())); +} + +// Test rendering a depth texture with mipmaps. +TEST_P(Texture2DTestES3, DepthTexturesWithMipmaps) +{ + //TODO(cwallez) this is failing on Intel Win7 OpenGL + if (IsIntel() && IsWindows() && IsOpenGL()) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + const int size = getWindowWidth(); + + auto dim = [size](int level) { return size >> level; }; + int levels = gl::log2(size); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexStorage2D(GL_TEXTURE_2D, levels, GL_DEPTH_COMPONENT24, size, size); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + ASSERT_GL_NO_ERROR(); + + glUseProgram(mProgram); + glUniform1i(mTexture2DUniformLocation, 0); + + std::vector<unsigned char> expected; + + for (int level = 0; level < levels; ++level) + { + double value = (static_cast<double>(level) / static_cast<double>(levels - 1)); + expected.push_back(UNorm<unsigned char>(value)); + + int levelDim = dim(level); + + ASSERT_GT(levelDim, 0); + + std::vector<unsigned int> initData(levelDim * levelDim, UNorm<unsigned int>(value)); + glTexSubImage2D(GL_TEXTURE_2D, level, 0, 0, levelDim, levelDim, GL_DEPTH_COMPONENT, + GL_UNSIGNED_INT, initData.data()); + } + ASSERT_GL_NO_ERROR(); + + for (int level = 0; level < levels; ++level) + { + glViewport(0, 0, dim(level), dim(level)); + drawQuad(mProgram, "position", 0.5f); + GLColor actual = ReadColor(0, 0); + EXPECT_NEAR(expected[level], actual.R, 10u); + } + + ASSERT_GL_NO_ERROR(); +} + +// Tests unpacking into the unsized GL_ALPHA format. +TEST_P(Texture2DTestES3, UnsizedAlphaUnpackBuffer) +{ + // TODO(jmadill): Figure out why this fails on OSX. + ANGLE_SKIP_TEST_IF(IsOSX()); + + // Initialize the texure. + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, getWindowWidth(), getWindowHeight(), 0, GL_ALPHA, + GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + std::vector<GLubyte> bufferData(getWindowWidth() * getWindowHeight(), 127); + + // Pull in the color data from the unpack buffer. + GLBuffer unpackBuffer; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get()); + glBufferData(GL_PIXEL_UNPACK_BUFFER, getWindowWidth() * getWindowHeight(), bufferData.data(), + GL_STATIC_DRAW); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth(), getWindowHeight(), GL_ALPHA, + GL_UNSIGNED_BYTE, nullptr); + + // Clear to a weird color to make sure we're drawing something. + glClearColor(0.5f, 0.8f, 1.0f, 0.2f); + glClear(GL_COLOR_BUFFER_BIT); + + // Draw with the alpha texture and verify. + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 127, 1); +} + +// Ensure stale unpack data doesn't propagate in D3D11. +TEST_P(Texture2DTestES3, StaleUnpackData) +{ + // Init unpack buffer. + GLsizei pixelCount = getWindowWidth() * getWindowHeight() / 2; + std::vector<GLColor> pixels(pixelCount, GLColor::red); + + GLBuffer unpackBuffer; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer.get()); + GLsizei bufferSize = pixelCount * sizeof(GLColor); + glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, pixels.data(), GL_STATIC_DRAW); + + // Create from unpack buffer. + glBindTexture(GL_TEXTURE_2D, mTexture2D); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth() / 2, getWindowHeight() / 2, 0, + GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red); + + // Fill unpack with green, recreating buffer. + pixels.assign(getWindowWidth() * getWindowHeight(), GLColor::green); + GLsizei size2 = getWindowWidth() * getWindowHeight() * sizeof(GLColor); + glBufferData(GL_PIXEL_UNPACK_BUFFER, size2, pixels.data(), GL_STATIC_DRAW); + + // Reinit texture with green. + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GL_RGBA, + GL_UNSIGNED_BYTE, nullptr); + + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); +} + +// This test covers a D3D format redefinition bug for 3D textures. The base level format was not +// being properly checked, and the texture storage of the previous texture format was persisting. +// This would result in an ASSERT in debug and incorrect rendering in release. +// See http://anglebug.com/1609 and WebGL 2 test conformance2/misc/views-with-offsets.html. +TEST_P(Texture3DTestES3, FormatRedefinitionBug) +{ + GLTexture tex; + glBindTexture(GL_TEXTURE_3D, tex.get()); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + + GLFramebuffer framebuffer; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get()); + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex.get(), 0, 0); + + glCheckFramebufferStatus(GL_FRAMEBUFFER); + + std::vector<uint8_t> pixelData(100, 0); + + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB565, 1, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, nullptr); + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, + pixelData.data()); + + ASSERT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +// TODO(oetuaho): Enable all below tests on OpenGL. Requires a fix for ANGLE bug 1278. +ANGLE_INSTANTIATE_TEST(Texture2DTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(TextureCubeTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Texture2DTestWithDrawScale, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Sampler2DAsFunctionParameterTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SamplerArrayTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SamplerArrayAsFunctionParameterTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Texture2DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Texture3DTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Texture2DIntegerAlpha1TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Texture2DUnsignedIntegerAlpha1TestES3, + ES3_D3D11(), + ES3_OPENGL(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(ShadowSamplerPlusSampler3DTestES3, + ES3_D3D11(), + ES3_OPENGL(), + ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SamplerTypeMixTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Texture2DArrayTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(TextureSizeTextureArrayTest, ES3_D3D11(), ES3_OPENGL()); +ANGLE_INSTANTIATE_TEST(SamplerInStructTest, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_D3D9(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SamplerInStructAsFunctionParameterTest, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_D3D9(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SamplerInStructArrayAsFunctionParameterTest, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_D3D9(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SamplerInNestedStructAsFunctionParameterTest, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_D3D9(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(SamplerInStructAndOtherVariableTest, + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_D3D9(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(TextureLimitsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(Texture2DNorm16TestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp b/gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp new file mode 100755 index 000000000..8f3725ec0 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/TimerQueriesTest.cpp @@ -0,0 +1,590 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TimerQueriesTest.cpp +// Various tests for EXT_disjoint_timer_query functionality and validation +// + +#include "system_utils.h" +#include "test_utils/ANGLETest.h" +#include "random_utils.h" + +using namespace angle; + +class TimerQueriesTest : public ANGLETest +{ + protected: + TimerQueriesTest() : mProgram(0), mProgramCostly(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + virtual void SetUp() + { + ANGLETest::SetUp(); + + const std::string passthroughVS = + "attribute highp vec4 position; void main(void)\n" + "{\n" + " gl_Position = position;\n" + "}\n"; + + const std::string passthroughPS = + "precision highp float; void main(void)\n" + "{\n" + " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" + "}\n"; + + const std::string costlyVS = + "attribute highp vec4 position; varying highp vec4 testPos; void main(void)\n" + "{\n" + " testPos = position;\n" + " gl_Position = position;\n" + "}\n"; + + const std::string costlyPS = + "precision highp float; varying highp vec4 testPos; void main(void)\n" + "{\n" + " vec4 test = testPos;\n" + " for (int i = 0; i < 500; i++)\n" + " {\n" + " test = sqrt(test);\n" + " }\n" + " gl_FragColor = test;\n" + "}\n"; + + mProgram = CompileProgram(passthroughVS, passthroughPS); + ASSERT_NE(0u, mProgram) << "shader compilation failed."; + + mProgramCostly = CompileProgram(costlyVS, costlyPS); + ASSERT_NE(0u, mProgramCostly) << "shader compilation failed."; + } + + virtual void TearDown() + { + glDeleteProgram(mProgram); + glDeleteProgram(mProgramCostly); + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLuint mProgramCostly; +}; + +// Test that all proc addresses are loadable +TEST_P(TimerQueriesTest, ProcAddresses) +{ + if (!extensionEnabled("GL_EXT_disjoint_timer_query")) + { + std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." + << std::endl; + return; + } + + ASSERT_NE(nullptr, eglGetProcAddress("glGenQueriesEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glDeleteQueriesEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glIsQueryEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glBeginQueryEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glEndQueryEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glQueryCounterEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryivEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectivEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectuivEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjecti64vEXT")); + ASSERT_NE(nullptr, eglGetProcAddress("glGetQueryObjectui64vEXT")); +} + +// Tests the time elapsed query +TEST_P(TimerQueriesTest, TimeElapsed) +{ + if (!extensionEnabled("GL_EXT_disjoint_timer_query")) + { + std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." + << std::endl; + return; + } + + GLint queryTimeElapsedBits = 0; + glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits); + ASSERT_GL_NO_ERROR(); + + std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl; + + // Skip test if the number of bits is 0 + if (queryTimeElapsedBits == 0) + { + std::cout << "Test skipped because of 0 counter bits" << std::endl; + return; + } + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + GLuint query1 = 0; + GLuint query2 = 0; + glGenQueriesEXT(1, &query1); + glGenQueriesEXT(1, &query2); + + // Test time elapsed for a single quad + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query1); + drawQuad(mProgram, "position", 0.8f); + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + ASSERT_GL_NO_ERROR(); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + // Test time elapsed for costly quad + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query2); + drawQuad(mProgramCostly, "position", 0.8f); + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + ASSERT_GL_NO_ERROR(); + + swapBuffers(); + + int timeout = 200000; + GLuint ready = GL_FALSE; + while (ready == GL_FALSE && timeout > 0) + { + angle::Sleep(0); + glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); + timeout--; + } + ready = GL_FALSE; + while (ready == GL_FALSE && timeout > 0) + { + angle::Sleep(0); + glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); + timeout--; + } + ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl; + + GLuint64 result1 = 0; + GLuint64 result2 = 0; + glGetQueryObjectui64vEXT(query1, GL_QUERY_RESULT_EXT, &result1); + glGetQueryObjectui64vEXT(query2, GL_QUERY_RESULT_EXT, &result2); + ASSERT_GL_NO_ERROR(); + + glDeleteQueriesEXT(1, &query1); + glDeleteQueriesEXT(1, &query2); + ASSERT_GL_NO_ERROR(); + + std::cout << "Elapsed time: " << result1 << " cheap quad" << std::endl; + std::cout << "Elapsed time: " << result2 << " costly quad" << std::endl; + + // The time elapsed should be nonzero + EXPECT_LT(0ul, result1); + EXPECT_LT(0ul, result2); + + // The costly quad should take longer than the cheap quad + EXPECT_LT(result1, result2); +} + +// Tests time elapsed for a non draw call (texture upload) +TEST_P(TimerQueriesTest, TimeElapsedTextureTest) +{ + // OSX drivers don't seem to properly time non-draw calls so we skip the test on Mac + if (IsOSX()) + { + std::cout << "Test skipped on OSX" << std::endl; + return; + } + + if (!extensionEnabled("GL_EXT_disjoint_timer_query")) + { + std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." + << std::endl; + return; + } + + GLint queryTimeElapsedBits = 0; + glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits); + ASSERT_GL_NO_ERROR(); + + std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl; + + // Skip test if the number of bits is 0 + if (queryTimeElapsedBits == 0) + { + std::cout << "Test skipped because of 0 counter bits" << std::endl; + return; + } + + GLubyte pixels[] = {0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0}; + + // Query and texture initialization + GLuint texture; + GLuint query = 0; + glGenQueriesEXT(1, &query); + glGenTextures(1, &texture); + + // Upload a texture inside the query + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels); + glGenerateMipmap(GL_TEXTURE_2D); + glFinish(); + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + ASSERT_GL_NO_ERROR(); + + int timeout = 200000; + GLuint ready = GL_FALSE; + while (ready == GL_FALSE && timeout > 0) + { + angle::Sleep(0); + glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); + timeout--; + } + ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl; + + GLuint64 result = 0; + glGetQueryObjectui64vEXT(query, GL_QUERY_RESULT_EXT, &result); + ASSERT_GL_NO_ERROR(); + + glDeleteTextures(1, &texture); + glDeleteQueriesEXT(1, &query); + + std::cout << "Elapsed time: " << result << std::endl; + EXPECT_LT(0ul, result); +} + +// Tests validation of query functions with respect to elapsed time query +TEST_P(TimerQueriesTest, TimeElapsedValidationTest) +{ + if (!extensionEnabled("GL_EXT_disjoint_timer_query")) + { + std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." + << std::endl; + return; + } + + GLint queryTimeElapsedBits = 0; + glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits); + ASSERT_GL_NO_ERROR(); + + std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl; + + // Skip test if the number of bits is 0 + if (queryTimeElapsedBits == 0) + { + std::cout << "Test skipped because of 0 counter bits" << std::endl; + return; + } + + GLuint query = 0; + glGenQueriesEXT(-1, &query); + EXPECT_GL_ERROR(GL_INVALID_VALUE); + + glGenQueriesEXT(1, &query); + EXPECT_GL_NO_ERROR(); + + glBeginQueryEXT(GL_TIMESTAMP_EXT, query); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, 0); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query); + EXPECT_GL_NO_ERROR(); + + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, query); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + EXPECT_GL_NO_ERROR(); + + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Tests timer queries operating under multiple EGL contexts with mid-query switching +TEST_P(TimerQueriesTest, TimeElapsedMulticontextTest) +{ + if (IsAMD() && IsOpenGL() && IsWindows() && IsDebug()) + { + // TODO(jmadill): Figure out why this test is flaky on Win/AMD/OpenGL/Debug. + std::cout << "Test skipped on Windows AMD OpenGL Debug." << std::endl; + return; + } + + if (!extensionEnabled("GL_EXT_disjoint_timer_query")) + { + std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." + << std::endl; + return; + } + + GLint queryTimeElapsedBits = 0; + glGetQueryivEXT(GL_TIME_ELAPSED_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimeElapsedBits); + ASSERT_GL_NO_ERROR(); + + std::cout << "Time elapsed counter bits: " << queryTimeElapsedBits << std::endl; + + // Skip test if the number of bits is 0 + if (queryTimeElapsedBits == 0) + { + std::cout << "Test skipped because of 0 counter bits" << std::endl; + return; + } + + // Without a glClear, the first draw call on GL takes a huge amount of time when run after the + // D3D test on certain NVIDIA drivers + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, + GetParam().majorVersion, + EGL_CONTEXT_MINOR_VERSION_KHR, + GetParam().minorVersion, + EGL_NONE, + }; + + EGLWindow *window = getEGLWindow(); + + EGLDisplay display = window->getDisplay(); + EGLConfig config = window->getConfig(); + EGLSurface surface = window->getSurface(); + + struct ContextInfo + { + EGLContext context; + GLuint program; + GLuint query; + EGLDisplay display; + + ContextInfo() : context(EGL_NO_CONTEXT), program(0), query(0), display(EGL_NO_DISPLAY) {} + + ~ContextInfo() + { + if (context != EGL_NO_CONTEXT && display != EGL_NO_DISPLAY) + { + eglDestroyContext(display, context); + } + } + }; + ContextInfo contexts[2]; + + // Shaders + const std::string cheapVS = + "attribute highp vec4 position; void main(void)\n" + "{\n" + " gl_Position = position;\n" + "}\n"; + + const std::string cheapPS = + "precision highp float; void main(void)\n" + "{\n" + " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" + "}\n"; + + const std::string costlyVS = + "attribute highp vec4 position; varying highp vec4 testPos; void main(void)\n" + "{\n" + " testPos = position;\n" + " gl_Position = position;\n" + "}\n"; + + const std::string costlyPS = + "precision highp float; varying highp vec4 testPos; void main(void)\n" + "{\n" + " vec4 test = testPos;\n" + " for (int i = 0; i < 500; i++)\n" + " {\n" + " test = sqrt(test);\n" + " }\n" + " gl_FragColor = test;\n" + "}\n"; + + // Setup the first context with a cheap shader + contexts[0].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); + contexts[0].display = display; + ASSERT_NE(contexts[0].context, EGL_NO_CONTEXT); + eglMakeCurrent(display, surface, surface, contexts[0].context); + contexts[0].program = CompileProgram(cheapVS, cheapPS); + glGenQueriesEXT(1, &contexts[0].query); + ASSERT_GL_NO_ERROR(); + + // Setup the second context with an expensive shader + contexts[1].context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); + contexts[1].display = display; + ASSERT_NE(contexts[1].context, EGL_NO_CONTEXT); + eglMakeCurrent(display, surface, surface, contexts[1].context); + contexts[1].program = CompileProgram(costlyVS, costlyPS); + glGenQueriesEXT(1, &contexts[1].query); + ASSERT_GL_NO_ERROR(); + + // Start the query and draw a quad on the first context without ending the query + eglMakeCurrent(display, surface, surface, contexts[0].context); + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[0].query); + drawQuad(contexts[0].program, "position", 0.8f); + ASSERT_GL_NO_ERROR(); + + // Switch contexts, draw the expensive quad and end its query + eglMakeCurrent(display, surface, surface, contexts[1].context); + glBeginQueryEXT(GL_TIME_ELAPSED_EXT, contexts[1].query); + drawQuad(contexts[1].program, "position", 0.8f); + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + ASSERT_GL_NO_ERROR(); + + // Go back to the first context, end its query, and get the result + eglMakeCurrent(display, surface, surface, contexts[0].context); + glEndQueryEXT(GL_TIME_ELAPSED_EXT); + + GLuint64 result1 = 0; + GLuint64 result2 = 0; + glGetQueryObjectui64vEXT(contexts[0].query, GL_QUERY_RESULT_EXT, &result1); + glDeleteQueriesEXT(1, &contexts[0].query); + glDeleteProgram(contexts[0].program); + ASSERT_GL_NO_ERROR(); + + // Get the 2nd context's results + eglMakeCurrent(display, surface, surface, contexts[1].context); + glGetQueryObjectui64vEXT(contexts[1].query, GL_QUERY_RESULT_EXT, &result2); + glDeleteQueriesEXT(1, &contexts[1].query); + glDeleteProgram(contexts[1].program); + ASSERT_GL_NO_ERROR(); + + // Switch back to main context + eglMakeCurrent(display, surface, surface, window->getContext()); + + // Compare the results. The cheap quad should be smaller than the expensive one if + // virtualization is working correctly + std::cout << "Elapsed time: " << result1 << " cheap quad" << std::endl; + std::cout << "Elapsed time: " << result2 << " costly quad" << std::endl; + EXPECT_LT(0ul, result1); + EXPECT_LT(0ul, result2); + EXPECT_LT(result1, result2); +} + +// Tests GPU timestamp functionality +TEST_P(TimerQueriesTest, Timestamp) +{ + if (!extensionEnabled("GL_EXT_disjoint_timer_query")) + { + std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." + << std::endl; + return; + } + + GLint queryTimestampBits = 0; + glGetQueryivEXT(GL_TIMESTAMP_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimestampBits); + ASSERT_GL_NO_ERROR(); + + std::cout << "Timestamp counter bits: " << queryTimestampBits << std::endl; + + // Macs for some reason return 0 bits so skip the test for now if either are 0 + if (queryTimestampBits == 0) + { + std::cout << "Test skipped because of 0 counter bits" << std::endl; + return; + } + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + GLuint query1 = 0; + GLuint query2 = 0; + glGenQueriesEXT(1, &query1); + glGenQueriesEXT(1, &query2); + glQueryCounterEXT(query1, GL_TIMESTAMP_EXT); + drawQuad(mProgram, "position", 0.8f); + glQueryCounterEXT(query2, GL_TIMESTAMP_EXT); + + ASSERT_GL_NO_ERROR(); + + swapBuffers(); + + int timeout = 200000; + GLuint ready = GL_FALSE; + while (ready == GL_FALSE && timeout > 0) + { + angle::Sleep(0); + glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); + timeout--; + } + ready = GL_FALSE; + while (ready == GL_FALSE && timeout > 0) + { + angle::Sleep(0); + glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_AVAILABLE_EXT, &ready); + timeout--; + } + ASSERT_LT(0, timeout) << "Query result available timed out" << std::endl; + + GLuint64 result1 = 0; + GLuint64 result2 = 0; + glGetQueryObjectui64vEXT(query1, GL_QUERY_RESULT_EXT, &result1); + glGetQueryObjectui64vEXT(query2, GL_QUERY_RESULT_EXT, &result2); + + ASSERT_GL_NO_ERROR(); + + glDeleteQueriesEXT(1, &query1); + glDeleteQueriesEXT(1, &query2); + + std::cout << "Timestamps: " << result1 << " " << result2 << std::endl; + EXPECT_LT(0ul, result1); + EXPECT_LT(0ul, result2); + EXPECT_LT(result1, result2); +} + +class TimerQueriesTestES3 : public TimerQueriesTest +{ +}; + +// Tests getting timestamps via glGetInteger64v +TEST_P(TimerQueriesTestES3, TimestampGetInteger64) +{ + if (!extensionEnabled("GL_EXT_disjoint_timer_query")) + { + std::cout << "Test skipped because GL_EXT_disjoint_timer_query is not available." + << std::endl; + return; + } + + GLint queryTimestampBits = 0; + glGetQueryivEXT(GL_TIMESTAMP_EXT, GL_QUERY_COUNTER_BITS_EXT, &queryTimestampBits); + ASSERT_GL_NO_ERROR(); + + std::cout << "Timestamp counter bits: " << queryTimestampBits << std::endl; + + if (queryTimestampBits == 0) + { + std::cout << "Test skipped because of 0 counter bits" << std::endl; + return; + } + + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + GLint64 result1 = 0; + GLint64 result2 = 0; + glGetInteger64v(GL_TIMESTAMP_EXT, &result1); + drawQuad(mProgram, "position", 0.8f); + glGetInteger64v(GL_TIMESTAMP_EXT, &result2); + ASSERT_GL_NO_ERROR(); + std::cout << "Timestamps (getInteger64v): " << result1 << " " << result2 << std::endl; + EXPECT_LT(0l, result1); + EXPECT_LT(0l, result2); + EXPECT_LT(result1, result2); +} + +ANGLE_INSTANTIATE_TEST(TimerQueriesTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_OPENGL(), + ES3_OPENGL()); + +ANGLE_INSTANTIATE_TEST(TimerQueriesTestES3, ES3_D3D11(), ES3_OPENGL());
\ No newline at end of file diff --git a/gfx/angle/src/tests/gl_tests/TransformFeedbackTest.cpp b/gfx/angle/src/tests/gl_tests/TransformFeedbackTest.cpp new file mode 100755 index 000000000..73c8a20d5 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/TransformFeedbackTest.cpp @@ -0,0 +1,980 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" +#include "random_utils.h" +#include "Vector.h" + +using namespace angle; + +namespace +{ + +class TransformFeedbackTest : public ANGLETest +{ + protected: + TransformFeedbackTest() + : mProgram(0), + mTransformFeedbackBuffer(0), + mTransformFeedback(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenBuffers(1, &mTransformFeedbackBuffer); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBufferSize, NULL, + GL_STATIC_DRAW); + + glGenTransformFeedbacks(1, &mTransformFeedback); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + if (mProgram != 0) + { + glDeleteProgram(mProgram); + mProgram = 0; + } + + if (mTransformFeedbackBuffer != 0) + { + glDeleteBuffers(1, &mTransformFeedbackBuffer); + mTransformFeedbackBuffer = 0; + } + + if (mTransformFeedback != 0) + { + glDeleteTransformFeedbacks(1, &mTransformFeedback); + mTransformFeedback = 0; + } + + ANGLETest::TearDown(); + } + + void compileDefaultProgram(const std::vector<std::string> &tfVaryings, GLenum bufferMode) + { + ASSERT_EQ(0u, mProgram); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + + void main() + { + gl_Position = position; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + precision highp float; + + void main() + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource, + tfVaryings, bufferMode); + ASSERT_NE(0u, mProgram); + } + + GLuint mProgram; + + static const size_t mTransformFeedbackBufferSize = 1 << 24; + GLuint mTransformFeedbackBuffer; + GLuint mTransformFeedback; +}; + +TEST_P(TransformFeedbackTest, ZeroSizedViewport) +{ + // Set the program's transform feedback varyings (just gl_Position) + std::vector<std::string> tfVaryings; + tfVaryings.push_back("gl_Position"); + compileDefaultProgram(tfVaryings, GL_INTERLEAVED_ATTRIBS); + + glUseProgram(mProgram); + + // Bind the buffer for transform feedback output and start transform feedback + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer); + glBeginTransformFeedback(GL_TRIANGLES); + + // Create a query to check how many primitives were written + GLuint primitivesWrittenQuery = 0; + glGenQueries(1, &primitivesWrittenQuery); + glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, primitivesWrittenQuery); + + // Set a viewport that would result in no pixels being written to the framebuffer and draw + // a quad + glViewport(0, 0, 0, 0); + + drawQuad(mProgram, "position", 0.5f); + + // End the query and transform feedkback + glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + glEndTransformFeedback(); + + glUseProgram(0); + + // Check how many primitives were written and verify that some were written even if + // no pixels were rendered + GLuint primitivesWritten = 0; + glGetQueryObjectuiv(primitivesWrittenQuery, GL_QUERY_RESULT_EXT, &primitivesWritten); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(2u, primitivesWritten); +} + +// Test that rebinding a buffer with the same offset resets the offset (no longer appending from the +// old position) +TEST_P(TransformFeedbackTest, BufferRebinding) +{ + glDisable(GL_DEPTH_TEST); + + // Set the program's transform feedback varyings (just gl_Position) + std::vector<std::string> tfVaryings; + tfVaryings.push_back("gl_Position"); + compileDefaultProgram(tfVaryings, GL_INTERLEAVED_ATTRIBS); + + glUseProgram(mProgram); + + // Make sure the buffer has zero'd data + std::vector<float> data(mTransformFeedbackBufferSize / sizeof(float), 0.0f); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBufferSize, data.data(), + GL_STATIC_DRAW); + + + // Create a query to check how many primitives were written + GLuint primitivesWrittenQuery = 0; + glGenQueries(1, &primitivesWrittenQuery); + glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, primitivesWrittenQuery); + + const float finalZ = 0.95f; + + RNG rng; + + const size_t loopCount = 64; + for (size_t loopIdx = 0; loopIdx < loopCount; loopIdx++) + { + // Bind the buffer for transform feedback output and start transform feedback + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer); + glBeginTransformFeedback(GL_TRIANGLES); + + float z = (loopIdx + 1 == loopCount) ? finalZ : rng.randomFloatBetween(0.1f, 0.5f); + drawQuad(mProgram, "position", z); + + glEndTransformFeedback(); + } + + // End the query and transform feedback + glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + + glUseProgram(0); + + // Check how many primitives were written and verify that some were written even if + // no pixels were rendered + GLuint primitivesWritten = 0; + glGetQueryObjectuiv(primitivesWrittenQuery, GL_QUERY_RESULT_EXT, &primitivesWritten); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(loopCount * 2, primitivesWritten); + + // Check the buffer data + const float *bufferData = static_cast<float *>(glMapBufferRange( + GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBufferSize, GL_MAP_READ_BIT)); + + for (size_t vertexIdx = 0; vertexIdx < 6; vertexIdx++) + { + // Check the third (Z) component of each vertex written and make sure it has the final + // value + EXPECT_NEAR(finalZ, bufferData[vertexIdx * 4 + 2], 0.0001); + } + + for (size_t dataIdx = 24; dataIdx < mTransformFeedbackBufferSize / sizeof(float); dataIdx++) + { + EXPECT_EQ(data[dataIdx], bufferData[dataIdx]) << "Buffer overrun detected."; + } + + glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); + + EXPECT_GL_NO_ERROR(); +} + +// Test that XFB can write back vertices to a buffer and that we can draw from this buffer afterward. +TEST_P(TransformFeedbackTest, RecordAndDraw) +{ + // TODO(jmadill): Figure out why this fails on Intel. + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Set the program's transform feedback varyings (just gl_Position) + std::vector<std::string> tfVaryings; + tfVaryings.push_back("gl_Position"); + compileDefaultProgram(tfVaryings, GL_INTERLEAVED_ATTRIBS); + + glUseProgram(mProgram); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + + // First pass: draw 6 points to the XFB buffer + glEnable(GL_RASTERIZER_DISCARD); + + const GLfloat vertices[] = + { + -1.0f, 1.0f, 0.5f, + -1.0f, -1.0f, 0.5f, + 1.0f, -1.0f, 0.5f, + + -1.0f, 1.0f, 0.5f, + 1.0f, -1.0f, 0.5f, + 1.0f, 1.0f, 0.5f, + }; + + glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(positionLocation); + + // Bind the buffer for transform feedback output and start transform feedback + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer); + glBeginTransformFeedback(GL_POINTS); + + // Create a query to check how many primitives were written + GLuint primitivesWrittenQuery = 0; + glGenQueries(1, &primitivesWrittenQuery); + glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, primitivesWrittenQuery); + + glDrawArrays(GL_POINTS, 0, 6); + + glDisableVertexAttribArray(positionLocation); + glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL); + // End the query and transform feedkback + glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + glEndTransformFeedback(); + + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0); + + glDisable(GL_RASTERIZER_DISCARD); + + // Check how many primitives were written and verify that some were written even if + // no pixels were rendered + GLuint primitivesWritten = 0; + glGetQueryObjectuiv(primitivesWrittenQuery, GL_QUERY_RESULT_EXT, &primitivesWritten); + EXPECT_GL_NO_ERROR(); + + EXPECT_EQ(6u, primitivesWritten); + + // Nothing should have been drawn to the framebuffer + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 0, 0); + + // Second pass: draw from the feedback buffer + + glBindBuffer(GL_ARRAY_BUFFER, mTransformFeedbackBuffer); + glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(positionLocation); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 0, 255); + EXPECT_GL_NO_ERROR(); +} + +// Test that buffer binding happens only on the current transform feedback object +TEST_P(TransformFeedbackTest, BufferBinding) +{ + // Reset any state + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); + + // Generate a new buffer + GLuint scratchBuffer = 0; + glGenBuffers(1, &scratchBuffer); + + EXPECT_GL_NO_ERROR(); + + // Bind TF 0 and a buffer + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer); + + EXPECT_GL_NO_ERROR(); + + // Check that the buffer ID matches the one that was just bound + GLint currentBufferBinding = 0; + glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, ¤tBufferBinding); + EXPECT_EQ(static_cast<GLuint>(currentBufferBinding), mTransformFeedbackBuffer); + + EXPECT_GL_NO_ERROR(); + + // Check that the buffer ID for the newly bound transform feedback is zero + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); + + glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, ¤tBufferBinding); + EXPECT_EQ(0, currentBufferBinding); + + EXPECT_GL_NO_ERROR(); + + // Bind a buffer to this TF + glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, scratchBuffer, 0, 32); + + glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, ¤tBufferBinding); + EXPECT_EQ(static_cast<GLuint>(currentBufferBinding), scratchBuffer); + + EXPECT_GL_NO_ERROR(); + + // Rebind the original TF and check it's bindings + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + + glGetIntegeri_v(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, ¤tBufferBinding); + EXPECT_EQ(0, currentBufferBinding); + + EXPECT_GL_NO_ERROR(); + + // Clean up + glDeleteBuffers(1, &scratchBuffer); +} + +// Test that we can capture varyings only used in the vertex shader. +TEST_P(TransformFeedbackTest, VertexOnly) +{ + const std::string &vertexShaderSource = + "#version 300 es\n" + "in vec2 position;\n" + "in float attrib;\n" + "out float varyingAttrib;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + " varyingAttrib = attrib;\n" + "}"; + + const std::string &fragmentShaderSource = + "#version 300 es\n" + "out mediump vec4 color;\n" + "void main() {\n" + " color = vec4(0.0, 1.0, 0.0, 1.0);\n" + "}"; + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("varyingAttrib"); + + mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource, + tfVaryings, GL_INTERLEAVED_ATTRIBS); + ASSERT_NE(0u, mProgram); + + glUseProgram(mProgram); + + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer); + + std::vector<float> attribData; + for (unsigned int cnt = 0; cnt < 100; ++cnt) + { + attribData.push_back(static_cast<float>(cnt)); + } + + GLint attribLocation = glGetAttribLocation(mProgram, "attrib"); + ASSERT_NE(-1, attribLocation); + + glVertexAttribPointer(attribLocation, 1, GL_FLOAT, GL_FALSE, 4, &attribData[0]); + glEnableVertexAttribArray(attribLocation); + + glBeginTransformFeedback(GL_TRIANGLES); + drawQuad(mProgram, "position", 0.5f); + glEndTransformFeedback(); + ASSERT_GL_NO_ERROR(); + + glUseProgram(0); + + GLvoid *mappedBuffer = + glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(float) * 6, GL_MAP_READ_BIT); + ASSERT_NE(nullptr, mappedBuffer); + + float *mappedFloats = static_cast<float *>(mappedBuffer); + for (unsigned int cnt = 0; cnt < 6; ++cnt) + { + EXPECT_EQ(attribData[cnt], mappedFloats[cnt]); + } + + EXPECT_GL_NO_ERROR(); +} + +// Test that multiple paused transform feedbacks do not generate errors or crash +TEST_P(TransformFeedbackTest, MultiplePaused) +{ + const size_t drawSize = 1024; + std::vector<float> transformFeedbackData(drawSize); + for (size_t i = 0; i < drawSize; i++) + { + transformFeedbackData[i] = static_cast<float>(i + 1); + } + + // Initialize the buffers to zero + size_t bufferSize = drawSize; + std::vector<float> bufferInitialData(bufferSize, 0); + + const size_t transformFeedbackCount = 8; + + // clang-format off + const std::string vertexShaderSource = SHADER_SOURCE + ( #version 300 es\n + in highp vec4 position; + in float transformFeedbackInput; + out float transformFeedbackOutput; + void main(void) + { + gl_Position = position; + transformFeedbackOutput = transformFeedbackInput; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( #version 300 es\n + out mediump vec4 color; + void main(void) + { + color = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + // clang-format on + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("transformFeedbackOutput"); + + mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource, + tfVaryings, GL_INTERLEAVED_ATTRIBS); + ASSERT_NE(0u, mProgram); + glUseProgram(mProgram); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + glDisableVertexAttribArray(positionLocation); + glVertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f); + + GLint tfInputLocation = glGetAttribLocation(mProgram, "transformFeedbackInput"); + glEnableVertexAttribArray(tfInputLocation); + glVertexAttribPointer(tfInputLocation, 1, GL_FLOAT, false, 0, &transformFeedbackData[0]); + + glDepthMask(GL_FALSE); + glEnable(GL_DEPTH_TEST); + ASSERT_GL_NO_ERROR(); + + GLuint transformFeedbacks[transformFeedbackCount]; + glGenTransformFeedbacks(transformFeedbackCount, transformFeedbacks); + + GLuint buffers[transformFeedbackCount]; + glGenBuffers(transformFeedbackCount, buffers); + + for (size_t i = 0; i < transformFeedbackCount; i++) + { + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]); + + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffers[i]); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferSize * sizeof(GLfloat), + &bufferInitialData[0], GL_DYNAMIC_DRAW); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffers[i]); + ASSERT_GL_NO_ERROR(); + + glBeginTransformFeedback(GL_POINTS); + + glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(drawSize)); + + glPauseTransformFeedback(); + + EXPECT_GL_NO_ERROR(); + } + + for (size_t i = 0; i < transformFeedbackCount; i++) + { + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbacks[i]); + glEndTransformFeedback(); + glDeleteTransformFeedbacks(1, &transformFeedbacks[i]); + + EXPECT_GL_NO_ERROR(); + } +} +// Test that running multiple simultaneous queries and transform feedbacks from multiple EGL +// contexts returns the correct results. Helps expose bugs in ANGLE's virtual contexts. +TEST_P(TransformFeedbackTest, MultiContext) +{ +#if defined(ANGLE_PLATFORM_APPLE) + if ((IsNVIDIA() || IsAMD()) && GetParam() == ES3_OPENGL()) + { + std::cout << "Test skipped on NVidia and AMD OpenGL on OSX." << std::endl; + return; + } +#endif + +#if defined(ANGLE_PLATFORM_LINUX) + if (IsAMD() && GetParam() == ES3_OPENGL()) + { + std::cout << "Test skipped on AMD OpenGL on Linux." << std::endl; + return; + } +#endif + + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, + GetParam().majorVersion, + EGL_CONTEXT_MINOR_VERSION_KHR, + GetParam().minorVersion, + EGL_NONE, + }; + + EGLWindow *window = getEGLWindow(); + + EGLDisplay display = window->getDisplay(); + EGLConfig config = window->getConfig(); + EGLSurface surface = window->getSurface(); + + const size_t passCount = 5; + struct ContextInfo + { + EGLContext context; + GLuint program; + GLuint query; + GLuint buffer; + size_t primitiveCounts[passCount]; + }; + ContextInfo contexts[32]; + + const size_t maxDrawSize = 1024; + + std::vector<float> transformFeedbackData(maxDrawSize); + for (size_t i = 0; i < maxDrawSize; i++) + { + transformFeedbackData[i] = static_cast<float>(i + 1); + } + + // Initialize the buffers to zero + size_t bufferSize = maxDrawSize * passCount; + std::vector<float> bufferInitialData(bufferSize, 0); + + for (auto &context : contexts) + { + context.context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes); + ASSERT_NE(context.context, EGL_NO_CONTEXT); + + eglMakeCurrent(display, surface, surface, context.context); + + // clang-format off + const std::string vertexShaderSource = SHADER_SOURCE + ( #version 300 es\n + in highp vec4 position; + in float transformFeedbackInput; + out float transformFeedbackOutput; + void main(void) + { + gl_Position = position; + transformFeedbackOutput = transformFeedbackInput; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( #version 300 es\n + out mediump vec4 color; + void main(void) + { + color = vec4(1.0, 1.0, 1.0, 1.0); + } + ); + // clang-format on + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("transformFeedbackOutput"); + + context.program = CompileProgramWithTransformFeedback( + vertexShaderSource, fragmentShaderSource, tfVaryings, GL_INTERLEAVED_ATTRIBS); + ASSERT_NE(context.program, 0u); + glUseProgram(context.program); + + GLint positionLocation = glGetAttribLocation(context.program, "position"); + glDisableVertexAttribArray(positionLocation); + glVertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f); + + GLint tfInputLocation = glGetAttribLocation(context.program, "transformFeedbackInput"); + glEnableVertexAttribArray(tfInputLocation); + glVertexAttribPointer(tfInputLocation, 1, GL_FLOAT, false, 0, &transformFeedbackData[0]); + + glDepthMask(GL_FALSE); + glEnable(GL_DEPTH_TEST); + glGenQueriesEXT(1, &context.query); + glBeginQueryEXT(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, context.query); + + ASSERT_GL_NO_ERROR(); + + glGenBuffers(1, &context.buffer); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, context.buffer); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferSize * sizeof(GLfloat), + &bufferInitialData[0], GL_DYNAMIC_DRAW); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, context.buffer); + + ASSERT_GL_NO_ERROR(); + + // For each pass, draw between 0 and maxDrawSize primitives + for (auto &primCount : context.primitiveCounts) + { + primCount = rand() % maxDrawSize; + } + + glBeginTransformFeedback(GL_POINTS); + } + + for (size_t pass = 0; pass < passCount; pass++) + { + for (const auto &context : contexts) + { + eglMakeCurrent(display, surface, surface, context.context); + + glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(context.primitiveCounts[pass])); + } + } + + for (const auto &context : contexts) + { + eglMakeCurrent(display, surface, surface, context.context); + + glEndTransformFeedback(); + + glEndQueryEXT(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); + + GLuint result = 0; + glGetQueryObjectuivEXT(context.query, GL_QUERY_RESULT_EXT, &result); + + EXPECT_GL_NO_ERROR(); + + size_t totalPrimCount = 0; + for (const auto &primCount : context.primitiveCounts) + { + totalPrimCount += primCount; + } + EXPECT_EQ(static_cast<GLuint>(totalPrimCount), result); + + const float *bufferData = reinterpret_cast<float *>(glMapBufferRange( + GL_TRANSFORM_FEEDBACK_BUFFER, 0, bufferSize * sizeof(GLfloat), GL_MAP_READ_BIT)); + + size_t curBufferIndex = 0; + for (const auto &primCount : context.primitiveCounts) + { + for (size_t prim = 0; prim < primCount; prim++) + { + EXPECT_EQ(bufferData[curBufferIndex], prim + 1); + curBufferIndex++; + } + } + + while (curBufferIndex < bufferSize) + { + EXPECT_EQ(bufferData[curBufferIndex], 0.0f); + curBufferIndex++; + } + + glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); + } + + eglMakeCurrent(display, surface, surface, window->getContext()); + + for (auto &context : contexts) + { + eglDestroyContext(display, context.context); + context.context = EGL_NO_CONTEXT; + } +} + +// Test that when two vec2s are packed into the same register, we can still capture both of them. +TEST_P(TransformFeedbackTest, PackingBug) +{ + // TODO(jmadill): With points and rasterizer discard? + const std::string &vertexShaderSource = + "#version 300 es\n" + "in vec2 inAttrib1;\n" + "in vec2 inAttrib2;\n" + "out vec2 outAttrib1;\n" + "out vec2 outAttrib2;\n" + "in vec2 position;\n" + "void main() {" + " outAttrib1 = inAttrib1;\n" + " outAttrib2 = inAttrib2;\n" + " gl_Position = vec4(position, 0, 1);\n" + "}"; + + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 color;\n" + "void main() {\n" + " color = vec4(0);\n" + "}"; + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("outAttrib1"); + tfVaryings.push_back("outAttrib2"); + + mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource, + tfVaryings, GL_INTERLEAVED_ATTRIBS); + ASSERT_NE(0u, mProgram); + + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(Vector2) * 2 * 6, nullptr, GL_STREAM_DRAW); + + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer); + + GLint attrib1Loc = glGetAttribLocation(mProgram, "inAttrib1"); + GLint attrib2Loc = glGetAttribLocation(mProgram, "inAttrib2"); + + std::vector<Vector2> attrib1Data; + std::vector<Vector2> attrib2Data; + int counter = 0; + for (size_t i = 0; i < 6; i++) { + attrib1Data.push_back(Vector2(counter + 0.0f, counter + 1.0f)); + attrib2Data.push_back(Vector2(counter + 2.0f, counter + 3.0f)); + counter += 4; + } + + glEnableVertexAttribArray(attrib1Loc); + glEnableVertexAttribArray(attrib2Loc); + + glVertexAttribPointer(attrib1Loc, 2, GL_FLOAT, GL_FALSE, 0, attrib1Data.data()); + glVertexAttribPointer(attrib2Loc, 2, GL_FLOAT, GL_FALSE, 0, attrib2Data.data()); + + glUseProgram(mProgram); + glBeginTransformFeedback(GL_TRIANGLES); + drawQuad(mProgram, "position", 0.5f); + glEndTransformFeedback(); + glUseProgram(0); + ASSERT_GL_NO_ERROR(); + + const GLvoid *mapPointer = + glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vector2) * 2 * 6, GL_MAP_READ_BIT); + ASSERT_NE(nullptr, mapPointer); + + const Vector2 *vecPointer = static_cast<const Vector2 *>(mapPointer); + for (unsigned int vectorIndex = 0; vectorIndex < 3; ++vectorIndex) + { + unsigned int stream1Index = vectorIndex * 2; + unsigned int stream2Index = vectorIndex * 2 + 1; + EXPECT_EQ(attrib1Data[vectorIndex], vecPointer[stream1Index]); + EXPECT_EQ(attrib2Data[vectorIndex], vecPointer[stream2Index]); + } + + ASSERT_GL_NO_ERROR(); +} + +// Test that transform feedback varyings that can be optimized out yet do not cause program +// compilation to fail +TEST_P(TransformFeedbackTest, OptimizedVaryings) +{ + const std::string &vertexShaderSource = + "#version 300 es\n" + "in vec4 a_vertex;\n" + "in vec3 a_normal; \n" + "\n" + "uniform Transform\n" + "{\n" + " mat4 u_modelViewMatrix;\n" + " mat4 u_projectionMatrix;\n" + " mat3 u_normalMatrix;\n" + "};\n" + "\n" + "out vec3 normal;\n" + "out vec4 ecPosition;\n" + "\n" + "void main()\n" + "{\n" + " normal = normalize(u_normalMatrix * a_normal);\n" + " ecPosition = u_modelViewMatrix * a_vertex;\n" + " gl_Position = u_projectionMatrix * ecPosition;\n" + "}\n"; + + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "\n" + "in vec3 normal;\n" + "in vec4 ecPosition;\n" + "\n" + "out vec4 fragColor;\n" + "\n" + "void main()\n" + "{\n" + " fragColor = vec4(normal/2.0+vec3(0.5), 1);\n" + "}\n"; + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("normal"); + tfVaryings.push_back("ecPosition"); + + mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource, + tfVaryings, GL_INTERLEAVED_ATTRIBS); + ASSERT_NE(0u, mProgram); +} + +// Test an edge case where two varyings are unreferenced in the frag shader. +TEST_P(TransformFeedbackTest, TwoUnreferencedInFragShader) +{ + // TODO(jmadill): With points and rasterizer discard? + const std::string &vertexShaderSource = + "#version 300 es\n" + "in vec3 position;\n" + "out vec3 outAttrib1;\n" + "out vec3 outAttrib2;\n" + "void main() {" + " outAttrib1 = position;\n" + " outAttrib2 = position;\n" + " gl_Position = vec4(position, 1);\n" + "}"; + + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 color;\n" + "in vec3 outAttrib1;\n" + "in vec3 outAttrib2;\n" + "void main() {\n" + " color = vec4(0);\n" + "}"; + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("outAttrib1"); + tfVaryings.push_back("outAttrib2"); + + mProgram = CompileProgramWithTransformFeedback(vertexShaderSource, fragmentShaderSource, + tfVaryings, GL_INTERLEAVED_ATTRIBS); + ASSERT_NE(0u, mProgram); + + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(Vector3) * 2 * 6, nullptr, GL_STREAM_DRAW); + + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer); + + glUseProgram(mProgram); + glBeginTransformFeedback(GL_TRIANGLES); + drawQuad(mProgram, "position", 0.5f); + glEndTransformFeedback(); + glUseProgram(0); + ASSERT_GL_NO_ERROR(); + + const GLvoid *mapPointer = + glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vector2) * 2 * 6, GL_MAP_READ_BIT); + ASSERT_NE(nullptr, mapPointer); + + const auto &quadVertices = GetQuadVertices(); + + const Vector3 *vecPointer = static_cast<const Vector3 *>(mapPointer); + for (unsigned int vectorIndex = 0; vectorIndex < 3; ++vectorIndex) + { + unsigned int stream1Index = vectorIndex * 2; + unsigned int stream2Index = vectorIndex * 2 + 1; + EXPECT_EQ(quadVertices[vectorIndex], vecPointer[stream1Index]); + EXPECT_EQ(quadVertices[vectorIndex], vecPointer[stream2Index]); + } + + ASSERT_GL_NO_ERROR(); +} +class TransformFeedbackLifetimeTest : public TransformFeedbackTest +{ + protected: + TransformFeedbackLifetimeTest() : mVertexArray(0) {} + + void SetUp() override + { + ANGLETest::SetUp(); + + glGenVertexArrays(1, &mVertexArray); + glBindVertexArray(mVertexArray); + + std::vector<std::string> tfVaryings; + tfVaryings.push_back("gl_Position"); + compileDefaultProgram(tfVaryings, GL_SEPARATE_ATTRIBS); + + glGenBuffers(1, &mTransformFeedbackBuffer); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBufferSize, NULL, + GL_DYNAMIC_DRAW); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); + + glGenTransformFeedbacks(1, &mTransformFeedback); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteVertexArrays(1, &mVertexArray); + TransformFeedbackTest::TearDown(); + } + + GLuint mVertexArray; +}; + +// Tests a bug with state syncing and deleted transform feedback buffers. +TEST_P(TransformFeedbackLifetimeTest, DeletedBuffer) +{ + // First stream vertex data to mTransformFeedbackBuffer. + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); + glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer); + + glUseProgram(mProgram); + + glBeginTransformFeedback(GL_TRIANGLES); + drawQuad(mProgram, "position", 0.5f, 1.0f, true); + glEndTransformFeedback(); + + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + + // TODO(jmadill): Remove this when http://anglebug.com/1351 is fixed. + glBindVertexArray(0); + drawQuad(mProgram, "position", 0.5f); + glBindVertexArray(1); + + // Next, draw vertices with mTransformFeedbackBuffer. This will link to mVertexArray. + glBindBuffer(GL_ARRAY_BUFFER, mTransformFeedbackBuffer); + GLint loc = glGetAttribLocation(mProgram, "position"); + ASSERT_NE(-1, loc); + glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, 4, nullptr); + glEnableVertexAttribArray(loc); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glDrawArrays(GL_TRIANGLES, 0, 3); + + // Delete resources, making a stranded pointer to mVertexArray in mTransformFeedbackBuffer. + glDeleteBuffers(1, &mTransformFeedbackBuffer); + mTransformFeedbackBuffer = 0; + glDeleteVertexArrays(1, &mVertexArray); + mVertexArray = 0; + + // Then draw again with transform feedback, dereferencing the stranded pointer. + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, mTransformFeedback); + glBeginTransformFeedback(GL_TRIANGLES); + drawQuad(mProgram, "position", 0.5f, 1.0f, true); + glEndTransformFeedback(); + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + + ASSERT_GL_NO_ERROR(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(TransformFeedbackTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +ANGLE_INSTANTIATE_TEST(TransformFeedbackLifetimeTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/UniformBufferTest.cpp b/gfx/angle/src/tests/gl_tests/UniformBufferTest.cpp new file mode 100755 index 000000000..b3577bf30 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/UniformBufferTest.cpp @@ -0,0 +1,573 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" +#include "test_utils/gl_raii.h" + +using namespace angle; + +namespace +{ + +class UniformBufferTest : public ANGLETest +{ + protected: + UniformBufferTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( #version 300 es\n + in vec4 position; + void main() + { + gl_Position = position; + } + ); + const std::string fragmentShaderSource = SHADER_SOURCE + ( #version 300 es\n + precision highp float; + uniform uni { + vec4 color; + }; + + out vec4 fragColor; + + void main() + { + fragColor = color; + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(mProgram, 0u); + + mUniformBufferIndex = glGetUniformBlockIndex(mProgram, "uni"); + ASSERT_NE(mUniformBufferIndex, -1); + + glGenBuffers(1, &mUniformBuffer); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteBuffers(1, &mUniformBuffer); + glDeleteProgram(mProgram); + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLint mUniformBufferIndex; + GLuint mUniformBuffer; +}; + +// Basic UBO functionality. +TEST_P(UniformBufferTest, Simple) +{ + glClear(GL_COLOR_BUFFER_BIT); + float floatData[4] = {0.5f, 0.75f, 0.25f, 1.0f}; + + glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(float) * 4, floatData, GL_STATIC_DRAW); + + glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer); + + glUniformBlockBinding(mProgram, mUniformBufferIndex, 0); + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1); +} + +// Test that using a UBO with a non-zero offset and size actually works. +// The first step of this test renders a color from a UBO with a zero offset. +// The second step renders a color from a UBO with a non-zero offset. +TEST_P(UniformBufferTest, UniformBufferRange) +{ + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + // Query the uniform buffer alignment requirement + GLint alignment; + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment); + + GLint64 maxUniformBlockSize; + glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize); + if (alignment >= maxUniformBlockSize) + { + // ANGLE doesn't implement UBO offsets for this platform. + // Ignore the test case. + return; + } + + ASSERT_GL_NO_ERROR(); + + // Let's create a buffer which contains two vec4. + GLuint vec4Size = 4 * sizeof(float); + GLuint stride = 0; + do + { + stride += alignment; + } + while (stride < vec4Size); + + std::vector<char> v(2 * stride); + float *first = reinterpret_cast<float*>(v.data()); + float *second = reinterpret_cast<float*>(v.data() + stride); + + first[0] = 10.f / 255.f; + first[1] = 20.f / 255.f; + first[2] = 30.f / 255.f; + first[3] = 40.f / 255.f; + + second[0] = 110.f / 255.f; + second[1] = 120.f / 255.f; + second[2] = 130.f / 255.f; + second[3] = 140.f / 255.f; + + glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer); + // We use on purpose a size which is not a multiple of the alignment. + glBufferData(GL_UNIFORM_BUFFER, stride + vec4Size, v.data(), GL_STATIC_DRAW); + + glUniformBlockBinding(mProgram, mUniformBufferIndex, 0); + + EXPECT_GL_NO_ERROR(); + + // Bind the first part of the uniform buffer and draw + // Use a size which is smaller than the alignment to check + // to check that this case is handle correctly in the conversion to 11.1. + glBindBufferRange(GL_UNIFORM_BUFFER, 0, mUniformBuffer, 0, vec4Size); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, 10, 20, 30, 40); + + // Bind the second part of the uniform buffer and draw + // Furthermore the D3D11.1 backend will internally round the vec4Size (16 bytes) to a stride (256 bytes) + // hence it will try to map the range [stride, 2 * stride] which is + // out-of-bound of the buffer bufferSize = stride + vec4Size < 2 * stride. + // Ensure that this behaviour works. + glBindBufferRange(GL_UNIFORM_BUFFER, 0, mUniformBuffer, stride, vec4Size); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, 110, 120, 130, 140); +} + +// Test uniform block bindings. +TEST_P(UniformBufferTest, UniformBufferBindings) +{ + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + ASSERT_GL_NO_ERROR(); + + // Let's create a buffer which contains one vec4. + GLuint vec4Size = 4 * sizeof(float); + std::vector<char> v(vec4Size); + float *first = reinterpret_cast<float*>(v.data()); + + first[0] = 10.f / 255.f; + first[1] = 20.f / 255.f; + first[2] = 30.f / 255.f; + first[3] = 40.f / 255.f; + + glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer); + glBufferData(GL_UNIFORM_BUFFER, vec4Size, v.data(), GL_STATIC_DRAW); + + EXPECT_GL_NO_ERROR(); + + // Try to bind the buffer to binding point 2 + glUniformBlockBinding(mProgram, mUniformBufferIndex, 2); + glBindBufferBase(GL_UNIFORM_BUFFER, 2, mUniformBuffer); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, 10, 20, 30, 40); + + // Clear the framebuffer + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + EXPECT_PIXEL_EQ(px, py, 0, 0, 0, 0); + + // Try to bind the buffer to another binding point + glUniformBlockBinding(mProgram, mUniformBufferIndex, 5); + glBindBufferBase(GL_UNIFORM_BUFFER, 5, mUniformBuffer); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, 10, 20, 30, 40); +} + +// Test that ANGLE handles used but unbound UBO. +// TODO: A test case shouldn't depend on the error code of an undefined behaviour. Move this to unit tests of the validation layer. +TEST_P(UniformBufferTest, UnboundUniformBuffer) +{ + glUniformBlockBinding(mProgram, mUniformBufferIndex, 0); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0); + EXPECT_GL_NO_ERROR(); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Update a UBO many time and verify that ANGLE uses the latest version of the data. +// https://code.google.com/p/angleproject/issues/detail?id=965 +TEST_P(UniformBufferTest, UniformBufferManyUpdates) +{ + // TODO(jmadill): Figure out why this fails on Intel OpenGL. + if (IsIntel() && IsOpenGL()) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + ASSERT_GL_NO_ERROR(); + + float data[4]; + + glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer); + glBufferData(GL_UNIFORM_BUFFER, sizeof(data), NULL, GL_DYNAMIC_DRAW); + glUniformBlockBinding(mProgram, mUniformBufferIndex, 0); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer); + + EXPECT_GL_NO_ERROR(); + + // Repeteadly update the data and draw + for (size_t i = 0; i < 10; ++i) + { + data[0] = (i + 10.f) / 255.f; + data[1] = (i + 20.f) / 255.f; + data[2] = (i + 30.f) / 255.f; + data[3] = (i + 40.f) / 255.f; + + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(data), data); + + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, i + 10, i + 20, i + 30, i + 40); + } +} + +// Use a large number of buffer ranges (compared to the actual size of the UBO) +TEST_P(UniformBufferTest, ManyUniformBufferRange) +{ + int px = getWindowWidth() / 2; + int py = getWindowHeight() / 2; + + // Query the uniform buffer alignment requirement + GLint alignment; + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment); + + GLint64 maxUniformBlockSize; + glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize); + if (alignment >= maxUniformBlockSize) + { + // ANGLE doesn't implement UBO offsets for this platform. + // Ignore the test case. + return; + } + + ASSERT_GL_NO_ERROR(); + + // Let's create a buffer which contains eight vec4. + GLuint vec4Size = 4 * sizeof(float); + GLuint stride = 0; + do + { + stride += alignment; + } + while (stride < vec4Size); + + std::vector<char> v(8 * stride); + + for (size_t i = 0; i < 8; ++i) + { + float *data = reinterpret_cast<float*>(v.data() + i * stride); + + data[0] = (i + 10.f) / 255.f; + data[1] = (i + 20.f) / 255.f; + data[2] = (i + 30.f) / 255.f; + data[3] = (i + 40.f) / 255.f; + } + + glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer); + glBufferData(GL_UNIFORM_BUFFER, v.size(), v.data(), GL_STATIC_DRAW); + + glUniformBlockBinding(mProgram, mUniformBufferIndex, 0); + + EXPECT_GL_NO_ERROR(); + + // Bind each possible offset + for (size_t i = 0; i < 8; ++i) + { + glBindBufferRange(GL_UNIFORM_BUFFER, 0, mUniformBuffer, i * stride, stride); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, 10 + i, 20 + i, 30 + i, 40 + i); + } + + // Try to bind larger range + for (size_t i = 0; i < 7; ++i) + { + glBindBufferRange(GL_UNIFORM_BUFFER, 0, mUniformBuffer, i * stride, 2 * stride); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, 10 + i, 20 + i, 30 + i, 40 + i); + } + + // Try to bind even larger range + for (size_t i = 0; i < 5; ++i) + { + glBindBufferRange(GL_UNIFORM_BUFFER, 0, mUniformBuffer, i * stride, 4 * stride); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(px, py, 10 + i, 20 + i, 30 + i, 40 + i); + } +} + +// Tests that active uniforms have the right names. +TEST_P(UniformBufferTest, ActiveUniformNames) +{ + const std::string &vertexShaderSource = + "#version 300 es\n" + "in vec2 position;\n" + "out vec2 v;\n" + "uniform blockName1 {\n" + " float f1;\n" + "} instanceName1;\n" + "uniform blockName2 {\n" + " float f2;\n" + "} instanceName2[1];\n" + "void main() {\n" + " v = vec2(instanceName1.f1, instanceName2[0].f2);\n" + " gl_Position = vec4(position, 0, 1);\n" + "}"; + + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "in vec2 v;\n" + "out vec4 color;\n" + "void main() {\n" + " color = vec4(v, 0, 1);\n" + "}"; + + GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); + ASSERT_NE(0u, program); + + GLint activeUniformBlocks; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks); + ASSERT_EQ(2, activeUniformBlocks); + + GLint maxLength; + GLsizei length; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxLength); + std::vector<GLchar> strBlockNameBuffer(maxLength + 1, 0); + glGetActiveUniformBlockName(program, 0, maxLength, &length, &strBlockNameBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ("blockName1", std::string(&strBlockNameBuffer[0])); + + glGetActiveUniformBlockName(program, 1, maxLength, &length, &strBlockNameBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ("blockName2[0]", std::string(&strBlockNameBuffer[0])); + + GLint activeUniforms; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms); + + ASSERT_EQ(2, activeUniforms); + + GLint size; + GLenum type; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); + std::vector<GLchar> strUniformNameBuffer(maxLength + 1, 0); + glGetActiveUniform(program, 0, maxLength, &length, &size, &type, &strUniformNameBuffer[0]); + + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_GLENUM_EQ(GL_FLOAT, type); + EXPECT_EQ("blockName1.f1", std::string(&strUniformNameBuffer[0])); + + glGetActiveUniform(program, 1, maxLength, &length, &size, &type, &strUniformNameBuffer[0]); + + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_GLENUM_EQ(GL_FLOAT, type); + EXPECT_EQ("blockName2.f2", std::string(&strUniformNameBuffer[0])); +} + +// Tests active uniforms and blocks when the layout is std140, shared and packed. +TEST_P(UniformBufferTest, ActiveUniformNumberAndName) +{ + // TODO(Jiajia): Figure out why this fails on Intel on Mac. + // This case can pass on Intel Mac-10.11/10.12. But it fails on Intel Mac-10.10. + if (IsIntel() && IsOSX()) + { + std::cout << "Test skipped on Intel on Mac." << std::endl; + return; + } + + // This case fails on all AMD platforms (Mac, Linux, Win). + // TODO(zmo): This actually passes on certain AMD cards, but we don't have + // a way to do device specific handling yet. + if (IsAMD()) + { + std::cout << "Test skipped on AMD." << std::endl; + return; + } + + const std::string &vertexShaderSource = + "#version 300 es\n" + "in vec2 position;\n" + "out float v;\n" + "struct S {\n" + " highp ivec3 a;\n" + " mediump ivec2 b[4];\n" + "};\n" + "layout(std140) uniform blockName0 {\n" + " S s0;\n" + " lowp vec2 v0;\n" + " S s1[2];\n" + " highp uint u0;\n" + "};\n" + "layout(std140) uniform blockName1 {\n" + " float f1;\n" + " bool b1;\n" + "} instanceName1;\n" + "layout(shared) uniform blockName2 {\n" + " float f2;\n" + "};\n" + "layout(packed) uniform blockName3 {\n" + " float f3;\n" + "};\n" + "void main() {\n" + " v = instanceName1.f1;\n" + " gl_Position = vec4(position, 0, 1);\n" + "}"; + + const std::string &fragmentShaderSource = + "#version 300 es\n" + "precision highp float;\n" + "in float v;\n" + "out vec4 color;\n" + "void main() {\n" + " color = vec4(v, 0, 0, 1);\n" + "}"; + + ANGLE_GL_PROGRAM(program, vertexShaderSource, fragmentShaderSource); + + // Note that the packed |blockName3| might (or might not) be optimized out. + GLint activeUniforms; + glGetProgramiv(program.get(), GL_ACTIVE_UNIFORMS, &activeUniforms); + EXPECT_GE(activeUniforms, 11); + + GLint activeUniformBlocks; + glGetProgramiv(program.get(), GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks); + EXPECT_GE(activeUniformBlocks, 3); + + GLint maxLength, size; + GLenum type; + GLsizei length; + glGetProgramiv(program.get(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); + std::vector<GLchar> strBuffer(maxLength + 1, 0); + + glGetActiveUniform(program.get(), 0, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("s0.a", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 1, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(4, size); + EXPECT_EQ("s0.b[0]", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 2, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("v0", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 3, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("s1[0].a", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 4, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(4, size); + EXPECT_EQ("s1[0].b[0]", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 5, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("s1[1].a", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 6, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(4, size); + EXPECT_EQ("s1[1].b[0]", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 7, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("u0", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 8, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("blockName1.f1", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 9, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("blockName1.b1", std::string(&strBuffer[0])); + + glGetActiveUniform(program.get(), 10, maxLength, &length, &size, &type, &strBuffer[0]); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, size); + EXPECT_EQ("f2", std::string(&strBuffer[0])); +} + +// Test that using a very large buffer to back a small uniform block works OK. +TEST_P(UniformBufferTest, VeryLarge) +{ + glClear(GL_COLOR_BUFFER_BIT); + float floatData[4] = {0.5f, 0.75f, 0.25f, 1.0f}; + + GLsizei bigSize = 4096 * 64; + std::vector<GLubyte> zero(bigSize, 0); + + glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer); + glBufferData(GL_UNIFORM_BUFFER, bigSize, zero.data(), GL_STATIC_DRAW); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(float) * 4, floatData); + + glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer); + + glUniformBlockBinding(mProgram, mUniformBufferIndex, 0); + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(UniformBufferTest, + ES3_D3D11(), + ES3_D3D11_FL11_1(), + ES3_D3D11_FL11_1_REFERENCE(), + ES3_OPENGL(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/UniformTest.cpp b/gfx/angle/src/tests/gl_tests/UniformTest.cpp new file mode 100755 index 000000000..4dd2738ef --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/UniformTest.cpp @@ -0,0 +1,682 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +#include <array> +#include <cmath> + +using namespace angle; + +namespace +{ + +class UniformTest : public ANGLETest +{ + protected: + UniformTest() : mProgram(0), mUniformFLocation(-1), mUniformILocation(-1), mUniformBLocation(-1) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string &vertexShader = "void main() { gl_Position = vec4(1); }"; + const std::string &fragShader = + "precision mediump float;\n" + "uniform float uniF;\n" + "uniform int uniI;\n" + "uniform bool uniB;\n" + "uniform bool uniBArr[4];\n" + "void main() {\n" + " gl_FragColor = vec4(uniF + float(uniI));\n" + " gl_FragColor += vec4(uniB ? 1.0 : 0.0);\n" + " gl_FragColor += vec4(uniBArr[0] ? 1.0 : 0.0);\n" + "}"; + + mProgram = CompileProgram(vertexShader, fragShader); + ASSERT_NE(mProgram, 0u); + + mUniformFLocation = glGetUniformLocation(mProgram, "uniF"); + ASSERT_NE(mUniformFLocation, -1); + + mUniformILocation = glGetUniformLocation(mProgram, "uniI"); + ASSERT_NE(mUniformILocation, -1); + + mUniformBLocation = glGetUniformLocation(mProgram, "uniB"); + ASSERT_NE(mUniformBLocation, -1); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + ANGLETest::TearDown(); + } + + GLuint mProgram; + GLint mUniformFLocation; + GLint mUniformILocation; + GLint mUniformBLocation; +}; + +TEST_P(UniformTest, GetUniformNoCurrentProgram) +{ + glUseProgram(mProgram); + glUniform1f(mUniformFLocation, 1.0f); + glUniform1i(mUniformILocation, 1); + glUseProgram(0); + + GLfloat f; + glGetnUniformfvEXT(mProgram, mUniformFLocation, 4, &f); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1.0f, f); + + glGetUniformfv(mProgram, mUniformFLocation, &f); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1.0f, f); + + GLint i; + glGetnUniformivEXT(mProgram, mUniformILocation, 4, &i); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, i); + + glGetUniformiv(mProgram, mUniformILocation, &i); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(1, i); +} + +TEST_P(UniformTest, UniformArrayLocations) +{ + // TODO(geofflang): Figure out why this is broken on Intel OpenGL + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + const std::string vertexShader = SHADER_SOURCE + ( + precision mediump float; + uniform float uPosition[4]; + void main(void) + { + gl_Position = vec4(uPosition[0], uPosition[1], uPosition[2], uPosition[3]); + } + ); + + const std::string fragShader = SHADER_SOURCE + ( + precision mediump float; + uniform float uColor[4]; + void main(void) + { + gl_FragColor = vec4(uColor[0], uColor[1], uColor[2], uColor[3]); + } + ); + + GLuint program = CompileProgram(vertexShader, fragShader); + ASSERT_NE(program, 0u); + + // Array index zero should be equivalent to the un-indexed uniform + EXPECT_NE(-1, glGetUniformLocation(program, "uPosition")); + EXPECT_EQ(glGetUniformLocation(program, "uPosition"), glGetUniformLocation(program, "uPosition[0]")); + + EXPECT_NE(-1, glGetUniformLocation(program, "uColor")); + EXPECT_EQ(glGetUniformLocation(program, "uColor"), glGetUniformLocation(program, "uColor[0]")); + + // All array uniform locations should be unique + GLint positionLocations[4] = + { + glGetUniformLocation(program, "uPosition[0]"), + glGetUniformLocation(program, "uPosition[1]"), + glGetUniformLocation(program, "uPosition[2]"), + glGetUniformLocation(program, "uPosition[3]"), + }; + + GLint colorLocations[4] = + { + glGetUniformLocation(program, "uColor[0]"), + glGetUniformLocation(program, "uColor[1]"), + glGetUniformLocation(program, "uColor[2]"), + glGetUniformLocation(program, "uColor[3]"), + }; + + for (size_t i = 0; i < 4; i++) + { + EXPECT_NE(-1, positionLocations[i]); + EXPECT_NE(-1, colorLocations[i]); + + for (size_t j = i + 1; j < 4; j++) + { + EXPECT_NE(positionLocations[i], positionLocations[j]); + EXPECT_NE(colorLocations[i], colorLocations[j]); + } + } + + glDeleteProgram(program); +} + +// Test that float to integer GetUniform rounds values correctly. +TEST_P(UniformTest, FloatUniformStateQuery) +{ + std::vector<double> inValues; + std::vector<GLfloat> expectedFValues; + std::vector<GLint> expectedIValues; + + double intMaxD = static_cast<double>(std::numeric_limits<GLint>::max()); + double intMinD = static_cast<double>(std::numeric_limits<GLint>::min()); + + // TODO(jmadill): Investigate rounding of .5 + inValues.push_back(-1.0); + inValues.push_back(-0.6); + // inValues.push_back(-0.5); // undefined behaviour? + inValues.push_back(-0.4); + inValues.push_back(0.0); + inValues.push_back(0.4); + // inValues.push_back(0.5); // undefined behaviour? + inValues.push_back(0.6); + inValues.push_back(1.0); + inValues.push_back(999999.2); + inValues.push_back(intMaxD * 2.0); + inValues.push_back(intMaxD + 1.0); + inValues.push_back(intMinD * 2.0); + inValues.push_back(intMinD - 1.0); + + for (double value : inValues) + { + expectedFValues.push_back(static_cast<GLfloat>(value)); + + double clampedValue = std::max(intMinD, std::min(intMaxD, value)); + double rounded = round(clampedValue); + expectedIValues.push_back(static_cast<GLint>(rounded)); + } + + glUseProgram(mProgram); + ASSERT_GL_NO_ERROR(); + + for (size_t index = 0; index < inValues.size(); ++index) + { + GLfloat inValue = static_cast<GLfloat>(inValues[index]); + GLfloat expectedValue = expectedFValues[index]; + + glUniform1f(mUniformFLocation, inValue); + GLfloat testValue; + glGetUniformfv(mProgram, mUniformFLocation, &testValue); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(expectedValue, testValue); + } + + for (size_t index = 0; index < inValues.size(); ++index) + { + GLfloat inValue = static_cast<GLfloat>(inValues[index]); + GLint expectedValue = expectedIValues[index]; + + glUniform1f(mUniformFLocation, inValue); + GLint testValue; + glGetUniformiv(mProgram, mUniformFLocation, &testValue); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(expectedValue, testValue); + } +} + +// Test that integer to float GetUniform rounds values correctly. +TEST_P(UniformTest, IntUniformStateQuery) +{ + std::vector<GLint> inValues; + std::vector<GLint> expectedIValues; + std::vector<GLfloat> expectedFValues; + + GLint intMax = std::numeric_limits<GLint>::max(); + GLint intMin = std::numeric_limits<GLint>::min(); + + inValues.push_back(-1); + inValues.push_back(0); + inValues.push_back(1); + inValues.push_back(999999); + inValues.push_back(intMax); + inValues.push_back(intMax - 1); + inValues.push_back(intMin); + inValues.push_back(intMin + 1); + + for (GLint value : inValues) + { + expectedIValues.push_back(value); + expectedFValues.push_back(static_cast<GLfloat>(value)); + } + + glUseProgram(mProgram); + ASSERT_GL_NO_ERROR(); + + for (size_t index = 0; index < inValues.size(); ++index) + { + GLint inValue = inValues[index]; + GLint expectedValue = expectedIValues[index]; + + glUniform1i(mUniformILocation, inValue); + GLint testValue; + glGetUniformiv(mProgram, mUniformILocation, &testValue); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(expectedValue, testValue); + } + + for (size_t index = 0; index < inValues.size(); ++index) + { + GLint inValue = inValues[index]; + GLfloat expectedValue = expectedFValues[index]; + + glUniform1i(mUniformILocation, inValue); + GLfloat testValue; + glGetUniformfv(mProgram, mUniformILocation, &testValue); + ASSERT_GL_NO_ERROR(); + EXPECT_EQ(expectedValue, testValue); + } +} + +// Test that queries of boolean uniforms round correctly. +TEST_P(UniformTest, BooleanUniformStateQuery) +{ + glUseProgram(mProgram); + GLint intValue = 0; + GLfloat floatValue = 0.0f; + + // Calling Uniform1i + glUniform1i(mUniformBLocation, GL_FALSE); + + glGetUniformiv(mProgram, mUniformBLocation, &intValue); + EXPECT_EQ(0, intValue); + + glGetUniformfv(mProgram, mUniformBLocation, &floatValue); + EXPECT_EQ(0.0f, floatValue); + + glUniform1i(mUniformBLocation, GL_TRUE); + + glGetUniformiv(mProgram, mUniformBLocation, &intValue); + EXPECT_EQ(1, intValue); + + glGetUniformfv(mProgram, mUniformBLocation, &floatValue); + EXPECT_EQ(1.0f, floatValue); + + // Calling Uniform1f + glUniform1f(mUniformBLocation, 0.0f); + + glGetUniformiv(mProgram, mUniformBLocation, &intValue); + EXPECT_EQ(0, intValue); + + glGetUniformfv(mProgram, mUniformBLocation, &floatValue); + EXPECT_EQ(0.0f, floatValue); + + glUniform1f(mUniformBLocation, 1.0f); + + glGetUniformiv(mProgram, mUniformBLocation, &intValue); + EXPECT_EQ(1, intValue); + + glGetUniformfv(mProgram, mUniformBLocation, &floatValue); + EXPECT_EQ(1.0f, floatValue); + + ASSERT_GL_NO_ERROR(); +} + +// Test queries for arrays of boolean uniforms. +TEST_P(UniformTest, BooleanArrayUniformStateQuery) +{ + glUseProgram(mProgram); + GLint boolValuesi[4] = {0, 1, 0, 1}; + GLfloat boolValuesf[4] = {0, 1, 0, 1}; + + GLint locations[4] = { + glGetUniformLocation(mProgram, "uniBArr"), + glGetUniformLocation(mProgram, "uniBArr[1]"), + glGetUniformLocation(mProgram, "uniBArr[2]"), + glGetUniformLocation(mProgram, "uniBArr[3]"), + }; + + // Calling Uniform1iv + glUniform1iv(locations[0], 4, boolValuesi); + + for (unsigned int idx = 0; idx < 4; ++idx) + { + int value = -1; + glGetUniformiv(mProgram, locations[idx], &value); + EXPECT_EQ(boolValuesi[idx], value); + } + + for (unsigned int idx = 0; idx < 4; ++idx) + { + float value = -1.0f; + glGetUniformfv(mProgram, locations[idx], &value); + EXPECT_EQ(boolValuesf[idx], value); + } + + // Calling Uniform1fv + glUniform1fv(locations[0], 4, boolValuesf); + + for (unsigned int idx = 0; idx < 4; ++idx) + { + int value = -1; + glGetUniformiv(mProgram, locations[idx], &value); + EXPECT_EQ(boolValuesi[idx], value); + } + + for (unsigned int idx = 0; idx < 4; ++idx) + { + float value = -1.0f; + glGetUniformfv(mProgram, locations[idx], &value); + EXPECT_EQ(boolValuesf[idx], value); + } + + ASSERT_GL_NO_ERROR(); +} + +class UniformTestES3 : public ANGLETest +{ + protected: + UniformTestES3() : mProgram(0) {} + + void SetUp() override + { + ANGLETest::SetUp(); + } + + void TearDown() override + { + if (mProgram != 0) + { + glDeleteProgram(mProgram); + mProgram = 0; + } + } + + GLuint mProgram; +}; + +// Test queries for transposed arrays of non-square matrix uniforms. +TEST_P(UniformTestES3, TranposedMatrixArrayUniformStateQuery) +{ + const std::string &vertexShader = + "#version 300 es\n" + "void main() { gl_Position = vec4(1); }"; + const std::string &fragShader = + "#version 300 es\n" + "precision mediump float;\n" + "uniform mat3x2 uniMat3x2[5];\n" + "out vec4 color;\n" + "void main() {\n" + " color = vec4(uniMat3x2[0][0][0]);\n" + "}"; + + mProgram = CompileProgram(vertexShader, fragShader); + ASSERT_NE(mProgram, 0u); + + glUseProgram(mProgram); + + std::vector<GLfloat> transposedValues; + + for (size_t arrayElement = 0; arrayElement < 5; ++arrayElement) + { + transposedValues.push_back(1.0f + arrayElement); + transposedValues.push_back(3.0f + arrayElement); + transposedValues.push_back(5.0f + arrayElement); + transposedValues.push_back(2.0f + arrayElement); + transposedValues.push_back(4.0f + arrayElement); + transposedValues.push_back(6.0f + arrayElement); + } + + // Setting as a clump + GLint baseLocation = glGetUniformLocation(mProgram, "uniMat3x2"); + ASSERT_NE(-1, baseLocation); + + glUniformMatrix3x2fv(baseLocation, 5, GL_TRUE, &transposedValues[0]); + + for (size_t arrayElement = 0; arrayElement < 5; ++arrayElement) + { + std::stringstream nameStr; + nameStr << "uniMat3x2[" << arrayElement << "]"; + std::string name = nameStr.str(); + GLint location = glGetUniformLocation(mProgram, name.c_str()); + ASSERT_NE(-1, location); + + std::vector<GLfloat> sequentialValues(6, 0); + glGetUniformfv(mProgram, location, &sequentialValues[0]); + + ASSERT_GL_NO_ERROR(); + + for (size_t comp = 0; comp < 6; ++comp) + { + EXPECT_EQ(static_cast<GLfloat>(comp + 1 + arrayElement), sequentialValues[comp]); + } + } +} + +// Check that trying setting too many elements of an array doesn't overflow +TEST_P(UniformTestES3, OverflowArray) +{ + const std::string &vertexShader = + "#version 300 es\n" + "void main() { gl_Position = vec4(1); }"; + const std::string &fragShader = + "#version 300 es\n" + "precision mediump float;\n" + "uniform float uniF[5];\n" + "uniform mat3x2 uniMat3x2[5];\n" + "out vec4 color;\n" + "void main() {\n" + " color = vec4(uniMat3x2[0][0][0] + uniF[0]);\n" + "}"; + + mProgram = CompileProgram(vertexShader, fragShader); + ASSERT_NE(mProgram, 0u); + + glUseProgram(mProgram); + + const size_t kOverflowSize = 10000; + std::vector<GLfloat> values(10000 * 6); + + // Setting as a clump + GLint floatLocation = glGetUniformLocation(mProgram, "uniF"); + ASSERT_NE(-1, floatLocation); + GLint matLocation = glGetUniformLocation(mProgram, "uniMat3x2"); + ASSERT_NE(-1, matLocation); + + // Set too many float uniforms + glUniform1fv(floatLocation, kOverflowSize, &values[0]); + + // Set too many matrix uniforms, transposed or not + glUniformMatrix3x2fv(matLocation, kOverflowSize, GL_FALSE, &values[0]); + glUniformMatrix3x2fv(matLocation, kOverflowSize, GL_TRUE, &values[0]); + + // Same checks but with offsets + GLint floatLocationOffset = glGetUniformLocation(mProgram, "uniF[3]"); + ASSERT_NE(-1, floatLocationOffset); + GLint matLocationOffset = glGetUniformLocation(mProgram, "uniMat3x2[3]"); + ASSERT_NE(-1, matLocationOffset); + + glUniform1fv(floatLocationOffset, kOverflowSize, &values[0]); + glUniformMatrix3x2fv(matLocationOffset, kOverflowSize, GL_FALSE, &values[0]); + glUniformMatrix3x2fv(matLocationOffset, kOverflowSize, GL_TRUE, &values[0]); +} + +// Check that sampler uniforms only show up one time in the list +TEST_P(UniformTest, SamplerUniformsAppearOnce) +{ + int maxVertexTextureImageUnits = 0; + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextureImageUnits); + + if (maxVertexTextureImageUnits == 0) + { + std::cout << "Renderer doesn't support vertex texture fetch, skipping test" << std::endl; + return; + } + + const std::string &vertShader = + "attribute vec2 position;\n" + "uniform sampler2D tex2D;\n" + "varying vec4 color;\n" + "void main() {\n" + " gl_Position = vec4(position, 0, 1);\n" + " color = texture2D(tex2D, vec2(0));\n" + "}"; + + const std::string &fragShader = + "precision mediump float;\n" + "varying vec4 color;\n" + "uniform sampler2D tex2D;\n" + "void main() {\n" + " gl_FragColor = texture2D(tex2D, vec2(0)) + color;\n" + "}"; + + GLuint program = CompileProgram(vertShader, fragShader); + ASSERT_NE(0u, program); + + GLint activeUniformsCount = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniformsCount); + ASSERT_EQ(1, activeUniformsCount); + + GLint size = 0; + GLenum type = GL_NONE; + GLchar name[120] = {0}; + glGetActiveUniform(program, 0, 100, nullptr, &size, &type, name); + EXPECT_EQ(1, size); + EXPECT_GLENUM_EQ(GL_SAMPLER_2D, type); + EXPECT_STREQ("tex2D", name); + + EXPECT_GL_NO_ERROR(); + + glDeleteProgram(program); +} + +template <typename T, typename GetUniformV> +void CheckOneElement(GetUniformV getUniformv, + GLuint program, + const std::string &name, + int components, + T canary) +{ + // The buffer getting the results has three chunks + // - A chunk to see underflows + // - A chunk that will hold the result + // - A chunk to see overflows for when components = kChunkSize + static const size_t kChunkSize = 4; + std::array<T, 3 * kChunkSize> buffer; + buffer.fill(canary); + + GLint location = glGetUniformLocation(program, name.c_str()); + ASSERT_NE(location, -1); + + getUniformv(program, location, &buffer[kChunkSize]); + for (size_t i = 0; i < kChunkSize; i++) + { + ASSERT_EQ(canary, buffer[i]); + } + for (size_t i = kChunkSize + components; i < buffer.size(); i++) + { + ASSERT_EQ(canary, buffer[i]); + } +} + +// Check that getting an element array doesn't return the whole array. +TEST_P(UniformTestES3, ReturnsOnlyOneArrayElement) +{ + static const size_t kArraySize = 4; + struct UniformArrayInfo + { + UniformArrayInfo(std::string type, std::string name, int components) + : type(type), name(name), components(components) + { + } + std::string type; + std::string name; + int components; + }; + + // Check for various number of components and types + std::vector<UniformArrayInfo> uniformArrays; + uniformArrays.emplace_back("bool", "uBool", 1); + uniformArrays.emplace_back("vec2", "uFloat", 2); + uniformArrays.emplace_back("ivec3", "uInt", 3); + uniformArrays.emplace_back("uvec4", "uUint", 4); + + std::ostringstream uniformStream; + std::ostringstream additionStream; + for (const auto &array : uniformArrays) + { + uniformStream << "uniform " << array.type << " " << array.name << "[" + << ToString(kArraySize) << "];\n"; + + // We need to make use of the uniforms or they get compiled out. + for (int i = 0; i < 4; i++) + { + if (array.components == 1) + { + additionStream << " + float(" << array.name << "[" << i << "])"; + } + else + { + for (int component = 0; component < array.components; component++) + { + additionStream << " + float(" << array.name << "[" << i << "][" << component + << "])"; + } + } + } + } + + const std::string &vertexShader = + "#version 300 es\n" + + uniformStream.str() + + "void main()\n" + "{\n" + " gl_Position = vec4(1.0" + additionStream.str() + ");\n" + "}"; + + const std::string &fragmentShader = + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 color;\n" + "void main ()\n" + "{\n" + " color = vec4(1, 0, 0, 1);\n" + "}"; + + mProgram = CompileProgram(vertexShader, fragmentShader); + ASSERT_NE(0u, mProgram); + + glUseProgram(mProgram); + + for (const auto &uniformArray : uniformArrays) + { + for (size_t index = 0; index < kArraySize; index++) + { + std::string strIndex = "[" + ToString(index) + "]"; + // Check all the different glGetUniformv functions + CheckOneElement<float>(glGetUniformfv, mProgram, uniformArray.name + strIndex, + uniformArray.components, 42.4242f); + CheckOneElement<int>(glGetUniformiv, mProgram, uniformArray.name + strIndex, + uniformArray.components, 0x7BADBED5); + CheckOneElement<unsigned int>(glGetUniformuiv, mProgram, uniformArray.name + strIndex, + uniformArray.components, 0xDEADBEEF); + } + } +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(UniformTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES2_OPENGLES()); +ANGLE_INSTANTIATE_TEST(UniformTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/UnpackAlignmentTest.cpp b/gfx/angle/src/tests/gl_tests/UnpackAlignmentTest.cpp new file mode 100755 index 000000000..2a3f76bc6 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/UnpackAlignmentTest.cpp @@ -0,0 +1,325 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class UnpackAlignmentTest : public ANGLETest +{ + protected: + UnpackAlignmentTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + + mProgram = 0; + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + + void main() + { + gl_Position = position; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + uniform sampler2D tex; + + void main() + { + gl_FragColor = texture2D(tex, vec2(0.0, 1.0)); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + void getPixelSize(GLenum format, GLenum type, unsigned int* size) + { + switch (type) + { + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + *size = sizeof(GLushort); + break; + + case GL_UNSIGNED_BYTE: + { + unsigned int compCount = 0; + switch (format) + { + case GL_RGBA: compCount = 4; break; + case GL_RGB: compCount = 3; break; + case GL_LUMINANCE_ALPHA: compCount = 2; break; + case GL_LUMINANCE: compCount = 1; break; + case GL_ALPHA: compCount = 1; break; + default: FAIL() << "unknown pixel format."; + } + *size = sizeof(GLubyte) * compCount; + } + break; + default: + FAIL() << "unknown pixel type."; + } + } + + bool formatHasRGB(GLenum format) + { + return (format != GL_ALPHA); + } + + void testAlignment(int alignment, unsigned int offset, GLenum format, GLenum type) + { + static const unsigned int width = 7; + static const unsigned int height = 2; + + glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); + + GLint readbackAlignment; + glGetIntegerv(GL_UNPACK_ALIGNMENT, &readbackAlignment); + EXPECT_EQ(alignment, readbackAlignment); + + GLubyte buf[1024]; + memset(buf, 0, sizeof(buf)); + + unsigned int pixelSize; + getPixelSize(format, type, &pixelSize); + for (unsigned int i = 0; i < pixelSize; i++) + { + buf[offset+i] = 0xFF; + } + + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, &buf[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + drawQuad(mProgram, "position", 0.5f); + + GLubyte expectedRGB = formatHasRGB(format) ? 255 : 0; + EXPECT_PIXEL_EQ(0, 0, expectedRGB, expectedRGB, expectedRGB, 255); + + glDeleteTextures(1, &tex); + } + + GLuint mProgram; +}; + +TEST_P(UnpackAlignmentTest, DefaultAlignment) +{ + GLint defaultAlignment; + glGetIntegerv(GL_UNPACK_ALIGNMENT, &defaultAlignment); + EXPECT_EQ(defaultAlignment, 4); +} + + +TEST_P(UnpackAlignmentTest, Alignment1RGBAUByte) +{ + testAlignment(1, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment1RGBUByte) +{ + testAlignment(1, 7 * 3, GL_RGB, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment1RGBAUShort4444) +{ + testAlignment(1, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); +} + +TEST_P(UnpackAlignmentTest, Alignment1RGBAUShort5551) +{ + testAlignment(1, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); +} + +TEST_P(UnpackAlignmentTest, Alignment1RGBAUShort565) +{ + testAlignment(1, 7 * 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); +} + +TEST_P(UnpackAlignmentTest, Alignment1LAUByte) +{ + testAlignment(1, 7 * 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment1LUByte) +{ + testAlignment(1, 7, GL_LUMINANCE, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment1AUByte) +{ + testAlignment(1, 7, GL_ALPHA, GL_UNSIGNED_BYTE); +} + + +TEST_P(UnpackAlignmentTest, Alignment2RGBAUByte) +{ + testAlignment(2, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment2RGBUByte) +{ + testAlignment(2, 7 * 3 + 1, GL_RGB, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment2RGBAUShort4444) +{ + testAlignment(2, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); +} + +TEST_P(UnpackAlignmentTest, Alignment2RGBAUShort5551) +{ + testAlignment(2, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); +} + +TEST_P(UnpackAlignmentTest, Alignment2RGBAUShort565) +{ + testAlignment(2, 7 * 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); +} + +TEST_P(UnpackAlignmentTest, Alignment2LAUByte) +{ + testAlignment(2, 7 * 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment2LAByte) +{ + testAlignment(2, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment2AUByte) +{ + testAlignment(2, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE); +} + + +TEST_P(UnpackAlignmentTest, Alignment4RGBAUByte) +{ + testAlignment(4, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment4RGBUByte) +{ + testAlignment(4, 7 * 3 + 3, GL_RGB, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment4RGBAUShort4444) +{ + testAlignment(4, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); +} + +TEST_P(UnpackAlignmentTest, Alignment4RGBAUShort5551) +{ + testAlignment(4, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); +} + +TEST_P(UnpackAlignmentTest, Alignment4RGBAUShort565) +{ + testAlignment(4, 7 * 2 + 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); +} + +TEST_P(UnpackAlignmentTest, Alignment4LAUByte) +{ + testAlignment(4, 7 * 2 + 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment4LUByte) +{ + testAlignment(4, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment4AUByte) +{ + testAlignment(4, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE); +} + + +TEST_P(UnpackAlignmentTest, Alignment8RGBAUByte) +{ + testAlignment(8, 7 * 4 + 4, GL_RGBA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment8RGBUByte) +{ + testAlignment(8, 7 * 3 + 3, GL_RGB, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment8RGBAUShort4444) +{ + testAlignment(8, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); +} + +TEST_P(UnpackAlignmentTest, Alignment8RGBAUShort5551) +{ + testAlignment(8, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1); +} + +TEST_P(UnpackAlignmentTest, Alignment8RGBAUShort565) +{ + testAlignment(8, 7 * 2 + 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5); +} + +TEST_P(UnpackAlignmentTest, Alignment8LAUByte) +{ + testAlignment(8, 7 * 2 + 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment8LUByte) +{ + testAlignment(8, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE); +} + +TEST_P(UnpackAlignmentTest, Alignment8AUByte) +{ + testAlignment(8, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(UnpackAlignmentTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/UnpackRowLength.cpp b/gfx/angle/src/tests/gl_tests/UnpackRowLength.cpp new file mode 100755 index 000000000..05ad59526 --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/UnpackRowLength.cpp @@ -0,0 +1,130 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class UnpackRowLengthTest : public ANGLETest +{ + protected: + UnpackRowLengthTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + + mProgram = 0; + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vertexShaderSource = SHADER_SOURCE + ( + precision highp float; + attribute vec4 position; + + void main() + { + gl_Position = position; + } + ); + + const std::string fragmentShaderSource = SHADER_SOURCE + ( + uniform sampler2D tex; + + void main() + { + gl_FragColor = texture2D(tex, vec2(0.0, 1.0)); + } + ); + + mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + void testRowLength(int texSize, int rowLength) + { + glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength); + + if ((getClientMajorVersion() == 3) || extensionEnabled("GL_EXT_unpack_subimage")) + { + // Only texSize * texSize region is filled as WHITE, other parts are BLACK. + // If the UNPACK_ROW_LENGTH is implemented correctly, all texels inside this texture are WHITE. + std::vector<GLubyte> buf(rowLength * texSize * 4); + for (int y = 0; y < texSize; y++) + { + std::vector<GLubyte>::iterator rowIter = buf.begin() + y * rowLength * 4; + std::fill(rowIter, rowIter + texSize * 4, static_cast<GLubyte>(255u)); + std::fill(rowIter + texSize * 4, rowIter + rowLength * 4, static_cast<GLubyte>(0u)); + } + + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texSize, texSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, &buf[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + drawQuad(mProgram, "position", 0.5f); + + EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255); + EXPECT_PIXEL_EQ(1, 0, 255, 255, 255, 255); + + glDeleteTextures(1, &tex); + } + else + { + EXPECT_GL_ERROR(GL_INVALID_ENUM); + } + } + + GLuint mProgram; +}; + +TEST_P(UnpackRowLengthTest, RowLength128) +{ + testRowLength(128, 128); +} + +TEST_P(UnpackRowLengthTest, RowLength1024) +{ + testRowLength(128, 1024); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +ANGLE_INSTANTIATE_TEST(UnpackRowLengthTest, + ES3_D3D11(), + ES2_D3D11(), + ES2_D3D9(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/VertexAttributeTest.cpp b/gfx/angle/src/tests/gl_tests/VertexAttributeTest.cpp new file mode 100755 index 000000000..b1b9dcd1f --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/VertexAttributeTest.cpp @@ -0,0 +1,894 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +GLsizei TypeStride(GLenum attribType) +{ + switch (attribType) + { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + return 1; + case GL_UNSIGNED_SHORT: + case GL_SHORT: + return 2; + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FLOAT: + return 4; + default: + UNREACHABLE(); + return 0; + } +} + +template <typename T> +GLfloat Normalize(T value) +{ + static_assert(std::is_integral<T>::value, "Integer required."); + if (std::is_signed<T>::value) + { + typedef typename std::make_unsigned<T>::type unsigned_type; + return (2.0f * static_cast<GLfloat>(value) + 1.0f) / + static_cast<GLfloat>(std::numeric_limits<unsigned_type>::max()); + } + else + { + return static_cast<GLfloat>(value) / static_cast<GLfloat>(std::numeric_limits<T>::max()); + } +} + +class VertexAttributeTest : public ANGLETest +{ + protected: + VertexAttributeTest() + : mProgram(0), mTestAttrib(-1), mExpectedAttrib(-1), mBuffer(0), mQuadBuffer(0) + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + } + + enum class Source + { + BUFFER, + IMMEDIATE, + }; + + struct TestData final : angle::NonCopyable + { + TestData(GLenum typeIn, + GLboolean normalizedIn, + Source sourceIn, + const void *inputDataIn, + const GLfloat *expectedDataIn) + : type(typeIn), + normalized(normalizedIn), + bufferOffset(0), + source(sourceIn), + inputData(inputDataIn), + expectedData(expectedDataIn) + { + } + + GLenum type; + GLboolean normalized; + size_t bufferOffset; + Source source; + + const void *inputData; + const GLfloat *expectedData; + }; + + void setupTest(const TestData &test, GLint typeSize) + { + if (mProgram == 0) + { + initBasicProgram(); + } + + if (test.source == Source::BUFFER) + { + GLsizei dataSize = mVertexCount * TypeStride(test.type); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glBufferData(GL_ARRAY_BUFFER, dataSize, test.inputData, GL_STATIC_DRAW); + glVertexAttribPointer(mTestAttrib, typeSize, test.type, test.normalized, 0, + reinterpret_cast<GLvoid *>(test.bufferOffset)); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + else + { + ASSERT_EQ(Source::IMMEDIATE, test.source); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(mTestAttrib, typeSize, test.type, test.normalized, 0, + test.inputData); + } + + glVertexAttribPointer(mExpectedAttrib, typeSize, GL_FLOAT, GL_FALSE, 0, test.expectedData); + + glEnableVertexAttribArray(mTestAttrib); + glEnableVertexAttribArray(mExpectedAttrib); + } + + void checkPixels() + { + GLint viewportSize[4]; + glGetIntegerv(GL_VIEWPORT, viewportSize); + + GLint midPixelX = (viewportSize[0] + viewportSize[2]) / 2; + GLint midPixelY = (viewportSize[1] + viewportSize[3]) / 2; + + // We need to offset our checks from triangle edges to ensure we don't fall on a single tri + // Avoid making assumptions of drawQuad with four checks to check the four possible tri + // regions + EXPECT_PIXEL_EQ((midPixelX + viewportSize[0]) / 2, midPixelY, 255, 255, 255, 255); + EXPECT_PIXEL_EQ((midPixelX + viewportSize[2]) / 2, midPixelY, 255, 255, 255, 255); + EXPECT_PIXEL_EQ(midPixelX, (midPixelY + viewportSize[1]) / 2, 255, 255, 255, 255); + EXPECT_PIXEL_EQ(midPixelX, (midPixelY + viewportSize[3]) / 2, 255, 255, 255, 255); + } + + void runTest(const TestData &test) + { + // TODO(geofflang): Figure out why this is broken on AMD OpenGL + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + + for (GLint i = 0; i < 4; i++) + { + GLint typeSize = i + 1; + setupTest(test, typeSize); + + drawQuad(mProgram, "position", 0.5f); + + glDisableVertexAttribArray(mTestAttrib); + glDisableVertexAttribArray(mExpectedAttrib); + + checkPixels(); + } + } + + void SetUp() override + { + ANGLETest::SetUp(); + + glClearColor(0, 0, 0, 0); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glDisable(GL_DEPTH_TEST); + + glGenBuffers(1, &mBuffer); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + glDeleteBuffers(1, &mBuffer); + glDeleteBuffers(1, &mQuadBuffer); + + ANGLETest::TearDown(); + } + + GLuint compileMultiAttribProgram(GLint attribCount) + { + std::stringstream shaderStream; + + shaderStream << "attribute mediump vec4 position;" << std::endl; + for (GLint attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + shaderStream << "attribute float a" << attribIndex << ";" << std::endl; + } + shaderStream << "varying mediump float color;" << std::endl + << "void main() {" << std::endl + << " gl_Position = position;" << std::endl + << " color = 0.0;" << std::endl; + for (GLint attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + shaderStream << " color += a" << attribIndex << ";" << std::endl; + } + shaderStream << "}" << std::endl; + + const std::string testFragmentShaderSource = + SHADER_SOURCE(varying mediump float color; void main(void) + { + gl_FragColor = vec4(color, 0.0, 0.0, 1.0); + }); + + return CompileProgram(shaderStream.str(), testFragmentShaderSource); + } + + void setupMultiAttribs(GLuint program, GLint attribCount, GLfloat value) + { + glUseProgram(program); + for (GLint attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + std::stringstream attribStream; + attribStream << "a" << attribIndex; + GLint location = glGetAttribLocation(program, attribStream.str().c_str()); + ASSERT_NE(-1, location); + glVertexAttrib1f(location, value); + glDisableVertexAttribArray(location); + } + } + + void initBasicProgram() + { + const std::string testVertexShaderSource = + "attribute mediump vec4 position;\n" + "attribute mediump vec4 test;\n" + "attribute mediump vec4 expected;\n" + "varying mediump vec4 color;\n" + "void main(void)\n" + "{\n" + " gl_Position = position;\n" + " vec4 threshold = max(abs(expected) * 0.01, 1.0 / 64.0);\n" + " color = vec4(lessThanEqual(abs(test - expected), threshold));\n" + "}\n"; + + const std::string testFragmentShaderSource = + "varying mediump vec4 color;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = color;\n" + "}\n"; + + mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource); + ASSERT_NE(0u, mProgram); + + mTestAttrib = glGetAttribLocation(mProgram, "test"); + ASSERT_NE(-1, mTestAttrib); + mExpectedAttrib = glGetAttribLocation(mProgram, "expected"); + ASSERT_NE(-1, mExpectedAttrib); + + glUseProgram(mProgram); + } + + static const size_t mVertexCount = 24; + + GLuint mProgram; + GLint mTestAttrib; + GLint mExpectedAttrib; + GLuint mBuffer; + GLuint mQuadBuffer; +}; + +TEST_P(VertexAttributeTest, UnsignedByteUnnormalized) +{ + GLubyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, 5, 6, 7, 125, 126, 127, 128, 129, 250, 251, 252, 253, 254, 255 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = inputData[i]; + } + + TestData data(GL_UNSIGNED_BYTE, GL_FALSE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTest, UnsignedByteNormalized) +{ + GLubyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, 5, 6, 7, 125, 126, 127, 128, 129, 250, 251, 252, 253, 254, 255 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = Normalize(inputData[i]); + } + + TestData data(GL_UNSIGNED_BYTE, GL_TRUE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTest, ByteUnnormalized) +{ + GLbyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, -1, -2, -3, -4, 125, 126, 127, -128, -127, -126 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = inputData[i]; + } + + TestData data(GL_BYTE, GL_FALSE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTest, ByteNormalized) +{ + GLbyte inputData[mVertexCount] = { 0, 1, 2, 3, 4, -1, -2, -3, -4, 125, 126, 127, -128, -127, -126 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = Normalize(inputData[i]); + } + + TestData data(GL_BYTE, GL_TRUE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTest, UnsignedShortUnnormalized) +{ + GLushort inputData[mVertexCount] = { 0, 1, 2, 3, 254, 255, 256, 32766, 32767, 32768, 65533, 65534, 65535 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = inputData[i]; + } + + TestData data(GL_UNSIGNED_SHORT, GL_FALSE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTest, UnsignedShortNormalized) +{ + GLushort inputData[mVertexCount] = { 0, 1, 2, 3, 254, 255, 256, 32766, 32767, 32768, 65533, 65534, 65535 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = Normalize(inputData[i]); + } + + TestData data(GL_UNSIGNED_SHORT, GL_TRUE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTest, ShortUnnormalized) +{ + GLshort inputData[mVertexCount] = { 0, 1, 2, 3, -1, -2, -3, -4, 32766, 32767, -32768, -32767, -32766 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = inputData[i]; + } + + TestData data(GL_SHORT, GL_FALSE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTest, ShortNormalized) +{ + GLshort inputData[mVertexCount] = { 0, 1, 2, 3, -1, -2, -3, -4, 32766, 32767, -32768, -32767, -32766 }; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = Normalize(inputData[i]); + } + + TestData data(GL_SHORT, GL_TRUE, Source::IMMEDIATE, inputData, expectedData); + runTest(data); +} + +class VertexAttributeTestES3 : public VertexAttributeTest +{ + protected: + VertexAttributeTestES3() {} +}; + +TEST_P(VertexAttributeTestES3, IntUnnormalized) +{ + GLint lo = std::numeric_limits<GLint>::min(); + GLint hi = std::numeric_limits<GLint>::max(); + GLint inputData[mVertexCount] = {0, 1, 2, 3, -1, -2, -3, -4, -1, hi, hi - 1, lo, lo + 1}; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = static_cast<GLfloat>(inputData[i]); + } + + TestData data(GL_INT, GL_FALSE, Source::BUFFER, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTestES3, IntNormalized) +{ + GLint lo = std::numeric_limits<GLint>::min(); + GLint hi = std::numeric_limits<GLint>::max(); + GLint inputData[mVertexCount] = {0, 1, 2, 3, -1, -2, -3, -4, -1, hi, hi - 1, lo, lo + 1}; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = Normalize(inputData[i]); + } + + TestData data(GL_INT, GL_TRUE, Source::BUFFER, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTestES3, UnsignedIntUnnormalized) +{ + GLuint mid = std::numeric_limits<GLuint>::max() >> 1; + GLuint hi = std::numeric_limits<GLuint>::max(); + GLuint inputData[mVertexCount] = {0, 1, 2, 3, 254, 255, 256, + mid - 1, mid, mid + 1, hi - 2, hi - 1, hi}; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = static_cast<GLfloat>(inputData[i]); + } + + TestData data(GL_UNSIGNED_INT, GL_FALSE, Source::BUFFER, inputData, expectedData); + runTest(data); +} + +TEST_P(VertexAttributeTestES3, UnsignedIntNormalized) +{ + GLuint mid = std::numeric_limits<GLuint>::max() >> 1; + GLuint hi = std::numeric_limits<GLuint>::max(); + GLuint inputData[mVertexCount] = {0, 1, 2, 3, 254, 255, 256, + mid - 1, mid, mid + 1, hi - 2, hi - 1, hi}; + GLfloat expectedData[mVertexCount]; + for (size_t i = 0; i < mVertexCount; i++) + { + expectedData[i] = Normalize(inputData[i]); + } + + TestData data(GL_UNSIGNED_INT, GL_TRUE, Source::BUFFER, inputData, expectedData); + runTest(data); +} + +// Validate that we can support GL_MAX_ATTRIBS attribs +TEST_P(VertexAttributeTest, MaxAttribs) +{ + // TODO(jmadill): Figure out why we get this error on AMD/OpenGL and Intel. + if ((IsIntel() || IsAMD()) && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel and AMD." << std::endl; + return; + } + + GLint maxAttribs; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); + ASSERT_GL_NO_ERROR(); + + // Reserve one attrib for position + GLint drawAttribs = maxAttribs - 1; + + GLuint program = compileMultiAttribProgram(drawAttribs); + ASSERT_NE(0u, program); + + setupMultiAttribs(program, drawAttribs, 0.5f / static_cast<float>(drawAttribs)); + drawQuad(program, "position", 0.5f); + + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 1); +} + +// Validate that we cannot support GL_MAX_ATTRIBS+1 attribs +TEST_P(VertexAttributeTest, MaxAttribsPlusOne) +{ + // TODO(jmadill): Figure out why we get this error on AMD/ES2/OpenGL + if (IsAMD() && GetParam() == ES2_OPENGL()) + { + std::cout << "Test disabled on AMD/ES2/OpenGL" << std::endl; + return; + } + + GLint maxAttribs; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs); + ASSERT_GL_NO_ERROR(); + + // Exceed attrib count by one (counting position) + GLint drawAttribs = maxAttribs; + + GLuint program = compileMultiAttribProgram(drawAttribs); + ASSERT_EQ(0u, program); +} + +// Simple test for when we use glBindAttribLocation +TEST_P(VertexAttributeTest, SimpleBindAttribLocation) +{ + // TODO(jmadill): Figure out why this fails on Intel. + if (IsIntel() && GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel." << std::endl; + return; + } + + // Re-use the multi-attrib program, binding attribute 0 + GLuint program = compileMultiAttribProgram(1); + glBindAttribLocation(program, 2, "position"); + glBindAttribLocation(program, 3, "a0"); + glLinkProgram(program); + + // Setup and draw the quad + setupMultiAttribs(program, 1, 0.5f); + drawQuad(program, "position", 0.5f); + EXPECT_GL_NO_ERROR(); + EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 1); +} + +// Verify that drawing with a large out-of-range offset generates INVALID_OPERATION. +TEST_P(VertexAttributeTest, DrawArraysBufferTooSmall) +{ + GLfloat inputData[mVertexCount]; + GLfloat expectedData[mVertexCount]; + for (size_t count = 0; count < mVertexCount; ++count) + { + inputData[count] = static_cast<GLfloat>(count); + expectedData[count] = inputData[count]; + } + + TestData data(GL_FLOAT, GL_FALSE, Source::BUFFER, inputData, expectedData); + data.bufferOffset = mVertexCount * TypeStride(GL_FLOAT); + + setupTest(data, 1); + drawQuad(mProgram, "position", 0.5f); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Verify that index draw with an out-of-range offset generates INVALID_OPERATION. +TEST_P(VertexAttributeTest, DrawElementsBufferTooSmall) +{ + GLfloat inputData[mVertexCount]; + GLfloat expectedData[mVertexCount]; + for (size_t count = 0; count < mVertexCount; ++count) + { + inputData[count] = static_cast<GLfloat>(count); + expectedData[count] = inputData[count]; + } + + TestData data(GL_FLOAT, GL_FALSE, Source::BUFFER, inputData, expectedData); + data.bufferOffset = (mVertexCount - 3) * TypeStride(GL_FLOAT); + + setupTest(data, 1); + drawIndexedQuad(mProgram, "position", 0.5f); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Verify that using a different start vertex doesn't mess up the draw. +TEST_P(VertexAttributeTest, DrawArraysWithBufferOffset) +{ + // TODO(jmadill): Diagnose this failure. + if (IsD3D11_FL93()) + { + std::cout << "Test disabled on D3D11 FL 9_3" << std::endl; + return; + } + + // TODO(geofflang): Figure out why this is broken on AMD OpenGL + if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + + initBasicProgram(); + glUseProgram(mProgram); + + GLfloat inputData[mVertexCount]; + GLfloat expectedData[mVertexCount]; + for (size_t count = 0; count < mVertexCount; ++count) + { + inputData[count] = static_cast<GLfloat>(count); + expectedData[count] = inputData[count]; + } + + auto quadVertices = GetQuadVertices(); + GLsizei quadVerticesSize = static_cast<GLsizei>(quadVertices.size() * sizeof(quadVertices[0])); + + glGenBuffers(1, &mQuadBuffer); + glBindBuffer(GL_ARRAY_BUFFER, mQuadBuffer); + glBufferData(GL_ARRAY_BUFFER, quadVerticesSize + sizeof(Vector3), nullptr, GL_STATIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, quadVerticesSize, quadVertices.data()); + + GLint positionLocation = glGetAttribLocation(mProgram, "position"); + ASSERT_NE(-1, positionLocation); + glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + glEnableVertexAttribArray(positionLocation); + + GLsizei dataSize = mVertexCount * TypeStride(GL_FLOAT); + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glBufferData(GL_ARRAY_BUFFER, dataSize + TypeStride(GL_FLOAT), nullptr, GL_STATIC_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, dataSize, inputData); + glVertexAttribPointer(mTestAttrib, 1, GL_FLOAT, GL_FALSE, 0, nullptr); + glEnableVertexAttribArray(mTestAttrib); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(mExpectedAttrib, 1, GL_FLOAT, GL_FALSE, 0, expectedData); + glEnableVertexAttribArray(mExpectedAttrib); + + // Vertex draw with no start vertex offset (second argument is zero). + glDrawArrays(GL_TRIANGLES, 0, 6); + checkPixels(); + + // Draw offset by one vertex. + glDrawArrays(GL_TRIANGLES, 1, 6); + checkPixels(); + + EXPECT_GL_NO_ERROR(); +} + +class VertexAttributeCachingTest : public VertexAttributeTest +{ + protected: + VertexAttributeCachingTest() {} + + void SetUp() override; + + template <typename DestT> + static std::vector<GLfloat> GetExpectedData(const std::vector<GLubyte> &srcData, + GLenum attribType, + GLboolean normalized); + + void initDoubleAttribProgram() + { + const std::string testVertexShaderSource = + "attribute mediump vec4 position;\n" + "attribute mediump vec4 test;\n" + "attribute mediump vec4 expected;\n" + "attribute mediump vec4 test2;\n" + "attribute mediump vec4 expected2;\n" + "varying mediump vec4 color;\n" + "void main(void)\n" + "{\n" + " gl_Position = position;\n" + " vec4 threshold = max(abs(expected) * 0.01, 1.0 / 64.0);\n" + " color = vec4(lessThanEqual(abs(test - expected), threshold));\n" + " vec4 threshold2 = max(abs(expected2) * 0.01, 1.0 / 64.0);\n" + " color += vec4(lessThanEqual(abs(test2 - expected2), threshold2));\n" + "}\n"; + + const std::string testFragmentShaderSource = + "varying mediump vec4 color;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = color;\n" + "}\n"; + + mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource); + ASSERT_NE(0u, mProgram); + + mTestAttrib = glGetAttribLocation(mProgram, "test"); + ASSERT_NE(-1, mTestAttrib); + mExpectedAttrib = glGetAttribLocation(mProgram, "expected"); + ASSERT_NE(-1, mExpectedAttrib); + + glUseProgram(mProgram); + } + + struct AttribData + { + AttribData(GLenum typeIn, GLint sizeIn, GLboolean normalizedIn, GLsizei strideIn); + + GLenum type; + GLint size; + GLboolean normalized; + GLsizei stride; + }; + + std::vector<AttribData> mTestData; + std::map<GLenum, std::vector<GLfloat>> mExpectedData; + std::map<GLenum, std::vector<GLfloat>> mNormExpectedData; +}; + +VertexAttributeCachingTest::AttribData::AttribData(GLenum typeIn, + GLint sizeIn, + GLboolean normalizedIn, + GLsizei strideIn) + : type(typeIn), size(sizeIn), normalized(normalizedIn), stride(strideIn) +{ +} + +// static +template <typename DestT> +std::vector<GLfloat> VertexAttributeCachingTest::GetExpectedData( + const std::vector<GLubyte> &srcData, + GLenum attribType, + GLboolean normalized) +{ + std::vector<GLfloat> expectedData; + + const DestT *typedSrcPtr = reinterpret_cast<const DestT *>(srcData.data()); + size_t iterations = srcData.size() / TypeStride(attribType); + + if (normalized) + { + for (size_t index = 0; index < iterations; ++index) + { + expectedData.push_back(Normalize(typedSrcPtr[index])); + } + } + else + { + for (size_t index = 0; index < iterations; ++index) + { + expectedData.push_back(static_cast<GLfloat>(typedSrcPtr[index])); + } + } + + return expectedData; +} + +void VertexAttributeCachingTest::SetUp() +{ + VertexAttributeTest::SetUp(); + + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + + std::vector<GLubyte> srcData; + for (size_t count = 0; count < 4; ++count) + { + for (GLubyte i = 0; i < std::numeric_limits<GLubyte>::max(); ++i) + { + srcData.push_back(i); + } + } + + glBufferData(GL_ARRAY_BUFFER, srcData.size(), srcData.data(), GL_STATIC_DRAW); + + GLint viewportSize[4]; + glGetIntegerv(GL_VIEWPORT, viewportSize); + + std::vector<GLenum> attribTypes; + attribTypes.push_back(GL_BYTE); + attribTypes.push_back(GL_UNSIGNED_BYTE); + attribTypes.push_back(GL_SHORT); + attribTypes.push_back(GL_UNSIGNED_SHORT); + + if (getClientMajorVersion() >= 3) + { + attribTypes.push_back(GL_INT); + attribTypes.push_back(GL_UNSIGNED_INT); + } + + const GLint maxSize = 4; + const GLsizei maxStride = 4; + + for (GLenum attribType : attribTypes) + { + for (GLint attribSize = 1; attribSize <= maxSize; ++attribSize) + { + for (GLsizei stride = 1; stride <= maxStride; ++stride) + { + mTestData.push_back(AttribData(attribType, attribSize, GL_FALSE, stride)); + if (attribType != GL_FLOAT) + { + mTestData.push_back(AttribData(attribType, attribSize, GL_TRUE, stride)); + } + } + } + } + + mExpectedData[GL_BYTE] = GetExpectedData<GLbyte>(srcData, GL_BYTE, GL_FALSE); + mExpectedData[GL_UNSIGNED_BYTE] = GetExpectedData<GLubyte>(srcData, GL_UNSIGNED_BYTE, GL_FALSE); + mExpectedData[GL_SHORT] = GetExpectedData<GLshort>(srcData, GL_SHORT, GL_FALSE); + mExpectedData[GL_UNSIGNED_SHORT] = + GetExpectedData<GLushort>(srcData, GL_UNSIGNED_SHORT, GL_FALSE); + mExpectedData[GL_INT] = GetExpectedData<GLint>(srcData, GL_INT, GL_FALSE); + mExpectedData[GL_UNSIGNED_INT] = GetExpectedData<GLuint>(srcData, GL_UNSIGNED_INT, GL_FALSE); + + mNormExpectedData[GL_BYTE] = GetExpectedData<GLbyte>(srcData, GL_BYTE, GL_TRUE); + mNormExpectedData[GL_UNSIGNED_BYTE] = + GetExpectedData<GLubyte>(srcData, GL_UNSIGNED_BYTE, GL_TRUE); + mNormExpectedData[GL_SHORT] = GetExpectedData<GLshort>(srcData, GL_SHORT, GL_TRUE); + mNormExpectedData[GL_UNSIGNED_SHORT] = + GetExpectedData<GLushort>(srcData, GL_UNSIGNED_SHORT, GL_TRUE); + mNormExpectedData[GL_INT] = GetExpectedData<GLint>(srcData, GL_INT, GL_TRUE); + mNormExpectedData[GL_UNSIGNED_INT] = GetExpectedData<GLuint>(srcData, GL_UNSIGNED_INT, GL_TRUE); +} + +// In D3D11, we must sometimes translate buffer data into static attribute caches. We also use a +// cache management scheme which garbage collects old attributes after we start using too much +// cache data. This test tries to make as many attribute caches from a single buffer as possible +// to stress-test the caching code. +TEST_P(VertexAttributeCachingTest, BufferMulticaching) +{ + if (IsAMD() && IsDesktopOpenGL()) + { + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + + initBasicProgram(); + + glEnableVertexAttribArray(mTestAttrib); + glEnableVertexAttribArray(mExpectedAttrib); + + ASSERT_GL_NO_ERROR(); + + for (const auto &data : mTestData) + { + const auto &expected = + (data.normalized) ? mNormExpectedData[data.type] : mExpectedData[data.type]; + + GLsizei baseStride = static_cast<GLsizei>(data.size) * data.stride; + GLsizei stride = TypeStride(data.type) * baseStride; + + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glVertexAttribPointer(mTestAttrib, data.size, data.type, data.normalized, stride, nullptr); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(mExpectedAttrib, data.size, GL_FLOAT, GL_FALSE, + sizeof(GLfloat) * baseStride, expected.data()); + drawQuad(mProgram, "position", 0.5f); + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 255, 255, 255); + } +} + +// With D3D11 dirty bits for VertxArray11, we can leave vertex state unchanged if there aren't any +// GL calls that affect it. This test targets leaving one vertex attribute unchanged between draw +// calls while changing another vertex attribute enough that it clears the static buffer cache +// after enough iterations. It validates the unchanged attributes don't get deleted incidentally. +TEST_P(VertexAttributeCachingTest, BufferMulticachingWithOneUnchangedAttrib) +{ + if (IsAMD() && IsDesktopOpenGL()) + { + std::cout << "Test skipped on AMD OpenGL." << std::endl; + return; + } + + initDoubleAttribProgram(); + + GLint testAttrib2Location = glGetAttribLocation(mProgram, "test2"); + ASSERT_NE(-1, testAttrib2Location); + GLint expectedAttrib2Location = glGetAttribLocation(mProgram, "expected2"); + ASSERT_NE(-1, expectedAttrib2Location); + + glEnableVertexAttribArray(mTestAttrib); + glEnableVertexAttribArray(mExpectedAttrib); + glEnableVertexAttribArray(testAttrib2Location); + glEnableVertexAttribArray(expectedAttrib2Location); + + ASSERT_GL_NO_ERROR(); + + // Use an attribute that we know must be converted. This is a bit sensitive. + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glVertexAttribPointer(testAttrib2Location, 3, GL_UNSIGNED_SHORT, GL_FALSE, 6, nullptr); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(expectedAttrib2Location, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, + mExpectedData[GL_UNSIGNED_SHORT].data()); + + for (const auto &data : mTestData) + { + const auto &expected = + (data.normalized) ? mNormExpectedData[data.type] : mExpectedData[data.type]; + + GLsizei baseStride = static_cast<GLsizei>(data.size) * data.stride; + GLsizei stride = TypeStride(data.type) * baseStride; + + glBindBuffer(GL_ARRAY_BUFFER, mBuffer); + glVertexAttribPointer(mTestAttrib, data.size, data.type, data.normalized, stride, nullptr); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(mExpectedAttrib, data.size, GL_FLOAT, GL_FALSE, + sizeof(GLfloat) * baseStride, expected.data()); + drawQuad(mProgram, "position", 0.5f); + + ASSERT_GL_NO_ERROR(); + EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 255, 255, 255); + } +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +// D3D11 Feature Level 9_3 uses different D3D formats for vertex attribs compared to Feature Levels 10_0+, so we should test them separately. +ANGLE_INSTANTIATE_TEST(VertexAttributeTest, + ES2_D3D9(), + ES2_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +ANGLE_INSTANTIATE_TEST(VertexAttributeTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); + +ANGLE_INSTANTIATE_TEST(VertexAttributeCachingTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES3_OPENGL()); + +} // anonymous namespace diff --git a/gfx/angle/src/tests/gl_tests/ViewportTest.cpp b/gfx/angle/src/tests/gl_tests/ViewportTest.cpp new file mode 100755 index 000000000..8cd9cd3df --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ViewportTest.cpp @@ -0,0 +1,272 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class ViewportTest : public ANGLETest +{ + protected: + ViewportTest() + { + setWindowWidth(512); + setWindowHeight(512); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + + mProgram = 0; + } + + void runNonScissoredTest() + { + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + runTest(); + } + + void runScissoredTest() + { + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_SCISSOR_TEST); + glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2); + + runTest(); + } + + void runTest() + { + // Firstly ensure that no errors have been hit. + EXPECT_GL_NO_ERROR(); + + GLint viewportSize[4]; + glGetIntegerv(GL_VIEWPORT, viewportSize); + + // Clear to green. Might be a scissored clear, if scissorSize != window size + glClearColor(0, 1, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + // Draw a red quad centered in the middle of the viewport, with dimensions 25% of the size of the viewport. + drawQuad(mProgram, "position", 0.5f, 0.25f); + + GLint centerViewportX = viewportSize[0] + (viewportSize[2] / 2); + GLint centerViewportY = viewportSize[1] + (viewportSize[3] / 2); + + GLint redQuadLeftSideX = viewportSize[0] + viewportSize[2] * 3 / 8; + GLint redQuadRightSideX = viewportSize[0] + viewportSize[2] * 5 / 8; + GLint redQuadTopSideY = viewportSize[1] + viewportSize[3] * 3 / 8; + GLint redQuadBottomSideY = viewportSize[1] + viewportSize[3] * 5 / 8; + + // The midpoint of the viewport should be red. + checkPixel(centerViewportX, centerViewportY, true); + + // Pixels just inside the red quad should be red. + checkPixel(redQuadLeftSideX, redQuadTopSideY, true); + checkPixel(redQuadLeftSideX, redQuadBottomSideY - 1, true); + checkPixel(redQuadRightSideX - 1, redQuadTopSideY, true); + checkPixel(redQuadRightSideX - 1, redQuadBottomSideY - 1, true); + + // Pixels just outside the red quad shouldn't be red. + checkPixel(redQuadLeftSideX - 1, redQuadTopSideY - 1, false); + checkPixel(redQuadLeftSideX - 1, redQuadBottomSideY, false); + checkPixel(redQuadRightSideX, redQuadTopSideY - 1, false); + checkPixel(redQuadRightSideX, redQuadBottomSideY, false); + + // Pixels just within the viewport shouldn't be red. + checkPixel(viewportSize[0], viewportSize[1], false); + checkPixel(viewportSize[0], viewportSize[1] + viewportSize[3] - 1, false); + checkPixel(viewportSize[0] + viewportSize[2] - 1, viewportSize[1], false); + checkPixel(viewportSize[0] + viewportSize[2] - 1, viewportSize[1] + viewportSize[3] - 1, false); + } + + void checkPixel(GLint x, GLint y, GLboolean renderedRed) + { + // By default, expect the pixel to be black. + GLint expectedRedChannel = 0; + GLint expectedGreenChannel = 0; + + GLint scissorSize[4]; + glGetIntegerv(GL_SCISSOR_BOX, scissorSize); + + EXPECT_GL_NO_ERROR(); + + if (scissorSize[0] <= x && x < scissorSize[0] + scissorSize[2] + && scissorSize[1] <= y && y < scissorSize[1] + scissorSize[3]) + { + // If the pixel lies within the scissor rect, then it should have been cleared to green. + // If we rendered a red square on top of it, then the pixel should be red (the green channel will have been reset to 0). + expectedRedChannel = renderedRed ? 255 : 0; + expectedGreenChannel = renderedRed ? 0 : 255; + } + + // If the pixel is within the bounds of the window, then we check it. Otherwise we skip it. + if (0 <= x && x < getWindowWidth() && 0 <= y && y < getWindowHeight()) + { + EXPECT_PIXEL_EQ(x, y, expectedRedChannel, expectedGreenChannel, 0, 255); + } + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string testVertexShaderSource = SHADER_SOURCE + ( + attribute highp vec4 position; + + void main(void) + { + gl_Position = position; + } + ); + + const std::string testFragmentShaderSource = SHADER_SOURCE + ( + void main(void) + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + glUseProgram(mProgram); + + glClearColor(0, 0, 0, 1); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Call glViewport and glScissor with default parameters. + glScissor(0, 0, getWindowWidth(), getWindowHeight()); + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + + glDisable(GL_DEPTH_TEST); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram; +}; + +TEST_P(ViewportTest, QuarterWindow) +{ + glViewport(0, 0, getWindowWidth() / 4, getWindowHeight() / 4); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, QuarterWindowCentered) +{ + glViewport(getWindowWidth() * 3 / 8, getWindowHeight() * 3 / 8, getWindowWidth() / 4, getWindowHeight() / 4); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, FullWindow) +{ + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, FullWindowOffCenter) +{ + glViewport(-getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth(), getWindowHeight()); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, DoubleWindow) +{ + glViewport(0, 0, getWindowWidth() * 2, getWindowHeight() * 2); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, DoubleWindowCentered) +{ + glViewport(-getWindowWidth() / 2, -getWindowHeight() / 2, getWindowWidth() * 2, getWindowHeight() * 2); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, DoubleWindowOffCenter) +{ + glViewport(-getWindowWidth() * 3 / 4, getWindowHeight() * 3 / 4, getWindowWidth(), getWindowHeight()); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, TripleWindow) +{ + glViewport(0, 0, getWindowWidth() * 3, getWindowHeight() * 3); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, TripleWindowCentered) +{ + glViewport(-getWindowWidth(), -getWindowHeight(), getWindowWidth() * 3, getWindowHeight() * 3); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, TripleWindowOffCenter) +{ + glViewport(-getWindowWidth() * 3 / 2, -getWindowHeight() * 3 / 2, getWindowWidth() * 3, getWindowHeight() * 3); + + runNonScissoredTest(); + + runScissoredTest(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +// D3D11 Feature Level 9 and D3D9 emulate large and negative viewports in the vertex shader. We should test both of these as well as D3D11 Feature Level 10_0+. +ANGLE_INSTANTIATE_TEST(ViewportTest, + ES2_D3D9(), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE), + ES2_D3D11_FL9_3(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/gfx/angle/src/tests/gl_tests/WebGLCompatibilityTest.cpp new file mode 100644 index 000000000..48a9d2bae --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/WebGLCompatibilityTest.cpp @@ -0,0 +1,154 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// WebGLCompatibilityTest.cpp : Tests of the GL_ANGLE_webgl_compatibility extension. + +#include "test_utils/ANGLETest.h" + +#include "test_utils/gl_raii.h" + +namespace angle +{ + +class WebGLCompatibilityTest : public ANGLETest +{ + protected: + WebGLCompatibilityTest() + { + setWindowWidth(128); + setWindowHeight(128); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setWebGLCompatibilityEnabled(true); + } + + void SetUp() override + { + ANGLETest::SetUp(); + glEnableExtensionANGLE = reinterpret_cast<PFNGLENABLEEXTENSIONANGLEPROC>( + eglGetProcAddress("glEnableExtensionANGLE")); + } + + void TearDown() override { ANGLETest::TearDown(); } + + PFNGLENABLEEXTENSIONANGLEPROC glEnableExtensionANGLE = nullptr; +}; + +// Context creation would fail if EGL_ANGLE_create_context_webgl_compatibility was not available so +// the GL extension should always be present +TEST_P(WebGLCompatibilityTest, ExtensionStringExposed) +{ + EXPECT_TRUE(extensionEnabled("GL_ANGLE_webgl_compatibility")); +} + +// Verify that all extension entry points are available +TEST_P(WebGLCompatibilityTest, EntryPoints) +{ + if (extensionEnabled("GL_ANGLE_webgl_compatibility")) + { + EXPECT_NE(nullptr, eglGetProcAddress("glEnableExtensionANGLE")); + } +} + +// WebGL 1 allows GL_DEPTH_STENCIL_ATTACHMENT as a valid binding point. Make sure it is usable, +// even in ES2 contexts. +TEST_P(WebGLCompatibilityTest, DepthStencilBindingPoint) +{ + GLRenderbuffer renderbuffer; + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer.get()); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 32, 32); + + GLFramebuffer framebuffer; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get()); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, + renderbuffer.get()); + + EXPECT_GL_NO_ERROR(); +} + +// Test that attempting to enable an extension that doesn't exist generates GL_INVALID_OPERATION +TEST_P(WebGLCompatibilityTest, EnableExtensionValidation) +{ + EXPECT_EQ(GL_FALSE, glEnableExtensionANGLE("invalid_extension_string")); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); +} + +// Test enabling the GL_OES_element_index_uint extension +TEST_P(WebGLCompatibilityTest, EnableExtensionUintIndices) +{ + if (getClientMajorVersion() != 2) + { + // This test only works on ES2 where uint indices are not available by default + return; + } + + EXPECT_FALSE(extensionEnabled("GL_OES_element_index_uint")); + + GLBuffer indexBuffer; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer.get()); + + GLuint data[] = {0, 1, 2, 1, 3, 2}; + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); + + ANGLE_GL_PROGRAM(program, "void main() { gl_Position = vec4(0, 0, 0, 1); }", + "void main() { gl_FragColor = vec4(0, 1, 0, 1); }") + glUseProgram(program.get()); + + glDrawElements(GL_TRIANGLES, 2, GL_UNSIGNED_INT, nullptr); + EXPECT_GL_ERROR(GL_INVALID_ENUM); + + if (glEnableExtensionANGLE("GL_OES_element_index_uint")) + { + EXPECT_GL_NO_ERROR(); + EXPECT_TRUE(extensionEnabled("GL_OES_element_index_uint")); + + glDrawElements(GL_TRIANGLES, 2, GL_UNSIGNED_INT, nullptr); + EXPECT_GL_NO_ERROR(); + } +} + +// Verify that shaders are of a compatible spec when the extension is enabled. +TEST_P(WebGLCompatibilityTest, ExtensionCompilerSpec) +{ + EXPECT_TRUE(extensionEnabled("GL_ANGLE_webgl_compatibility")); + + // Use of reserved _webgl prefix should fail when the shader specification is for WebGL. + const std::string &vert = + "struct Foo {\n" + " int _webgl_bar;\n" + "};\n" + "void main()\n" + "{\n" + " Foo foo = Foo(1);\n" + "}"; + + // Default fragement shader. + const std::string &frag = + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n" + "}"; + + GLuint program = CompileProgram(vert, frag); + EXPECT_EQ(0u, program); + glDeleteProgram(program); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest, + ES2_D3D9(), + ES2_D3D11(), + ES3_D3D11(), + ES2_D3D11_FL9_3(), + ES2_OPENGL(), + ES3_OPENGL(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace diff --git a/gfx/angle/src/tests/gl_tests/media/pixel.inl b/gfx/angle/src/tests/gl_tests/media/pixel.inl new file mode 100755 index 000000000..586e6942e --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/media/pixel.inl @@ -0,0 +1,11000 @@ +// Automatically generated header from pixel.dds, a 512x512 (10 mip levels) +// DXT1 texture using DDSToHeader.exe. +static const size_t pixel_width = 512; +static const size_t pixel_height = 512; +static const size_t pixel_levels = 10; + +static const size_t pixel_0_width = 512; +static const size_t pixel_0_height = 512; +static const size_t pixel_0_size = 131072; +static const unsigned char pixel_0_data[131072] = +{ + 0x46,0x62,0x63,0x41,0x8B,0x8B,0xFD,0x55,0xE5,0x51,0x22,0x39,0xAA,0xA8,0xFE,0xD5, + 0xC5,0x51,0x23,0x39,0x60,0x60,0xAE,0xAF,0xA5,0x49,0x02,0x39,0x0B,0x2D,0x97,0xFF, + 0x47,0x62,0x02,0x39,0x0A,0xAB,0x5F,0x7D,0xE5,0x51,0xC1,0x30,0x80,0xAA,0xDF,0xD5, + 0xA5,0x49,0x23,0x39,0x60,0xEF,0xE9,0x2D,0xC5,0x51,0xE2,0x30,0xAD,0xFD,0xFF,0x80, + 0x27,0x5A,0x43,0x39,0x0E,0xF5,0x55,0x7F,0xE5,0x49,0xC1,0x30,0xA8,0xFF,0xD5,0xF7, + 0xE5,0x49,0x23,0x39,0xEB,0xED,0xAF,0x2B,0xC9,0x6A,0x23,0x39,0x55,0x55,0xF7,0x82, + 0x06,0x52,0x03,0x31,0xFD,0x7D,0x6B,0xA8,0x84,0x41,0xE2,0x30,0xAE,0xD5,0xDF,0x7C, + 0xC5,0x49,0x43,0x39,0x5D,0xBF,0x09,0x29,0xA8,0x6A,0x42,0x39,0x55,0x5F,0xE2,0x82, + 0xE6,0x51,0x23,0x39,0x55,0x5E,0xEA,0xA8,0x84,0x41,0xE2,0x30,0xD5,0xD5,0xDE,0xD8, + 0xC5,0x49,0x43,0x41,0xFD,0x37,0x2F,0x3D,0xE9,0x72,0x43,0x41,0x55,0xEA,0x82,0xBB, + 0xC5,0x49,0xE2,0x38,0x7F,0xEA,0xE8,0xAA,0x44,0x41,0xC2,0x30,0x2D,0xB5,0xDE,0xF8, + 0xE5,0x51,0xE2,0x30,0xAB,0x2B,0xAB,0xB5,0x67,0x62,0x64,0x41,0x5B,0xC0,0x83,0xD7, + 0xA5,0x49,0x02,0x39,0x7B,0xFA,0x88,0xFE,0xA5,0x51,0x02,0x39,0x2D,0x3F,0xBE,0xAA, + 0x67,0x62,0x84,0x49,0x2A,0x2A,0xB7,0x7D,0x88,0x6A,0x64,0x49,0xA8,0xFA,0xFE,0x55, + 0x06,0x5A,0x64,0x49,0x68,0xE8,0xBB,0xFF,0xA5,0x51,0x02,0x39,0x37,0x97,0xDE,0x78, + 0x47,0x62,0x02,0x39,0x0A,0xAB,0xD7,0x55,0xA9,0x6A,0xC2,0x30,0xE8,0xFA,0xFF,0xD5, + 0xA5,0x49,0x23,0x39,0xE0,0xB7,0xB7,0xAF,0xA5,0x49,0x02,0x39,0x2D,0xD7,0xDA,0xFA, + 0x27,0x5A,0x03,0x39,0x0A,0xFF,0x55,0x55,0xA5,0x49,0x23,0x39,0x28,0x6F,0x7D,0xAD, + 0xC6,0x51,0x03,0x39,0x7E,0xFF,0xBD,0x0B,0xC5,0x51,0xE2,0x38,0xAD,0xD7,0xFE,0xE8, + 0x85,0x49,0xE2,0x30,0x0A,0xDF,0xD7,0x7E,0xA5,0x49,0x24,0x39,0xF8,0x7D,0xF9,0x0B, + 0x27,0x5A,0x43,0x39,0x55,0x7D,0xFF,0x82,0x85,0x49,0xC2,0x30,0xEF,0x7F,0xA8,0x02, + 0x85,0x49,0xC3,0x30,0xAB,0xBD,0x3F,0xFA,0xC6,0x51,0x23,0x39,0xD5,0xBF,0x02,0x02, + 0xE6,0x51,0x03,0x39,0x7F,0xEA,0xA0,0x80,0xC6,0x51,0x02,0x39,0x55,0x5E,0xEA,0x08, + 0xC5,0x51,0x23,0x39,0xBD,0x2D,0xA5,0xD5,0x47,0x5A,0x64,0x41,0x7F,0x8A,0x0B,0x8B, + 0xE6,0x51,0x43,0x41,0x5D,0xEE,0xB8,0xE0,0x85,0x49,0x03,0x39,0x57,0x76,0xF0,0xC0, + 0xC5,0x51,0xE3,0x30,0x2B,0x0B,0x2B,0xA5,0xC9,0x72,0xA4,0x49,0x5D,0x0A,0x8B,0xD5, + 0x88,0x6A,0xA5,0x51,0x5F,0x82,0x00,0x5F,0x06,0x5A,0x64,0x41,0x5B,0xB8,0xAE,0xBE, + 0xC5,0x51,0x63,0x41,0xAE,0x28,0xCA,0x5F,0xC6,0x51,0x43,0x39,0x00,0x80,0xAA,0xF7, + 0x06,0x52,0x23,0x39,0xFA,0x2A,0x3A,0x95,0x66,0x62,0x63,0x41,0xD5,0xAE,0x22,0x22, + 0x47,0x62,0xA4,0x49,0xDD,0xAB,0xA0,0x80,0x68,0x62,0xE5,0x51,0xAD,0x0B,0xAA,0x2A, + 0x67,0x6A,0xE5,0x51,0x56,0x28,0x2E,0x3B,0xC7,0x72,0x24,0x5A,0xD5,0xBF,0x2F,0x6E, + 0xA7,0x6A,0x05,0x5A,0xAE,0x82,0xA8,0x75,0x66,0x62,0xC4,0x51,0x08,0x2A,0xEA,0xFD, + 0x67,0x6A,0xE5,0x51,0x2C,0x8A,0x8A,0xA6,0x88,0x6A,0x47,0x62,0x77,0x5F,0xD7,0x99, + 0x87,0x6A,0x25,0x5A,0x68,0xAA,0xEB,0xFB,0xA7,0x6A,0xC5,0x51,0x7A,0xE8,0x8A,0x2A, + 0x46,0x5A,0x23,0x39,0x55,0x5E,0xDA,0xA0,0x85,0x49,0x23,0x39,0x0F,0xF5,0x35,0xD7, + 0x68,0x62,0x44,0x41,0x57,0x75,0x27,0x3D,0x88,0x62,0x64,0x41,0x55,0x55,0xDE,0xF0, + 0xA5,0x49,0x03,0x31,0xE7,0xFF,0x60,0x58,0xE6,0x51,0x43,0x39,0x55,0x35,0xB9,0xB5, + 0x0A,0x73,0x43,0x39,0x55,0xFB,0xE2,0x8B,0xC5,0x49,0x03,0x39,0x5F,0x7A,0xC8,0x80, + 0x64,0x41,0xE2,0x30,0x2A,0x09,0x2F,0xFE,0xA8,0x6A,0x84,0x41,0x7D,0x8B,0x29,0xD5, + 0x88,0x62,0x63,0x39,0x55,0xFE,0xF0,0xFA,0xA5,0x49,0x02,0x39,0xBD,0xB6,0xFC,0x78, + 0x68,0x62,0x02,0x39,0xFB,0x0A,0x8B,0xF5,0x88,0x62,0xC5,0x51,0x75,0xC0,0xFE,0x55, + 0x52,0xC5,0xC5,0x51,0x35,0xD5,0x55,0x55,0x55,0xE6,0x46,0x62,0x00,0x02,0x0D,0xB5, + 0xB6,0xEE,0x35,0xE6,0x88,0x20,0x22,0x8D,0xB6,0xEE,0x96,0xEE,0xDF,0x7F,0x6F,0x7F, + 0xB6,0xF6,0x96,0xEE,0xED,0xED,0xF9,0x97,0x96,0xF6,0xB6,0xEE,0xEE,0xFA,0x7F,0xBF, + 0xB6,0xF6,0x96,0xEE,0xAE,0xB9,0x3D,0x57,0x96,0xF6,0xB6,0xEE,0xFE,0x7E,0xF6,0xF7, + 0xF7,0xF6,0xB6,0xEE,0x75,0xB5,0xA5,0xAD,0xF7,0xF6,0x96,0xEE,0xAA,0xAA,0xA8,0x7F, + 0xD7,0xF6,0x96,0xEE,0xFA,0xFA,0xBA,0xDE,0xD6,0xF6,0xB6,0xEE,0xAF,0xAB,0x8F,0x2D, + 0xD6,0xF6,0x96,0xEE,0xE8,0xF0,0xE8,0x78,0xB6,0xEE,0x75,0xE6,0x57,0xBE,0x2E,0xBA, + 0xD6,0xF6,0x96,0xEE,0xF7,0xBF,0x2A,0x03,0xF7,0xF6,0x96,0xEE,0xF7,0xAA,0xBA,0xAC, + 0xD7,0xF6,0xB6,0xEE,0xC0,0x60,0x78,0x08,0xF7,0xF6,0xB7,0xEE,0xF5,0xBD,0xAF,0x8A, + 0xF7,0xF6,0xD7,0xF6,0xD5,0x35,0x0F,0x0A,0x18,0xFF,0xD7,0xF6,0xBF,0xAF,0xBB,0xAF, + 0x18,0xFF,0xF8,0xF6,0xAB,0x7A,0x6B,0xEE,0x18,0xFF,0xF8,0xF6,0xAF,0x8B,0x0B,0xAA, + 0x18,0xFF,0xF7,0xEE,0xA8,0xA8,0x80,0x08,0xF8,0xFE,0x18,0xF7,0x3F,0xAD,0xFD,0xF7, + 0x18,0xFF,0xD7,0xF6,0xFF,0xFB,0xBE,0xF0,0x18,0xF7,0xD7,0xF6,0xBF,0xEB,0x8E,0xBA, + 0x18,0xFF,0xF7,0xF6,0xBD,0xFF,0xD5,0xD5,0x37,0xF7,0xD8,0xF6,0xDF,0xBF,0xDF,0xF5, + 0xF8,0xF6,0xD7,0xF6,0x5F,0x20,0x00,0xB8,0xF7,0xF6,0xB6,0xEE,0xAB,0x7B,0x6C,0x8A, + 0xD7,0xF6,0x97,0xEE,0x00,0x08,0x9E,0x78,0xF8,0xF6,0xB7,0xEE,0xBF,0xF6,0xEA,0x3D, + 0xF7,0xF6,0xB7,0xEE,0x83,0xAF,0xE5,0x7B,0xF7,0xF6,0xB7,0xEE,0xAA,0x0A,0xAA,0xB5, + 0xF7,0xF6,0x96,0xEE,0x7F,0xEA,0x22,0x2A,0xD7,0xF6,0x75,0xE6,0x7E,0xFF,0xDE,0xB8, + 0x96,0xEE,0x55,0xE6,0x6A,0x6A,0xF8,0xEC,0x35,0xE6,0x10,0xBD,0xFC,0x78,0x78,0x70, + 0x34,0xE6,0x10,0xC5,0x00,0x03,0x0B,0x29,0x55,0xE6,0xF3,0xDD,0x7E,0xFE,0xFE,0xFC, + 0x14,0xDE,0xD3,0xDD,0xE2,0x62,0x80,0xA0,0x14,0xDE,0xD3,0xDD,0xB3,0xBA,0xBE,0xDE, + 0x14,0xDE,0xD2,0xDD,0xA3,0xA0,0x88,0xBB,0x14,0xDE,0xB2,0xD5,0xE8,0xA2,0xA2,0x88, + 0xF3,0xDD,0xD3,0xD5,0x27,0x0E,0xB6,0x8A,0x14,0xDE,0xD3,0xDD,0xEA,0xC2,0xC8,0xD2, + 0x87,0x6A,0x63,0x49,0xF5,0x3D,0xB7,0xDD,0x29,0x7B,0x05,0x5A,0x55,0xA0,0x88,0xBD, + 0x88,0x62,0x64,0x49,0x77,0x7E,0xF8,0xF8,0xC6,0x51,0x63,0x41,0xF5,0x7B,0xA8,0x6B, + 0xA5,0x49,0x43,0x41,0xE8,0xA8,0x20,0xDE,0xE6,0x51,0x23,0x39,0x55,0x5F,0xEA,0xCB, + 0xE6,0x51,0xE2,0x30,0x2A,0x0B,0xAB,0x57,0x88,0x6A,0x02,0x31,0x80,0x0A,0xFB,0x55, + 0xE6,0x51,0x02,0x31,0xA8,0xA0,0xFE,0x57,0xA5,0x49,0x02,0x31,0x5E,0x68,0xCB,0xCB, + 0xA5,0x49,0x02,0x31,0x02,0x29,0x55,0x57,0xA9,0x6A,0xC1,0x28,0x02,0xAB,0xFF,0xD5, + 0x27,0x5A,0x02,0x31,0xA8,0xFA,0xF7,0x5F,0xC5,0x49,0xE2,0x30,0x78,0x6E,0xEB,0xE2, + 0x85,0x49,0xE2,0x30,0x0B,0xBF,0x77,0x6A,0x06,0x5A,0xE2,0x30,0x02,0xB7,0xD5,0x75, + 0xC5,0x49,0x23,0x39,0xAC,0x5F,0x5D,0xBB,0x05,0x52,0x02,0x31,0x5F,0xB7,0xBD,0x00, + 0xA5,0x41,0x02,0x39,0xFF,0x55,0x6E,0x88,0x84,0x49,0xE2,0x30,0x30,0xD5,0x97,0xDF, + 0xC5,0x49,0x23,0x39,0x75,0x55,0xBF,0x23,0x87,0x62,0x22,0x39,0x55,0x55,0xDF,0xC2, + 0x85,0x49,0xE2,0x30,0x55,0x77,0xEA,0x80,0x23,0x39,0xE2,0x30,0x2D,0x35,0x97,0x58, + 0xA5,0x51,0xC2,0x30,0xFD,0xBE,0x2A,0x2B,0x27,0x62,0x63,0x41,0x75,0x7D,0xEA,0xA0, + 0xA5,0x51,0x64,0x49,0xCD,0x95,0xFF,0xA0,0xA5,0x51,0x44,0x49,0xEF,0x9A,0xBA,0x3A, + 0x07,0x62,0x64,0x49,0xFD,0x2D,0x3F,0xFF,0x48,0x6A,0x64,0x41,0x5F,0xE0,0x80,0xEA, + 0xC5,0x51,0x23,0x39,0x57,0x7F,0xFA,0xAC,0x85,0x49,0xE3,0x30,0xA5,0x2F,0xBE,0x5F, + 0xE6,0x59,0x23,0x39,0xAA,0x22,0xAA,0xF5,0x68,0x62,0x44,0x41,0x5F,0xF0,0xEA,0x5D, + 0x85,0x49,0x23,0x39,0xFF,0xA8,0xA8,0xF5,0x85,0x49,0xE3,0x30,0x0D,0x2D,0xD7,0x7F, + 0xA9,0x6A,0x44,0x41,0x0F,0x2F,0xF5,0x55,0x89,0x6A,0x03,0x31,0xFA,0xB0,0xFE,0x55, + 0xC6,0x51,0x23,0x39,0x7A,0x62,0xEA,0xF5,0xE6,0x51,0xC2,0x30,0x0F,0xA7,0xF7,0xFE, + 0x68,0x62,0x44,0x39,0x82,0xAF,0x55,0x55,0xE6,0x51,0xC2,0x30,0x88,0xA8,0xFF,0xD7, + 0x85,0x49,0xC2,0x30,0x7C,0xE8,0xAE,0x23,0xC5,0x49,0xE2,0x38,0x2B,0xB5,0xF7,0x20, + 0xE6,0x59,0x02,0x31,0x00,0xFE,0x7F,0xEE,0xE6,0x51,0xE2,0x30,0xA8,0xFF,0xF5,0xFF, + 0x26,0x5A,0x43,0x41,0x55,0x5F,0xAF,0x0B,0x88,0x62,0x22,0x39,0xFD,0x55,0xFF,0xA0, + 0xE5,0x51,0x03,0x39,0xB8,0x7F,0x7F,0xAA,0xA5,0x49,0x02,0x39,0xCE,0xBD,0x25,0xB7, + 0xA8,0x6A,0x23,0x39,0x55,0x5D,0xAF,0x2F,0xA8,0x6A,0x43,0x41,0x55,0xFF,0xAE,0x00, + 0x88,0x6A,0x64,0x41,0x55,0x55,0xFE,0xF8,0x06,0x5A,0x43,0x41,0x55,0xFF,0xAA,0xA0, + 0x06,0x5A,0x43,0x41,0x55,0xF7,0x2E,0x0A,0x27,0x5A,0x44,0x41,0xF5,0xAF,0xAC,0xA8, + 0xE6,0x51,0x64,0x49,0xF5,0x2E,0xAA,0x82,0x47,0x62,0xC6,0x51,0x03,0xAB,0x75,0xD5, + 0x89,0x6A,0xE6,0x51,0xFA,0x8A,0xE1,0xED,0x88,0x6A,0x27,0x5A,0xF7,0xDD,0xED,0xAD, + 0x88,0x6A,0xE6,0x59,0xBA,0x27,0x2C,0xBA,0x87,0x6A,0x05,0x5A,0x60,0xE0,0x42,0xA0, + 0xE5,0x51,0x23,0x41,0x2E,0xDF,0x56,0x5C,0x87,0x6A,0x63,0x41,0xAF,0x2A,0xBD,0xD5, + 0x47,0x62,0x84,0x49,0xBA,0xE0,0xB8,0x55,0x47,0x62,0x64,0x49,0x22,0x2A,0x2E,0x95, + 0x87,0x6A,0x26,0x62,0xA8,0xE2,0x2E,0x59,0x87,0x6A,0x26,0x5A,0x88,0x82,0xAB,0xD5, + 0x87,0x62,0x26,0x5A,0xE3,0xC0,0xEA,0x75,0x06,0x5A,0x03,0x39,0x7E,0x78,0xE0,0xE0, + 0xE6,0x51,0x23,0x39,0x2D,0xBD,0x55,0x55,0x68,0x62,0x23,0x39,0xA0,0xEA,0x55,0xDD, + 0x47,0x62,0x44,0x39,0x7F,0x57,0x5D,0x8B,0x85,0x49,0x02,0x31,0xB7,0xD7,0xDF,0x80, + 0x06,0x52,0x23,0x39,0x0B,0xF5,0xFF,0xBF,0xC5,0x49,0x23,0x39,0xA8,0xD7,0xFF,0xBA, + 0xA5,0x49,0x03,0x31,0x5E,0x5F,0xAA,0xA0,0x64,0x41,0x23,0x39,0xBD,0xF5,0xE2,0x40, + 0x84,0x41,0x23,0x39,0xAA,0xFF,0x3F,0xAD,0xE6,0x51,0x43,0x39,0x55,0x77,0xEB,0x0B, + 0xE6,0x51,0xE2,0x30,0xBF,0x5F,0x7E,0xE8,0xA5,0x49,0x02,0x39,0x00,0x8B,0xAD,0xB5, + 0xA5,0x49,0x64,0x49,0xBE,0xB6,0x8A,0x68,0xA8,0x72,0x84,0x49,0x3D,0xF5,0xD5,0x55, + 0x75,0xEE,0xC5,0x51,0x02,0x2D,0xB5,0xD5,0x96,0xEE,0x8F,0xAC,0x00,0x00,0x00,0x09, + 0xB6,0xF6,0x96,0xEE,0xB7,0x3F,0xB5,0x7D,0xB6,0xF6,0x96,0xEE,0x62,0xC0,0xCB,0x4A, + 0xB6,0xEE,0x96,0xEE,0xBD,0xAD,0xAA,0x2B,0xD7,0xF6,0x96,0xEE,0xBF,0x2F,0x0A,0x0A, + 0xD7,0xF6,0x75,0xEE,0x00,0x88,0xA8,0x78,0xB6,0xEE,0x75,0xE6,0xA8,0xBE,0xBF,0xBF, + 0xB6,0xEE,0x96,0xEE,0xBB,0xD9,0xEC,0x75,0xD7,0xF6,0x96,0xEE,0x07,0x0F,0xAF,0xAD, + 0xD6,0xF6,0x96,0xEE,0x7A,0xFA,0xEA,0x6B,0xD7,0xF6,0x54,0xE6,0xA2,0xA8,0xAA,0x97, + 0xF7,0xF6,0x96,0xEE,0x8A,0x2A,0xFA,0xF7,0xF7,0xF6,0xB6,0xEE,0x8A,0x28,0xEB,0xFF, + 0xF7,0xF6,0xB7,0xF6,0x08,0x2E,0xBF,0x7E,0xF7,0xF6,0x96,0xEE,0x00,0x00,0x2B,0xDF, + 0xF7,0xF6,0x96,0xEE,0x00,0x00,0x00,0x3D,0x18,0xFF,0xF7,0xF6,0x55,0x57,0x7F,0x55, + 0x18,0xFF,0xD7,0xF6,0xEA,0xFE,0xFB,0xFE,0x18,0xF7,0xD7,0xF6,0x2A,0xAE,0xF7,0xFF, + 0x18,0xF7,0xF7,0xF6,0x2B,0xA7,0x55,0x55,0x18,0xF7,0xD7,0xF6,0x22,0x0A,0x2E,0xFF, + 0x18,0xF7,0xD8,0xF6,0xA8,0x88,0x2A,0xA9,0x18,0xFF,0xF8,0xF6,0x57,0xF6,0xBF,0xAF, + 0x18,0xF7,0xF7,0xF6,0x55,0x62,0x88,0x00,0x18,0xF7,0xD7,0xEE,0xDF,0xF7,0xAE,0xA8, + 0x18,0xF7,0xD7,0xF6,0x77,0xFF,0xAE,0xAA,0x18,0xF7,0xD7,0xF6,0xFF,0x7F,0x6E,0x7A, + 0xF7,0xF6,0xB7,0xEE,0x78,0xEE,0xBF,0xEB,0xD7,0xF6,0x75,0xE6,0xAE,0x7C,0xE0,0x02, + 0xD7,0xF6,0x96,0xEE,0x88,0x01,0x0D,0x37,0xD7,0xF6,0xB6,0xEE,0xA5,0xAD,0xAE,0x98, + 0xD7,0xF6,0x96,0xEE,0x02,0xA6,0xFE,0xFC,0xD7,0xF6,0x96,0xEE,0xE0,0x88,0x02,0xAE, + 0xD6,0xF6,0x34,0xE6,0x7A,0x7E,0x7E,0xF8,0x34,0xE6,0x71,0xCD,0x70,0x70,0x60,0x60, + 0xF3,0xDD,0x10,0xC5,0x2F,0x3D,0xB5,0xA5,0x34,0xE6,0xD3,0xD5,0xA0,0xA2,0x8B,0x09, + 0x14,0xDE,0xB2,0xD5,0xA8,0xAA,0x80,0xC8,0x13,0xDE,0xD2,0xD5,0xDA,0xEC,0xB8,0xBE, + 0x13,0xDE,0xD3,0xDD,0xBD,0x2F,0xAA,0x0A,0x34,0xE6,0xF3,0xDD,0xF7,0xEA,0x6A,0xFA, + 0xF3,0xDD,0xD3,0xD5,0x20,0x3A,0xA0,0x00,0x13,0xDE,0xD3,0xD5,0xA8,0xEF,0xFE,0xFA, + 0x84,0x49,0x03,0x39,0xEF,0xB5,0xA7,0x26,0x67,0x62,0x43,0x41,0x55,0xFD,0x0B,0x0F, + 0xEA,0x72,0x64,0x41,0x55,0xD5,0xA2,0x02,0xC8,0x72,0x43,0x39,0x75,0x57,0xFA,0x20, + 0xE6,0x72,0x62,0x41,0x55,0x55,0xFA,0xA0,0x06,0x52,0x64,0x41,0xE5,0xAF,0xFE,0xEC, + 0xC5,0x49,0xE2,0x30,0x5F,0x7A,0xAA,0x82,0x64,0x41,0xA1,0x28,0xF5,0xBF,0xFA,0xE8, + 0xE5,0x51,0x43,0x39,0x55,0xED,0x29,0xAD,0xE9,0x6A,0x43,0x39,0xF5,0xF3,0x82,0xEF, + 0xE5,0x51,0x43,0x39,0x7B,0xBA,0xA8,0xF8,0x85,0x41,0xE2,0x30,0xB5,0xDE,0xE8,0xEA, + 0xA5,0x49,0x02,0x31,0xA2,0x0A,0x2D,0x95,0xA8,0x6A,0x64,0x41,0xEB,0x03,0xAF,0x55, + 0xE6,0x51,0x02,0x31,0xEA,0xE8,0xF8,0xD7,0x85,0x41,0xE2,0x30,0x7B,0x70,0x7E,0x6B, + 0xA5,0x49,0x02,0x31,0x0B,0x09,0xB5,0x55,0xE8,0x6A,0x23,0x39,0x82,0xAB,0xF7,0x55, + 0x27,0x5A,0x02,0x31,0xBA,0xE8,0xFB,0x57,0x64,0x41,0xC2,0x28,0x5A,0xF8,0xF8,0xBB, + 0xE6,0x51,0xC1,0x28,0x2B,0xAD,0xD5,0xFF,0x87,0x62,0x23,0x39,0x82,0xFF,0x55,0x55, + 0x84,0x49,0xE2,0x30,0x00,0x08,0xFF,0xF5,0x64,0x41,0x02,0x39,0x5E,0xF0,0xE0,0x80, + 0x85,0x49,0xE2,0x30,0x2F,0x2D,0xBF,0x8A,0xE5,0x59,0x44,0x41,0xA8,0xFF,0x5D,0xDF, + 0xC5,0x51,0x64,0x49,0x7C,0xD5,0x75,0x3F,0xE5,0x59,0x44,0x49,0x7B,0xEB,0xBA,0xAA, + 0x47,0x6A,0x44,0x49,0x77,0x5F,0xFE,0xA2,0xA5,0x51,0x02,0x39,0xAA,0x6B,0xCB,0xAA, + 0x64,0x41,0xC1,0x30,0xEE,0x95,0xFF,0xFC,0xC5,0x51,0xE2,0x30,0x7D,0xEF,0x2B,0x0B, + 0xEA,0x72,0xE2,0x38,0x55,0xFF,0xFE,0x82,0xC6,0x51,0x23,0x39,0x55,0x5E,0xEA,0xA8, + 0x85,0x41,0xE2,0x30,0x95,0x35,0x1E,0x7A,0xA8,0x6A,0x44,0x41,0x55,0xBF,0x2D,0xB9, + 0x6A,0x83,0x23,0x39,0x55,0x7F,0xE2,0x82,0xA5,0x49,0x03,0x39,0x5F,0xFA,0xA0,0x80, + 0xA5,0x49,0xE2,0x30,0x25,0xA5,0xBE,0x7E,0x27,0x5A,0x84,0x41,0x27,0x0F,0x2B,0x75, + 0x68,0x62,0x84,0x41,0x77,0x7C,0xFA,0x7E,0xA5,0x49,0x03,0x39,0x56,0xE0,0x88,0xAE, + 0xE6,0x51,0x03,0x39,0xBD,0x37,0xB5,0x57,0x88,0x6A,0x23,0x39,0x8A,0xAA,0xEF,0x75, + 0x06,0x5A,0x63,0x41,0xFE,0xEC,0xFA,0xD5,0xA4,0x49,0x03,0x39,0x7C,0x7C,0xEA,0xAA, + 0x06,0x5A,0x02,0x31,0x09,0x0D,0xD5,0x55,0xC9,0x6A,0x22,0x39,0xE2,0x8A,0xDF,0xD5, + 0xC5,0x51,0x63,0x39,0xB8,0xE0,0x7A,0xBF,0xA5,0x49,0xE2,0x30,0xFC,0x52,0xEA,0x00, + 0x26,0x5A,0x03,0x31,0x2B,0xBD,0xFD,0xA2,0x88,0x6A,0x43,0x39,0x00,0xFF,0x75,0xFF, + 0x88,0x6A,0x43,0x41,0xA8,0xFF,0x55,0x7F,0xE6,0x51,0xE3,0x38,0x00,0xFA,0x55,0xF7, + 0x06,0x5A,0x44,0x41,0x88,0xFF,0xFD,0x2F,0x87,0x62,0xA4,0x49,0x5F,0x55,0xFD,0x00, + 0x46,0x5A,0x64,0x41,0x6F,0x57,0xFA,0xE0,0xC6,0x51,0x64,0x41,0xFE,0x7D,0xBB,0x82, + 0x26,0x5A,0x64,0x41,0x0B,0x2D,0xAF,0xBF,0x68,0x62,0xC5,0x51,0x82,0x8A,0xA8,0xE5, + 0x67,0x62,0x63,0x41,0x08,0xAA,0xFF,0xD5,0x67,0x6A,0xC5,0x51,0xA0,0xDF,0xBD,0x35, + 0x67,0x6A,0x43,0x41,0x7A,0x7A,0xEA,0xE8,0xC5,0x51,0xE2,0x38,0xB7,0xB7,0xFA,0xF0, + 0xE5,0x59,0x43,0x41,0xD7,0xF9,0x2B,0xA5,0x88,0x6A,0x64,0x49,0xD5,0xDF,0xC2,0xAA, + 0x26,0x62,0xA5,0x49,0x8A,0xEB,0xBA,0x5E,0xE5,0x51,0x03,0x39,0x8A,0xAE,0xDE,0xDE, + 0x26,0x5A,0x43,0x41,0xAF,0x3F,0x2F,0xF5,0x68,0x62,0x84,0x49,0x7F,0xFE,0xF8,0xDD, + 0xE6,0x51,0x43,0x41,0x5F,0x78,0x40,0x5B,0x64,0x41,0x03,0x39,0x03,0x3D,0x55,0x5E, + 0x0A,0x7B,0x23,0x39,0x8B,0xAF,0xFD,0x55,0x47,0x5A,0x23,0x39,0xBE,0xA8,0xFE,0x55, + 0xE5,0x51,0x03,0x39,0x8A,0xAA,0xFA,0x57,0xA5,0x49,0x03,0x39,0x00,0xAC,0xFF,0x55, + 0xA5,0x49,0x03,0x39,0x88,0xBE,0x76,0x55,0x85,0x49,0x03,0x39,0xE8,0xF8,0x55,0x55, + 0x43,0x39,0xE3,0x38,0x8E,0xAA,0xEA,0xFD,0xE6,0x51,0xE2,0x38,0x0A,0xBF,0xF5,0x5D, + 0xE6,0x51,0xE2,0x38,0xA8,0xFE,0x5F,0xF5,0x64,0x41,0x02,0x39,0xFC,0x7A,0x7B,0xFA, + 0x64,0x49,0x02,0x39,0xA8,0xFD,0x7D,0xFE,0x64,0x49,0x02,0x39,0x08,0xFF,0xAF,0xAD, + 0xA6,0x51,0x02,0x39,0x28,0xB9,0xBD,0x2F,0x54,0xE6,0x06,0x5A,0x29,0xB5,0xD5,0xD5, + 0x96,0xEE,0xCE,0xB4,0x00,0x00,0x03,0x09,0xB6,0xF6,0x96,0xEE,0xAA,0xEE,0xAA,0x0E, + 0xF7,0xF6,0x96,0xEE,0xF7,0xBF,0xBD,0x2B,0xD7,0xF6,0x96,0xEE,0x00,0xE0,0x68,0x70, + 0xB6,0xF6,0x76,0xEE,0x7A,0x7F,0xD6,0x75,0xB6,0xEE,0x76,0xEE,0xBD,0xAD,0x3D,0xAD, + 0xB6,0xEE,0x96,0xEE,0xDD,0xB5,0xE7,0x77,0xD7,0xF6,0x96,0xEE,0xEF,0xFB,0x69,0xE9, + 0x96,0xEE,0xF4,0xDD,0x80,0x80,0xF0,0x70,0x76,0xE6,0xF4,0xDD,0x3E,0xBD,0x3D,0xAD, + 0xB6,0xEE,0x55,0xE6,0x0A,0x2F,0xA9,0xB7,0xD7,0xF6,0x75,0xE6,0x0E,0x2B,0xFB,0xFF, + 0xD6,0xF6,0x96,0xEE,0x20,0x22,0xAF,0xFD,0xF8,0xFE,0x75,0xE6,0x5E,0xAA,0x82,0x0A, + 0xF8,0xF6,0x55,0xE6,0xFF,0x5F,0xE0,0xA0,0xD7,0xF6,0x34,0xDE,0x22,0xEF,0x5F,0xF8, + 0xD7,0xF6,0x34,0xDE,0x00,0x02,0xE7,0x55,0xF7,0xF6,0x54,0xE6,0x00,0x00,0x2A,0xB5, + 0x38,0xF7,0xD7,0xF6,0x57,0x7F,0xFF,0xB5,0xF7,0xF6,0xD7,0xF6,0xBF,0xAB,0xB0,0x20, + 0xF8,0xF6,0xD7,0xF6,0x75,0x4E,0x88,0x80,0x18,0xF7,0xD7,0xF6,0x27,0x5D,0x57,0xEB, + 0x18,0xF7,0xD7,0xF6,0x82,0xFF,0xD5,0xD7,0x18,0xF7,0xD7,0xEE,0x28,0xA8,0xEF,0xE7, + 0x18,0xF7,0xD7,0xF6,0x8A,0x02,0xA2,0x7B,0x18,0xF7,0xB7,0xF6,0xE0,0xAA,0xAA,0xA2, + 0xF8,0xFE,0xD7,0xEE,0x7A,0xEA,0xEA,0x7A,0xF7,0xF6,0xB7,0xEE,0xB7,0x7F,0xBF,0x82, + 0xD7,0xF6,0x96,0xEE,0x5E,0x62,0x8A,0x00,0xD7,0xF6,0x75,0xE6,0x22,0xA9,0x2F,0x9F, + 0xD7,0xF6,0xB7,0xEE,0x62,0x0B,0xA7,0xEB,0xD7,0xF6,0x76,0xEE,0xAE,0xBE,0xFE,0x78, + 0xD7,0xF6,0x75,0xE6,0x70,0x73,0xFF,0xEA,0x96,0xEE,0xD2,0xD5,0x7E,0x5A,0x7A,0x6A, + 0x92,0xCD,0x30,0xC5,0xA5,0xD6,0xBC,0xAC,0x34,0xE6,0x91,0xCD,0x09,0x2D,0xAD,0x35, + 0x14,0xE6,0xF3,0xD5,0xF8,0xFC,0x7E,0xFA,0x14,0xDE,0xD2,0xDD,0xAF,0xAB,0x8A,0x0A, + 0x34,0xE6,0xF3,0xDD,0x27,0x2F,0xAB,0x8A,0x33,0xE6,0xF3,0xDD,0x7A,0x7E,0x7E,0x7C, + 0x15,0xE6,0xF3,0xD5,0xFF,0xBF,0x9F,0xB7,0x14,0xDE,0xF3,0xDD,0x9F,0x9E,0xB8,0xB4, + 0x25,0x5A,0x43,0x41,0x55,0x5E,0x5E,0x68,0x27,0x5A,0x23,0x39,0x0B,0xAA,0xDD,0xF5, + 0xA9,0x6A,0x64,0x41,0x0A,0xEF,0x75,0x55,0x87,0x6A,0x43,0x41,0xA0,0xFB,0x55,0x77, + 0x45,0x5A,0x22,0x39,0x28,0xFF,0x5F,0x57,0xE5,0x51,0x43,0x39,0xA8,0xDF,0xD5,0xF5, + 0xA5,0x49,0x03,0x39,0x88,0xFC,0xDE,0xFA,0xA5,0x49,0x02,0x31,0x62,0x8B,0x0B,0x02, + 0xC5,0x49,0xE2,0x30,0xED,0xF7,0xAA,0xA0,0xA5,0x49,0x02,0x31,0x8F,0x5F,0x6A,0x2A, + 0x43,0x41,0xC1,0x28,0xAA,0xF5,0xB7,0xBC,0x84,0x41,0x23,0x39,0x05,0xA5,0x7A,0xA2, + 0xA9,0x6A,0xE2,0x30,0x55,0xFF,0xEA,0x02,0xC6,0x49,0x23,0x39,0x5D,0x7F,0xA9,0x80, + 0x64,0x41,0xC1,0x28,0x95,0x9F,0xBA,0xE8,0xC5,0x49,0x03,0x31,0xF7,0xAA,0x2B,0x0D, + 0xEA,0x72,0x43,0x39,0x55,0xFF,0x8B,0xAB,0x27,0x5A,0x43,0x41,0x55,0xF5,0xBE,0xE0, + 0xC5,0x49,0xE2,0x30,0xD5,0x56,0x7E,0x78,0x85,0x41,0xE2,0x30,0xAA,0x2B,0x09,0x2F, + 0xA9,0x6A,0x64,0x41,0x57,0x83,0x8B,0xF7,0xE6,0x51,0x23,0x39,0xF5,0xAE,0xA8,0xEE, + 0xA5,0x49,0xE2,0x30,0xD7,0x7A,0xE0,0xA2,0xA4,0x49,0xE2,0x30,0xAA,0x2B,0x2D,0xD5, + 0xA9,0x6A,0x44,0x41,0xAB,0x8B,0xEF,0x55,0xC6,0x51,0x43,0x49,0xFA,0xFC,0xFC,0xFF, + 0xA5,0x51,0x64,0x51,0x2E,0x2A,0x2B,0xC9,0xE6,0x61,0x84,0x51,0xFA,0xED,0xCF,0x82, + 0x27,0x6A,0xA4,0x59,0xC3,0xFD,0xD5,0xF5,0xA5,0x59,0x23,0x41,0xE8,0xF8,0x7C,0xF8, + 0x84,0x49,0xE2,0x38,0x7E,0x78,0xEA,0x20,0xA5,0x49,0xE2,0x30,0x01,0xAD,0xD7,0xBA, + 0x68,0x62,0x44,0x41,0x02,0xFF,0x5D,0xDD,0x48,0x62,0x23,0x39,0xFC,0x57,0x77,0xFF, + 0xA5,0x49,0xE2,0x30,0x7A,0xEE,0xAA,0x00,0xC6,0x51,0x03,0x31,0x0F,0x55,0xBF,0xAA, + 0x06,0x52,0x43,0x41,0x80,0xDD,0xBF,0xEE,0xC5,0x49,0x23,0x39,0xFA,0x7E,0xEA,0x0A, + 0xA5,0x49,0x02,0x31,0x7A,0xA2,0x02,0x00,0xC5,0x49,0x23,0x39,0xF5,0xBD,0x2A,0xAA, + 0xE6,0x51,0x43,0x39,0xF7,0xDB,0xA0,0xAA,0xC6,0x49,0x44,0x41,0x95,0xAF,0x2A,0xAA, + 0xC6,0x51,0x02,0x39,0x5E,0x70,0xE0,0xA8,0x84,0x49,0xE1,0x30,0xAD,0x2F,0x3F,0xF6, + 0x26,0x5A,0x44,0x41,0xBF,0x2B,0xBF,0xB5,0x87,0x62,0xA4,0x49,0x7D,0x82,0xA0,0xD5, + 0xE5,0x51,0x22,0x31,0x58,0xE8,0xEC,0xBE,0x85,0x41,0x23,0x39,0x2D,0xBD,0xD6,0x7E, + 0xE5,0x51,0x43,0x39,0x00,0x8A,0xAA,0xDD,0x06,0x52,0x84,0x41,0x00,0x0A,0x9F,0xF5, + 0x88,0x62,0x43,0x39,0x02,0x82,0xF7,0xD7,0x06,0x52,0x64,0x41,0xC0,0xB0,0xFF,0x55, + 0xE6,0x51,0x43,0x39,0x80,0xA8,0xBB,0xD7,0xA5,0x49,0x03,0x31,0x5C,0xF8,0x6A,0xFF, + 0xE5,0x51,0x03,0x31,0x2F,0xBD,0xF5,0x57,0x47,0x62,0x03,0x31,0x02,0xAB,0xFF,0x55, + 0x66,0x62,0x03,0x31,0xE8,0xFE,0xFF,0x55,0xA5,0x49,0xE2,0x30,0x00,0x88,0xEA,0x7D, + 0xC5,0x49,0xE2,0x30,0x22,0x8A,0xFF,0x55,0xC5,0x51,0x22,0x39,0x0A,0x2A,0xED,0xD5, + 0x46,0x5A,0xE2,0x30,0xF7,0x5E,0x7A,0xC2,0xE6,0x51,0xE2,0x30,0x02,0xBF,0xD5,0x57, + 0x46,0x62,0x02,0x39,0xA0,0xFF,0x55,0x55,0xC5,0x51,0x02,0x39,0x78,0xFA,0x95,0xB5, + 0xE6,0x59,0x02,0x39,0xF5,0x5F,0x5E,0x60,0xA5,0x51,0x02,0x39,0x00,0x7D,0x55,0xD7, + 0xA5,0x49,0x03,0x39,0xC8,0xDF,0xDD,0x2B,0x06,0x5A,0x43,0x41,0x75,0xE5,0x0F,0x0A, + 0x06,0x5A,0x03,0x39,0xF5,0xF7,0xFA,0xA0,0xA4,0x49,0x03,0x39,0xFF,0xFF,0xFD,0xA0, + 0xC5,0x51,0x02,0x39,0x75,0x75,0xFD,0x02,0xC5,0x51,0xE3,0x38,0x5F,0xDF,0xFF,0x00, + 0xE5,0x51,0xE2,0x30,0xFD,0xFD,0xB7,0x02,0x07,0x5A,0xE2,0x30,0x57,0x7D,0xEB,0x02, + 0x27,0x5A,0x23,0x39,0x55,0x55,0xDF,0x08,0x06,0x5A,0x02,0x39,0x55,0xD5,0xBA,0x00, + 0x06,0x62,0x03,0x39,0x55,0x7E,0xAA,0x00,0x67,0x62,0x03,0x39,0x75,0x7D,0xAA,0x88, + 0x06,0x5A,0x43,0x41,0x55,0xF5,0x20,0x20,0x47,0x62,0x43,0x41,0x55,0xF7,0xA2,0x80, + 0x47,0x62,0x23,0x39,0xD5,0xBF,0x00,0x02,0x27,0x62,0x44,0x41,0x55,0x8A,0x00,0x00, + 0x48,0x6A,0x64,0x49,0x55,0xEA,0xA0,0x2A,0x48,0x6A,0xA5,0x51,0x55,0xAA,0x0A,0x88, + 0x0A,0x83,0xC6,0x51,0xD5,0xBF,0xAF,0x2B,0x92,0xD5,0x47,0x62,0xD5,0xBF,0x2F,0x2B, + 0x75,0xEE,0x0F,0xC5,0x09,0x0B,0x02,0x02,0xD7,0xF6,0x96,0xF6,0xED,0xAF,0xBF,0x0B, + 0xD7,0xF6,0xB6,0xEE,0xC3,0xC2,0xE0,0xC0,0xB6,0xF6,0x76,0xEE,0xE0,0xE8,0xBA,0xB8, + 0x96,0xF6,0x75,0xE6,0xBE,0xDE,0xDA,0x6A,0x96,0xEE,0x55,0xEE,0x0B,0x0B,0xAB,0x6B, + 0x96,0xEE,0x34,0xE6,0x88,0xA8,0x7E,0xD7,0xB6,0xEE,0x55,0xE6,0x8B,0xFF,0xD5,0x55, + 0x76,0xEE,0xB3,0xD5,0xF0,0xF8,0x7E,0xFE,0x55,0xE6,0xF4,0xDD,0x29,0xED,0xB7,0x0F, + 0x75,0xE6,0xD3,0xD5,0x28,0xAE,0x7A,0xAA,0x75,0xEE,0x71,0xCD,0x00,0x0A,0xFF,0x7B, + 0x96,0xEE,0x51,0xC5,0x00,0x22,0xAA,0xDD,0x18,0xFF,0xF3,0xDD,0x0A,0x2A,0xBF,0xF5, + 0x18,0xFF,0x95,0xE6,0xE8,0x80,0xAB,0xFD,0xB7,0xF6,0xD6,0xEE,0xBA,0xAA,0xBB,0xAB, + 0xD7,0xF6,0x55,0xE6,0x5F,0xE0,0x82,0x8A,0xB6,0xEE,0x35,0xDE,0xD5,0xFF,0xEC,0xA0, + 0xD7,0xF6,0x35,0xDE,0x2B,0xD5,0x5F,0xEE,0x18,0xF7,0x35,0xE6,0x0A,0x2A,0xAF,0xD5, + 0x18,0xFF,0x96,0xEE,0x2A,0x20,0x0B,0xAD,0x18,0xFF,0xD7,0xF6,0xA8,0xEE,0x7A,0xE8, + 0x18,0xF7,0xD7,0xF6,0x8E,0x8A,0x8B,0xDF,0x18,0xFF,0xD7,0xF6,0xFE,0xEA,0xBA,0x7F, + 0x18,0xF7,0xD7,0xEE,0x5F,0x5E,0xF0,0xE2,0xD7,0xF6,0xF7,0xEE,0xA8,0xA8,0x02,0x22, + 0xD7,0xF6,0xB7,0xEE,0xC8,0xEC,0x8A,0x80,0xD7,0xF6,0xB7,0xEE,0x00,0x7E,0x6B,0xAA, + 0xF7,0xF6,0xB7,0xEE,0xEA,0xAF,0xBD,0xA7,0xF7,0xF6,0x55,0xE6,0xDA,0x60,0xE8,0xA2, + 0xD7,0xF6,0x55,0xE6,0x82,0x0B,0x09,0x35,0xD7,0xF6,0x55,0xE6,0x78,0xFA,0x78,0x68, + 0xB6,0xEE,0x55,0xE6,0x0B,0x0F,0xBF,0xF5,0x75,0xEE,0xD2,0xD5,0x68,0x68,0x60,0xC0, + 0xD3,0xDD,0x51,0xCD,0xD6,0xEE,0xBE,0xFC,0xF3,0xDD,0x71,0xCD,0x3F,0xBD,0xBD,0xBF, + 0x14,0xDE,0xF3,0xDD,0x34,0xF0,0xE2,0x81,0x14,0xDE,0xF3,0xDD,0xAF,0xEF,0xB7,0x03, + 0x34,0xE6,0xF4,0xDD,0x0B,0x83,0xAB,0xEA,0x34,0xE6,0xF3,0xDD,0x78,0x7A,0xFF,0xFF, + 0x14,0xDE,0xF3,0xDD,0xCF,0x5F,0xD7,0xF5,0x14,0xDE,0xD3,0xD5,0x8E,0xA7,0xAA,0x8A, + 0x25,0x5A,0x63,0x41,0x78,0xE2,0x80,0x8A,0xA4,0x49,0x02,0x39,0x3F,0xAF,0x2B,0x9E, + 0x68,0x62,0x63,0x41,0xBF,0x0F,0x2F,0xFD,0x88,0x62,0x43,0x41,0xBA,0x00,0x88,0x7F, + 0x27,0x5A,0x64,0x41,0x57,0xF8,0xE8,0x7F,0xC5,0x51,0x63,0x41,0xFF,0x83,0xA8,0x5F, + 0xC5,0x49,0x64,0x41,0x6A,0x0A,0x0A,0xD5,0xC5,0x49,0x43,0x39,0x2A,0xA8,0xE8,0x57, + 0xC5,0x49,0x23,0x39,0xA8,0x22,0xAB,0xF5,0xA5,0x49,0x02,0x31,0x2A,0xAA,0xFB,0x57, + 0xC5,0x49,0x02,0x31,0x7E,0xE3,0xA9,0x2D,0xA5,0x49,0x23,0x39,0x2B,0x35,0xF5,0xAB, + 0xA8,0x62,0x84,0x41,0xA9,0x55,0x55,0x0D,0xA8,0x62,0x43,0x39,0xFE,0x75,0x57,0xE0, + 0x84,0x41,0x02,0x31,0x78,0x7D,0x57,0x70,0xA5,0x41,0xE2,0x28,0xAD,0xF5,0xBF,0x2F, + 0xC5,0x49,0x23,0x39,0xE2,0xFD,0xBF,0xA8,0xA8,0x6A,0x43,0x39,0x7F,0xD5,0xAB,0x82, + 0xE6,0x51,0x23,0x31,0x76,0xDF,0xBE,0xF8,0xC6,0x51,0xC2,0x30,0xD7,0xD6,0xF8,0x68, + 0x84,0x49,0x23,0x39,0xDF,0xAF,0x03,0xAD,0x84,0x41,0x43,0x41,0xFB,0xCE,0x08,0x02, + 0x84,0x49,0x23,0x39,0xB5,0x3F,0x2F,0x8E,0xA5,0x49,0x03,0x39,0xD7,0xBA,0xA8,0xAE, + 0xA5,0x51,0x23,0x41,0xD5,0xFB,0xFA,0x9F,0x84,0x51,0x44,0x49,0xAD,0x9E,0x3A,0x95, + 0x06,0x62,0x43,0x49,0xAF,0x29,0x3F,0xBF,0xE5,0x69,0xC5,0x61,0xEF,0x6B,0x39,0x77, + 0xE5,0x61,0xA4,0x59,0xE8,0x60,0xE0,0xEC,0xC5,0x59,0x64,0x51,0xBB,0xB2,0xE2,0x7A, + 0xA5,0x51,0x44,0x49,0x22,0xBE,0x97,0x7F,0xA5,0x49,0x24,0x41,0xA8,0xBA,0xFE,0x55, + 0x85,0x49,0x24,0x41,0x02,0x3E,0x2F,0xF7,0xA5,0x49,0x44,0x41,0x82,0xEB,0xFF,0x95, + 0xA5,0x49,0x24,0x39,0x20,0xE2,0xCE,0x7F,0xA5,0x49,0x23,0x39,0x02,0xBA,0x2B,0x5F, + 0x85,0x41,0x03,0x39,0x00,0xA8,0xF8,0x77,0x85,0x49,0x03,0x39,0xA0,0x2A,0xAA,0x55, + 0xA5,0x49,0x03,0x39,0xA2,0xEF,0xEF,0x75,0x84,0x41,0xC2,0x30,0x00,0xA0,0xBA,0x57, + 0x84,0x49,0xE2,0x30,0x00,0x2A,0xAF,0x55,0xA5,0x49,0xE2,0x30,0x0A,0xAA,0xFB,0x55, + 0xA4,0x49,0xE2,0x30,0x0A,0xAA,0xF7,0x55,0x64,0x41,0xC2,0x30,0xF8,0x6B,0xEB,0x0B, + 0x84,0x41,0xE2,0x30,0x03,0xAD,0x55,0x55,0x63,0x41,0xC2,0x30,0x00,0xA8,0xD7,0xFD, + 0x64,0x41,0xC1,0x30,0x00,0xBF,0xDF,0xFF,0xC5,0x51,0x22,0x39,0x7F,0xFD,0xB5,0x05, + 0xA5,0x49,0x02,0x31,0xBF,0x55,0x57,0x5C,0x64,0x41,0x02,0x31,0x28,0x5D,0x55,0xFD, + 0x84,0x41,0x02,0x31,0x7F,0x55,0x5D,0x8F,0x64,0x41,0xC2,0x28,0xBA,0xF5,0xFF,0x28, + 0x64,0x41,0xE2,0x30,0xFB,0x5F,0x7F,0x02,0xE5,0x51,0x02,0x31,0xD5,0xB5,0xB5,0x0A, + 0x06,0x5A,0x02,0x31,0x5F,0x5E,0xF0,0x80,0xC6,0x51,0xC2,0x30,0x75,0xD5,0xBB,0x00, + 0xE7,0x59,0x03,0x31,0x55,0x55,0xFF,0x80,0xE6,0x59,0xE2,0x30,0x55,0x55,0xAF,0x00, + 0xE6,0x59,0x03,0x31,0x55,0x55,0x3B,0x00,0x26,0x5A,0x23,0x39,0x55,0xF5,0xAA,0x08, + 0x67,0x62,0xC5,0x51,0x43,0xE9,0xFD,0xBA,0x06,0x5A,0x03,0x39,0x57,0xFA,0x88,0x00, + 0x06,0x5A,0x24,0x41,0x55,0xBA,0x08,0x02,0x26,0x62,0x23,0x41,0xFD,0xAA,0x02,0x8A, + 0x27,0x62,0xC5,0x51,0x43,0x6A,0xA8,0xAA,0x27,0x62,0xA5,0x51,0x55,0xA3,0x28,0xA8, + 0x26,0x62,0xA4,0x51,0xBD,0xA8,0x22,0x8A,0x47,0x62,0xC5,0x51,0x7F,0xAE,0x2A,0xDF, + 0x26,0x62,0xA5,0x51,0x22,0x2A,0xA8,0xBD,0x26,0x62,0xC5,0x51,0xDA,0xA2,0xAA,0x6F, + 0x27,0x62,0xC5,0x51,0x2F,0xBE,0x2A,0xF6,0x27,0x62,0xA5,0x51,0xA8,0x08,0x0A,0x97, + 0x27,0x62,0xC4,0x51,0xEA,0xA2,0xFC,0xD7,0x47,0x62,0xA4,0x51,0x8B,0x8A,0xDF,0xBF, + 0xA8,0x72,0xC6,0x51,0xEF,0xEF,0x57,0x3B,0xA8,0x72,0x85,0x51,0xAA,0xFB,0xD7,0x00, + 0x29,0x83,0xE5,0x59,0x5D,0x55,0x55,0x0B,0x8B,0x8B,0xA4,0x51,0xF7,0x75,0xFD,0x00, + 0x4D,0xA4,0x05,0x5A,0x55,0x55,0x55,0x02,0xCF,0xB4,0xE5,0x59,0x55,0x55,0xDD,0x00, + 0x30,0xBD,0xE5,0x59,0x55,0x55,0xFF,0x00,0x71,0xC5,0x05,0x5A,0x55,0x55,0xEF,0x00, + 0xB3,0xD5,0x07,0x62,0x55,0x55,0xAB,0x00,0x14,0xDE,0x47,0x62,0x55,0x55,0xAA,0x00, + 0x34,0xE6,0x87,0x6A,0xD5,0xBD,0x22,0x00,0x55,0xE6,0x4D,0xAC,0xBD,0x2B,0x00,0x00, + 0xD7,0xF6,0x35,0xE6,0xAD,0xAD,0xAB,0x0B,0xF8,0xFE,0xB7,0xF6,0xBD,0xEF,0x6B,0x7A, + 0xD6,0xF6,0x96,0xEE,0xEC,0xF7,0xBF,0x7B,0xB6,0xF6,0x76,0xEE,0xFA,0xBA,0x7A,0x7E, + 0x96,0xEE,0x75,0xEE,0x58,0xFF,0xED,0x7F,0x76,0xEE,0xF3,0xDD,0xC2,0xE8,0x78,0x7A, + 0x34,0xE6,0xD3,0xD5,0x2E,0xBD,0xBD,0xA5,0x75,0xEE,0x14,0xDE,0xAF,0xEF,0xAD,0x2B, + 0x96,0xEE,0xF3,0xDD,0xF7,0x9F,0xBF,0x22,0x96,0xEE,0x34,0xE6,0x7D,0xFB,0xA2,0x80, + 0x75,0xEE,0x35,0xE6,0xE9,0x0B,0x02,0x0A,0x96,0xEE,0x14,0xDE,0x7F,0xA8,0x00,0x0A, + 0x96,0xEE,0x51,0xCD,0x57,0xA0,0x00,0x00,0x96,0xEE,0x10,0xC5,0xBD,0x57,0xE0,0x00, + 0x96,0xEE,0x71,0xC5,0x0A,0xBD,0xD5,0x5E,0xB6,0xEE,0x92,0xCD,0x00,0x0A,0xAF,0xFD, + 0xD7,0xF6,0x55,0xE6,0xAA,0xA2,0x0B,0xF5,0xD7,0xF6,0x96,0xEE,0x4B,0x2B,0x2B,0x2B, + 0xD7,0xF6,0x96,0xEE,0x55,0xBF,0x20,0x00,0xD7,0xF6,0xD3,0xD5,0xFA,0x78,0x60,0xA0, + 0xB6,0xEE,0x72,0xCD,0x02,0x0B,0xA5,0xD5,0x18,0xF7,0x55,0xE6,0x02,0x0A,0xBB,0xB5, + 0x18,0xFF,0xD8,0xF6,0xFE,0xEE,0xA2,0x0B,0x18,0xFF,0xD7,0xF6,0xFD,0xEF,0xBA,0xAA, + 0x18,0xF7,0xF7,0xF6,0xF9,0x77,0xFD,0xF7,0x18,0xF7,0xD7,0xEE,0xFA,0xBA,0xAF,0xBA, + 0xF7,0xF6,0xB6,0xEE,0xF2,0xFA,0xFC,0xE0,0xB7,0xF6,0xF7,0xEE,0xAF,0xEB,0xAA,0xAB, + 0xF7,0xF6,0x96,0xEE,0xFF,0xFE,0xFA,0x6A,0xD7,0xF6,0x96,0xEE,0xE0,0x8B,0xEB,0xEF, + 0xB6,0xEE,0x14,0xDE,0x2F,0x36,0xDE,0x7E,0xD7,0xF6,0x55,0xE6,0x78,0xEA,0xEA,0xEB, + 0x96,0xEE,0x34,0xE6,0x2D,0x8F,0xBE,0xB7,0x96,0xEE,0x14,0xDE,0x60,0x40,0x62,0xE8, + 0xF3,0xDD,0x72,0xCD,0xDE,0x7E,0x5C,0x5C,0xB2,0xD5,0x72,0xCD,0x3E,0xBF,0xF7,0xF5, + 0x14,0xDE,0xD3,0xD5,0x8B,0x0D,0xA9,0x29,0x34,0xE6,0xF4,0xDD,0xA7,0xBF,0xEA,0xAB, + 0x34,0xE6,0x14,0xDE,0x70,0x80,0x2E,0x2F,0x34,0xE6,0xF4,0xDD,0xDE,0xFA,0xF8,0xFF, + 0x14,0xDE,0xD3,0xD5,0xFE,0xBA,0x6E,0xF2,0x34,0xE6,0xF4,0xDD,0xF5,0xBD,0x2D,0x3F, + 0x46,0x62,0xC5,0x51,0x7F,0xF6,0xD6,0xFC,0x05,0x52,0x23,0x39,0xDE,0x7A,0x60,0x60, + 0xC5,0x49,0x22,0x39,0xEF,0xED,0xE9,0x35,0x27,0x62,0x43,0x41,0x55,0xBD,0x03,0x0B, + 0x88,0x6A,0x63,0x41,0x55,0xFF,0x80,0xEA,0xC5,0x49,0x43,0x41,0x55,0xAA,0xA8,0xE8, + 0xC4,0x49,0x42,0x39,0xFD,0x2A,0xAA,0xFB,0xA4,0x49,0x43,0x39,0xDA,0x28,0xAA,0xEF, + 0xA4,0x49,0x64,0x41,0xAE,0x28,0xFC,0x59,0xA5,0x49,0x43,0x39,0x6B,0xF0,0xFA,0x7B, + 0x84,0x41,0x23,0x39,0xBD,0xFA,0xCA,0xAA,0xA5,0x49,0x02,0x31,0x22,0x03,0x2D,0xE5, + 0xCA,0x8B,0xA4,0x49,0x0D,0xB5,0x55,0x55,0xEC,0x8B,0x63,0x41,0xE0,0xEA,0x57,0x55, + 0xA5,0x49,0x03,0x31,0x60,0xE0,0xC8,0xEE,0x44,0x31,0xA1,0x28,0x2B,0xFE,0xDE,0x5F, + 0x84,0x41,0xC1,0x28,0x28,0xAA,0xAB,0xAD,0x26,0x5A,0x02,0x31,0x02,0xFF,0xFF,0x75, + 0xC5,0x49,0x02,0x39,0xB8,0xFE,0xFB,0x55,0xE6,0x51,0x03,0x39,0x72,0xE3,0xEF,0x55, + 0x44,0x41,0xC1,0x30,0x0B,0x8F,0xF8,0x58,0xA4,0x49,0xE1,0x30,0xA2,0xBA,0xFF,0x55, + 0x84,0x49,0xE2,0x30,0x28,0xF8,0xFF,0x55,0x64,0x41,0xC1,0x30,0x00,0x82,0xFB,0x55, + 0x64,0x49,0xC1,0x30,0x00,0x00,0xFF,0x55,0x84,0x51,0x02,0x39,0x3A,0x0E,0x2D,0x05, + 0x26,0x6A,0x84,0x59,0xFD,0xBF,0x2B,0xAB,0x47,0x72,0xC5,0x61,0xF5,0xBF,0xF8,0xEA, + 0x26,0x72,0xE5,0x61,0x73,0x5C,0xBE,0xEA,0x05,0x6A,0x64,0x51,0x7E,0x7E,0x58,0x60, + 0x85,0x59,0x04,0x41,0xFA,0x7E,0x58,0x7A,0x04,0x41,0xA2,0x30,0x00,0xFA,0x5E,0x80, + 0x24,0x41,0xA2,0x30,0x3E,0x7F,0x7F,0x0B,0x24,0x41,0xA2,0x28,0xAC,0x7F,0x7F,0x02, + 0x44,0x41,0xA2,0x28,0xEB,0x5D,0xFB,0x20,0x85,0x49,0xC2,0x30,0x55,0x55,0xDD,0x20, + 0x85,0x49,0xC3,0x30,0x75,0x55,0xFF,0x00,0xA5,0x51,0xE2,0x30,0x55,0x55,0xF7,0x00, + 0x27,0x5A,0xE3,0x38,0x55,0xD5,0xF7,0xA8,0x07,0x5A,0xA2,0x28,0x55,0x5F,0xAE,0x02, + 0x07,0x5A,0xC2,0x30,0x55,0x7F,0xAB,0x20,0x06,0x5A,0xC2,0x30,0x55,0xFD,0xBA,0x00, + 0x27,0x5A,0xE2,0x30,0x55,0xFF,0xAA,0x02,0x06,0x5A,0x03,0x39,0xAD,0xAF,0x20,0x00, + 0x67,0x62,0x23,0x39,0x57,0xFF,0xAA,0xA2,0x27,0x5A,0x23,0x39,0x55,0xAB,0x08,0x80, + 0x06,0x5A,0x43,0x41,0xD5,0x2B,0x00,0x00,0x46,0x62,0xA4,0x49,0xD5,0xAF,0xAA,0xEA, + 0x27,0x62,0x84,0x49,0xD7,0x2A,0x00,0xA2,0x27,0x5A,0x84,0x49,0xF5,0x8A,0xA0,0xEA, + 0x06,0x5A,0xA5,0x49,0xF5,0x8A,0x00,0xA2,0x46,0x5A,0xA5,0x51,0xD7,0x2A,0xA0,0xBB, + 0x26,0x5A,0xA4,0x51,0xAB,0x80,0x20,0xD7,0x26,0x5A,0x84,0x49,0x22,0xA8,0xA8,0xF7, + 0x27,0x62,0x84,0x49,0xA8,0x82,0xAA,0xB5,0x07,0x5A,0xA5,0x51,0xC2,0x2F,0xE9,0xDE, + 0x28,0x62,0x85,0x51,0xA0,0x8A,0xF5,0xAE,0x48,0x6A,0x65,0x49,0xAA,0xEA,0x5F,0x2B, + 0x68,0x72,0x85,0x49,0xFB,0xFF,0x7F,0x8A,0x47,0x62,0xA5,0x51,0xBE,0xBF,0xF5,0x02, + 0x88,0x72,0x06,0x5A,0x7F,0x7F,0xF5,0x3B,0x6B,0x8B,0x84,0x49,0x5F,0x5D,0xFF,0x02, + 0x4E,0xAC,0xC5,0x51,0x55,0x55,0xD5,0x00,0xB0,0xB4,0xC5,0x51,0x55,0x55,0xFF,0x00, + 0x52,0xC5,0xC6,0x59,0x55,0x55,0xFF,0x00,0x93,0xCD,0xC5,0x59,0x55,0x55,0xAF,0x00, + 0xB3,0xD5,0xE6,0x59,0x55,0x55,0xAA,0x00,0xF5,0xDD,0x85,0x51,0x55,0xFF,0xAA,0x00, + 0x56,0xE6,0xA5,0x51,0x55,0xFF,0xAA,0x00,0x97,0xEE,0x26,0x62,0x55,0xFF,0xAA,0x00, + 0x15,0xDE,0x27,0x62,0x55,0xAB,0x20,0x00,0x36,0xE6,0x88,0x6A,0x55,0xAA,0x00,0x00, + 0x75,0xE6,0x29,0x83,0x55,0xAA,0x08,0x00,0x96,0xEE,0xCB,0x93,0x55,0xAA,0x00,0x00, + 0x96,0xEE,0x0D,0x9C,0xD5,0xAA,0x00,0x00,0x97,0xEE,0x90,0xAC,0xF5,0xA2,0x00,0x00, + 0x96,0xEE,0x11,0xBD,0xF5,0xAA,0x00,0x00,0xB6,0xEE,0x72,0xCD,0xD5,0xAA,0x00,0x00, + 0x96,0xEE,0xD3,0xD5,0xD5,0xAA,0x00,0x00,0xB6,0xEE,0xD3,0xD5,0xFD,0xAA,0x00,0x00, + 0xF6,0xF6,0x34,0xDE,0x55,0xFF,0xEB,0xAA,0xB6,0xEE,0x34,0xDE,0xF7,0xAA,0x82,0x00, + 0xB6,0xEE,0x55,0xE6,0xDD,0xAA,0x22,0x00,0xB6,0xEE,0x55,0xE6,0xED,0xAA,0x02,0x00, + 0xD6,0xF6,0x75,0xE6,0xDD,0xEB,0xAA,0x2A,0xF8,0xF6,0x96,0xEE,0x55,0xD7,0xAF,0xAB, + 0xF7,0xFE,0x96,0xEE,0xBD,0xAB,0xAA,0xB8,0xD6,0xF6,0x96,0xEE,0xF8,0xFE,0xFE,0xFA, + 0xB6,0xF6,0x96,0xEE,0xE8,0xBA,0xD2,0xF3,0x96,0xEE,0x55,0xEE,0xE0,0xE0,0x80,0x82, + 0x75,0xEE,0x34,0xE6,0x88,0xEA,0xA8,0x78,0x55,0xE6,0xF3,0xDD,0x7A,0x78,0x7E,0x7E, + 0x55,0xE6,0x92,0xD5,0xB7,0x97,0xAA,0x00,0xD7,0xF6,0x14,0xDE,0xBD,0xAD,0xAF,0x2B, + 0xF7,0xF6,0x96,0xEE,0xFD,0xAF,0x0A,0x8A,0xF7,0xF6,0x96,0xF6,0x6B,0x8A,0x80,0xA2, + 0xD7,0xF6,0x75,0xE6,0x57,0xDA,0xE8,0x28,0x96,0xEE,0x55,0xE6,0xAF,0xFA,0xFA,0xC8, + 0xB6,0xEE,0x75,0xE6,0xBF,0xD5,0x95,0x7F,0xB6,0xEE,0x55,0xE6,0x88,0xAA,0xBB,0xFF, + 0x96,0xEE,0xF3,0xD5,0x70,0x00,0x00,0x00,0x96,0xEE,0xB3,0xD5,0xD5,0xDE,0xE0,0x00, + 0x55,0xE6,0xF4,0xD5,0x2A,0x29,0xAD,0x98,0xB7,0xEE,0x35,0xE6,0x02,0xAF,0xB9,0xFD, + 0xF8,0xF6,0x75,0xE6,0x2A,0x2F,0xA5,0x75,0xF7,0xF6,0xB7,0xF6,0xFA,0xA0,0x8A,0x2D, + 0xF7,0xF6,0xD3,0xD5,0x5E,0xEA,0x20,0x00,0xF8,0xF6,0xB3,0xD5,0xBD,0xFF,0xE8,0x00, + 0xD7,0xF6,0x34,0xDE,0x0A,0x0B,0xB5,0xBA,0x18,0xFF,0x96,0xE6,0xA0,0x82,0x2F,0xAD, + 0x18,0xFF,0xF8,0xF6,0x95,0xDE,0xDF,0xBA,0x18,0xF7,0xF7,0xF6,0x7A,0xFF,0x5F,0x5D, + 0x18,0xFF,0xD7,0xF6,0x6F,0xFA,0xA2,0xE2,0xF7,0xF6,0xB6,0xEE,0xEA,0xBB,0xFC,0xF0, + 0xD7,0xF6,0xB6,0xEE,0xDA,0xFE,0xFC,0x54,0xB6,0xEE,0x96,0xEE,0xB2,0xB2,0x50,0xD0, + 0xB6,0xEE,0x13,0xDE,0x58,0xF8,0xE0,0xF8,0x96,0xEE,0x34,0xE6,0x83,0x0B,0x89,0xA5, + 0x75,0xEE,0x14,0xDE,0x36,0xBE,0xDC,0xFC,0x75,0xEE,0x55,0xE6,0x78,0x7B,0xED,0xFD, + 0x34,0xE6,0x92,0xCD,0x5E,0x5E,0x5C,0x58,0x92,0xCD,0x31,0xCD,0x2A,0x3A,0xA8,0x08, + 0x34,0xE6,0x92,0xCD,0xAB,0xAB,0x29,0x2B,0x55,0xE6,0xF3,0xDD,0xBD,0xF7,0xF5,0xAB, + 0x34,0xE6,0xF4,0xDD,0x8A,0xEC,0xCA,0xE2,0x35,0xE6,0xF4,0xDD,0xB7,0xFF,0xAF,0xEF, + 0x14,0xDE,0xF3,0xDD,0xFA,0x28,0xB0,0x7E,0x34,0xE6,0xF4,0xDD,0xF7,0xDF,0x77,0xEE, + 0x88,0x6A,0xA5,0x51,0x58,0x78,0xE0,0xF0,0xE6,0x59,0x84,0x41,0x7A,0xF2,0xAE,0xF0, + 0x84,0x49,0xE1,0x30,0x2F,0xFE,0x5C,0x58,0xC5,0x51,0xC1,0x30,0x0B,0xAB,0xBF,0xD5, + 0xE5,0x51,0x02,0x31,0xA0,0x8B,0xEA,0x57,0xC4,0x49,0xE1,0x28,0xA2,0x88,0xA8,0x5D, + 0xA5,0x49,0xC2,0x30,0x8A,0x08,0xEA,0xDF,0xC5,0x49,0xA1,0x28,0xAA,0x02,0xEA,0x7F, + 0x64,0x41,0xC1,0x28,0x00,0x00,0xBF,0xE9,0x64,0x41,0xE2,0x30,0x00,0x28,0x5F,0xFF, + 0xA5,0x49,0x02,0x31,0xE8,0xB7,0xB5,0x0D,0x64,0x41,0xC1,0x28,0xB6,0x5C,0xB8,0x80, + 0x43,0x39,0xC1,0x28,0x2A,0xDF,0xFF,0xEA,0x44,0x39,0xC2,0x28,0x28,0xD7,0x7F,0xEF, + 0x64,0x41,0xA1,0x28,0xFB,0xFD,0xFD,0x82,0x64,0x41,0xC2,0x28,0x57,0x5D,0xFF,0x2B, + 0x64,0x41,0xC1,0x28,0x75,0xD5,0xEF,0x02,0x85,0x49,0xC1,0x28,0x55,0xD5,0xFF,0x82, + 0xA6,0x49,0xE2,0x30,0x5D,0x55,0x5D,0x8A,0xC5,0x51,0xE2,0x30,0xF5,0x95,0x95,0x02, + 0xE6,0x51,0xE2,0x30,0x5E,0xFA,0xEA,0x00,0x06,0x52,0xC1,0x30,0x55,0xD5,0xEB,0x08, + 0x06,0x5A,0xC1,0x30,0x55,0x77,0xAA,0x0A,0x06,0x5A,0xC1,0x30,0x55,0xFD,0xAA,0x02, + 0x06,0x62,0xC1,0x30,0x55,0xFF,0xAA,0x00,0x06,0x62,0x02,0x41,0xB5,0xEF,0x2A,0xA0, + 0x27,0x72,0xA4,0x59,0x3D,0x2F,0x07,0xAF,0x26,0x72,0xE5,0x69,0x82,0x02,0xE8,0xFE, + 0x26,0x72,0xE5,0x69,0xFA,0x22,0xAF,0xDD,0x46,0x72,0xE6,0x69,0x5A,0xDC,0xA7,0xFD, + 0x26,0x6A,0x85,0x59,0x56,0xF8,0xA8,0xA2,0x06,0x62,0x64,0x49,0x7E,0xAA,0x0A,0x8C, + 0x06,0x62,0x64,0x49,0x75,0xA8,0xB0,0xBA,0x06,0x5A,0x84,0x49,0xF5,0x2A,0xAA,0xAA, + 0x27,0x5A,0xA5,0x51,0xDF,0x32,0xAB,0x57,0x07,0x5A,0x84,0x49,0xAE,0xA2,0x82,0x7B, + 0xE6,0x59,0x84,0x49,0x2A,0x02,0xA0,0x77,0x07,0x5A,0x84,0x49,0xA8,0x0A,0xAB,0xDF, + 0x27,0x62,0x84,0x49,0x8A,0xAB,0xFF,0xF5,0x27,0x62,0xA4,0x51,0x2A,0xEB,0x7E,0x57, + 0x46,0x62,0x84,0x49,0xBA,0xAB,0x7D,0x3D,0x47,0x62,0x44,0x49,0xAA,0xEA,0xFF,0x08, + 0xC8,0x72,0x83,0x49,0xFF,0xFF,0xF5,0x2A,0x2A,0x7B,0x84,0x51,0xFF,0x57,0x5D,0x02, + 0xAC,0x93,0xA5,0x51,0xD7,0x55,0xD5,0x22,0x0D,0xA4,0xC5,0x51,0x55,0x55,0x77,0x02, + 0x6F,0xAC,0x43,0x41,0xF7,0x55,0xBF,0x00,0xD1,0xBC,0xC5,0x51,0x55,0x55,0xFF,0x00, + 0x72,0xCD,0xE6,0x59,0x55,0x55,0xFF,0x00,0x93,0xCD,0xE5,0x59,0x55,0x55,0xBB,0x00, + 0xB3,0xD5,0x63,0x49,0x55,0xFF,0xAA,0x00,0xF4,0xDD,0xA4,0x51,0x55,0xFD,0xAA,0x00, + 0x56,0xEE,0xA4,0x51,0x55,0xFF,0x2A,0x00,0x76,0xEE,0x06,0x62,0x55,0xFF,0x2A,0x00, + 0xF4,0xDD,0xE5,0x59,0x55,0xAA,0x20,0x00,0x15,0xE6,0xA8,0x72,0x55,0xAA,0x00,0x00, + 0x55,0xE6,0x2B,0x83,0x55,0xAA,0x08,0x00,0x55,0xE6,0x8C,0x93,0xD5,0xAA,0x00,0x00, + 0x35,0xE6,0x2D,0xA4,0x55,0xAA,0xA0,0x80,0x52,0xCD,0xCC,0x9B,0x55,0xE8,0xE0,0x78, + 0xAC,0x93,0x46,0x6A,0xEA,0x60,0x58,0x56,0xAF,0xB4,0x06,0x62,0x2B,0x2F,0x25,0xB5, + 0x76,0xEE,0x10,0xBD,0xAF,0x2B,0x09,0x09,0xB7,0xF6,0xF4,0xDD,0x55,0xAA,0x22,0x02, + 0xB7,0xF6,0x15,0xDE,0xF5,0xEA,0x02,0x00,0xD7,0xF6,0x35,0xE6,0xF5,0xAB,0x2A,0x2A, + 0xD7,0xF6,0x55,0xE6,0x57,0xAE,0xA2,0x2A,0xD7,0xF6,0x76,0xEE,0x75,0xBE,0x2A,0x82, + 0xD7,0xF6,0x76,0xEE,0xFD,0xAA,0x28,0x08,0xD7,0xF6,0x96,0xEE,0x75,0xDE,0xAA,0xA8, + 0xD7,0xF6,0x76,0xEE,0xFD,0xBF,0xAA,0x28,0xD6,0xF6,0xB7,0xEE,0x75,0xFD,0x6A,0xFA, + 0xD7,0xF6,0x96,0xEE,0xBF,0xEF,0xAA,0xAA,0x96,0xF6,0xD7,0xEE,0xAE,0xBF,0xF7,0xFF, + 0xD7,0xF6,0x96,0xEE,0xD7,0xFF,0xAA,0x2A,0xD6,0xF6,0xB7,0xEE,0x77,0xFF,0xFA,0x6B, + 0xB7,0xF6,0xB6,0xEE,0xFF,0xFB,0xEF,0xFF,0xD7,0xF6,0xB6,0xEE,0xFD,0x6F,0xEB,0xEA, + 0xD6,0xF6,0xB6,0xEE,0xA9,0xB9,0xBF,0xFD,0xD7,0xF6,0xB6,0xEE,0xFF,0xEA,0x68,0xFA, + 0xD7,0xF6,0xB6,0xEE,0x55,0xBF,0x77,0xFF,0xB6,0xF6,0xD7,0xEE,0x8A,0xC8,0x82,0x22, + 0xD7,0xF6,0xB6,0xEE,0x7B,0x7B,0xFB,0xBB,0xD7,0xF6,0x96,0xEE,0xBA,0xBA,0xBE,0xFE, + 0xD7,0xF6,0xB7,0xEE,0x2B,0x32,0x28,0x2A,0xF7,0xF6,0xB6,0xF6,0x8E,0x83,0xA0,0x72, + 0xD6,0xF6,0x96,0xEE,0xA8,0xB8,0xFF,0xD7,0xB6,0xF6,0x96,0xEE,0xA2,0x60,0x7A,0xB7, + 0x96,0xEE,0x75,0xEE,0x00,0xBB,0x5F,0x5C,0xB7,0xF6,0x35,0xE6,0xA2,0xEA,0xEE,0x5F, + 0x55,0xE6,0x14,0xDE,0xA8,0xBA,0xA7,0xAF,0x96,0xEE,0xF3,0xDD,0xD7,0xBF,0xBF,0x2F, + 0xD7,0xF6,0x34,0xE6,0xF7,0xFF,0x0A,0x22,0xF7,0xF6,0x96,0xEE,0xBD,0x0B,0xA2,0x8A, + 0xF7,0xF6,0xD7,0xF6,0xA7,0xA7,0xA2,0xEB,0xF7,0xF6,0xD7,0xF6,0xEA,0x6A,0xFB,0xED, + 0xF7,0xF6,0xB6,0xEE,0xFA,0xFA,0xEA,0xA2,0xD7,0xF6,0x96,0xEE,0x5E,0xEE,0xCA,0x80, + 0xB6,0xEE,0x76,0xEE,0x7B,0xAB,0xAA,0x00,0xB6,0xEE,0x76,0xE6,0xD5,0xFE,0xFA,0xFC, + 0x96,0xEE,0x76,0xE6,0xEF,0xDE,0x6F,0xBA,0xB6,0xEE,0x56,0xE6,0x2A,0x2A,0x2B,0x0A, + 0xF7,0xF6,0x55,0xE6,0x5E,0x7A,0xEA,0xAA,0xD7,0xF6,0x34,0xDE,0xB5,0xFF,0xAA,0x80, + 0xB6,0xEE,0x75,0xE6,0x5D,0xAF,0xAB,0xA0,0xF7,0xF6,0x96,0xEE,0x2D,0xBD,0xE5,0xBF, + 0x18,0xFF,0xD7,0xF6,0xAA,0xBB,0xBD,0xB5,0x18,0xF7,0xD7,0xF6,0xFD,0xBA,0xEA,0xA8, + 0xF8,0xF6,0xD7,0xF6,0x56,0xF8,0x08,0xAC,0xF8,0xF6,0xB7,0xEE,0x55,0x7A,0xC0,0x00, + 0x18,0xFF,0x96,0xE6,0x82,0x0D,0xB7,0xFE,0x18,0xFF,0xD7,0xEE,0xAE,0xAE,0xAE,0xAD, + 0x18,0xFF,0xF7,0xF6,0xF7,0xD7,0xAF,0xBD,0x18,0xFF,0xD7,0xF6,0x5A,0x7E,0x7E,0x7A, + 0xD7,0xF6,0x96,0xEE,0xFE,0x72,0xEF,0xEB,0xB6,0xEE,0x75,0xE6,0xAA,0xBA,0x7E,0x7E, + 0x96,0xEE,0x14,0xDE,0xE0,0xE0,0xE8,0x7B,0x96,0xEE,0xF3,0xDD,0x2D,0xBD,0xB5,0xD5, + 0x75,0xEE,0xF3,0xDD,0xFC,0x78,0xF0,0xF8,0x55,0xE6,0x14,0xE6,0x8A,0xA3,0xA9,0xFD, + 0x34,0xE6,0x92,0xCD,0x78,0x78,0x70,0x68,0x92,0xCD,0x51,0xC5,0x3E,0xB5,0xD5,0x9E, + 0x14,0xE6,0x92,0xCD,0x0B,0x0B,0x29,0x0F,0x54,0xE6,0x14,0xDE,0xEB,0xDF,0x57,0xD7, + 0x34,0xE6,0xF4,0xDD,0xC2,0xAA,0xAE,0x6E,0x14,0xDE,0xB3,0xD5,0x0A,0xA8,0xAA,0x2B, + 0x14,0xDE,0xD3,0xD5,0x37,0x2F,0x2A,0x20,0x34,0xE6,0xF4,0xDD,0xEA,0x7E,0x5F,0x76, + 0x8B,0x8B,0x06,0x5A,0x7E,0x7E,0x78,0x78,0x06,0x5A,0xA5,0x49,0xDE,0xFA,0x58,0x60, + 0xA5,0x49,0xC1,0x30,0x68,0xE8,0x82,0x00,0xA5,0x49,0xA1,0x28,0xD5,0xFF,0xAA,0x08, + 0x47,0x62,0xE1,0x30,0x55,0xD5,0xAB,0x0A,0x88,0x6A,0xE1,0x30,0x55,0xFF,0x2A,0x00, + 0xE9,0x72,0x23,0x39,0x55,0xAB,0x0A,0x22,0xE9,0x72,0x84,0x41,0x55,0xFA,0xA0,0xA8, + 0x67,0x62,0x64,0x41,0xF5,0xAA,0x00,0xA0,0x87,0x62,0x64,0x41,0x55,0xFE,0xA8,0xAA, + 0x68,0x62,0x43,0x39,0xBD,0xAA,0x22,0xAA,0x27,0x5A,0x84,0x49,0x5E,0xA0,0xA8,0xAA, + 0x07,0x5A,0x84,0x41,0x55,0x20,0x00,0xA0,0x27,0x5A,0x84,0x49,0x55,0x08,0x00,0xFB, + 0x27,0x5A,0x84,0x49,0xBD,0xA0,0x88,0xEF,0x07,0x5A,0xA5,0x49,0xAD,0x28,0x26,0x77, + 0x27,0x5A,0x84,0x49,0xAA,0x00,0xAF,0x77,0x47,0x5A,0x85,0x49,0xEB,0xA2,0xFB,0x55, + 0x07,0x5A,0x64,0x49,0x2A,0x02,0xAA,0x55,0x27,0x62,0x84,0x49,0xAA,0xF0,0x7F,0x55, + 0x47,0x62,0x64,0x49,0x02,0xEA,0x7F,0x55,0x27,0x5A,0x65,0x49,0x00,0xA8,0x57,0xD5, + 0x27,0x62,0x85,0x49,0x0A,0x8A,0x55,0x55,0x06,0x5A,0x65,0x49,0x80,0xE3,0xDD,0x3A, + 0x47,0x6A,0x64,0x49,0xEA,0xFF,0x55,0x82,0x47,0x6A,0x84,0x51,0xFE,0x5F,0xD5,0xE8, + 0x06,0x6A,0xC5,0x61,0xBB,0x9F,0xA9,0xA5,0x06,0x72,0xE5,0x69,0xD4,0x5F,0x5F,0x5A, + 0x46,0x7A,0xE5,0x69,0xF5,0xFD,0xAF,0xF9,0x26,0x72,0xE5,0x69,0x6F,0xFF,0xA2,0x2A, + 0x88,0x82,0xE6,0x69,0x7F,0xAD,0x29,0x2B,0x4E,0xAC,0xA5,0x59,0x55,0x57,0xAF,0x0A, + 0x73,0xCD,0xE6,0x61,0x55,0x55,0xAB,0x08,0xB3,0xD5,0x84,0x51,0x55,0xDD,0xAA,0x00, + 0x14,0xDE,0x83,0x49,0x55,0xFF,0xAA,0x00,0x34,0xDE,0xE5,0x59,0x55,0xFF,0x2A,0x00, + 0x95,0xEE,0x26,0x62,0x55,0xFF,0x2A,0x00,0xF3,0xDD,0x46,0x62,0x55,0xAB,0x08,0x00, + 0x14,0xDE,0x88,0x6A,0x55,0xAA,0x00,0x00,0x34,0xDE,0x0A,0x7B,0x55,0xAA,0x00,0x00, + 0x55,0xE6,0x6B,0x8B,0x5D,0xAA,0x00,0x00,0x75,0xE6,0x2D,0x9C,0x55,0xAA,0x00,0x00, + 0x96,0xEE,0x6E,0xAC,0x55,0x2A,0x00,0x00,0x96,0xEE,0xF0,0xBC,0x55,0xAA,0x00,0x00, + 0xB6,0xEE,0x52,0xC5,0x75,0xAA,0x22,0x80,0xB6,0xEE,0x93,0xCD,0xD5,0xAA,0x00,0x00, + 0x96,0xEE,0xF4,0xDD,0x55,0xBB,0x00,0x00,0xB6,0xF6,0x14,0xDE,0x55,0xAE,0xAA,0x00, + 0xB6,0xF6,0x15,0xDE,0xF7,0xAA,0x28,0x00,0xB6,0xEE,0x35,0xE6,0x5D,0xAA,0x28,0x00, + 0xB6,0xEE,0x55,0xE6,0x7D,0xEA,0x22,0x00,0xB6,0xEE,0x55,0xE6,0xFD,0x2A,0x00,0x00, + 0xB6,0xEE,0x76,0xEE,0x57,0xBB,0x22,0x00,0xB6,0xF6,0x56,0xEE,0xF7,0xAF,0x0A,0x00, + 0xB6,0xF6,0x96,0xEE,0x75,0xED,0xB8,0x00,0xB6,0xF6,0x96,0xEE,0xF5,0xFE,0xFA,0x00, + 0x96,0xF6,0xB6,0xEE,0xA8,0xEE,0xEE,0xD5,0xB6,0xF6,0x14,0xE6,0xAA,0xE0,0x6A,0x60, + 0x34,0xE6,0x4E,0xAC,0xA0,0xE8,0x68,0x7A,0xAF,0xBC,0x06,0x62,0xE0,0xF8,0x7E,0x5E, + 0x66,0x72,0xE6,0x61,0xFC,0x7B,0x7E,0x5E,0xE9,0x82,0xC5,0x61,0x3D,0xBD,0xB7,0xD5, + 0x75,0xEE,0x8B,0x93,0x0B,0x29,0x0D,0x2D,0x18,0xFF,0x96,0xEE,0xF5,0xFF,0xAB,0x2B, + 0xF8,0xF6,0xB7,0xF6,0xD5,0xBF,0x2A,0x08,0xF7,0xF6,0xB7,0xEE,0xFD,0xAA,0x00,0x00, + 0x17,0xFF,0xD7,0xF6,0x7D,0xBF,0xEA,0xAA,0x18,0xF7,0xD7,0xF6,0xD5,0xBA,0x3B,0xAA, + 0xF7,0xF6,0xB6,0xEE,0xEA,0xE8,0xD0,0xE8,0xF7,0xF6,0xB6,0xEE,0xDB,0xBB,0xAA,0xAB, + 0xD7,0xF6,0xB6,0xEE,0xBA,0x28,0x0A,0x22,0xD7,0xF6,0xB7,0xEE,0x82,0x82,0x00,0x02, + 0xD7,0xF6,0xB7,0xEE,0xF0,0x3A,0x82,0x89,0xD7,0xF6,0xB7,0xEE,0x9C,0xBE,0xAB,0x82, + 0xD7,0xF6,0xB7,0xEE,0x3F,0xFB,0xAE,0x0E,0xD7,0xF6,0xB7,0xEE,0xEA,0xE2,0xAA,0xA8, + 0xD7,0xF6,0xB6,0xEE,0xEF,0xA2,0xA0,0xA0,0xD7,0xF6,0xB6,0xEE,0xF1,0xEB,0xA8,0xAA, + 0xD7,0xF6,0xB7,0xEE,0xBF,0xEB,0x4A,0xAA,0xD6,0xF6,0xB7,0xEE,0xD7,0xF5,0xAF,0x8A, + 0xD7,0xF6,0xB6,0xEE,0x7F,0xFB,0xFA,0xEA,0xD7,0xF6,0xB6,0xEE,0xE3,0x8A,0x7D,0x2F, + 0xD7,0xF6,0xB6,0xEE,0xEF,0x6A,0x2B,0x29,0xF7,0xF6,0xB6,0xEE,0x5D,0xFF,0xBF,0x2B, + 0xF7,0xF6,0xB6,0xF6,0x2B,0x8A,0xE2,0xF8,0xD7,0xF6,0x75,0xEE,0xF0,0xF8,0x7E,0xFE, + 0x96,0xEE,0x75,0xEE,0x26,0xBF,0x64,0x6D,0xB6,0xF6,0x75,0xEE,0xAB,0x7B,0x7F,0x55, + 0x96,0xEE,0x34,0xE6,0xC0,0xE8,0xEE,0x7A,0x55,0xE6,0xF3,0xDD,0xA0,0xA8,0xFA,0x7E, + 0x55,0xE6,0xF3,0xDD,0x2A,0x2A,0x2B,0x09,0xB7,0xF6,0x55,0xE6,0x2D,0x2B,0x0B,0x8B, + 0xD7,0xF6,0x96,0xEE,0x3A,0xE8,0xEA,0xFF,0xD7,0xF6,0x96,0xEE,0x02,0x3B,0xAB,0x2B, + 0x17,0xF7,0xB7,0xF6,0xFB,0xFF,0xFD,0x55,0xF7,0xF6,0xD7,0xF6,0xAD,0xAD,0x65,0x6D, + 0xF7,0xF6,0x97,0xEE,0x28,0x88,0xAA,0x8E,0xF7,0xF6,0xD7,0xF6,0xD6,0xF6,0x55,0x77, + 0xD7,0xF6,0xB7,0xEE,0x7E,0xB8,0xA8,0x08,0xD7,0xF6,0x96,0xEE,0xFB,0xFA,0xEA,0x08, + 0x96,0xF6,0xB7,0xEE,0xBB,0xDD,0x7D,0x55,0xB7,0xEE,0x96,0xEE,0xF5,0x7E,0x68,0x80, + 0xB6,0xEE,0x96,0xEE,0x03,0xB5,0xB6,0x2E,0xF7,0xF6,0xB6,0xEE,0x7F,0xAD,0x2D,0xAD, + 0xF7,0xF6,0xB6,0xEE,0x55,0x5A,0x6A,0x20,0xD7,0xF6,0xB7,0xEE,0xE5,0xED,0xEF,0x98, + 0x18,0xFF,0xB6,0xF6,0xBF,0xAD,0xBE,0xAB,0x38,0xFF,0xF8,0xF6,0xFF,0xAF,0xA9,0xAF, + 0x39,0xFF,0xF8,0xF6,0x57,0x5E,0x7A,0xFA,0x18,0xF7,0xD7,0xF6,0xFA,0x7B,0xFA,0xF8, + 0xF7,0xF6,0x96,0xEE,0x68,0x80,0x02,0x08,0xF7,0xF6,0xB6,0xEE,0x2D,0xB7,0xD6,0x7E, + 0xF7,0xF6,0xD7,0xF6,0x02,0x0A,0x20,0x29,0x38,0xFF,0xD7,0xF6,0x7F,0x7B,0xFF,0x7D, + 0xD7,0xF6,0x96,0xEE,0xFE,0xEC,0xFE,0xB8,0xB6,0xEE,0x55,0xE6,0xFA,0x78,0xF8,0x7A, + 0x75,0xE6,0x14,0xDE,0x6A,0x6A,0x6E,0x68,0x34,0xE6,0x92,0xCD,0xAE,0x3F,0x95,0xD5, + 0x55,0xE6,0x14,0xE6,0x72,0x62,0x42,0x63,0xF4,0xE5,0x34,0xDE,0x7F,0xFA,0xFA,0xFA, + 0x55,0xEE,0xB3,0xD5,0x60,0x68,0xE0,0xE2,0xB2,0xD5,0x51,0xC5,0x2F,0xB7,0xF6,0xF6, + 0x34,0xE6,0x92,0xCD,0x2F,0x0F,0xA9,0x29,0x34,0xE6,0x14,0xDE,0x02,0x88,0x0B,0xFA, + 0x35,0xE6,0xF4,0xDD,0xFA,0xFE,0x9E,0xB7,0x14,0xDE,0xD3,0xDD,0x3E,0xFC,0xEE,0xBA, + 0x14,0xDE,0xD3,0xDD,0x28,0xBA,0x9F,0xE7,0x14,0xDE,0x92,0xCD,0xA8,0xA8,0xEA,0x60, + 0x51,0xC5,0x87,0x6A,0x5E,0x78,0xE0,0x80,0xCB,0x93,0xC5,0x51,0x57,0x57,0x5E,0xE8, + 0xE5,0x59,0x63,0x49,0xAE,0xAF,0xF7,0xA0,0xE5,0x59,0x42,0x41,0x22,0x0A,0xFF,0xDF, + 0x47,0x62,0x43,0x41,0x00,0xAE,0xFF,0xE7,0x67,0x62,0x43,0x41,0x00,0xBA,0x7F,0xFA, + 0x88,0x6A,0x84,0x49,0x20,0xFF,0x55,0xFF,0x67,0x6A,0x84,0x49,0x8A,0x6F,0x75,0x20, + 0xC9,0x7A,0x84,0x49,0xFF,0x5D,0x55,0x02,0x6B,0x8B,0x84,0x49,0x7F,0x55,0x55,0x02, + 0xED,0x9B,0x84,0x49,0x55,0x55,0xFF,0x00,0x6E,0xAC,0xA5,0x49,0x55,0x55,0xFF,0x00, + 0xD0,0xB4,0xA5,0x51,0x55,0x55,0xFF,0x00,0x32,0xBD,0xA5,0x51,0x55,0x55,0xEF,0x00, + 0x32,0xC5,0xA5,0x51,0x55,0x55,0xAA,0x00,0x92,0xCD,0xA5,0x49,0x55,0xF5,0xAA,0x00, + 0xF3,0xDD,0x84,0x49,0x55,0xFF,0xAA,0x00,0x34,0xE6,0xA5,0x51,0x55,0xFF,0xAA,0x00, + 0x14,0xDE,0x06,0x5A,0x55,0xFF,0x8A,0x00,0xB3,0xD5,0xC5,0x51,0x55,0xAA,0x00,0x00, + 0xF4,0xDD,0x67,0x6A,0x55,0xAA,0x00,0x00,0x14,0xDE,0xE9,0x72,0x55,0xAA,0x00,0x00, + 0x35,0xDE,0x6B,0x8B,0x55,0xAA,0x08,0x00,0x35,0xE6,0xAD,0x93,0xF5,0xAA,0x00,0x00, + 0x35,0xE6,0x70,0xAC,0x55,0xAA,0x00,0x00,0x35,0xE6,0xA8,0x7A,0x7E,0xFA,0xE0,0xE0, + 0x87,0x7A,0x84,0x59,0xF7,0xF6,0x54,0x54,0xE5,0x69,0xA4,0x61,0x20,0x22,0x23,0x3D, + 0x05,0x72,0xC5,0x69,0xBE,0xBF,0x3E,0x37,0x26,0x72,0xE5,0x69,0xFA,0xBA,0xB8,0xD7, + 0x88,0x7A,0x06,0x72,0x2D,0xBD,0xB5,0xD5,0x6E,0xB4,0x67,0x72,0x0B,0x2D,0xB5,0xF5, + 0x35,0xE6,0x0C,0xAC,0x2A,0x0B,0x2F,0xAD,0x96,0xF6,0x35,0xE6,0xB5,0xAA,0xAB,0x09, + 0xB6,0xF6,0x55,0xE6,0xDD,0xFB,0xAB,0x2A,0xB6,0xF6,0x75,0xEE,0x55,0xFF,0xEA,0xAA, + 0x96,0xF6,0x75,0xE6,0x5F,0xAE,0x8B,0x08,0xB6,0xF6,0x75,0xE6,0xD7,0xEF,0x2A,0x22, + 0xB6,0xF6,0x96,0xE6,0x57,0xAB,0xAE,0xA2,0xB6,0xF6,0x75,0xEE,0xFD,0xEE,0xB0,0x3A, + 0xB7,0xF6,0x75,0xEE,0xBD,0xBB,0xAA,0xAA,0xB6,0xF6,0x96,0xEE,0x7E,0xCA,0x03,0x0F, + 0x96,0xF6,0xB6,0xEE,0x76,0x5F,0x77,0xFF,0xD7,0xF6,0x96,0xEE,0xD5,0xFF,0xFF,0xBC, + 0xB6,0xF6,0x95,0xEE,0xEF,0xAA,0x0A,0x0A,0x96,0xFE,0xB6,0xEE,0x7D,0xF7,0xDF,0xFF, + 0xB7,0xF6,0xB6,0xEE,0xFF,0xBE,0xEB,0xAA,0xD6,0xF6,0x95,0xEE,0xFB,0xAA,0x29,0xAF, + 0xD7,0xF6,0xB6,0xEE,0x7D,0xAA,0x00,0x02,0xF6,0xF6,0xD7,0xF6,0x55,0x57,0x7F,0xEB, + 0xF7,0xF6,0xB6,0xEE,0xD7,0xAB,0x82,0x00,0xF7,0xF6,0xB7,0xEE,0xF7,0x2A,0x22,0x80, + 0xF7,0xF6,0xB6,0xEE,0xFB,0xEA,0x8A,0x22,0xF7,0xF6,0xB6,0xEE,0xBF,0x2A,0x00,0x00, + 0xF7,0xF6,0xD7,0xF6,0x55,0x58,0xE2,0xA0,0xF8,0xFE,0xB6,0xF6,0xDD,0xAA,0x2B,0xEA, + 0xD7,0xF6,0x75,0xEE,0x88,0x80,0xE0,0x60,0xB6,0xF6,0xEF,0xBC,0xA0,0xE8,0xEA,0x7A, + 0x51,0xCD,0x87,0x7A,0xE0,0xE8,0x5A,0x5E,0xC8,0x7A,0x26,0x6A,0x7C,0xFF,0xF5,0xF5, + 0x46,0x72,0xE5,0x61,0x7C,0xC0,0x88,0x60,0x66,0x72,0xC5,0x61,0x15,0x95,0x9E,0xBF, + 0x75,0xEE,0x8A,0x93,0x2D,0x2D,0x2D,0x2D,0x18,0xFF,0x96,0xF6,0x29,0x2B,0xAB,0x8B, + 0xF8,0xFE,0x17,0xF7,0xAA,0xAA,0xAA,0xE2,0x18,0xFF,0xF7,0xF6,0xD7,0xD5,0xAF,0xBE, + 0x18,0xFF,0xF7,0xF6,0xAF,0xFF,0xEE,0xB9,0x18,0xFF,0xF7,0xF6,0x7E,0xAA,0xAA,0x6E, + 0xF7,0xF6,0xD7,0xF6,0x70,0xE8,0xE2,0xA8,0xF7,0xF6,0xD7,0xF6,0xDB,0xDA,0x5D,0xD5, + 0xF7,0xF6,0xD7,0xF6,0x55,0x5D,0x6B,0x7B,0xF6,0xF6,0xD7,0xF6,0x55,0x5F,0x7E,0x7F, + 0xB7,0xF6,0xD6,0xEE,0xBA,0xEA,0xAA,0xFB,0xD7,0xF6,0xB7,0xEE,0x8A,0x02,0x02,0xC8, + 0xD7,0xF6,0xB6,0xEE,0xAA,0x22,0x28,0x2F,0xD7,0xF6,0xB7,0xEE,0x82,0x02,0x28,0x2E, + 0xD7,0xF6,0xB7,0xEE,0x80,0xA8,0x3E,0xA3,0xD7,0xF6,0xF7,0xEE,0x00,0x0A,0x82,0x82, + 0xF7,0xF6,0xB6,0xEE,0xFF,0xDA,0xFE,0xBA,0xD7,0xF6,0xB6,0xEE,0x8B,0x8A,0xA2,0x28, + 0xD7,0xF6,0xB6,0xEE,0xE2,0xEA,0xBE,0xBE,0xF7,0xF6,0xB6,0xEE,0xF7,0xFF,0xEA,0xEA, + 0xF7,0xF6,0xD7,0xF6,0x55,0x5F,0xBD,0x2D,0x18,0xFF,0xD7,0xF6,0xAD,0xE9,0xFB,0x5E, + 0xF7,0xF6,0x96,0xEE,0xE8,0xFA,0xDE,0x7E,0xB6,0xF6,0x96,0xEE,0xDE,0x7D,0x77,0x7F, + 0x96,0xEE,0x75,0xEE,0x72,0xFA,0x5E,0x54,0x96,0xEE,0x14,0xE6,0xEA,0xF8,0x7A,0x5A, + 0x55,0xEE,0xF4,0xDD,0xA0,0xA2,0xEA,0xFF,0x14,0xDE,0x71,0xCD,0x80,0xE8,0x7C,0xD6, + 0x55,0xE6,0xB2,0xD5,0x03,0xAD,0xBD,0x8B,0x76,0xEE,0x14,0xDE,0x00,0xEB,0x55,0xF2, + 0x96,0xEE,0xB2,0xD5,0x00,0x2A,0xD7,0x5F,0x96,0xF6,0xD3,0xD5,0x00,0x00,0xAF,0xD5, + 0xB7,0xF6,0x14,0xDE,0x08,0x02,0xAA,0xF5,0xD7,0xF6,0x55,0xE6,0x00,0x88,0xEB,0xF7, + 0xD7,0xF6,0x96,0xEE,0x0A,0x0A,0x2D,0xD5,0xF7,0xF6,0xB6,0xF6,0xEE,0x0A,0x2B,0xBD, + 0xF7,0xF6,0xD7,0xF6,0x75,0xD6,0xB7,0x29,0xF8,0xF6,0xD7,0xF6,0x55,0xFD,0xDF,0xE7, + 0xD7,0xF6,0xB7,0xEE,0x5E,0x58,0xF8,0x70,0x97,0xF6,0xB6,0xEE,0xDF,0xFF,0xFF,0x5F, + 0xD7,0xF6,0x96,0xEE,0x2E,0xA3,0xFE,0xFA,0xD7,0xF6,0xB7,0xEE,0x08,0x2A,0xAF,0xF5, + 0xF7,0xF6,0xB7,0xEE,0x82,0xAA,0xAF,0x0B,0xF7,0xF6,0xD7,0xF6,0xEA,0x08,0x20,0x82, + 0x18,0xF7,0xD8,0xF6,0x3D,0xAF,0xBF,0xEB,0x38,0xFF,0xF7,0xF6,0xAB,0x2E,0xAB,0xAF, + 0x39,0xFF,0x18,0xF7,0x7F,0xEA,0xEA,0x22,0x38,0xFF,0xF8,0xF6,0x5F,0xDE,0xFF,0x68, + 0x18,0xF7,0xD7,0xF6,0xBF,0xFA,0xEA,0xFE,0xF7,0xF6,0xB7,0xEE,0xE8,0xA0,0xA2,0xFA, + 0xF7,0xF6,0xB6,0xEE,0x0D,0x25,0x17,0xD7,0xF7,0xF6,0x97,0xEE,0xA0,0x88,0xA8,0xEA, + 0xD7,0xF6,0x96,0xEE,0xEA,0xFA,0x60,0xE2,0x96,0xEE,0x55,0xE6,0xE0,0xE0,0xE0,0xE0, + 0x55,0xE6,0xD3,0xD5,0x60,0xEA,0xF2,0xF0,0xB3,0xD5,0x0F,0xBD,0x2E,0x2E,0x3E,0x16, + 0x55,0xE6,0xF3,0xDD,0xA3,0x0B,0x09,0xA9,0x14,0xDE,0xB3,0xDD,0x0A,0x0A,0xA8,0xBA, + 0x34,0xE6,0xF4,0xDD,0x82,0xEA,0xEB,0x8B,0xD3,0xD5,0x30,0xC5,0xD6,0xDC,0xDC,0x5C, + 0x14,0xE6,0x71,0xCD,0x2B,0x29,0x2D,0x0F,0x34,0xE6,0x14,0xDE,0xD4,0xF5,0x95,0x55, + 0x35,0xE6,0xF3,0xDD,0xEF,0xEE,0xDA,0xE0,0x14,0xDE,0xF3,0xDD,0xFA,0x00,0x28,0x54, + 0x14,0xDE,0xD3,0xDD,0xAA,0xBC,0xFE,0x3A,0xF3,0xDD,0x10,0xC5,0xC0,0x60,0x60,0x60, + 0xB6,0xEE,0x92,0xCD,0x7F,0xFA,0xA8,0x80,0x55,0xE6,0x2D,0xA4,0x5E,0xAA,0x20,0x00, + 0x14,0xDE,0x29,0x7B,0x55,0xAA,0x80,0x00,0xF4,0xDD,0xC8,0x72,0x55,0xAA,0x00,0x00, + 0x14,0xDE,0x09,0x7B,0x55,0xAA,0x02,0x00,0x15,0xDE,0x8B,0x8B,0x55,0xAA,0x00,0x00, + 0x35,0xE6,0x0D,0x9C,0x55,0xAA,0x00,0x00,0x55,0xE6,0x70,0xAC,0x55,0xAA,0x08,0x00, + 0x55,0xE6,0xF1,0xBC,0x55,0xAA,0x0A,0x00,0x76,0xE6,0x32,0xC5,0x57,0xAB,0x28,0x00, + 0x76,0xEE,0x72,0xCD,0xD5,0xBA,0x08,0x00,0x75,0xEE,0xD3,0xD5,0x55,0xBB,0x20,0x00, + 0x75,0xEE,0xD3,0xD5,0x55,0xEA,0x00,0x00,0x75,0xEE,0xD4,0xD5,0xDD,0xAA,0x82,0x00, + 0x76,0xEE,0xF4,0xDD,0x75,0x82,0x02,0x00,0x96,0xF6,0x14,0xDE,0x57,0xEE,0xAA,0x0A, + 0x95,0xEE,0x34,0xE6,0x55,0xBB,0xAA,0x00,0x96,0xEE,0x34,0xE6,0x7F,0xAE,0x8A,0x08, + 0x96,0xEE,0x34,0xE6,0xD7,0xEA,0xAA,0x88,0x96,0xEE,0x55,0xE6,0xFD,0xAF,0xA8,0xA8, + 0x96,0xEE,0x34,0xE6,0xFD,0xA8,0xA8,0x08,0xB7,0xF6,0x55,0xE6,0xDD,0xFF,0xBF,0x2B, + 0x96,0xEE,0x75,0xEE,0xFD,0x8B,0x23,0x00,0x96,0xEE,0x76,0xEE,0x55,0xF0,0x00,0x00, + 0xB6,0xF6,0x76,0xEE,0xF5,0xFD,0xBB,0xAD,0xB6,0xF6,0x4D,0xAC,0x78,0x6A,0x78,0x68, + 0xC8,0x82,0x83,0x61,0x54,0xD8,0x7C,0xFC,0xE5,0x69,0x84,0x61,0x3B,0x57,0xFF,0xBF, + 0x26,0x72,0x84,0x61,0x2F,0x27,0xBF,0xBF,0x26,0x72,0xE5,0x69,0xDF,0xF0,0xA8,0x02, + 0x27,0x72,0xA4,0x69,0x20,0x2B,0x2E,0x96,0xE8,0x82,0x26,0x72,0x3D,0xD5,0xD5,0x55, + 0x51,0xCD,0xA8,0x82,0x0B,0x2D,0xBD,0xB5,0x96,0xF6,0x31,0xCD,0x0A,0x0B,0x2F,0x3D, + 0x96,0xF6,0xB6,0xEE,0xA3,0xA8,0xA0,0x80,0xB6,0xF6,0x96,0xEE,0xEF,0x2B,0xBA,0xA8, + 0xB6,0xF6,0x96,0xEE,0x2F,0xE8,0x2B,0xA7,0xB6,0xF6,0x96,0xEE,0xBF,0xBF,0xFA,0xA8, + 0xB6,0xF6,0x96,0xEE,0xB8,0xEA,0xAA,0x2F,0xB6,0xF6,0x96,0xEE,0xF3,0xBB,0xFB,0xBA, + 0xB6,0xF6,0x96,0xEE,0xEA,0xFA,0xFE,0x9F,0xB7,0xF6,0x96,0xEE,0x07,0xBB,0xE8,0x8A, + 0xB6,0xF6,0x96,0xEE,0x88,0xAA,0xFF,0xAB,0xB6,0xF6,0x96,0xEE,0x0E,0x0F,0x82,0x82, + 0xB6,0xF6,0x96,0xEE,0xEA,0xAB,0xBA,0xA8,0xB6,0xF6,0x97,0xEE,0x8B,0xA0,0x0A,0x22, + 0xB6,0xF6,0xD7,0xEE,0x08,0xA0,0xA8,0xE8,0xD7,0xF6,0xB6,0xEE,0xDD,0x1D,0xAB,0x22, + 0xF7,0xF6,0xD7,0xF6,0xB5,0x25,0x23,0x0A,0xD7,0xFE,0xF7,0xF6,0xDD,0x77,0x5D,0xF5, + 0xF7,0xF6,0xD7,0xF6,0x88,0xAA,0xA2,0x08,0x17,0xFF,0xD7,0xF6,0x6E,0x6E,0xFB,0xEF, + 0x17,0xFF,0xD7,0xF6,0xED,0xAD,0xBF,0xBF,0xF7,0xFE,0xF7,0xF6,0xFF,0xDF,0x77,0xF7, + 0xD7,0xFE,0xF7,0xF6,0xF7,0xED,0xFF,0xAB,0xF7,0xFE,0xB6,0xF6,0xA8,0xAA,0xEA,0x7A, + 0xB7,0xF6,0x92,0xD5,0x80,0xE0,0xE8,0x7A,0xD2,0xDD,0xA7,0x82,0xA0,0xE8,0xE8,0x7A, + 0x8A,0x93,0x26,0x72,0x7C,0x5E,0xFF,0x7D,0xA7,0x82,0x26,0x72,0xF6,0xE7,0xBA,0xAA, + 0xA7,0x7A,0x05,0x6A,0x7F,0xFE,0xEA,0xCE,0x87,0x7A,0xE4,0x61,0xF7,0x95,0x37,0x37, + 0x75,0xEE,0xCC,0xA3,0x2D,0x2D,0x2D,0x29,0xF7,0xF6,0x96,0xF6,0x03,0x09,0x0B,0x02, + 0x18,0xFF,0xF7,0xF6,0xF7,0xE5,0xFF,0xB6,0x17,0xFF,0xF7,0xF6,0xEF,0xBD,0xED,0x9F, + 0xF8,0xFE,0x17,0xF7,0x7F,0x77,0xFF,0xFF,0x18,0xFF,0xF7,0xF6,0xF8,0x28,0xF0,0x4A, + 0x17,0xFF,0xD7,0xF6,0xFA,0xEA,0xAA,0x7A,0xF7,0xF6,0xD7,0xF6,0x77,0xDD,0x3D,0x2D, + 0xF7,0xF6,0xD7,0xF6,0xEF,0xDD,0xFD,0xFA,0xF7,0xF6,0xD7,0xF6,0xD6,0xFF,0xFB,0xBB, + 0xD7,0xF6,0xB6,0xEE,0x0A,0x00,0x88,0x20,0xD7,0xF6,0xF6,0xEE,0x02,0x20,0x28,0x28, + 0xF7,0xF6,0xB6,0xEE,0xBD,0xAA,0x2A,0xAE,0xD7,0xF6,0xB6,0xEE,0x08,0xA2,0x80,0x08, + 0xD7,0xF6,0xB7,0xEE,0x08,0xBE,0x20,0x80,0xD7,0xF6,0xD6,0xEE,0xA8,0xAA,0xAA,0xAA, + 0xD7,0xF6,0xB6,0xEE,0x20,0xA8,0xA8,0x20,0xD7,0xF6,0xF7,0xEE,0x20,0x20,0xE8,0xA0, + 0xF7,0xF6,0xB6,0xEE,0xBE,0xFA,0xAE,0xBE,0xF7,0xF6,0xD7,0xF6,0x55,0x55,0xF5,0x2D, + 0xF7,0xFE,0xD7,0xEE,0xAB,0x8A,0xE0,0x7A,0xF7,0xF6,0xB6,0xF6,0xE0,0x7A,0x5E,0x57, + 0xD6,0xF6,0x96,0xEE,0x5E,0xDE,0x5E,0x5F,0x75,0xF6,0x96,0xEE,0x55,0xF7,0xFD,0xE7, + 0x96,0xEE,0x34,0xE6,0xAA,0xBA,0xF0,0x7A,0x55,0xE6,0xF3,0xDD,0x7C,0x7C,0x7A,0x5E, + 0xF3,0xDD,0x92,0xD5,0xC2,0xFA,0x68,0xF2,0x34,0xE6,0x51,0xCD,0xF7,0x9D,0x27,0x0B, + 0xB6,0xF6,0x13,0xDE,0xAD,0x2B,0x0A,0x02,0xB6,0xF6,0x76,0xEE,0x7E,0x08,0x08,0x20, + 0x96,0xEE,0xF4,0xDD,0x7E,0xF8,0x80,0x00,0x55,0xEE,0xD3,0xD5,0x57,0xFA,0x8A,0x00, + 0x55,0xEE,0xF3,0xDD,0xFD,0xFD,0x2C,0x02,0x75,0xEE,0x14,0xDE,0xAB,0xB5,0xFA,0x0A, + 0x96,0xEE,0x34,0xE6,0x2B,0xBD,0xF5,0x7A,0xD6,0xF6,0x55,0xE6,0x0A,0xAF,0xED,0xF5, + 0xF8,0xF6,0x96,0xEE,0x0A,0xAB,0xBF,0xD5,0xF7,0xF6,0xB6,0xF6,0xA2,0xAA,0x2B,0xA7, + 0xF8,0xF6,0xB6,0xEE,0x7B,0xFA,0xE8,0xAA,0xD7,0xF6,0xB7,0xEE,0xE7,0xAF,0x22,0x02, + 0xD7,0xF6,0x96,0xEE,0xFE,0x6A,0xF0,0x20,0xD7,0xF6,0x96,0xEE,0x8D,0xAD,0xF7,0xBE, + 0xF7,0xF6,0xB7,0xEE,0x2F,0xBB,0xAB,0xAB,0x18,0xFF,0xD7,0xF6,0xFF,0xBF,0x2B,0xAE, + 0x18,0xF7,0xF8,0xF6,0xAD,0xD6,0xD6,0xEE,0x18,0xF7,0xF8,0xF6,0x27,0x95,0xD5,0xF7, + 0x39,0xFF,0xF7,0xF6,0x02,0x2B,0x0B,0xB7,0x38,0xFF,0xF8,0xF6,0xE0,0xA8,0x20,0x02, + 0x18,0xFF,0xD7,0xEE,0xFE,0xF8,0xFC,0x78,0xB7,0xF6,0xD7,0xEE,0xFD,0xDB,0xFF,0xBB, + 0xB6,0xEE,0x76,0xE6,0x28,0xB8,0x58,0x58,0xD7,0xF6,0x96,0xEE,0x80,0x8A,0x09,0x0D, + 0xD7,0xF6,0x96,0xEE,0xE2,0xE2,0x6A,0x7A,0xB6,0xEE,0x55,0xE6,0x62,0x6E,0xEE,0xEF, + 0x75,0xEE,0xD3,0xD5,0x6A,0x6A,0x7A,0x78,0x71,0xCD,0xEF,0xBC,0x3C,0x16,0x34,0xD4, + 0x55,0xEE,0xB2,0xD5,0x83,0x0B,0x09,0x0D,0x55,0xE6,0xF3,0xDD,0x57,0x5E,0x5C,0x5E, + 0x34,0xE6,0xF4,0xDD,0x89,0xBD,0xAF,0xBD,0x34,0xE6,0x30,0xC5,0x5E,0x5C,0x5A,0x58, + 0x75,0xEE,0x30,0xC5,0x2D,0x2D,0x2D,0xBD,0xB6,0xF6,0x14,0xDE,0x77,0x80,0x80,0x22, + 0x96,0xEE,0xF4,0xDD,0x7F,0xFA,0xA0,0x08,0x75,0xEE,0xF3,0xDD,0x57,0xFF,0xA8,0x00, + 0x55,0xE6,0xF3,0xDD,0x5F,0x77,0xFF,0xF8,0x14,0xDE,0x31,0xC5,0x62,0xC8,0x80,0x00, + 0x96,0xF6,0xB6,0xEE,0xA5,0xD7,0x75,0x75,0xB6,0xEE,0x76,0xEE,0x5D,0xEE,0xAA,0xA0, + 0x95,0xEE,0x55,0xE6,0xFE,0xBE,0x08,0x00,0xB6,0xEE,0x55,0xE6,0xDD,0xFF,0xAE,0x8B, + 0xB6,0xEE,0x55,0xE6,0x57,0xBF,0xAA,0x02,0xB6,0xEE,0x54,0xE6,0xF5,0xBA,0xAA,0xA0, + 0xB6,0xEE,0x55,0xE6,0x7F,0xBF,0xAA,0x88,0xB6,0xEE,0x55,0xE6,0xD7,0xFF,0xAA,0x00, + 0xB6,0xEE,0x75,0xE6,0xD5,0xBF,0xAF,0x80,0xB6,0xEE,0x75,0xE6,0x5D,0xFA,0xFA,0x8A, + 0xB6,0xEE,0x75,0xEE,0x5F,0xBA,0xAA,0x0A,0xB6,0xF6,0x75,0xE6,0xF7,0xAF,0x8A,0x20, + 0x96,0xEE,0x75,0xEE,0xFF,0x88,0x80,0x80,0x96,0xEE,0x75,0xEE,0xFE,0xC8,0x08,0x20, + 0x96,0xEE,0x75,0xEE,0xB7,0x8A,0x20,0x28,0xB6,0xEE,0x75,0xEE,0xDD,0xFA,0xFF,0xDE, + 0x96,0xEE,0x75,0xEE,0xA8,0xAE,0xFE,0x2E,0x76,0xF6,0x96,0xEE,0x7D,0x7F,0x7F,0xF9, + 0xB6,0xF6,0x96,0xEE,0x7F,0x72,0xC2,0x86,0xB6,0xF6,0x96,0xEE,0x79,0xAA,0x2A,0x02, + 0xB6,0xF6,0x96,0xEE,0xFF,0x0B,0x3E,0xA0,0xD6,0xF6,0x96,0xEE,0x9D,0xFF,0x08,0x2A, + 0xD6,0xF6,0x96,0xEE,0xFF,0xAA,0xAA,0x2A,0xD6,0xF6,0x96,0xEE,0xDF,0xF7,0xB3,0xBA, + 0xD6,0xF6,0x96,0xEE,0xF5,0x5B,0xFE,0xCA,0x34,0xE6,0xAA,0x9B,0x60,0x70,0x60,0x60, + 0x87,0x7A,0xA4,0x61,0x5C,0xFC,0xFE,0xFE,0xE5,0x69,0x84,0x61,0xFF,0x53,0xF8,0xAA, + 0xC5,0x69,0x64,0x61,0x0A,0x2D,0x8A,0x0A,0x48,0x7A,0xC5,0x69,0x2B,0x8D,0xDD,0x55, + 0x06,0x72,0xC6,0x69,0xBC,0xEE,0x88,0x00,0x88,0x82,0x06,0x72,0x15,0x55,0xD5,0xF5, + 0x4B,0x9B,0x06,0x6A,0x2F,0xBD,0xFD,0xFD,0xD3,0xDD,0xE9,0x82,0x0A,0x0B,0x2D,0xB5, + 0x96,0xF6,0xF3,0xDD,0x02,0x02,0x03,0x0D,0xB6,0xF6,0x96,0xEE,0xA8,0xA0,0xA2,0xAA, + 0xD6,0xF6,0x96,0xEE,0xFE,0xFF,0xFF,0x3F,0xD6,0xF6,0x97,0xEE,0xEF,0xAF,0xAB,0xEA, + 0xB7,0xF6,0xB5,0xEE,0xA8,0xAA,0xAA,0xAA,0xB6,0xF6,0x96,0xEE,0xEE,0xA2,0x20,0x88, + 0xB6,0xF6,0x96,0xEE,0xEF,0x2A,0xAA,0x2A,0xD7,0xF6,0x96,0xEE,0xEB,0xBB,0xBA,0xAA, + 0xB6,0xF6,0x96,0xEE,0x3C,0xBB,0xB8,0x08,0xB6,0xF6,0x96,0xEE,0x88,0xE2,0xA8,0x00, + 0xB6,0xF6,0x96,0xEE,0x80,0x02,0x00,0xC0,0xB6,0xF6,0xD8,0xEE,0x00,0xA2,0x08,0xA0, + 0xB6,0xF6,0xD6,0xEE,0xAA,0xE8,0xF8,0xB8,0xF7,0xF6,0xB6,0xEE,0x3F,0xBB,0xBF,0x2F, + 0xD7,0xFE,0xF7,0xF6,0x5D,0x57,0x5F,0xDF,0xF7,0xFE,0xF7,0xF6,0xD7,0xF7,0x5F,0xDF, + 0x17,0xFF,0xF7,0xF6,0x7D,0xFD,0xF5,0xF9,0xF6,0xFE,0xF7,0xF6,0x7D,0xF7,0xFF,0xDF, + 0xF7,0xF6,0xD6,0xF6,0x2A,0x2A,0x22,0x88,0xD7,0xFE,0xF7,0xF6,0xF5,0x57,0xF5,0x95, + 0xF7,0xFE,0xD7,0xF6,0xEB,0x8A,0xEA,0x5A,0xB6,0xF6,0xD3,0xDD,0x00,0x80,0xE0,0x70, + 0x35,0xEE,0x8B,0x9B,0xA0,0xE8,0x7A,0x7E,0x6F,0xB4,0x87,0x7A,0x78,0x5E,0x57,0x55, + 0x87,0x7A,0x47,0x7A,0x8A,0x80,0x0E,0xA7,0xA7,0x82,0x46,0x72,0xBD,0x6B,0x6A,0xAA, + 0x87,0x7A,0x26,0x72,0xC2,0x5A,0x6A,0xE0,0x8B,0x9B,0x26,0x72,0x95,0x95,0x35,0x3D, + 0xB7,0xF6,0x6E,0xB4,0x2D,0x2D,0x2D,0x2B,0x17,0xFF,0xD7,0xF6,0xAD,0x8F,0xAD,0xFB, + 0x18,0xFF,0xF7,0xF6,0xBB,0xAB,0xAB,0xAA,0x17,0xFF,0xF8,0xF6,0xAA,0xEF,0x2E,0x2A, + 0x18,0xFF,0xF7,0xF6,0xAB,0xAA,0xE8,0xA0,0x18,0xFF,0xF7,0xEE,0x82,0x82,0xA0,0x8A, + 0xF7,0xF6,0xD7,0xF6,0x60,0xA0,0xE0,0xE0,0xF7,0xF6,0xD7,0xF6,0xAB,0xA8,0xA2,0xB8, + 0xF7,0xF6,0xD7,0xF6,0xF3,0xD5,0xFF,0xFF,0xF7,0xF6,0xD7,0xF6,0x7F,0xBF,0xAD,0xED, + 0xF7,0xF6,0xB6,0xEE,0xBF,0xAE,0xEA,0xFA,0xF7,0xF6,0xB6,0xEE,0xEA,0xAB,0xAE,0xFF, + 0xF7,0xF6,0xD7,0xF6,0x7F,0xAF,0xAD,0xAD,0xF7,0xF6,0xD7,0xF6,0xD5,0x75,0x5F,0x7F, + 0xB7,0xF6,0xF7,0xEE,0xAA,0xAA,0xBA,0xBE,0xD7,0xF6,0xF7,0xEE,0x00,0xB8,0x28,0x82, + 0xF7,0xF6,0xD7,0xF6,0x69,0xFD,0x55,0x79,0xF7,0xF6,0xB6,0xEE,0xFE,0xAA,0xAF,0xAF, + 0xF7,0xF6,0xD7,0xF6,0xD5,0xDF,0x1E,0x37,0x17,0xFF,0xD7,0xF6,0xBD,0xE9,0xAA,0xFE, + 0xF7,0xF6,0x96,0xEE,0xE0,0xF8,0x68,0xFE,0xB6,0xF6,0x96,0xEE,0xAA,0xAA,0xFB,0xFB, + 0x96,0xEE,0x55,0xEE,0x00,0x80,0xC0,0x80,0x96,0xEE,0x55,0xEE,0xC2,0xA2,0xF0,0x58, + 0x55,0xE6,0x14,0xDE,0xA0,0xF8,0x5A,0x5F,0x34,0xE6,0xD3,0xD5,0xEC,0xDE,0xFE,0xDF, + 0x55,0xE6,0xD3,0xD5,0x7F,0xBD,0xBF,0x0F,0xB7,0xF6,0x14,0xDE,0xAD,0x2B,0x23,0x0A, + 0xF7,0xF6,0xB7,0xF6,0xD5,0x55,0xBB,0xBE,0xD7,0xF6,0xB6,0xF6,0xFF,0x8C,0xBE,0xEE, + 0xD7,0xF6,0x96,0xEE,0xEF,0xF8,0xFA,0xFA,0xB7,0xF6,0x76,0xEE,0x7A,0xA0,0x20,0x02, + 0xB6,0xF6,0x35,0xE6,0xDF,0xFA,0x00,0x00,0xD6,0xF6,0x55,0xE6,0xD5,0x75,0xE2,0x88, + 0xB6,0xEE,0x75,0xEE,0x5F,0xAD,0xFB,0xB8,0xB6,0xEE,0x55,0xE6,0x5D,0xAA,0x00,0x00, + 0xB6,0xEE,0x75,0xE6,0xBD,0xD7,0xFA,0xAC,0xD7,0xF6,0x76,0xE6,0x0B,0xAB,0xBF,0xDF, + 0xF7,0xF6,0xB6,0xEE,0xAA,0x8A,0x2F,0x35,0xF7,0xF6,0xD7,0xF6,0xF5,0xBF,0xFB,0xBA, + 0xF7,0xF6,0xB7,0xEE,0xFA,0xFA,0xA8,0xA2,0xD7,0xF6,0x97,0xEE,0x9E,0xEE,0xAA,0xA2, + 0xF8,0xF6,0xB7,0xEE,0x2F,0xAD,0x3F,0xAB,0xD7,0xFE,0x18,0xF7,0xFF,0xFA,0xEF,0xAE, + 0x18,0xFF,0xF8,0xF6,0xAE,0x3B,0xED,0x95,0x18,0xFF,0xF8,0xF6,0xFF,0xAB,0xAE,0xDE, + 0x18,0xF7,0xF8,0xF6,0x37,0xB6,0x5E,0xF7,0x38,0xFF,0xF7,0xF6,0x82,0x22,0x2B,0xAF, + 0x38,0xFF,0xF7,0xF6,0x5E,0x62,0x62,0x68,0xF7,0xF6,0x96,0xEE,0xBA,0xFA,0x7C,0x7E, + 0xB6,0xEE,0x55,0xE6,0x7A,0x78,0xFE,0x7B,0xD7,0xF6,0x54,0xE6,0x0B,0x0B,0x2D,0x2D, + 0xD7,0xF6,0x34,0xDE,0xA0,0xF8,0xFA,0x78,0x96,0xEE,0x34,0xE6,0x8F,0xBF,0xDD,0xF5, + 0x55,0xE6,0x31,0xC5,0xE0,0x60,0x68,0x78,0x31,0xC5,0xD0,0xBC,0x9C,0x16,0x3F,0x2F, + 0x55,0xE6,0x72,0xCD,0x09,0x2D,0x2D,0x2D,0x55,0xE6,0xB2,0xD5,0xFC,0xF8,0x58,0x7A, + 0x14,0xDE,0xB2,0xD5,0x2A,0xAE,0x35,0x15,0x55,0xE6,0x10,0xBD,0x78,0x78,0x7A,0x78, + 0x14,0xDE,0xF0,0xBC,0x2D,0x2D,0xBD,0xF5,0xB6,0xF6,0x92,0xCD,0x22,0x0A,0xAF,0xBD, + 0x96,0xEE,0x55,0xEE,0xF8,0xE2,0xF2,0xFF,0x95,0xEE,0x55,0xE6,0xEB,0xFF,0xF7,0x55, + 0x95,0xEE,0x55,0xE6,0x57,0x7B,0xFF,0x2F,0x96,0xEE,0x34,0xE6,0x5D,0x8E,0xAE,0xBE, + 0xD6,0xF6,0xB6,0xEE,0x56,0xDE,0x6A,0x75,0xD6,0xF6,0xB6,0xEE,0x5D,0x75,0x6F,0xE5, + 0xF6,0xF6,0x96,0xEE,0xDD,0xF5,0x7F,0x7E,0xD6,0xF6,0x96,0xEE,0xEB,0xFB,0xBA,0x7B, + 0x96,0xF6,0xB6,0xEE,0x7F,0x77,0x9F,0x75,0xD5,0xF6,0x96,0xEE,0x7A,0xBB,0xEE,0xBA, + 0xD7,0xF6,0x96,0xEE,0x7E,0xFE,0x3A,0x2A,0x96,0xF6,0xD6,0xEE,0xEA,0xBB,0xBB,0xBF, + 0xB6,0xEE,0x96,0xEE,0xB0,0x80,0x88,0xB8,0xB6,0xEE,0x96,0xEE,0x2A,0x2E,0x2A,0x02, + 0xD7,0xF6,0x96,0xEE,0xBF,0xFA,0xFA,0xEB,0x95,0xF6,0xD6,0xEE,0xAA,0xEF,0xBF,0xAF, + 0xB6,0xEE,0x75,0xEE,0xFA,0xF8,0xE0,0xE0,0x96,0xEE,0x75,0xEE,0x00,0x0E,0x0E,0xA2, + 0x96,0xEE,0x75,0xEE,0xA8,0xAE,0x32,0x28,0x96,0xF6,0x95,0xEE,0xD7,0xFF,0xFF,0xDF, + 0xB6,0xFE,0x96,0xEE,0x57,0x57,0x5F,0xF7,0xB6,0xF6,0x75,0xEE,0xE6,0x2E,0xAB,0x2A, + 0xD6,0xF6,0x96,0xEE,0xFF,0xBF,0xAB,0xAB,0xD7,0xF6,0xB6,0xF6,0xFD,0xD7,0xDD,0x2F, + 0xD7,0xF6,0xB6,0xEE,0x7F,0xAE,0xCB,0xA8,0xB6,0xF6,0xD7,0xEE,0x8A,0xAE,0xEE,0xBE, + 0xB6,0xF6,0xD6,0xEE,0xAA,0x2E,0xA9,0xFF,0xD7,0xF6,0xB6,0xF6,0x75,0xBD,0x1D,0xAB, + 0xD7,0xF6,0xB6,0xF6,0x6A,0xE2,0xE8,0xBA,0x76,0xF6,0x8A,0x9B,0x60,0x60,0xE0,0xE0, + 0xA8,0x82,0xA4,0x61,0xFE,0xFE,0x5C,0x7C,0x26,0x7A,0xC5,0x69,0x7B,0xDA,0xDE,0xE3, + 0x06,0x72,0xA5,0x69,0xD7,0xF5,0xFE,0x62,0xE6,0x71,0x84,0x61,0x2F,0xAF,0xAD,0xAD, + 0x27,0x7A,0xC5,0x69,0xBA,0xBB,0xAD,0x3D,0x27,0x72,0xE6,0x69,0x3B,0xBF,0x74,0x5A, + 0x87,0x7A,0xE6,0x69,0x0A,0xAA,0xAF,0xF7,0x2D,0xAC,0x67,0x7A,0x2F,0xBD,0xFD,0xF5, + 0x35,0xEE,0x8B,0x9B,0x02,0x03,0x2B,0x2D,0xB6,0xF6,0x76,0xF6,0xAA,0x8A,0xAA,0x83, + 0xB6,0xF6,0x96,0xEE,0xA8,0xBE,0x23,0xA2,0xB6,0xF6,0x96,0xEE,0x02,0x80,0x82,0xA0, + 0xD6,0xF6,0xB6,0xF6,0xD5,0xFB,0x5B,0xB5,0xB6,0xF6,0xD6,0xEE,0x28,0x80,0x08,0x02, + 0xB6,0xF6,0xB7,0xEE,0x8A,0xA8,0x00,0x2A,0x96,0xF6,0xD7,0xEE,0xFA,0xEE,0xAB,0xEF, + 0xB6,0xF6,0x96,0xEE,0x08,0x02,0x20,0xA8,0xB6,0xF6,0x96,0xEE,0x02,0x00,0x02,0xE8, + 0xD7,0xF6,0x96,0xEE,0xAE,0xAE,0xAF,0xBB,0xD7,0xF6,0xB6,0xF6,0xDE,0xDE,0xB3,0x2B, + 0xD6,0xF6,0xB6,0xEE,0xB4,0xA2,0x8B,0xEA,0xD7,0xF6,0xB6,0xEE,0x0A,0x0B,0x2B,0x3F, + 0x17,0xFF,0xD7,0xF6,0xFF,0xBD,0xBE,0xAB,0x17,0xFF,0xF7,0xF6,0x5D,0x55,0x5F,0x5F, + 0x18,0xFF,0xF7,0xF6,0xDD,0xF9,0xCF,0x6D,0x17,0xFF,0xF7,0xF6,0x7D,0x77,0xD5,0x75, + 0xD6,0xFE,0xF7,0xF6,0x5D,0x55,0xD7,0xDF,0x18,0xFF,0xD7,0xF6,0xEA,0xEF,0xFF,0x7F, + 0xF6,0xFE,0x14,0xE6,0x80,0xE0,0xF8,0x7A,0x34,0xE6,0xAB,0x9B,0x80,0xA0,0xE8,0x7A, + 0xAF,0xBC,0x46,0x72,0x68,0x7C,0x5E,0x57,0x67,0x82,0x46,0x72,0xBB,0x2B,0x33,0x0A, + 0x87,0x82,0x46,0x7A,0x3D,0x3F,0x8C,0x3A,0xC7,0x8A,0x87,0x82,0xF5,0xCE,0xAD,0x3D, + 0xE8,0x8A,0x66,0x7A,0x7E,0xFB,0xF0,0x70,0x8E,0xBC,0x46,0x7A,0xB5,0xB5,0x35,0x25, + 0xD7,0xFE,0x30,0xCD,0x2D,0x0D,0x09,0x2B,0xF7,0xFE,0x18,0xF7,0xE0,0xA0,0x88,0xA0, + 0x17,0xFF,0xF7,0xF6,0xBE,0xAA,0x0A,0x0F,0x17,0xFF,0xF7,0xF6,0x2A,0x2A,0xBE,0x3F, + 0x18,0xFF,0xF7,0xF6,0x8A,0x2A,0xAB,0xAE,0x18,0xFF,0xF7,0xF6,0xE3,0xFA,0xF8,0xB8, + 0xF7,0xF6,0xD7,0xF6,0xA0,0xBC,0x2A,0x80,0xF7,0xF6,0xD7,0xF6,0xAA,0xAE,0x20,0x88, + 0xF7,0xF6,0xD7,0xF6,0xBA,0xEA,0xAE,0xFA,0xF7,0xF6,0xD7,0xF6,0xF9,0xFF,0x5D,0x57, + 0xD7,0xF6,0xB7,0xEE,0xA0,0x2A,0x83,0x88,0xD7,0xF6,0xB7,0xEE,0x2A,0xA2,0x82,0xAA, + 0xD7,0xF6,0xD7,0xEE,0x00,0x8A,0x20,0x22,0xF7,0xF6,0xD7,0xF6,0x5F,0xF5,0xAD,0xBD, + 0xF7,0xF6,0xD7,0xF6,0xBD,0x55,0x77,0xE5,0xD7,0xF6,0xF7,0xEE,0x0A,0x82,0x00,0x22, + 0xF7,0xF6,0xD7,0xF6,0x7F,0x5D,0xFD,0x2B,0x17,0xFF,0xD7,0xF6,0x75,0xD7,0xF7,0x3F, + 0x17,0xFF,0xD7,0xF6,0x2D,0xAF,0x8A,0x70,0xF7,0xF6,0xB6,0xEE,0xE0,0xF0,0x54,0x5F, + 0x96,0xF6,0xD6,0xEE,0xBB,0xAF,0xBF,0x2A,0xB6,0xF6,0x76,0xEE,0xA2,0xFA,0xDE,0xDE, + 0x96,0xEE,0x55,0xEE,0xA8,0x6A,0x78,0x78,0x75,0xEE,0x14,0xDE,0xF8,0x78,0x5A,0x5F, + 0x35,0xE6,0xB2,0xD5,0xA2,0xFA,0x7E,0x5F,0x75,0xEE,0xB2,0xD5,0xF7,0xD5,0xB5,0x35, + 0xB6,0xF6,0x14,0xDE,0xBD,0x2D,0x2A,0x02,0xD7,0xF6,0x96,0xEE,0x9D,0xFE,0xAA,0xAA, + 0xD7,0xF6,0xB6,0xEE,0x0A,0x8B,0x2B,0x80,0xD7,0xF6,0xB7,0xEE,0xE0,0x80,0xA2,0xA0, + 0xD7,0xF6,0x96,0xEE,0x6A,0xA8,0xA8,0x22,0xD7,0xF6,0x96,0xEE,0xAB,0xF9,0xBA,0xEA, + 0xD6,0xF6,0x96,0xEE,0xAE,0xAE,0xA7,0xF7,0xD6,0xF6,0xB6,0xEE,0xAA,0xEB,0xE9,0xE5, + 0xD6,0xF6,0xB6,0xEE,0x7E,0xDE,0xD0,0x5E,0xD7,0xF6,0xB6,0xEE,0x2D,0x0F,0xBF,0x57, + 0xF7,0xF6,0x96,0xEE,0x7E,0xFA,0x2A,0x2B,0xF7,0xF6,0x96,0xEE,0x55,0x57,0x7A,0x80, + 0xF7,0xF6,0x96,0xEE,0x27,0xBD,0xE5,0xFF,0xF7,0xF6,0xD7,0xF6,0xF2,0xE2,0x25,0x0D, + 0x18,0xFF,0xD7,0xF6,0xFB,0xFF,0x7E,0xFA,0xF7,0xF6,0xB7,0xEE,0xB6,0xAF,0xFA,0xAA, + 0xF8,0xF6,0xD7,0xF6,0xE5,0xCD,0x2B,0xC2,0xF8,0xF6,0xD7,0xEE,0xDA,0xBB,0xBF,0xAE, + 0xF8,0xF6,0xD7,0xEE,0x3B,0xF2,0xF8,0x58,0x18,0xF7,0xD7,0xF6,0xAA,0xAB,0xAF,0xAD, + 0x17,0xF7,0xF8,0xF6,0xF6,0x7A,0xFA,0x5D,0x18,0xF7,0xD7,0xF6,0x2A,0xBA,0xEE,0xD5, + 0x38,0xFF,0xF7,0xF6,0xEA,0xFA,0xF5,0x75,0xF7,0xF6,0x96,0xEE,0x7A,0x78,0x78,0x78, + 0x96,0xEE,0x55,0xE6,0x62,0xFA,0xFA,0x7A,0xD7,0xF6,0x34,0xDE,0x2F,0xB7,0xB5,0xB5, + 0xB6,0xEE,0x14,0xE6,0xF0,0xE0,0x60,0x40,0x55,0xE6,0x14,0xDE,0x0D,0xA7,0x35,0xFD, + 0x55,0xE6,0x51,0xC5,0x78,0x58,0x78,0x7A,0x10,0xC5,0xF0,0xBC,0x25,0x2E,0x36,0x14, + 0x34,0xE6,0x71,0xCD,0x2D,0x29,0xAD,0x2D,0x34,0xE6,0x92,0xCD,0xE0,0xE8,0xE2,0x60, + 0xF3,0xDD,0x92,0xCD,0x2F,0x2E,0xB5,0xBD,0xF4,0xDD,0x30,0xC5,0x70,0x60,0x40,0xC0, + 0x10,0xC5,0x6D,0xAC,0x2E,0x9F,0xDF,0xBE,0x55,0xE6,0x31,0xC5,0x2F,0x0D,0x29,0x0B, + 0x96,0xEE,0x55,0xE6,0xFF,0x6B,0x7A,0xE0,0x75,0xEE,0x55,0xE6,0x57,0x55,0xB7,0xE6, + 0x75,0xEE,0x55,0xE6,0x09,0xFD,0x27,0x37,0x96,0xEE,0x75,0xEE,0x5D,0x3F,0xBD,0xF5, + 0xD7,0xF6,0x96,0xEE,0xEF,0xBE,0xAB,0xEF,0xD6,0xF6,0xB6,0xEE,0xAF,0xBF,0xFD,0xD7, + 0xD6,0xF6,0xB6,0xEE,0x5F,0x57,0x57,0x7B,0xD6,0xF6,0xB6,0xEE,0xDD,0xF7,0x6D,0xFD, + 0xD6,0xF6,0xB6,0xEE,0xFD,0x75,0x7D,0xF3,0xD6,0xF6,0xB6,0xEE,0xBF,0xEA,0xBD,0xFF, + 0xD7,0xF6,0xB6,0xEE,0xD1,0x9F,0x5F,0x7F,0xD7,0xF6,0xB6,0xEE,0xDF,0xF7,0xDD,0xF5, + 0xD7,0xF6,0xB6,0xEE,0x57,0xED,0xFF,0xE4,0xD7,0xF6,0xB6,0xEE,0x77,0x7F,0xF5,0xFD, + 0xD7,0xF6,0xB6,0xEE,0x75,0xD5,0xF7,0xFF,0xD6,0xF6,0x96,0xEE,0x7A,0xEA,0xEA,0xEA, + 0xB6,0xEE,0x96,0xEE,0x68,0x76,0x5E,0x76,0xB6,0xF6,0x75,0xEE,0xFF,0xAF,0xA7,0xBF, + 0x75,0xF6,0x95,0xEE,0x7D,0x75,0x5D,0x57,0x76,0xF6,0x95,0xEE,0x55,0x75,0x5F,0x7D, + 0xB6,0xF6,0x95,0xEE,0xAE,0xF6,0x3B,0xFA,0x96,0xF6,0xB6,0xEE,0xFF,0xFF,0xBB,0xBB, + 0xB6,0xF6,0xD7,0xEE,0xA8,0xAA,0xAA,0xB8,0xD7,0xF6,0xB6,0xEE,0x2B,0x0A,0xAA,0x82, + 0xD7,0xF6,0xB6,0xEE,0xF8,0xE2,0xEA,0x98,0xF7,0xF6,0xB6,0xEE,0x77,0xAF,0xAB,0xAF, + 0xD7,0xF6,0xB6,0xEE,0xAF,0xAA,0x88,0x2A,0xD7,0xF6,0xB6,0xF6,0xE7,0xB5,0xDE,0xAE, + 0xD7,0xF6,0x95,0xF6,0xEA,0xFA,0xFA,0xE8,0x75,0xEE,0x29,0x93,0xE0,0xE0,0x78,0x78, + 0xC8,0x8A,0xA5,0x61,0x7C,0xDE,0x56,0x57,0x26,0x7A,0xE5,0x69,0xEF,0x8D,0xAD,0x2D, + 0x26,0x7A,0xC5,0x69,0x7B,0xFC,0x80,0x82,0xC5,0x69,0x64,0x61,0x2A,0xF8,0xFC,0xB0, + 0x06,0x72,0x84,0x61,0x2B,0x2F,0xBF,0xDF,0x27,0x72,0xC5,0x69,0xE2,0xFA,0xEA,0x75, + 0x26,0x72,0xC5,0x69,0x2C,0xBA,0xAF,0xB6,0xE8,0x82,0xE5,0x69,0x2F,0x2F,0xBD,0xF5, + 0xD2,0xDD,0x08,0x8B,0x2D,0xB5,0xF5,0xD5,0x95,0xF6,0xEE,0xBC,0x00,0x02,0x0B,0x29, + 0xB6,0xF6,0x96,0xEE,0xA0,0x88,0x00,0x00,0xD5,0xF6,0xB6,0xF6,0x5D,0x5D,0xF7,0xBF, + 0xD6,0xF6,0xB6,0xF6,0xEB,0xE7,0xEF,0xFA,0xD6,0xF6,0xB6,0xF6,0xDD,0xF7,0xDA,0xAA, + 0xF6,0xF6,0xB6,0xF6,0x55,0x55,0x5F,0x5F,0xB6,0xF6,0xB7,0xEE,0x08,0xA0,0x2A,0xA2, + 0xD7,0xF6,0x96,0xEE,0xFE,0xFA,0xBE,0xAA,0xB6,0xF6,0xD7,0xEE,0x02,0x82,0x80,0x00, + 0xD7,0xF6,0xB6,0xF6,0x59,0x57,0xF5,0xDD,0xD7,0xF6,0xB6,0xF6,0xAF,0x8D,0x37,0x9D, + 0xD7,0xF6,0xB6,0xEE,0x22,0x28,0x60,0xE2,0xF7,0xF6,0xB6,0xEE,0xBF,0x2B,0xBB,0x3F, + 0x17,0xFF,0xD6,0xF6,0xAB,0xEF,0xFF,0xDE,0xF7,0xF6,0xD6,0xF6,0x80,0x22,0x02,0xAA, + 0x17,0xFF,0xF7,0xF6,0x75,0x5D,0x5D,0x7F,0x17,0xFF,0xF7,0xF6,0xB5,0xDD,0xF5,0x75, + 0xF7,0xFE,0xD6,0xF6,0xEB,0xA8,0xAA,0xBC,0xF7,0xFE,0x34,0xE6,0xA0,0xA0,0xE8,0x7A, + 0x75,0xEE,0x4D,0xB4,0xA0,0xE0,0xF8,0x7E,0xEF,0xC4,0x66,0x7A,0x60,0x78,0x5E,0x57, + 0x67,0x7A,0x05,0x6A,0xBE,0x86,0x8A,0x02,0x67,0x7A,0x06,0x72,0x28,0x20,0x2A,0xDE, + 0xA8,0x8A,0x46,0x7A,0xBF,0x8D,0x8A,0x83,0xC8,0x8A,0x67,0x82,0x27,0xA5,0xAE,0x8B, + 0xC8,0x8A,0x66,0x7A,0x80,0xB0,0x9A,0xF2,0x11,0xCD,0x67,0x7A,0x35,0x35,0x25,0x2D, + 0xF7,0xFE,0xD3,0xDD,0x09,0x29,0x0B,0x0B,0x17,0xFF,0xF8,0xF6,0xAE,0xAA,0xBA,0x72, + 0x18,0xFF,0xF7,0xF6,0xAA,0xBA,0xAA,0xAA,0xF7,0xFE,0x18,0xF7,0x7B,0x7E,0x79,0x5F, + 0x38,0xFF,0x17,0xF7,0x75,0xF7,0xFF,0xDB,0x17,0xFF,0xF7,0xF6,0xA0,0xEB,0xEE,0xEB, + 0xF7,0xF6,0xF7,0xF6,0x00,0x00,0x00,0x00,0xF7,0xF6,0xD7,0xF6,0xAA,0xAA,0xA2,0x5A, + 0xF7,0xF6,0xD7,0xF6,0xAB,0x8B,0x7D,0x5F,0xF7,0xF6,0xD7,0xF6,0x57,0x7F,0x7A,0x5B, + 0xD7,0xF6,0xF6,0xEE,0x00,0xA2,0xA2,0xA8,0xD7,0xF6,0xD6,0xEE,0xAA,0x20,0x0A,0x08, + 0xF7,0xF6,0xB6,0xEE,0xBA,0x7A,0xBA,0xBE,0xF7,0xF6,0xD7,0xF6,0x65,0x7F,0x79,0xAA, + 0xD7,0xF6,0xF7,0xEE,0xA0,0x00,0x80,0xA0,0xF6,0xF6,0xD7,0xF6,0xDD,0xF5,0x57,0xAF, + 0xF7,0xF6,0xB6,0xEE,0x03,0x0F,0x21,0x02,0x18,0xFF,0xF7,0xF6,0xA5,0x89,0x83,0xC0, + 0x18,0xF7,0xD7,0xF6,0x78,0x5E,0x5F,0x57,0x95,0xF6,0xD6,0xEE,0xFD,0xAB,0xAF,0xBB, + 0x76,0xF6,0xB6,0xEE,0xFD,0xAD,0xBF,0x2E,0x96,0xF6,0x55,0xE6,0xAA,0xFA,0xAA,0x7B, + 0x75,0xEE,0x14,0xDE,0xA8,0xF8,0xFE,0x7F,0x34,0xE6,0x92,0xCD,0xE8,0xE8,0xF8,0x7E, + 0x14,0xDE,0x51,0xC5,0xFE,0xFE,0xB7,0x25,0x96,0xEE,0x92,0xD5,0x2D,0x0B,0x02,0x00, + 0xD7,0xF6,0xB6,0xEE,0x95,0xBF,0xBF,0x88,0xD7,0xF6,0xB6,0xEE,0x33,0x82,0xA0,0x80, + 0xD7,0xF6,0xB6,0xEE,0x80,0xB0,0x3E,0xAC,0xD7,0xF6,0xB6,0xEE,0x0B,0x8E,0xA8,0xA2, + 0xD7,0xF6,0xB7,0xEE,0xA2,0xA2,0x08,0xBA,0xD7,0xF6,0xB6,0xEE,0xEB,0xEA,0xAA,0xEA, + 0xD7,0xF6,0x96,0xEE,0xFF,0xFA,0xEA,0xBA,0xD7,0xF6,0x96,0xEE,0xA7,0xFF,0xEA,0xAA, + 0x97,0xFE,0xB6,0xEE,0xD5,0x5F,0x75,0x5F,0x96,0xF6,0xB6,0xEE,0x77,0x57,0xD5,0xF5, + 0xD7,0xF6,0x96,0xEE,0x2E,0x3F,0xBD,0xBF,0xF7,0xF6,0xB7,0xEE,0x02,0x02,0x2F,0x2D, + 0x18,0xFF,0xD7,0xF6,0x5F,0xFE,0xAA,0x2A,0x17,0xF7,0xB8,0xF6,0xAB,0xAA,0xAA,0x02, + 0x18,0xFF,0xF7,0xF6,0x6E,0x6F,0xCB,0x02,0x18,0xF7,0xD7,0xF6,0xFF,0xFB,0xF8,0xF8, + 0xF7,0xF6,0xD7,0xEE,0xA2,0xFA,0x68,0xA2,0xF8,0xF6,0xD7,0xEE,0x2C,0x2A,0x03,0x2A, + 0x18,0xF7,0xB7,0xF6,0xDA,0xF8,0xEE,0xEA,0xF8,0xF6,0xD7,0xF6,0x8D,0x88,0xE3,0xDB, + 0xF8,0xF6,0xD7,0xF6,0x00,0x21,0xAC,0xFE,0xF7,0xF6,0xD7,0xF6,0xFD,0xF8,0x78,0x5A, + 0xF8,0xF6,0xB7,0xEE,0xAA,0xBE,0xFF,0xF6,0xD7,0xF6,0x96,0xEE,0xE0,0x68,0xE8,0xAA, + 0x96,0xEE,0x34,0xDE,0xBA,0x6E,0x78,0x78,0x96,0xEE,0x13,0xDE,0x3D,0x27,0xB5,0xB5, + 0xD7,0xF6,0x54,0xE6,0x62,0xE2,0xE0,0xAA,0x75,0xEE,0x14,0xDE,0x7D,0xFE,0xAA,0xAC, + 0x55,0xE6,0x71,0xCD,0x7A,0x58,0x78,0x78,0x51,0xC5,0xEF,0xBC,0x96,0xB8,0x20,0x00, + 0x13,0xDE,0x51,0xC5,0x29,0x29,0xAD,0xBD,0x55,0xE6,0xB2,0xD5,0x7A,0xF2,0x7A,0x6B, + 0xB2,0xD5,0x72,0xCD,0x2E,0xAF,0xBF,0x2F,0xF3,0xDD,0x71,0xCD,0x62,0x43,0xE2,0x82, + 0xD3,0xD5,0xAE,0xB4,0xD5,0x37,0x2F,0x2E,0xD6,0xF6,0xB2,0xD5,0xAD,0x2B,0x0B,0x2B, + 0xB6,0xF6,0x55,0xE6,0xFA,0xF8,0x60,0xE0,0x76,0xE6,0x35,0xE6,0xFE,0xF6,0xD7,0xDE, + 0x55,0xEE,0x34,0xE6,0x08,0x2C,0x5E,0x55,0x96,0xEE,0x34,0xE6,0xAB,0x2B,0xAF,0xAD, + 0xD6,0xF6,0xB6,0xEE,0xD5,0xA5,0xFD,0x95,0xD6,0xF6,0xB6,0xEE,0x7D,0x7E,0x5E,0x75, + 0xD6,0xF6,0xB6,0xEE,0x72,0x5B,0x95,0xA9,0xD6,0xF6,0xB6,0xEE,0xDF,0xB6,0xBE,0x77, + 0xD6,0xF6,0xB6,0xEE,0x4D,0x8B,0xAB,0xFD,0xD6,0xF6,0x96,0xEE,0xAE,0x8A,0x82,0x8F, + 0xD6,0xF6,0xB6,0xEE,0xFB,0xE9,0xB5,0x5B,0xD6,0xF6,0xB6,0xEE,0xFD,0xAE,0x39,0x77, + 0xD6,0xF6,0xB6,0xEE,0xBE,0x3F,0xBA,0xAA,0xD6,0xF6,0xB6,0xEE,0xAF,0xE7,0xFF,0xD6, + 0xD7,0xF6,0xB6,0xEE,0xEE,0xEB,0x7B,0xEF,0xD6,0xF6,0xB6,0xEE,0xFB,0xFF,0x7A,0xFE, + 0xD6,0xEE,0x75,0xEE,0xFE,0xDE,0xFF,0xF8,0xB6,0xF6,0x75,0xEE,0xFA,0xBA,0xEA,0xFA, + 0xB5,0xF6,0x55,0xE6,0xAA,0xA2,0xAA,0xEA,0xB6,0xF6,0x95,0xEE,0xDF,0xFD,0xBB,0x6A, + 0xB5,0xEE,0x95,0xEE,0xAF,0xFB,0xFF,0xF9,0xB7,0xF6,0x96,0xEE,0xF9,0xDF,0xD7,0xAD, + 0xD6,0xF6,0xB6,0xEE,0xAF,0x8D,0xBD,0xB5,0xD7,0xF6,0xB6,0xEE,0xA2,0x8E,0x0A,0x02, + 0xD7,0xF6,0xF7,0xEE,0x00,0x20,0x88,0x88,0xD6,0xF6,0xB7,0xE6,0x0A,0x22,0x20,0x82, + 0xF7,0xF6,0xB6,0xEE,0xFE,0xBE,0xAA,0xEA,0xD6,0xF6,0xB7,0xF6,0xAE,0xAA,0x00,0xA8, + 0xD7,0xFE,0x34,0xEE,0xE0,0xC8,0x60,0x6A,0xF2,0xDD,0x46,0x72,0x78,0x7C,0x5E,0x5E, + 0x47,0x7A,0x85,0x61,0xFA,0xE2,0xE8,0xF0,0x26,0x72,0x43,0x59,0x0A,0xAB,0xAF,0x95, + 0x26,0x72,0xE6,0x71,0xEA,0x63,0xFB,0xD7,0x06,0x72,0xA5,0x69,0x55,0x7E,0x68,0xEA, + 0xA5,0x69,0x64,0x61,0xC0,0xF9,0x57,0x5C,0xC5,0x69,0x85,0x61,0x0A,0x8B,0xBB,0xFF, + 0xE6,0x69,0x64,0x59,0x2A,0x8A,0x2B,0x29,0x46,0x72,0xC5,0x61,0x2F,0x2D,0xBF,0xD7, + 0x69,0x93,0x26,0x72,0x2F,0xBD,0xBD,0xF5,0x35,0xEE,0x29,0x8B,0x0B,0x0D,0x2D,0xB5, + 0xD7,0xFE,0x55,0xEE,0xAA,0x2A,0x0B,0x2D,0xD7,0xF6,0xB6,0xF6,0x75,0x5B,0xFA,0xAA, + 0xD6,0xF6,0xB6,0xF6,0xFD,0xA5,0x87,0x8F,0xD6,0xF6,0xB6,0xF6,0xAD,0xBF,0xA3,0x0A, + 0xD6,0xF6,0xB6,0xF6,0xA8,0xAA,0xBE,0x97,0xD6,0xF6,0xB6,0xF6,0xD4,0x7C,0x5C,0x77, + 0xB6,0xF6,0xD7,0xEE,0x0A,0x02,0x08,0x08,0xB6,0xF6,0x96,0xEE,0x08,0x0A,0x88,0x00, + 0xB6,0xF6,0xD6,0xEE,0xA0,0x00,0x08,0x28,0xD7,0xF6,0xB6,0xF6,0xAF,0xBD,0xB5,0xEF, + 0xD6,0xF6,0xB6,0xEE,0xA0,0x7A,0x3A,0xAF,0xF7,0xF6,0xD6,0xF6,0x9D,0xDD,0xBF,0xB7, + 0xD7,0xFE,0xF7,0xF6,0xDF,0x7D,0x57,0x55,0xF6,0xFE,0xF7,0xF6,0xFD,0x7F,0xF7,0xFD, + 0xD7,0xFE,0xF7,0xF6,0x55,0x55,0x7D,0xFD,0xF7,0xFE,0xD7,0xF6,0xA8,0xAE,0xAB,0x82, + 0xF7,0xFE,0x55,0xEE,0xA0,0xA8,0xE0,0x7A,0xB6,0xF6,0xAF,0xBC,0xA0,0xE8,0xFA,0x7A, + 0x30,0xCD,0x66,0x7A,0xE0,0x78,0x5E,0x5F,0x66,0x7A,0x05,0x72,0xA0,0xDA,0xFE,0xAE, + 0x66,0x7A,0x26,0x7A,0x8A,0x9B,0x9E,0xBA,0x46,0x82,0x26,0x7A,0x7F,0xFF,0xAD,0xB3, + 0x87,0x8A,0x26,0x7A,0x2B,0xA9,0xAB,0x8A,0xA8,0x8A,0x67,0x82,0xBA,0xF3,0xB3,0xFE, + 0x87,0x82,0x46,0x7A,0xA0,0xE2,0x7A,0x38,0x14,0xE6,0x09,0x93,0x35,0xAD,0x2D,0x2D, + 0xF7,0xFE,0x55,0xEE,0x0D,0x01,0x03,0x03,0x17,0xFF,0xF7,0xF6,0xF0,0xAA,0xEA,0xCA, + 0x17,0xFF,0xF8,0xF6,0xAB,0xB8,0xAE,0xAB,0x38,0xFF,0xF7,0xF6,0xAF,0xAB,0xED,0xAB, + 0x18,0xFF,0x17,0xF7,0xEF,0xBB,0xFE,0xBE,0x36,0xFF,0x18,0xF7,0x5D,0x77,0xF7,0xFF, + 0x37,0xF7,0xD7,0xF6,0xDE,0x7F,0xD7,0x5F,0xF7,0xF6,0xD7,0xF6,0xE8,0xA2,0xAF,0xBF, + 0xF7,0xF6,0xD7,0xF6,0x7A,0xF2,0xBB,0xBD,0xF7,0xF6,0xD7,0xF6,0xFD,0x7D,0xD7,0xFD, + 0xF7,0xF6,0xD7,0xF6,0xFD,0xFD,0xD6,0x56,0xF7,0xF6,0xD7,0xF6,0xD7,0x75,0xD7,0x7F, + 0xD7,0xF6,0xB7,0xEE,0x20,0x00,0x68,0x80,0xF7,0xF6,0xB7,0xF6,0x22,0xAA,0xA9,0xAF, + 0xF7,0xF6,0xD7,0xF6,0x75,0xF5,0x97,0xAF,0x37,0xFF,0xD7,0xF6,0x75,0xF7,0xF5,0xB7, + 0x18,0xFF,0xD7,0xF6,0x2F,0x8A,0x82,0xC0,0x17,0xFF,0xB6,0xEE,0xA8,0xFA,0x7E,0xD7, + 0xB6,0xF6,0xD6,0xEE,0x2D,0x2B,0x0A,0x80,0xB6,0xF6,0x75,0xEE,0xE8,0x6A,0xFC,0xFA, + 0x96,0xEE,0x75,0xEE,0xE0,0x68,0x4C,0xFA,0x75,0xEE,0x14,0xE6,0xA0,0x78,0xF8,0x7E, + 0x35,0xE6,0xB3,0xD5,0xC8,0xE2,0xFA,0xDE,0x14,0xDE,0x71,0xCD,0x7E,0xDF,0x97,0x2D, + 0xB6,0xF6,0x92,0xCD,0xA5,0x2F,0x22,0x02,0xD7,0xF6,0x96,0xEE,0x09,0x0A,0x02,0x08, + 0xD7,0xF6,0xD6,0xEE,0x20,0x22,0x22,0x00,0xF7,0xF6,0xB6,0xEE,0xAB,0xBB,0xAE,0xB3, + 0xD7,0xF6,0xF7,0xEE,0x00,0x00,0x8A,0x0A,0xD7,0xF6,0xB6,0xEE,0x80,0x00,0xA0,0xC0, + 0xD7,0xF6,0xB7,0xEE,0x28,0x22,0xE8,0xEA,0xD7,0xF6,0xB7,0xEE,0xFC,0x57,0x76,0xEF, + 0xD7,0xF6,0xB6,0xEE,0x97,0x8F,0x2F,0x2A,0xD7,0xF6,0xB7,0xEE,0xE3,0xA2,0xA2,0x22, + 0xD7,0xF6,0xB6,0xEE,0x5F,0xEA,0xF2,0xFE,0xD7,0xF6,0xB6,0xEE,0x5F,0x5E,0x5E,0x7E, + 0xB6,0xEE,0x96,0xEE,0xA3,0xFE,0x3A,0x00,0xF7,0xF6,0x96,0xEE,0x2F,0xBD,0xBF,0xFD, + 0x17,0xFF,0xB7,0xEE,0xAA,0x2E,0xAF,0xFD,0x18,0xFF,0xF7,0xF6,0xBB,0x0B,0x0A,0x2B, + 0x38,0xFF,0x18,0xF7,0xF7,0xEF,0xCB,0xEB,0x39,0xFF,0xF7,0xF6,0x7E,0xFA,0xEA,0x8B, + 0x18,0xFF,0xD7,0xEE,0xFF,0xBF,0xBE,0xF8,0x18,0xF7,0xF8,0xF6,0x55,0x5F,0xD5,0xFD, + 0xF8,0xF6,0xD7,0xF6,0xAA,0xA8,0xB0,0x80,0xF8,0xF6,0xD7,0xF6,0x55,0xB7,0xCF,0x6B, + 0xF7,0xF6,0xD7,0xF6,0xBE,0x0A,0x0A,0x09,0xF7,0xF6,0xB7,0xEE,0x68,0xE0,0x78,0x7A, + 0xD7,0xF6,0xB7,0xEE,0x8D,0x02,0x82,0xAB,0xD7,0xF6,0xB7,0xEE,0xEA,0x88,0xAA,0xAA, + 0xB6,0xEE,0x55,0xE6,0x58,0x78,0x68,0xE0,0x55,0xE6,0xF3,0xD5,0x26,0x37,0x1F,0x16, + 0xD7,0xF6,0x96,0xEE,0x2B,0xA9,0x2B,0x2D,0xB7,0xEE,0x34,0xE6,0x5E,0x7C,0x78,0x58, + 0x34,0xE6,0x92,0xCD,0x70,0x78,0x70,0x78,0x92,0xD5,0x30,0xC5,0xFB,0x6A,0x68,0xB0, + 0xD3,0xDD,0x51,0xC5,0x2D,0x2D,0x3D,0xA7,0x14,0xDE,0xB2,0xD5,0x82,0xC2,0x42,0xC2, + 0xB2,0xD5,0x30,0xC5,0x2A,0xBE,0x9F,0xD6,0xF4,0xDD,0x51,0xCD,0x82,0x8B,0xCB,0x7D, + 0xF3,0xDD,0x31,0xC5,0x37,0x2E,0xA6,0xAD,0xB6,0xF6,0xF3,0xDD,0x0B,0x29,0x09,0x0B, + 0xD7,0xF6,0x75,0xEE,0x7A,0xFA,0xFA,0xCA,0x96,0xEE,0x34,0xE6,0xFE,0x56,0x5A,0xFC, + 0x55,0xE6,0x34,0xE6,0x09,0x25,0x9D,0xFE,0x96,0xEE,0x34,0xE6,0xAD,0xAB,0xAF,0xAF, + 0xD6,0xF6,0xB6,0xEE,0xAF,0xBB,0x7D,0x7D,0xD5,0xF6,0xB6,0xEE,0x57,0x75,0xF5,0xF7, + 0xD6,0xF6,0xB6,0xEE,0xD9,0xDF,0xFA,0xEB,0xD6,0xF6,0xB6,0xEE,0xD9,0x7A,0xAE,0xA7, + 0xD6,0xF6,0xB6,0xEE,0x7F,0x6B,0xAB,0x8D,0xD6,0xF6,0xB6,0xEE,0xAD,0xCF,0xFE,0xFE, + 0xD6,0xF6,0x96,0xEE,0x6A,0xAA,0x32,0x38,0xD6,0xF6,0xB6,0xEE,0xE3,0xEA,0xDA,0x7E, + 0xD6,0xF6,0xB6,0xEE,0xDD,0x57,0xD6,0xB7,0xB6,0xF6,0xD7,0xEE,0xEB,0xEB,0xEA,0xFB, + 0xD7,0xF6,0xB6,0xEE,0xFF,0xFE,0x7E,0x5A,0xD6,0xF6,0xB6,0xEE,0xAF,0x2B,0xAB,0xFE, + 0xB6,0xEE,0x95,0xEE,0xF8,0xA0,0x78,0x50,0xB6,0xF6,0x95,0xEE,0x77,0xEE,0xEB,0xF7, + 0xB6,0xF6,0x75,0xEE,0x6F,0x3E,0xAF,0x3A,0xB5,0xF6,0x96,0xEE,0x0B,0xCA,0xBA,0x7E, + 0x95,0xF6,0xB6,0xEE,0xFF,0xFB,0xFA,0xAE,0x96,0xF6,0xB6,0xEE,0xE5,0xFD,0x7B,0x5E, + 0xD6,0xF6,0xB6,0xEE,0x95,0xB5,0xAB,0xBA,0xD7,0xF6,0xB6,0xE6,0x80,0x22,0xA2,0x20, + 0xD7,0xF6,0xF6,0xEE,0x20,0x22,0x28,0x00,0xD7,0xF6,0xB6,0xEE,0x8A,0x5E,0xFE,0xAA, + 0xF8,0xF6,0xD7,0xF6,0x7D,0x79,0x7D,0xD5,0xD6,0xF6,0xB6,0xF6,0x18,0xBE,0xAA,0x20, + 0xB6,0xF6,0x52,0xCD,0xC0,0xC0,0x60,0x40,0x2C,0xAC,0x05,0x6A,0x58,0x5C,0x54,0x5E, + 0x06,0x6A,0x64,0x59,0xB0,0x6A,0x7E,0x77,0x64,0x61,0xE2,0x48,0x2A,0x96,0xDE,0xDE, + 0x06,0x72,0x23,0x59,0xAA,0x0B,0xA9,0x2D,0x06,0x72,0xA5,0x61,0x78,0xA8,0xA2,0xEA, + 0xA5,0x69,0x44,0x59,0x28,0xEC,0x7E,0x98,0x85,0x61,0x44,0x59,0xEA,0x4E,0xA6,0x27, + 0xC5,0x61,0x23,0x51,0x3B,0xB7,0xBF,0xA5,0xE6,0x69,0x85,0x59,0x3F,0xBD,0xBF,0x97, + 0x88,0x7A,0x06,0x6A,0x0D,0x3D,0x3D,0x35,0x2C,0xAC,0x47,0x72,0x2F,0xAF,0xBF,0xBD, + 0x96,0xF6,0x0C,0xA4,0x02,0x0B,0x0D,0x25,0xF7,0xFE,0x96,0xF6,0xAA,0xAA,0xAB,0xA9, + 0xD6,0xFE,0xD7,0xF6,0xFF,0xFF,0xFF,0xFF,0xB6,0xFE,0xD7,0xF6,0x55,0x75,0x67,0x7D, + 0xF7,0xFE,0xB6,0xF6,0xD7,0x5E,0x76,0x7E,0xD7,0xF6,0xB6,0xF6,0x6E,0xCF,0xBD,0xDF, + 0xD7,0xF6,0xB6,0xF6,0x55,0x56,0x54,0x57,0xD7,0xF6,0xB6,0xF6,0x75,0xBD,0xB7,0x2F, + 0xD7,0xF6,0xB6,0xF6,0xDE,0xF8,0xBC,0x53,0xD6,0xF6,0xB6,0xF6,0x6D,0xFF,0xF6,0xA4, + 0xD6,0xF6,0xB6,0xF6,0x1F,0x0F,0x8B,0xB8,0xF7,0xF6,0xD6,0xF6,0x35,0x15,0x95,0x55, + 0x17,0xFF,0xD7,0xF6,0xEE,0xEA,0xEF,0xEF,0x17,0xFF,0xF7,0xF6,0xD5,0x75,0xFD,0xFD, + 0xD7,0xFE,0xF7,0xF6,0xF9,0xB7,0xAD,0x2B,0xF7,0xFE,0x95,0xEE,0x00,0xAA,0xEA,0x78, + 0xD6,0xF6,0xF0,0xC4,0xA0,0xE8,0x6A,0x5A,0x71,0xD5,0x46,0x7A,0xE0,0xE8,0x5A,0x5E, + 0xC8,0x82,0xC5,0x69,0xE8,0xBE,0xFB,0xF7,0x46,0x7A,0x05,0x72,0xE8,0x90,0x60,0x8F, + 0x46,0x82,0xE5,0x71,0xAC,0xBA,0x2D,0xEA,0x87,0x8A,0x26,0x7A,0xBD,0xF3,0x89,0x2B, + 0xA8,0x8A,0x46,0x82,0x2A,0xBF,0xDF,0xFE,0xA8,0x8A,0x26,0x7A,0xA8,0xA0,0xEF,0xDF, + 0xA8,0x82,0xE5,0x71,0x2A,0x3E,0x1F,0x37,0x55,0xEE,0x8A,0x9B,0x0D,0x29,0x09,0x0B, + 0x18,0xFF,0xD7,0xFE,0x39,0xA9,0xAB,0x2B,0x17,0xFF,0x18,0xF7,0xF8,0xA8,0xBA,0xEA, + 0x17,0xFF,0x18,0xF7,0xFB,0xBE,0xEB,0xEE,0x18,0xFF,0x17,0xF7,0xFF,0xEF,0xFE,0xEB, + 0x18,0xFF,0x17,0xF7,0xEE,0xFE,0xAF,0xFB,0x18,0xFF,0xF7,0xF6,0x82,0xE0,0x70,0x7A, + 0xF7,0xF6,0xD7,0xF6,0x78,0xFA,0x5E,0xAA,0xF7,0xF6,0xD7,0xF6,0xAA,0xAA,0x8A,0x83, + 0xF7,0xF6,0xD7,0xF6,0xFD,0xFA,0xBA,0xA6,0xF7,0xF6,0xD7,0xF6,0xF7,0xBF,0xFF,0xFF, + 0xF7,0xF6,0xD7,0xF6,0x36,0xBA,0x76,0x5E,0xF7,0xF6,0xD7,0xF6,0x75,0xD7,0x9D,0xD5, + 0xF7,0xF6,0x97,0xF6,0xB2,0xAA,0xA0,0xA2,0xD7,0xF6,0xF7,0xEE,0x80,0xA0,0x00,0xA0, + 0xF7,0xF6,0xD7,0xF6,0x8F,0xED,0x35,0x31,0x18,0xFF,0xF7,0xF6,0x35,0x0D,0xBA,0xEA, + 0x18,0xFF,0xB6,0xEE,0xE0,0x78,0xFE,0xDF,0xB7,0xF6,0xB6,0xEE,0xFF,0x97,0xBF,0xAA, + 0xB6,0xF6,0x96,0xEE,0xA2,0xAA,0xA0,0xFA,0x96,0xF6,0x75,0xEE,0x70,0x60,0xE8,0x78, + 0x96,0xEE,0x14,0xDE,0xA8,0xE8,0xE8,0x5A,0x55,0xE6,0xB3,0xD5,0xA8,0xAA,0xE2,0x7A, + 0x14,0xDE,0x71,0xCD,0x78,0x7A,0xD7,0x25,0xB6,0xF6,0x92,0xD5,0xBD,0x2D,0x0B,0x02, + 0xF7,0xFE,0x96,0xF6,0xBD,0xAF,0xBB,0x8A,0xF7,0xF6,0xB7,0xEE,0xEA,0xBA,0xEA,0xAE, + 0xF7,0xF6,0xD7,0xF6,0xFF,0xDD,0x57,0x55,0xF7,0xF6,0xD7,0xF6,0x59,0xD5,0x55,0xB5, + 0xF8,0xF6,0xB6,0xEE,0xEE,0x7F,0xBE,0x2A,0xF7,0xF6,0xB7,0xEE,0xFF,0xFF,0xEB,0xAA, + 0xD7,0xF6,0xB7,0xEE,0xEC,0xBF,0xAC,0x38,0xD7,0xF6,0xB7,0xEE,0xAB,0x2E,0x8E,0xAA, + 0xD7,0xF6,0xB6,0xEE,0x08,0xA2,0xA8,0xEA,0xD7,0xF6,0xB6,0xEE,0x88,0x3E,0xBE,0xB7, + 0xD7,0xF6,0xB6,0xEE,0xFE,0x6E,0xFE,0x7E,0xD7,0xF6,0xB6,0xEE,0xFF,0x3F,0x3F,0xAF, + 0xD7,0xF6,0xB6,0xEE,0xDD,0x7E,0x70,0xEA,0xD6,0xF6,0xB7,0xEE,0x5D,0x5F,0x5F,0xFB, + 0xD7,0xF6,0xB7,0xEE,0xAD,0xFD,0xAD,0xB7,0xF8,0xFE,0xD7,0xEE,0x2B,0x27,0x2D,0xF5, + 0x38,0xFF,0xF8,0xF6,0x2A,0xAA,0xAF,0xBF,0x38,0xFF,0x19,0xFF,0x2E,0xA6,0xAF,0xAF, + 0x38,0xFF,0xF7,0xF6,0x7A,0xEA,0xE0,0x80,0x18,0xF7,0xF7,0xF6,0x55,0x55,0x57,0x5E, + 0xF8,0xF6,0xD7,0xF6,0xE8,0xAA,0xFB,0x2E,0xF7,0xF6,0xD7,0xF6,0x6A,0x2E,0x2B,0xA8, + 0xF7,0xF6,0xD7,0xF6,0xA5,0xD6,0xFA,0x7A,0xF7,0xF6,0x96,0xEE,0xE0,0xAA,0xD8,0xFA, + 0xB7,0xF6,0xD7,0xEE,0xBE,0x8A,0xAA,0xA0,0xD7,0xF6,0xB6,0xEE,0x2B,0x2A,0xAA,0x0F, + 0xD7,0xF6,0x34,0xDE,0xF8,0x78,0xE8,0x78,0x54,0xE6,0xD2,0xD5,0x36,0x36,0x3E,0x2E, + 0xD7,0xF6,0x75,0xE6,0x0F,0x89,0x01,0x0B,0xD7,0xF6,0x34,0xE6,0x78,0x78,0xE8,0xE2, + 0x34,0xE6,0x92,0xCD,0x58,0x5A,0x58,0x78,0xB3,0xD5,0x71,0xCD,0x5F,0xEA,0xC3,0xC2, + 0xD2,0xD5,0x71,0xCD,0x2D,0x17,0xA5,0xA5,0x14,0xDE,0xD3,0xDD,0x63,0xEB,0x8A,0xCD, + 0x92,0xCD,0xEF,0xBC,0xEA,0xB8,0xF8,0x5C,0x51,0xC5,0x10,0xC5,0x28,0xBE,0xBE,0x55, + 0x75,0xEE,0x51,0xCD,0xBD,0xA5,0x2D,0x0D,0xD7,0xF6,0x75,0xEE,0xAD,0x29,0x0A,0x02, + 0xD7,0xF6,0x75,0xEE,0xC2,0xAA,0x68,0xA8,0x96,0xEE,0x34,0xE6,0x7C,0xFA,0x7A,0x6E, + 0x55,0xE6,0x34,0xE6,0xDE,0xDB,0x77,0x5B,0x75,0xEE,0x55,0xE6,0x07,0x09,0x29,0x75, + 0xD6,0xF6,0x95,0xEE,0xAF,0xA9,0xAB,0xAB,0xB5,0xF6,0xD6,0xEE,0xAF,0xAA,0xFA,0xE2, + 0xD6,0xF6,0xB6,0xEE,0x8F,0x78,0x50,0x71,0xD6,0xF6,0xB6,0xEE,0xAD,0xAB,0xFF,0xA7, + 0xD6,0xF6,0xB6,0xEE,0xAD,0x77,0x77,0xFF,0xD6,0xF6,0xB6,0xEE,0xEA,0xBB,0xAB,0x8A, + 0xD6,0xF6,0xB6,0xEE,0xBF,0x6F,0x6A,0x72,0xD6,0xF6,0xB6,0xEE,0x5F,0x59,0xFE,0x7E, + 0xD6,0xF6,0xB6,0xEE,0x2B,0xAF,0xFF,0xF7,0xD6,0xF6,0xB6,0xEE,0xAE,0xBA,0xDE,0xFB, + 0xD6,0xF6,0xB6,0xEE,0x78,0xBF,0x75,0xFD,0xD6,0xF6,0xB6,0xEE,0xFE,0xFE,0xFF,0x6B, + 0xD6,0xF6,0x95,0xEE,0x56,0xDA,0x7E,0xFF,0xB6,0xF6,0x96,0xEE,0xDF,0x77,0xBF,0xCD, + 0xB6,0xF6,0x96,0xEE,0x9A,0x7E,0xF2,0xE2,0xB5,0xF6,0x96,0xEE,0x5E,0xDF,0xFF,0xFE, + 0xB6,0xF6,0x96,0xEE,0xFB,0xEB,0xFD,0xED,0xD6,0xF6,0x96,0xEE,0xAD,0xAF,0xBD,0xFF, + 0xD6,0xF6,0xB6,0xEE,0xBA,0x36,0x2F,0x0B,0xF6,0xF6,0xB7,0xEE,0xBE,0xBE,0xAA,0xAB, + 0xD7,0xF6,0xB6,0xEE,0xEC,0xAC,0xA8,0x28,0xD7,0xF6,0xF6,0xEE,0x00,0xA8,0xA8,0x88, + 0xD6,0xF6,0xF7,0xEE,0x88,0x0A,0x02,0x00,0xD6,0xF6,0xB7,0xF6,0xE8,0xC2,0xE0,0xFA, + 0xB6,0xF6,0x72,0xD5,0x60,0x60,0x60,0x40,0x8B,0x9B,0x84,0x59,0x7C,0x5C,0x5C,0x5C, + 0xA5,0x61,0x43,0x51,0xEC,0x7A,0xFA,0x8F,0x65,0x59,0xE3,0x48,0xEE,0x6A,0x78,0xE0, + 0xA5,0x61,0xC2,0x48,0x0F,0x2D,0xBD,0xBF,0x06,0x72,0x84,0x59,0x8A,0xAA,0xFF,0xBD, + 0xC5,0x69,0x64,0x59,0x58,0x7E,0xEE,0x6A,0x64,0x59,0x04,0x51,0x8A,0xAA,0x98,0xAA, + 0x64,0x59,0x24,0x51,0x2F,0xFB,0xFA,0xAB,0xC5,0x61,0x44,0x51,0x2E,0x3F,0xBD,0xD5, + 0x27,0x72,0xC5,0x61,0x2F,0x2D,0x5D,0x55,0x09,0x8B,0xE6,0x61,0x2B,0xAF,0xBD,0xB5, + 0x92,0xD5,0x29,0x8B,0x2D,0xBD,0xF5,0x55,0xB6,0xF6,0x6E,0xB4,0x00,0x02,0x0B,0x0D, + 0xD7,0xFE,0xD6,0xF6,0xFF,0xFE,0xEA,0xAA,0xB7,0xFE,0xD7,0xF6,0x77,0xFD,0x57,0x55, + 0xD7,0xF6,0xB6,0xF6,0xF8,0xE2,0xE0,0x80,0xD7,0xF6,0xB6,0xF6,0x7E,0xEB,0xF9,0xA9, + 0xD7,0xF6,0xB6,0xF6,0xD5,0xB5,0xAF,0xBF,0xD7,0xF6,0xB6,0xF6,0xAE,0xF6,0xAA,0xEB, + 0xD6,0xF6,0xB7,0xF6,0x60,0xE2,0x20,0xAA,0xD6,0xF6,0xB6,0xF6,0x1A,0xAE,0x9A,0x3A, + 0xD6,0xF6,0xB7,0xF6,0x78,0xCA,0x80,0xA0,0xF7,0xFE,0xB6,0xF6,0xAB,0xBF,0xA7,0xAD, + 0xF7,0xFE,0xD7,0xF6,0x8B,0xAA,0x8B,0xAB,0xF7,0xFE,0xD7,0xF6,0x8B,0xAE,0xAA,0xAA, + 0xF7,0xFE,0xB6,0xF6,0xA8,0xA2,0xEA,0x68,0xB6,0xF6,0x31,0xCD,0x80,0x80,0xE8,0x78, + 0x72,0xD5,0x25,0x72,0xA0,0xE0,0x78,0x7E,0x09,0x8B,0xE5,0x69,0xDC,0xDE,0xD7,0xFD, + 0x46,0x7A,0x05,0x72,0xD1,0xAF,0x3F,0x2A,0x67,0x82,0x26,0x7A,0xB5,0x5F,0x1F,0x03, + 0x67,0x82,0x26,0x7A,0x57,0xDC,0x38,0x80,0x87,0x8A,0x06,0x7A,0x23,0x82,0xCA,0x5E, + 0x67,0x82,0x26,0x7A,0x28,0xE2,0xCB,0x59,0x67,0x82,0x26,0x7A,0xB2,0xBE,0xBD,0x77, + 0x0D,0xAC,0x66,0x7A,0xD5,0x95,0xB5,0x35,0xD7,0xFE,0x8E,0xBC,0x2D,0x29,0x09,0x0B, + 0x18,0xFF,0xF7,0xFE,0xBD,0xB5,0xAD,0x2D,0xF7,0xFE,0x38,0xF7,0xBE,0xEA,0xFA,0x7E, + 0x18,0xFF,0x37,0xF7,0x82,0xAA,0xAB,0xAB,0x38,0xFF,0x17,0xF7,0x77,0x5F,0xDD,0xFE, + 0x38,0xFF,0xF7,0xF6,0xAB,0xBA,0xAB,0xAA,0x18,0xFF,0xF7,0xF6,0x7B,0xEA,0xF8,0xD8, + 0xF7,0xF6,0xD7,0xF6,0xA0,0xB0,0xE8,0xAE,0xF7,0xF6,0xD7,0xF6,0xAA,0xEE,0xAE,0xA8, + 0xF7,0xF6,0xD7,0xF6,0xBB,0xEA,0xEA,0xC2,0xF7,0xF6,0xB7,0xEE,0xBA,0xF8,0xAA,0x2A, + 0xF7,0xF6,0xD7,0xF6,0xD5,0x55,0x57,0x28,0xF7,0xF6,0xD7,0xF6,0xF5,0xAD,0xEB,0xC8, + 0xF7,0xF6,0xD7,0xF6,0x7E,0xDF,0xEF,0x0E,0xF7,0xF6,0xD7,0xF6,0xB5,0x5F,0x9E,0x2E, + 0x17,0xFF,0xD7,0xF6,0xAF,0x0B,0xAB,0xA2,0x17,0xFF,0xB6,0xF6,0xC8,0xE8,0x5A,0x57, + 0xD6,0xF6,0x96,0xEE,0x28,0xAA,0xBF,0xAF,0xB6,0xF6,0xD7,0xEE,0x8A,0x0A,0x20,0x82, + 0xD6,0xF6,0x96,0xEE,0x7F,0x5E,0x5E,0x7E,0x96,0xEE,0x34,0xE6,0xA0,0xE8,0xF8,0xFE, + 0x75,0xE6,0xF3,0xD5,0xF8,0xFA,0x6A,0x7A,0x35,0xE6,0x92,0xCD,0x7A,0x5E,0xBF,0x2E, + 0xD7,0xF6,0x92,0xD5,0xB5,0xAF,0x2A,0x02,0xD7,0xF6,0xB6,0xF6,0x21,0x0D,0x0D,0x09, + 0xF7,0xF6,0xD7,0xF6,0x79,0xFD,0xF5,0x55,0xF7,0xF6,0xD7,0xF6,0xF5,0xFB,0x5F,0x5D, + 0xF7,0xF6,0xB7,0xEE,0xAB,0xAB,0xAF,0xAF,0xF7,0xF6,0xB7,0xEE,0x2A,0xAA,0xEA,0xFA, + 0xD7,0xF6,0xF7,0xEE,0x2A,0x00,0x00,0x20,0xD7,0xF6,0xB7,0xEE,0x82,0x80,0xA0,0x80, + 0xD7,0xF6,0xB7,0xEE,0xA8,0xEB,0x82,0xC8,0xD7,0xF6,0xB7,0xEE,0x28,0x02,0xC2,0xEA, + 0xD7,0xF6,0xB7,0xEE,0xF8,0x2A,0xAE,0xAF,0xD7,0xF6,0xB6,0xEE,0xA7,0xB5,0xFF,0xDF, + 0xD7,0xF6,0xB7,0xEE,0x77,0xBE,0xBC,0xA8,0xD7,0xF6,0xB6,0xEE,0x8B,0x8B,0x2F,0xBE, + 0xD7,0xF6,0xB7,0xEE,0xC8,0x82,0x00,0x80,0xD7,0xF6,0xB7,0xEE,0xE8,0xAE,0xEA,0x2A, + 0xD7,0xF6,0xB6,0xEE,0xEF,0xFB,0xAA,0xAF,0xD7,0xF6,0xB6,0xEE,0x29,0xEF,0xAA,0x0A, + 0x18,0xF7,0xD7,0xF6,0x2B,0xAB,0xAF,0xBD,0x38,0xFF,0xF7,0xF6,0xAB,0x2A,0x2B,0xED, + 0x39,0xFF,0x38,0xFF,0xEB,0xAF,0xAF,0xBF,0x38,0xFF,0xF7,0xF6,0x5E,0x7A,0x78,0x60, + 0xF7,0xF6,0xD7,0xF6,0xAF,0x09,0xA8,0x83,0xF7,0xF6,0xD7,0xF6,0xC8,0x62,0x7E,0x57, + 0xF7,0xF6,0x96,0xEE,0xA0,0xAA,0xEA,0xDF,0xD7,0xF6,0x96,0xEE,0x70,0xFE,0x5F,0x57, + 0xB6,0xEE,0x96,0xEE,0x8A,0xAF,0x3F,0xA5,0xD7,0xF6,0xB6,0xEE,0x0D,0x0D,0x2D,0x25, + 0xD7,0xF6,0xF4,0xDD,0xE8,0xE0,0x60,0x60,0x14,0xDE,0x51,0xC5,0x00,0x20,0x2E,0x35, + 0xD6,0xF6,0x55,0xE6,0x09,0x2D,0xAD,0xBD,0xD7,0xF6,0x55,0xEE,0x62,0xE8,0xEA,0xE8, + 0x35,0xE6,0x92,0xCD,0x5A,0x58,0x58,0x58,0xB2,0xD5,0x71,0xCD,0x63,0xC2,0xC2,0xC2, + 0xB2,0xD5,0x71,0xCD,0xB5,0xAD,0x2D,0x2D,0x13,0xDE,0xB2,0xD5,0x8B,0x83,0x29,0xA9, + 0x92,0xD5,0xCF,0xBC,0x7C,0x5C,0x5C,0x5C,0x31,0xC5,0xAE,0xB4,0x0B,0x2B,0xB5,0xD7, + 0x96,0xEE,0x51,0xCD,0x2D,0xAF,0xBD,0xF5,0xD7,0xF6,0xF3,0xDD,0x00,0x0A,0x0B,0x2D, + 0xD7,0xF6,0x75,0xEE,0xEA,0xF8,0x58,0xFA,0x75,0xEE,0x34,0xE6,0xE8,0xC0,0x70,0x78, + 0x35,0xEE,0x54,0xE6,0xE5,0x57,0xDF,0x76,0x76,0xEE,0x35,0xE6,0xFB,0xAF,0xB6,0xFE, + 0xD6,0xF6,0xB6,0xEE,0xFD,0xFE,0xEE,0x2A,0xD6,0xF6,0xB6,0xEE,0xDB,0xFF,0x7B,0x6A, + 0xD6,0xF6,0xB6,0xEE,0xAD,0xEF,0xAD,0x3F,0xB6,0xF6,0xD6,0xEE,0xFF,0xFF,0xFF,0xAF, + 0xD6,0xF6,0xB6,0xEE,0xA6,0xEA,0xEA,0xAA,0xD6,0xF6,0xB6,0xEE,0xF2,0xAF,0xAA,0xA2, + 0xD6,0xF6,0xB6,0xEE,0xA1,0x8E,0xFE,0xAA,0xD6,0xF6,0xB6,0xEE,0xE2,0xA3,0x82,0xBA, + 0xD6,0xF6,0x96,0xEE,0xA2,0x8A,0xD8,0x8A,0xD6,0xF6,0xB6,0xEE,0xEB,0xA2,0x68,0xA2, + 0xD6,0xF6,0xB6,0xEE,0x6E,0xF2,0xE2,0xEB,0xD6,0xF6,0xB6,0xEE,0xF9,0xFF,0x7A,0xAA, + 0xD6,0xF6,0x96,0xEE,0xFF,0xDF,0xFA,0xFA,0xB6,0xF6,0x96,0xEE,0x9F,0xAA,0x8B,0xBA, + 0x96,0xF6,0xB6,0xEE,0xBF,0xED,0xBB,0xFF,0xB6,0xF6,0x96,0xEE,0x7E,0xFA,0xCA,0xA8, + 0x96,0xF6,0xB6,0xEE,0x7E,0x7F,0xF7,0xF7,0xB6,0xEE,0x96,0xEE,0x22,0x2A,0xAA,0xC2, + 0xD6,0xF6,0xB6,0xEE,0x8F,0x0B,0x03,0x2D,0xF6,0xF6,0xB6,0xEE,0xEE,0xFA,0xFA,0xFE, + 0xD6,0xF6,0xB7,0xE6,0x20,0xA2,0x0A,0x80,0xD6,0xF6,0xF6,0xEE,0x08,0x28,0x20,0x02, + 0xF6,0xF6,0xB6,0xEE,0xEB,0xAF,0xAF,0xFE,0xD6,0xF6,0xB6,0xF6,0x72,0xDA,0xBA,0x20, + 0xD6,0xF6,0xB2,0xD5,0x60,0x60,0x60,0xE0,0x6C,0xAC,0x83,0x51,0x5E,0x5C,0x5C,0x5C, + 0xA5,0x61,0x23,0x51,0x2F,0xB7,0x7F,0xDA,0x85,0x59,0x23,0x51,0x6A,0xE8,0xAA,0xB7, + 0x85,0x59,0x23,0x51,0xF5,0x77,0x5C,0xEE,0xC6,0x61,0x24,0x51,0x0B,0xAF,0xEF,0x57, + 0xA6,0x61,0x44,0x51,0x88,0xEB,0x7E,0x6B,0x64,0x59,0x03,0x49,0x2A,0xFE,0xDE,0xFF, + 0x44,0x51,0x03,0x49,0x00,0xAE,0x96,0x57,0x85,0x59,0x23,0x49,0xAF,0x2F,0xAF,0xFD, + 0xE5,0x61,0x65,0x51,0x2A,0x2F,0xAD,0xAD,0x87,0x7A,0xE5,0x61,0x3D,0xED,0x35,0xB5, + 0x4B,0x93,0x88,0x7A,0x2B,0x2D,0x2D,0x2D,0xD3,0xDD,0x6A,0x93,0x2D,0xBD,0xF5,0xD5, + 0xB6,0xF6,0x0D,0xA4,0x00,0x02,0x2F,0xB5,0xD7,0xFE,0xF4,0xDD,0x00,0x00,0xAA,0xF5, + 0xD7,0xF6,0xB2,0xD5,0x00,0x80,0xEA,0x5F,0xB6,0xF6,0x50,0xCD,0x00,0x00,0x0A,0xF5, + 0xD6,0xF6,0x55,0xEE,0x80,0x22,0x22,0xBD,0xD6,0xF6,0xB6,0xF6,0xED,0x7F,0x7A,0x9D, + 0xD6,0xF6,0xB6,0xF6,0x2F,0xAB,0xBB,0x55,0xD6,0xF6,0xB6,0xF6,0xA8,0xDE,0xFE,0xBF, + 0xD6,0xF6,0xB6,0xF6,0xA3,0x2B,0x88,0x6A,0xF7,0xFE,0xB6,0xF6,0xA9,0xA7,0x3D,0x0D, + 0xF7,0xFE,0xD7,0xF6,0x6F,0xBF,0xE8,0xFC,0xF7,0xFE,0xD7,0xF6,0x2A,0x2B,0xCA,0x60, + 0xD7,0xFE,0x72,0xD5,0x80,0x80,0xE0,0x7A,0x34,0xE6,0x87,0x7A,0xA0,0xE8,0x6A,0x7E, + 0x8B,0x9B,0x05,0x72,0x58,0x5E,0x57,0x55,0x46,0x7A,0x05,0x72,0xA7,0xEF,0xE8,0x03, + 0x67,0x82,0x26,0x7A,0x2F,0x0D,0x05,0x2D,0x87,0x8A,0x46,0x82,0x39,0x2E,0xAF,0xE2, + 0x88,0x8A,0x26,0x82,0xA8,0xE2,0x53,0x7B,0x67,0x8A,0xE5,0x79,0x76,0xF0,0xFE,0xEF, + 0x46,0x82,0xE4,0x71,0xEB,0x6F,0xCB,0x03,0xC8,0x92,0x25,0x7A,0xDD,0xF7,0xBF,0x2F, + 0x52,0xD5,0xA8,0x8A,0x35,0x35,0x3D,0x2D,0xF8,0xFE,0xD3,0xE5,0x2D,0x0B,0x0B,0x03, + 0x17,0xFF,0xF8,0xFE,0xB9,0xA9,0xEF,0xBB,0x38,0xFF,0xF7,0xF6,0xAB,0xBB,0xAF,0x8F, + 0x18,0xFF,0x37,0xF7,0xEB,0xAA,0xBA,0xAA,0x38,0xFF,0x18,0xFF,0x5E,0x5A,0xDA,0xBF, + 0x18,0xFF,0x38,0xF7,0x28,0xA2,0x28,0xAA,0x18,0xFF,0xF7,0xF6,0x78,0x78,0x7C,0x78, + 0xF7,0xF6,0xD7,0xF6,0xD6,0xAC,0x2A,0x02,0xF7,0xF6,0xD7,0xF6,0xF8,0xE8,0x2A,0xAE, + 0xF7,0xF6,0xD7,0xF6,0xEA,0x62,0x8A,0xAA,0xF7,0xF6,0xD7,0xF6,0x0E,0x3A,0xEE,0xF6, + 0xF7,0xF6,0xD7,0xF6,0x80,0x00,0xBA,0xBF,0xF7,0xF6,0xD7,0xF6,0xA8,0xFE,0xB8,0xAA, + 0xF7,0xF6,0xD7,0xF6,0x2C,0xAC,0xAA,0x28,0x17,0xFF,0xD7,0xF6,0xBF,0x0B,0x0B,0x82, + 0x18,0xF7,0xB6,0xF6,0xE0,0xF8,0x78,0x5F,0xD6,0xF6,0x96,0xEE,0xFA,0xFA,0xEA,0xFF, + 0xB6,0xF6,0x96,0xEE,0x2B,0xAF,0xF7,0x5F,0xB6,0xF6,0x96,0xEE,0x38,0xEF,0x5F,0x7D, + 0xB7,0xF6,0x55,0xE6,0xE8,0xFA,0x6E,0x57,0x75,0xEE,0x14,0xE6,0xE8,0xE2,0xFA,0x7F, + 0x96,0xEE,0xF3,0xDD,0x5B,0xBF,0xAF,0x0F,0xD7,0xFE,0x34,0xE6,0xB5,0x2F,0x02,0x02, + 0xF7,0xF6,0xB7,0xF6,0xFF,0xFA,0xEA,0xA8,0xF7,0xF6,0xD7,0xF6,0x55,0xEF,0x9D,0x3D, + 0xF7,0xF6,0xD7,0xF6,0x5F,0x76,0x5F,0xFF,0xF7,0xF6,0xB6,0xEE,0xDB,0xAB,0xAE,0xAE, + 0xD7,0xF6,0xF7,0xEE,0x00,0x82,0xA2,0x08,0xB7,0xF6,0xF7,0xEE,0xAB,0x2F,0xAB,0x2A, + 0xF7,0xF6,0xB7,0xF6,0x2A,0xBB,0xEF,0xFF,0xD7,0xF6,0xB6,0xEE,0x80,0xE0,0xF8,0xFC, + 0xD7,0xF6,0xB7,0xEE,0x4E,0xAA,0xAA,0x0A,0xD7,0xF6,0xB7,0xEE,0xAA,0xAE,0xFA,0x4A, + 0xD7,0xF6,0xB6,0xEE,0xEF,0xFF,0xEF,0xA2,0xD7,0xF6,0xB7,0xEE,0xFF,0xAA,0x82,0x00, + 0xD7,0xF6,0xB7,0xEE,0x2A,0x82,0xA8,0xBA,0xD7,0xF6,0xB7,0xEE,0xA8,0x08,0x00,0x00, + 0xF7,0xF6,0xB6,0xEE,0xFF,0xEB,0xEA,0xEA,0xD7,0xF6,0xB6,0xEE,0x88,0xAC,0x3E,0xAA, + 0xB7,0xF6,0xF7,0xEE,0xBA,0xFA,0xAE,0xAE,0xF7,0xF6,0xD7,0xEE,0xF5,0xFD,0xAF,0xA9, + 0xF7,0xF6,0xD7,0xF6,0xED,0xAD,0xBE,0xAE,0x18,0xFF,0xD7,0xF6,0x0B,0x29,0xAF,0xAF, + 0x38,0xFF,0x18,0xF7,0x23,0x2B,0xAF,0xB5,0x38,0xFF,0xF8,0xF6,0xE8,0xE8,0xA0,0xA2, + 0x18,0xF7,0xD7,0xF6,0x7E,0x5E,0x5E,0x50,0xD7,0xF6,0xB7,0xEE,0xE8,0x70,0x72,0x5E, + 0xD7,0xF6,0x96,0xEE,0xFA,0xFE,0x7F,0xDF,0x96,0xEE,0x97,0xE6,0x00,0x88,0x22,0x80, + 0x96,0xEE,0x76,0xE6,0x20,0x20,0x0B,0x08,0xD7,0xF6,0x96,0xEE,0x2F,0x1D,0xA7,0x3D, + 0xD7,0xF6,0xF4,0xDD,0x60,0x60,0x60,0x68,0xF3,0xD5,0xEF,0xBC,0xBF,0x27,0xBF,0x3F, + 0xB7,0xF6,0x34,0xE6,0x29,0x09,0x2B,0x29,0xB6,0xF6,0x76,0xEE,0xE8,0xA8,0xE2,0x6A, + 0x55,0xEE,0x92,0xD5,0x58,0x58,0x58,0xF8,0xD3,0xD5,0x92,0xCD,0x55,0x7B,0x6A,0x7E, + 0xB2,0xD5,0x71,0xCD,0x0D,0x35,0xF5,0x97,0xF3,0xDD,0xB2,0xD5,0x0F,0x0D,0x0F,0x01, + 0x92,0xD5,0x8E,0xB4,0xD8,0xFC,0x58,0x7C,0xCF,0xBC,0x4D,0xA4,0x2A,0x0A,0x2B,0x27, + 0xD3,0xDD,0x10,0xC5,0x09,0x29,0xA9,0xAD,0x75,0xEE,0xD3,0xD5,0x2D,0x3D,0xB5,0xF5, + 0xB6,0xF6,0x55,0xE6,0x8A,0xAA,0xEB,0xB5,0x75,0xEE,0x34,0xE6,0x60,0xF0,0xE0,0x22, + 0x55,0xE6,0x34,0xE6,0x3B,0x28,0x48,0x5C,0x75,0xEE,0x34,0xE6,0xF7,0xF5,0xB5,0xB5, + 0xD6,0xF6,0xB6,0xEE,0xAA,0xA8,0xAD,0xED,0xD6,0xF6,0xB6,0xEE,0xFB,0xAF,0xAB,0xA2, + 0xD6,0xF6,0xB6,0xEE,0xFC,0xB0,0xAA,0xFA,0xD6,0xF6,0xB7,0xEE,0xEA,0xFA,0xF8,0xE8, + 0xD7,0xF6,0xB6,0xEE,0xAB,0xAA,0xAA,0xAB,0xD6,0xF6,0xD7,0xEE,0xAA,0x8A,0xA8,0x8A, + 0xD6,0xF6,0xB6,0xEE,0xAA,0xEA,0xE0,0x02,0xD6,0xF6,0xB6,0xEE,0xEA,0x21,0xEE,0xB2, + 0xD6,0xF6,0xB6,0xEE,0xFF,0xFE,0xBE,0x22,0xD6,0xF6,0xB6,0xEE,0xDA,0x77,0xDE,0x90, + 0xD6,0xF6,0xB6,0xEE,0xE9,0xAB,0xAB,0x2B,0xD6,0xF6,0xB6,0xEE,0x2A,0x3D,0x07,0x5A, + 0xD6,0xF6,0x96,0xEE,0xFE,0xFE,0xFE,0xFE,0xB6,0xF6,0x96,0xEE,0xDA,0xBA,0x9E,0x7F, + 0xB6,0xF6,0x96,0xEE,0xAE,0xAE,0x8A,0x2B,0x96,0xF6,0xB6,0xEE,0xBF,0xAB,0xAF,0xF7, + 0x95,0xF6,0xB6,0xEE,0xFD,0xD5,0x56,0x57,0xD6,0xF6,0x95,0xEE,0xEB,0xFF,0x9F,0x2F, + 0xD6,0xF6,0xB6,0xEE,0x2D,0x2B,0x0D,0x2E,0xD6,0xF6,0xF7,0xEE,0x80,0xA0,0x00,0x28, + 0xF6,0xF6,0xB6,0xEE,0xE2,0xBA,0xEE,0xFF,0xF6,0xF6,0xD6,0xF6,0x56,0xD5,0xFD,0xFF, + 0xF6,0xF6,0xB6,0xEE,0xBF,0xAE,0xFE,0xEA,0xF5,0xFE,0xD7,0xF6,0x57,0x55,0xF5,0x5D, + 0xD7,0xF6,0x33,0xEE,0x60,0xE0,0x80,0xA0,0xF2,0xDD,0x83,0x59,0x5E,0x5C,0x78,0x78, + 0x84,0x51,0x03,0x49,0xA0,0x7E,0xFE,0x7E,0x64,0x51,0x03,0x49,0x3E,0xD7,0xBB,0xBB, + 0x64,0x59,0x23,0x49,0xB8,0xBC,0xFB,0x7F,0x63,0x51,0x24,0x51,0x5E,0x7E,0xBA,0x5F, + 0x45,0x51,0x04,0x49,0x02,0xB7,0x58,0x5D,0x24,0x51,0xE3,0x40,0x08,0xAA,0x77,0x77, + 0x24,0x49,0xC2,0x40,0xA8,0xAE,0x09,0xB7,0x85,0x59,0x03,0x49,0xBB,0x07,0x2D,0xBD, + 0x06,0x6A,0x64,0x59,0xAB,0xAF,0xAF,0x2D,0xA8,0x7A,0xC5,0x61,0xB5,0xAD,0x2F,0x2B, + 0x2A,0x8B,0x88,0x72,0x2D,0x2F,0xBD,0xAD,0xAB,0x9B,0x0A,0x8B,0x2B,0xAF,0xA9,0xBD, + 0x4E,0xAC,0x6A,0x93,0x3F,0xDD,0x55,0x55,0x31,0xC5,0x6B,0x93,0x02,0xFF,0x55,0x55, + 0x31,0xC5,0x4A,0x8B,0xA0,0xFB,0xF7,0x5D,0x0F,0xC5,0x4A,0x8B,0x2A,0xAF,0xDF,0x55, + 0x34,0xE6,0x8B,0x93,0x02,0xBB,0xF5,0x55,0x75,0xEE,0x8A,0x93,0x00,0x8A,0xFF,0x55, + 0x96,0xF6,0x2C,0xA4,0x00,0x02,0xAF,0x55,0x96,0xF6,0xCF,0xBC,0x00,0x00,0xAA,0x55, + 0xB6,0xF6,0xCF,0xBC,0x00,0x22,0xFE,0x55,0xD7,0xF6,0xF0,0xC4,0x00,0x02,0x2B,0xBD, + 0xD7,0xFE,0x14,0xE6,0x00,0x00,0x82,0x55,0xB7,0xF6,0xD0,0xC4,0x00,0x80,0xA0,0x7E, + 0x15,0xE6,0xC9,0x82,0xA0,0xE8,0x7A,0x5F,0xCC,0xA3,0xE5,0x69,0x78,0x5E,0x5F,0x75, + 0x26,0x72,0xC4,0x69,0xDA,0x8A,0x08,0xEA,0x46,0x82,0x05,0x72,0x8F,0x81,0x8B,0xEB, + 0x87,0x8A,0x47,0x82,0xBD,0x03,0x29,0x75,0x88,0x8A,0x05,0x7A,0xA0,0x98,0xB8,0xF3, + 0x67,0x8A,0xE5,0x79,0xEA,0xAA,0xFE,0xF6,0x67,0x8A,0xE5,0x79,0xA7,0xAB,0x27,0x0F, + 0xA8,0x92,0x05,0x82,0xBD,0xFF,0x2A,0x2A,0x29,0x9B,0x67,0x82,0xB5,0xBF,0xAB,0x2F, + 0xD3,0xE5,0x29,0x9B,0x25,0x3D,0x2D,0x2D,0xF7,0xFE,0x55,0xEE,0x01,0x09,0x03,0x03, + 0x18,0xFF,0xF8,0xFE,0xAB,0xAD,0xFB,0xBB,0x38,0xFF,0xF8,0xF6,0xAF,0xEF,0xFF,0xAF, + 0x18,0xFF,0x38,0xF7,0xA2,0xA0,0x22,0xA8,0x38,0xFF,0x18,0xF7,0xAF,0xFF,0xBE,0xAF, + 0x38,0xFF,0x18,0xFF,0xFE,0x7A,0x7A,0x6E,0x18,0xFF,0xF7,0xF6,0x78,0x7E,0xDA,0xEA, + 0x17,0xFF,0xF7,0xF6,0xD7,0x5D,0x55,0x7D,0xF7,0xF6,0xD7,0xF6,0xA8,0x0E,0x2B,0x88, + 0xF7,0xFE,0xF7,0xF6,0xFD,0xD7,0x7D,0xDF,0xF7,0xF6,0xD7,0xF6,0x60,0xF0,0x80,0x8B, + 0xF7,0xF6,0xD7,0xF6,0xAB,0x0A,0x2F,0x26,0xD7,0xFE,0xF7,0xF6,0xDD,0xD7,0x57,0xD5, + 0x18,0xFF,0xF7,0xF6,0x95,0x2D,0x2B,0xCF,0x17,0xFF,0xB6,0xF6,0xA0,0xE0,0x7C,0x7E, + 0xD6,0xF6,0x96,0xEE,0xFA,0xFA,0xDE,0xFE,0xB6,0xF6,0x96,0xEE,0xFF,0xBF,0x3F,0x77, + 0xB6,0xF6,0x96,0xEE,0xFF,0xAF,0xA9,0x2B,0xB6,0xF6,0x35,0xE6,0xAA,0xE0,0xFA,0x78, + 0x55,0xE6,0xD3,0xDD,0x20,0xE2,0xFA,0x5A,0x35,0xE6,0x93,0xCD,0x20,0xAA,0xB7,0x37, + 0xD7,0xFE,0x55,0xE6,0xB5,0xA5,0xAD,0x2B,0xD7,0xF6,0xB7,0xF6,0x01,0x2D,0x08,0x02, + 0xF7,0xF6,0xD7,0xF6,0xDF,0xED,0x7D,0xFB,0xF7,0xF6,0xD7,0xF6,0xAF,0xE3,0xED,0x5B, + 0xF7,0xF6,0xD7,0xF6,0x6A,0xEE,0xFD,0x55,0xF7,0xF6,0xB6,0xEE,0xAA,0xFF,0xA6,0xAF, + 0xF7,0xF6,0xD7,0xF6,0x75,0x77,0x55,0xFD,0xD7,0xF6,0xB6,0xEE,0xD8,0xE8,0x80,0x80, + 0xD7,0xF6,0xB6,0xEE,0x3B,0xBB,0x7C,0xE0,0xD7,0xF6,0xB6,0xEE,0x7E,0xEF,0x2B,0x8A, + 0xF7,0xF6,0xB7,0xEE,0xAB,0xEE,0xE2,0xFA,0xD7,0xF6,0xB7,0xEE,0xA8,0x80,0x02,0x02, + 0xD7,0xF6,0xB7,0xEE,0x82,0xBA,0x3A,0xFA,0xD7,0xF6,0xB7,0xEE,0x88,0x2A,0xFA,0xEA, + 0xD7,0xF6,0xB7,0xEE,0xAE,0xAF,0xEB,0x7D,0xD7,0xF6,0xB6,0xEE,0x8A,0x23,0x0A,0x5F, + 0xF7,0xF6,0xB7,0xEE,0xEA,0xAB,0xFB,0xFF,0xD7,0xF6,0xB7,0xEE,0xAA,0xB2,0xA8,0x0A, + 0xD7,0xF6,0xD7,0xEE,0xE2,0xA8,0xAA,0xAA,0xD7,0xF6,0xF7,0xE6,0x88,0x20,0x82,0x20, + 0xD7,0xF6,0xF7,0xEE,0xAA,0xA8,0x80,0x00,0x18,0xFF,0xD7,0xF6,0xBA,0xAF,0xBF,0xFD, + 0x38,0xFF,0xF7,0xF6,0xAF,0xBD,0xB5,0xD5,0x18,0xFF,0x38,0xF7,0xAC,0xA2,0xA8,0x80, + 0x38,0xFF,0xD7,0xF6,0x5A,0x7A,0x68,0xE8,0xD7,0xF6,0x96,0xEE,0x7A,0x5A,0x5E,0x5C, + 0x96,0xEE,0x76,0xE6,0x20,0x38,0xC0,0x80,0x96,0xEE,0x76,0xE6,0xF0,0x38,0x80,0xB9, + 0x96,0xEE,0x76,0xEE,0x08,0x20,0xA8,0x5E,0xD7,0xF6,0x76,0xEE,0x2E,0xAF,0xBF,0xBD, + 0xB7,0xF6,0x13,0xDE,0x60,0x40,0x60,0x40,0xD2,0xD5,0x30,0xC5,0x17,0x37,0x37,0x37, + 0xB6,0xF6,0x14,0xDE,0x09,0x29,0x29,0x2D,0xB6,0xF6,0x76,0xEE,0xE2,0xE2,0xE8,0xA0, + 0x76,0xEE,0xD3,0xD5,0x5A,0x58,0x58,0x78,0x93,0xD5,0xD2,0xCD,0xAB,0xAA,0xAE,0xBF, + 0xB2,0xD5,0x72,0xCD,0xBE,0xAE,0xAA,0xAB,0x15,0xDE,0xB3,0xD5,0xAF,0x3D,0xA5,0xA7, + 0xB3,0xD5,0x4D,0xAC,0x58,0x78,0x78,0x78,0xCE,0xBC,0x2C,0xA4,0xBF,0xBF,0xBF,0x35, + 0x71,0xCD,0xEF,0xBC,0x09,0x2D,0xAD,0x03,0xF4,0xDD,0x72,0xCD,0x2B,0x2D,0x3F,0x2F, + 0x95,0xEE,0xF3,0xDD,0x2B,0x8F,0x2F,0x29,0x96,0xEE,0x55,0xE6,0xBE,0x7E,0x7A,0x5E, + 0x75,0xEE,0x35,0xE6,0x7C,0xF2,0xEB,0xEB,0x75,0xEE,0x34,0xE6,0xAD,0x3F,0xBF,0x56, + 0xD6,0xF6,0xB6,0xEE,0xAD,0xFA,0xFA,0xEA,0xD6,0xF6,0xB6,0xEE,0xBA,0xAB,0x9B,0x72, + 0xD6,0xF6,0xB6,0xEE,0xAA,0x2A,0xAE,0xF7,0xD7,0xF6,0xB6,0xEE,0x2A,0xA8,0x38,0x36, + 0xD7,0xF6,0xB6,0xEE,0xBE,0xB8,0x09,0x2B,0xD6,0xF6,0xB6,0xEE,0x8B,0xAA,0x22,0x00, + 0xD7,0xF6,0xF6,0xEE,0x80,0xA0,0x88,0x22,0xD6,0xF6,0xD7,0xEE,0x8A,0xAA,0xA2,0xAA, + 0xD6,0xF6,0xB6,0xEE,0x8A,0x0A,0x22,0x02,0xD6,0xF6,0xF7,0xEE,0x00,0x0A,0x28,0x82, + 0xF7,0xF6,0xB6,0xEE,0xFF,0xEB,0xEC,0xEA,0xD6,0xF6,0xB6,0xEE,0x76,0x5B,0xFE,0xFE, + 0x96,0xF6,0xB6,0xEE,0xED,0xBD,0xED,0xE5,0xB6,0xF6,0x96,0xEE,0xAA,0xBA,0x2A,0x82, + 0xB6,0xF6,0x96,0xEE,0xAE,0xF8,0xAB,0x81,0xB7,0xF6,0xB6,0xEE,0x6B,0xEA,0xEE,0xFF, + 0x95,0xF6,0xB6,0xEE,0x7D,0x57,0x55,0x55,0xD6,0xF6,0xB6,0xEE,0xB5,0xFF,0xBF,0xF7, + 0xD6,0xF6,0xF6,0xEE,0x80,0xA8,0xA0,0x80,0xF7,0xF6,0xD6,0xF6,0x75,0x7B,0x5A,0x7A, + 0xD6,0xF6,0xB6,0xEE,0xA2,0x28,0xA0,0x00,0xD6,0xF6,0xB6,0xEE,0x02,0x00,0x28,0xA0, + 0xF6,0xF6,0xD6,0xF6,0x5F,0x5F,0xB6,0xB5,0xD6,0xF6,0xD7,0xEE,0x0A,0x28,0x2A,0xA8, + 0xF7,0xFE,0xB6,0xF6,0x7E,0xEA,0xAB,0xDA,0x95,0xEE,0x26,0x62,0x78,0x60,0xE0,0xE0, + 0x84,0x51,0x03,0x41,0x7F,0x7C,0xD4,0x5C,0x65,0x51,0xE3,0x40,0x2A,0x83,0xA2,0xA9, + 0x44,0x51,0xE2,0x40,0xAE,0x26,0xF0,0x8A,0x44,0x51,0x03,0x49,0x4B,0x7A,0x4D,0xAB, + 0x24,0x49,0x03,0x49,0x49,0xF4,0xFE,0x78,0x24,0x49,0xC2,0x38,0xFA,0xDA,0xF2,0xF8, + 0x23,0x41,0xE3,0x40,0x75,0x85,0x69,0xF5,0x64,0x51,0xE2,0x40,0x0F,0x0B,0x2F,0x25, + 0x26,0x6A,0x64,0x51,0x35,0x0F,0x0F,0x29,0xC9,0x7A,0x67,0x72,0x2D,0x29,0x29,0x0D, + 0x09,0x83,0xA8,0x7A,0xAF,0xB9,0xF7,0x2F,0x6A,0x93,0xE9,0x82,0x2B,0x09,0xAD,0xBF, + 0x6B,0x93,0x09,0x8B,0x8A,0x0A,0xFB,0x7E,0x4A,0x8B,0xC9,0x82,0x20,0xB2,0xFA,0x77, + 0x4A,0x8B,0xA8,0x7A,0x88,0xFC,0x5F,0x57,0x29,0x8B,0xA8,0x7A,0x08,0xEA,0xFD,0x55, + 0x6A,0x93,0xC8,0x7A,0x0F,0xB7,0xD5,0x55,0x8B,0x93,0xE9,0x82,0x08,0xAF,0xFF,0x75, + 0xCB,0x9B,0x09,0x8B,0x20,0xAB,0xAF,0xB5,0x2C,0xAC,0x6A,0x93,0x2A,0xAF,0xBD,0x7D, + 0x2D,0xAC,0xCC,0xA3,0x02,0xFE,0xFF,0x7D,0xF0,0xC4,0x8B,0x9B,0x2B,0xBF,0xD5,0x55, + 0x10,0xCD,0xE8,0x8A,0x00,0xEA,0xFF,0x7F,0x6E,0xB4,0x46,0x7A,0x80,0xFA,0x7F,0x5F, + 0xE9,0x8A,0xE5,0x69,0xF8,0x7E,0x7F,0x7F,0x67,0x7A,0x05,0x6A,0x7F,0xA5,0xAF,0xEB, + 0x47,0x7A,0xE5,0x71,0x5A,0x78,0x5A,0x7E,0x26,0x7A,0xC5,0x71,0xB2,0x2F,0xBF,0xFD, + 0x46,0x82,0xE5,0x71,0x0A,0x0B,0xEA,0xF5,0x47,0x82,0xE5,0x79,0xF8,0xEB,0x6B,0xAB, + 0x67,0x8A,0xE5,0x79,0x9E,0xBB,0x2D,0x2A,0xC9,0x92,0x46,0x82,0xF5,0xBD,0xBA,0xA2, + 0xA8,0x92,0x46,0x82,0xDF,0x17,0x2E,0x88,0x4A,0x9B,0xC8,0x92,0xBD,0xBD,0xBD,0x35, + 0x76,0xF6,0xAB,0xAB,0x2D,0x0D,0x2B,0x09,0xF7,0xFE,0xB6,0xF6,0x03,0x03,0x00,0x00, + 0x17,0xFF,0xF7,0xF6,0xEF,0xEF,0xAA,0xAB,0x38,0xFF,0xF7,0xF6,0xEF,0xAD,0xAF,0xBF, + 0x38,0xFF,0x17,0xF7,0xFF,0xBD,0xD7,0xF5,0x37,0xFF,0x18,0xF7,0xBE,0xBF,0xFF,0xFF, + 0x38,0xFF,0x17,0xF7,0xFA,0x6E,0xFE,0xDF,0xF7,0xFE,0x18,0xF7,0xFD,0x5F,0xFF,0x7F, + 0x17,0xF7,0xF7,0xF6,0x77,0xF6,0x7E,0xF2,0x17,0xF7,0xF7,0xF6,0x55,0x77,0x56,0x57, + 0x17,0xFF,0xF7,0xF6,0xD7,0x7F,0xF7,0x55,0x18,0xFF,0xD7,0xF6,0xFB,0xAB,0xEA,0xFE, + 0x18,0xFF,0xD7,0xF6,0xFF,0xFB,0xAB,0x2A,0x18,0xFF,0xF7,0xF6,0x7D,0xAF,0x0D,0x82, + 0x18,0xFF,0x95,0xEE,0xA0,0xA8,0x78,0x56,0xD6,0xF6,0x74,0xEE,0xA0,0xAA,0xFA,0xFD, + 0xB6,0xF6,0x96,0xEE,0x22,0x8F,0x2B,0xAA,0xD6,0xF6,0x97,0xEE,0x7E,0xBA,0xAB,0xBF, + 0xD7,0xF6,0x76,0xEE,0x8E,0xEA,0xFE,0x7B,0x96,0xEE,0x34,0xE6,0xF8,0x7A,0x5E,0x7E, + 0x76,0xEE,0x92,0xD5,0x7E,0x5E,0xAF,0x02,0xF7,0xFE,0xB3,0xD5,0xB5,0x2F,0x0A,0x22, + 0xF7,0xFE,0xB7,0xF6,0xBF,0xAB,0xAA,0xAA,0xF7,0xF6,0xD7,0xF6,0xFD,0xD7,0xDD,0x5F, + 0xF7,0xF6,0xD7,0xF6,0x8F,0xAD,0xB6,0xF7,0xF7,0xF6,0xD7,0xF6,0x4E,0x7A,0x78,0xF8, + 0xF7,0xF6,0xD7,0xF6,0x75,0x57,0x5F,0xDF,0xD7,0xF6,0xB7,0xEE,0x02,0xA8,0xA2,0x80, + 0xD7,0xF6,0xB6,0xEE,0x00,0x0A,0x2B,0xEE,0xD7,0xF6,0xF7,0xEE,0x02,0x20,0xA0,0x00, + 0xF7,0xF6,0xB6,0xEE,0xFE,0xE8,0xAA,0xBA,0xD7,0xF6,0xB6,0xEE,0x08,0x02,0x00,0xAC, + 0xF7,0xF6,0xB7,0xEE,0xF2,0xFA,0xEF,0xBB,0xD7,0xF6,0xB7,0xEE,0x8A,0x0A,0xAA,0xFA, + 0xD7,0xF6,0xB7,0xEE,0xEA,0x68,0xFA,0xB2,0xD7,0xF6,0xB6,0xEE,0x77,0xFD,0x7B,0x7F, + 0xD7,0xF6,0xB6,0xEE,0x6D,0xED,0xAD,0xEA,0xD7,0xF6,0xB7,0xEE,0x7F,0xE9,0xBF,0xBE, + 0xB7,0xF6,0xD7,0xEE,0xEE,0xAB,0xFA,0xF9,0xD7,0xF6,0x97,0xEE,0x8A,0xE2,0xAA,0x08, + 0xD7,0xF6,0xB7,0xEE,0x88,0xA2,0x88,0x00,0xD7,0xF6,0xF7,0xEE,0x88,0xA0,0x88,0x02, + 0xF8,0xF6,0xD7,0xF6,0x75,0x8F,0xAF,0xAB,0x18,0xFF,0xD7,0xF6,0xE9,0xFB,0xFA,0xAB, + 0x19,0xF7,0xF8,0xF6,0xD5,0xED,0xB5,0x57,0x38,0xFF,0xF8,0xF6,0xAF,0xAB,0x9F,0x75, + 0x38,0xFF,0xF8,0xF6,0x72,0x6A,0x7A,0xFB,0xF8,0xF6,0x56,0xE6,0xFE,0xEC,0xFC,0xF8, + 0xB7,0xEE,0x76,0xEE,0xFF,0xFA,0xFE,0xFA,0x96,0xEE,0x76,0xE6,0xEF,0xAF,0xC0,0xAA, + 0x96,0xEE,0x55,0xE6,0xEA,0xAA,0xEB,0xF8,0xB7,0xF6,0x76,0xEE,0x3D,0x3D,0x25,0xB5, + 0xB7,0xF6,0x13,0xDE,0x40,0x60,0x60,0xE0,0x13,0xDE,0x0F,0xC5,0xB5,0x37,0x37,0xB7, + 0x96,0xEE,0x14,0xDE,0x0D,0x2B,0x29,0x0F,0xB7,0xF6,0x96,0xEE,0xAA,0xAA,0x2A,0xDA, + 0x76,0xEE,0xD3,0xD5,0x60,0xF8,0x60,0xE0,0xD3,0xDD,0xB3,0xD5,0x6A,0x82,0xE2,0xBF, + 0xB3,0xD5,0x92,0xCD,0xF6,0x14,0xBC,0x70,0xF3,0xDD,0x92,0xCD,0x2F,0xB7,0xAF,0xFF, + 0xB2,0xD5,0x0C,0x9C,0xF8,0x70,0x78,0x7A,0x71,0xCD,0x4D,0xAC,0xB5,0x35,0x25,0x2D, + 0x13,0xDE,0x71,0xCD,0xED,0xAF,0xAA,0xAB,0x35,0xE6,0xB3,0xD5,0xE5,0xFD,0xAB,0x2E, + 0x96,0xEE,0x14,0xE6,0x2D,0x0D,0x0B,0xA9,0x96,0xEE,0x55,0xE6,0x78,0x5E,0x7E,0x5A, + 0x55,0xE6,0x34,0xE6,0x04,0x0C,0xB2,0x79,0x55,0xE6,0x34,0xE6,0xA2,0x3F,0xB9,0x37, + 0xB6,0xF6,0xD6,0xEE,0xFF,0xAB,0xCF,0x6B,0xD6,0xF6,0xB7,0xEE,0x82,0xAA,0x82,0xE8, + 0xD6,0xF6,0xB7,0xEE,0xAA,0xEA,0x08,0x80,0xD6,0xF6,0xB6,0xEE,0x3F,0xAB,0xAA,0xA2, + 0xD6,0xF6,0xB6,0xEE,0x82,0x80,0xE0,0x70,0xD7,0xF6,0xB6,0xEE,0x82,0x07,0xAE,0xAA, + 0xD6,0xF6,0xB6,0xEE,0x02,0x09,0x2B,0xAA,0xD6,0xF6,0xB6,0xE6,0x00,0x88,0x20,0x2A, + 0xD6,0xF6,0xF8,0xEE,0x88,0x08,0xA2,0x08,0xF7,0xF6,0xB6,0xEE,0xEA,0xCE,0xBB,0x6B, + 0xD7,0xF6,0xF6,0xEE,0x08,0x20,0x20,0x2A,0xB6,0xF6,0xD7,0xEE,0xED,0xFF,0xB7,0xFD, + 0xD6,0xF6,0xB6,0xEE,0x57,0x5E,0xDE,0x5E,0x96,0xF6,0xB6,0xEE,0xDD,0xFD,0x55,0xD5, + 0xD6,0xF6,0x96,0xEE,0xAB,0x29,0xBB,0xAB,0xD6,0xF6,0xB6,0xEE,0x5F,0xFE,0xBD,0xD5, + 0xD7,0xF6,0xB6,0xEE,0xF5,0xF7,0x7E,0x5D,0xD6,0xF6,0xB6,0xEE,0xDD,0xEB,0xF9,0x5F, + 0xD6,0xF6,0xB6,0xEE,0x22,0x8A,0x2A,0x02,0xD6,0xF6,0xF6,0xEE,0xAA,0x80,0x88,0x88, + 0xF7,0xF6,0xD6,0xF6,0x77,0xDD,0x75,0xFF,0xF7,0xF6,0xB5,0xF6,0xEA,0xA8,0x2B,0xAF, + 0xF7,0xF6,0xD6,0xF6,0xF5,0x7F,0x6E,0x6A,0xF7,0xF6,0xD7,0xF6,0x5F,0xBB,0xBF,0xFD, + 0xB6,0xFE,0xF7,0xF6,0xAE,0xAD,0xBF,0xEF,0xB6,0xF6,0x8E,0xAC,0x60,0x60,0xC0,0xC0, + 0xCC,0x9B,0x02,0x41,0x57,0x56,0x5E,0x5C,0x64,0x51,0xE2,0x38,0xAF,0x39,0xAA,0xAD, + 0x64,0x51,0x23,0x49,0xAF,0xE2,0xFF,0x77,0x23,0x49,0xE2,0x40,0x28,0x88,0x68,0x62, + 0x24,0x49,0xE2,0x40,0x78,0x6E,0x7A,0xFB,0x03,0x41,0xC2,0x38,0xAF,0xA7,0xDF,0x9A, + 0x23,0x49,0xC2,0x38,0xF7,0xB7,0xBD,0x2F,0x84,0x51,0x03,0x41,0xA5,0xAF,0xA5,0x27, + 0x06,0x6A,0x84,0x51,0x0F,0xAD,0xAD,0x2D,0xA8,0x7A,0x06,0x62,0x23,0x0D,0x27,0xBD, + 0x2A,0x8B,0x87,0x72,0x2B,0x29,0x3D,0xAD,0x4A,0x93,0xE9,0x82,0x2A,0x88,0x7A,0xD2, + 0x4A,0x93,0xA8,0x7A,0xEC,0xFE,0x5F,0x5F,0xA8,0x7A,0x88,0x72,0xE0,0x52,0xC0,0x23, + 0xA8,0x7A,0x47,0x6A,0x82,0xEC,0x7A,0xE8,0xC8,0x7A,0x47,0x6A,0x8A,0xEF,0xBD,0xF7, + 0xC9,0x7A,0x67,0x72,0x3A,0xFE,0xDE,0xB7,0xE9,0x82,0x87,0x72,0x03,0xAD,0xE5,0xDF, + 0x6A,0x93,0xA8,0x7A,0x2B,0x2F,0x2D,0x2D,0x8A,0x9B,0x4A,0x93,0x2A,0xAB,0xB5,0xBF, + 0xCC,0xA3,0x6A,0x93,0x83,0x8B,0xEF,0x7D,0x6B,0x9B,0xC8,0x82,0xA8,0x68,0x78,0x7E, + 0x09,0x93,0x26,0x72,0x80,0xE8,0xFA,0x7E,0x66,0x7A,0xC4,0x69,0xA8,0xFC,0x7E,0x5F, + 0x47,0x7A,0xA3,0x61,0xAA,0xAF,0xB5,0x27,0x88,0x82,0x27,0x72,0x6D,0xEF,0xEB,0x2F, + 0x47,0x7A,0xC5,0x69,0xFA,0xFC,0x5A,0x78,0x06,0x7A,0xC5,0x71,0xA9,0xAE,0xDF,0xD5, + 0x06,0x7A,0xC5,0x71,0x9E,0xAF,0x3F,0xBE,0x47,0x8A,0xE6,0x79,0xAF,0x29,0xAD,0x2B, + 0x87,0x8A,0x26,0x82,0xAD,0xA5,0xAD,0xAB,0xC8,0x92,0x67,0x8A,0xF0,0x69,0xFC,0x5D, + 0x2A,0xA3,0x88,0x8A,0xFD,0xBD,0xAD,0x3D,0x4A,0xA3,0xC8,0x92,0x2D,0x8A,0x82,0x2A, + 0xB6,0xF6,0xAC,0xAB,0x09,0x0D,0x2D,0x2D,0xD7,0xFE,0x18,0xF7,0xAA,0xAE,0xEE,0xBC, + 0x18,0xFF,0xF7,0xF6,0xAB,0x2B,0xAB,0xA3,0x17,0xFF,0xF8,0xF6,0x2A,0x0A,0x8A,0x2A, + 0x17,0xFF,0x39,0xF7,0xA2,0x88,0xB0,0xA8,0x37,0xFF,0x18,0xF7,0xFB,0xFD,0xF7,0xFF, + 0x38,0xFF,0x17,0xF7,0x77,0x57,0xDD,0x7B,0x38,0xFF,0x17,0xF7,0x7F,0xDD,0x7F,0xFF, + 0x17,0xFF,0x38,0xF7,0x0A,0x08,0xA2,0xAE,0x17,0xFF,0xF7,0xF6,0x76,0x7F,0xAA,0xA8, + 0x17,0xFF,0xD7,0xF6,0xBF,0xBF,0xB2,0xA0,0x17,0xFF,0xF7,0xF6,0x77,0xA7,0xAE,0x08, + 0x18,0xFF,0xF7,0xF6,0xAB,0x0B,0x0A,0xA0,0x18,0xFF,0xB6,0xEE,0x60,0x78,0x58,0x5E, + 0xB6,0xEE,0x75,0xEE,0x7E,0xD7,0xBF,0x8A,0x96,0xF6,0x75,0xE6,0xB5,0xFD,0xFE,0x88, + 0xB6,0xF6,0x75,0xEE,0xAB,0xAD,0xF5,0x7F,0xB6,0xF6,0x55,0xEE,0x2A,0xAA,0xEF,0xDF, + 0x96,0xEE,0x75,0xEE,0x40,0x28,0x66,0x5D,0xB6,0xF6,0x54,0xE6,0xBF,0x2F,0xEF,0x75, + 0xD7,0xF6,0x54,0xE6,0x02,0x02,0xBA,0xD5,0xF7,0xFE,0x76,0xEE,0x02,0x22,0xAF,0xDD, + 0xF7,0xFE,0xD7,0xF6,0xAA,0xAA,0x3F,0x95,0xF7,0xF6,0xD7,0xF6,0x7A,0xE2,0x8A,0xA8, + 0xF7,0xF6,0xD7,0xF6,0x8F,0x85,0xB7,0xE7,0xF7,0xF6,0xD7,0xF6,0xFA,0xDE,0xD6,0xFE, + 0xF7,0xF6,0xD7,0xF6,0x5B,0x5A,0xFA,0x00,0xF7,0xF6,0xD7,0xF6,0x75,0x7B,0x5E,0xE4, + 0xF7,0xF6,0xB7,0xF6,0xFF,0xEF,0xAB,0x08,0xD7,0xF6,0xB7,0xEE,0x0A,0x02,0x0A,0x00, + 0xD7,0xF6,0xB6,0xEE,0xA8,0xA0,0x28,0x00,0xD7,0xF6,0xB7,0xEE,0x7C,0xBE,0xEA,0x00, + 0xD7,0xF6,0xB6,0xEE,0x28,0x3E,0x7A,0x5A,0xD7,0xF6,0xB7,0xEE,0xF8,0xAA,0xEA,0xFE, + 0xD7,0xF6,0xB7,0xEE,0xAA,0xAB,0xA5,0xEE,0xD7,0xF6,0xB7,0xEE,0xF7,0x2F,0xAE,0xAA, + 0xD7,0xF6,0xB7,0xEE,0x3A,0xBE,0xAA,0xBE,0xD7,0xF6,0xB7,0xEE,0xA3,0xA6,0xFE,0xAC, + 0xF7,0xF6,0xB7,0xF6,0xFF,0xFE,0xFF,0xCB,0xF8,0xF6,0x97,0xEE,0xAE,0x2A,0x2A,0x0A, + 0xF8,0xF6,0xB7,0xF6,0xAF,0xAE,0xBA,0x0A,0xF8,0xF6,0xD7,0xF6,0xDD,0xBD,0x2A,0x28, + 0xF8,0xF6,0xD7,0xF6,0xEA,0xAE,0xAA,0x3A,0xF8,0xF6,0xD7,0xF6,0x00,0x08,0xAA,0x22, + 0xF8,0xF6,0xD8,0xF6,0x00,0x28,0xBE,0xAA,0xD7,0xFE,0xF8,0xF6,0x55,0x77,0x5D,0x7F, + 0x18,0xFF,0xF8,0xF6,0x2A,0x2A,0x2F,0x2D,0x18,0xFF,0x76,0xE6,0x58,0x7A,0xF8,0xF8, + 0x96,0xEE,0x55,0xE6,0x80,0x2A,0xB6,0xBA,0x96,0xEE,0x76,0xE6,0xB2,0xEF,0x37,0xA3, + 0x96,0xEE,0x76,0xEE,0x5C,0xD7,0xBE,0xF6,0xB6,0xF6,0x76,0xEE,0xB5,0x3F,0xA9,0xBD, + 0xB7,0xF6,0xF3,0xDD,0xC8,0x60,0x60,0x60,0xD3,0xD5,0xF0,0xBC,0x3E,0x2F,0x37,0x3F, + 0x96,0xEE,0xF4,0xDD,0x2B,0x0D,0x0B,0x29,0xB6,0xF6,0x96,0xEE,0x7F,0xF6,0x78,0xFB, + 0x96,0xEE,0x14,0xDE,0x78,0x78,0x78,0x68,0xB3,0xD5,0x51,0xC5,0x00,0xB8,0x7C,0x7E, + 0xB3,0xD5,0x71,0xCD,0xA0,0xFA,0x75,0x55,0xB2,0xCD,0x51,0xC5,0xAA,0x8A,0xAA,0xED, + 0x72,0xCD,0x0C,0xA4,0x78,0x78,0x78,0xF8,0xB3,0xD5,0x8E,0xAC,0x2D,0x2D,0x29,0x09, + 0x14,0xDE,0xB2,0xD5,0xAD,0x2F,0xB7,0xB5,0x55,0xEE,0xF3,0xDD,0xBF,0xBF,0xAF,0x37, + 0x96,0xEE,0x34,0xE6,0x2F,0xAD,0xBF,0x2F,0x96,0xEE,0x55,0xE6,0x78,0xFA,0xA8,0x7A, + 0x55,0xE6,0x14,0xE6,0xE0,0x08,0xA8,0x80,0x55,0xE6,0x35,0xE6,0x3F,0x9E,0xDB,0x23, + 0xD6,0xF6,0xB6,0xEE,0xAF,0xEA,0xAA,0xAA,0xD7,0xF6,0xB6,0xEE,0xBA,0xE8,0xBE,0xBA, + 0xB7,0xF6,0xD6,0xEE,0xBF,0xFF,0xB7,0x1F,0xD7,0xF6,0xB6,0xEE,0xA2,0xB3,0x2A,0xBB, + 0xD7,0xF6,0xB6,0xEE,0xA2,0x0A,0x82,0x02,0xD6,0xF6,0xD7,0xEE,0xAA,0xAA,0xA2,0xAA, + 0xD6,0xF6,0xB6,0xEE,0x21,0xCB,0x0A,0xAA,0xD6,0xF6,0xB6,0xEE,0xA2,0xA8,0x2A,0x02, + 0xD7,0xF6,0xD6,0xEE,0xA2,0xAB,0x2A,0xA8,0xF7,0xF6,0xB6,0xEE,0xBF,0xAE,0xAB,0xAF, + 0xF7,0xF6,0xD7,0xF6,0xFD,0xF5,0xD7,0x5E,0xF7,0xF6,0xB6,0xEE,0xFA,0xEA,0xEE,0xEA, + 0xD6,0xF6,0xB6,0xEE,0x5E,0x5E,0x5F,0xFF,0xD6,0xF6,0x96,0xEE,0xFE,0xEF,0xAA,0xFA, + 0xD6,0xF6,0x95,0xEE,0xAF,0xB7,0xFF,0xFF,0xD6,0xF6,0xB6,0xEE,0xFD,0x5F,0xFF,0x7D, + 0xB7,0xF6,0xB6,0xEE,0xFD,0xFF,0xD7,0xFF,0xD6,0xF6,0xB6,0xEE,0xBD,0xB7,0xD5,0xB5, + 0xD6,0xF6,0xF8,0xEE,0xA0,0x88,0x20,0x08,0xD7,0xF6,0xF6,0xEE,0x02,0xA8,0x2A,0x80, + 0xF7,0xF6,0xB6,0xEE,0xBE,0xAF,0xEB,0x8A,0xF7,0xF6,0xB6,0xEE,0xB6,0xAB,0xBA,0xAB, + 0xD6,0xF6,0xF8,0xEE,0x20,0x88,0x20,0x00,0xF7,0xF6,0xD7,0xF6,0xFD,0xEF,0xF5,0x55, + 0xF7,0xF6,0xB6,0xF6,0xBA,0xFA,0xF8,0xFE,0xB7,0xF6,0x14,0xDE,0x40,0xC0,0xC0,0x00, + 0x51,0xC5,0x43,0x49,0x5E,0x5C,0x5C,0x58,0x23,0x41,0xE2,0x40,0x01,0x2D,0xDD,0xEF, + 0x43,0x49,0x03,0x41,0xB8,0x2A,0x2F,0x0D,0x64,0x51,0x23,0x41,0x5D,0xAB,0x2E,0xBB, + 0x44,0x49,0x03,0x41,0x57,0xD8,0x70,0x70,0x44,0x49,0xE2,0x38,0xF7,0xF7,0xBF,0x2E, + 0x64,0x51,0x03,0x41,0xD7,0xB7,0x0F,0x02,0xE5,0x59,0x43,0x49,0xB5,0x2F,0x05,0xAD, + 0x47,0x6A,0xA4,0x59,0xAD,0x2B,0x2B,0x0A,0x88,0x72,0x26,0x6A,0x29,0x8F,0xAF,0xC3, + 0xC8,0x7A,0x67,0x72,0x03,0xAA,0x2B,0xC9,0x09,0x83,0xA8,0x7A,0x82,0x83,0xED,0x5D, + 0xC9,0x82,0x47,0x72,0xF8,0xE2,0xEA,0x7B,0xA8,0x7A,0x47,0x6A,0x2E,0xFA,0xDF,0x9F, + 0xA8,0x7A,0x47,0x6A,0xE2,0xFA,0x5F,0x57,0x87,0x72,0x26,0x6A,0xA8,0xB6,0x0A,0x8E, + 0x67,0x72,0x26,0x6A,0x3C,0xF7,0xB0,0x20,0xC8,0x7A,0x26,0x6A,0xAA,0xA3,0xA9,0xFB, + 0x4A,0x93,0x87,0x72,0x2F,0xAF,0xE5,0x7D,0x6B,0x9B,0xC8,0x82,0x0A,0x8B,0xAF,0xFD, + 0x8B,0x9B,0x09,0x8B,0xCA,0x8B,0xEA,0xFD,0x29,0x8B,0xC8,0x82,0xD8,0xF8,0x78,0x60, + 0xC8,0x82,0xE6,0x69,0xF8,0xE8,0xF8,0x5A,0x05,0x6A,0xA4,0x61,0xF8,0xDE,0xDA,0xFA, + 0x47,0x72,0xC4,0x69,0xB5,0xBF,0xB9,0x25,0x88,0x82,0x27,0x72,0xAB,0xAA,0x2B,0xE5, + 0x47,0x7A,0x84,0x69,0xF0,0x60,0xE0,0xE8,0xC5,0x71,0x64,0x61,0x28,0x2E,0xB5,0xF5, + 0x06,0x82,0xA5,0x69,0xAF,0xBF,0xBD,0xBF,0x67,0x8A,0xE6,0x79,0xAD,0xA7,0x2F,0xAE, + 0x87,0x8A,0x46,0x82,0x4F,0xE7,0x77,0x5D,0x87,0x8A,0x26,0x82,0x28,0xBA,0xB7,0x55, + 0xE8,0x92,0x46,0x82,0x2D,0xB5,0xBF,0xFF,0x6A,0xA3,0xA8,0x8A,0x2B,0xA9,0xAD,0x25, + 0x96,0xF6,0x8A,0xA3,0x2D,0x2D,0x2D,0x2D,0xD7,0xFE,0x17,0xF7,0xF8,0xE8,0xF8,0xEA, + 0x17,0xFF,0xF7,0xF6,0xAA,0xA2,0xAA,0x0B,0x18,0xFF,0xF7,0xF6,0x8A,0x02,0x0A,0x2A, + 0x18,0xFF,0xF7,0xEE,0x8A,0x8A,0x00,0x80,0x38,0xFF,0x17,0xF7,0xB7,0xED,0xEF,0xFD, + 0x18,0xFF,0x38,0xF7,0xEE,0xAF,0xAE,0xA8,0x37,0xFF,0x18,0xF7,0xBE,0xAF,0xDB,0xBF, + 0x38,0xFF,0x18,0xFF,0xAA,0xEA,0x8A,0x8B,0x38,0xFF,0x18,0xF7,0xFF,0xAB,0xA8,0xA8, + 0x18,0xFF,0x37,0xF7,0x0A,0x2A,0x0A,0x02,0x18,0xFF,0x37,0xF7,0x08,0x20,0xB0,0x20, + 0x18,0xFF,0xB6,0xEE,0xA0,0xE8,0x78,0x7A,0xD7,0xF6,0x96,0xEE,0xD8,0x5E,0xFF,0xEE, + 0xB6,0xF6,0x96,0xEE,0xAF,0xFE,0xFE,0xA0,0xB6,0xF6,0x96,0xEE,0xEA,0xEB,0xEA,0xFB, + 0x96,0xEE,0x54,0xEE,0xE0,0xC0,0xC0,0xC0,0x54,0xE6,0x71,0xCD,0x00,0x80,0xA8,0x78, + 0x55,0xEE,0x10,0xC5,0x00,0xAA,0xFB,0x57,0x14,0xE6,0x71,0xCD,0x80,0xEA,0xFD,0x09, + 0xF3,0xDD,0x10,0xC5,0x00,0xFE,0x7E,0xA8,0x55,0xE6,0x31,0xC5,0x00,0x0F,0xBD,0xF7, + 0xD7,0xFE,0x14,0xDE,0x02,0x2B,0x2F,0xAD,0xF7,0xF6,0x96,0xF6,0x82,0x2A,0xAA,0xAB, + 0xF7,0xF6,0xD7,0xF6,0xA7,0xBD,0xED,0xA6,0xF7,0xF6,0xD7,0xF6,0xAB,0x21,0x89,0xA2, + 0x18,0xFF,0xD7,0xF6,0xBE,0xEA,0xFB,0xFB,0xD7,0xFE,0xF7,0xF6,0xFD,0x5D,0xF5,0xF7, + 0xF7,0xF6,0xD7,0xF6,0xA8,0x5E,0x55,0xFF,0xF7,0xF6,0xD7,0xF6,0x55,0xD5,0xAB,0xAA, + 0xF7,0xF6,0xD7,0xF6,0x5F,0xFB,0x7F,0xBC,0xD7,0xF6,0xF7,0xEE,0x20,0x08,0x00,0x22, + 0xD7,0xF6,0xB7,0xEE,0xB8,0xA8,0xC8,0x42,0xD7,0xF6,0xB6,0xEE,0xA4,0x22,0xBF,0xFD, + 0xD7,0xF6,0xB7,0xEE,0xEE,0x2A,0x8A,0x02,0xB6,0xF6,0xF7,0xEE,0xAA,0xAA,0xBB,0xFA, + 0xF7,0xF6,0xB6,0xEE,0xDF,0xFF,0xAF,0xAB,0xF7,0xF6,0xB7,0xEE,0xAF,0xA9,0x2F,0xA8, + 0xF7,0xF6,0xD8,0xF6,0x8F,0x8A,0xA8,0xA0,0xF8,0xF6,0xD7,0xF6,0xA2,0xF8,0xDE,0xEA, + 0xF8,0xF6,0xD7,0xF6,0xBA,0xAB,0x3E,0x8A,0x18,0xFF,0xD7,0xF6,0xAF,0xAB,0xFE,0xBF, + 0xF7,0xFE,0xF8,0xF6,0xF7,0xFD,0xD7,0x7F,0x18,0xFF,0xD7,0xF6,0xEE,0xAA,0xEE,0x7F, + 0xF7,0xF6,0xB8,0xF6,0xA2,0xAE,0xAA,0xEB,0xF8,0xF6,0xD7,0xF6,0xFF,0xDE,0x5D,0x55, + 0x18,0xFF,0xD7,0xF6,0x2B,0x3F,0xBD,0xBF,0x18,0xFF,0xB6,0xEE,0x58,0x78,0xFA,0xFA, + 0xB6,0xEE,0x76,0xE6,0x57,0x57,0xFE,0xFC,0x76,0xEE,0x96,0xE6,0x2F,0x8B,0xAA,0x28, + 0x96,0xEE,0x76,0xEE,0x9B,0xA2,0xFB,0xFD,0x96,0xEE,0x76,0xEE,0x0D,0x2B,0x2D,0x3F, + 0xB6,0xF6,0xF4,0xDD,0x60,0x60,0x68,0x62,0xD3,0xD5,0xF0,0xBC,0x37,0x3F,0x2F,0x2E, + 0x96,0xF6,0x14,0xE6,0x2D,0xAD,0xAD,0x25,0xB6,0xF6,0x76,0xEE,0xEA,0xFB,0xFF,0xFF, + 0x96,0xEE,0x14,0xE6,0x60,0x70,0xEA,0xE8,0xF4,0xDD,0x31,0xC5,0x7E,0x7A,0x7C,0xF8, + 0x71,0xCD,0x51,0xC5,0x2E,0xB9,0xE7,0xCE,0x71,0xCD,0x51,0xC5,0x20,0x2E,0x25,0x3D, + 0x72,0xCD,0xCF,0xB4,0x5C,0x5C,0x7C,0xA8,0xB3,0xD5,0x10,0xC5,0x0D,0x0B,0x03,0x0A, + 0x14,0xDE,0xB3,0xD5,0xBD,0x3F,0x2F,0x23,0x55,0xE6,0xF4,0xDD,0x2D,0x35,0xB7,0xB7, + 0x76,0xEE,0x55,0xE6,0x23,0x82,0x0B,0x0D,0x96,0xEE,0x35,0xE6,0xA8,0xC8,0xA8,0xAA, + 0x75,0xEE,0x35,0xE6,0xFF,0xF8,0xFA,0xEA,0x35,0xEE,0x55,0xE6,0x77,0x6D,0x7F,0x5F, + 0xD6,0xF6,0xB6,0xEE,0xAA,0xAA,0x8A,0x02,0xD7,0xF6,0xB5,0xEE,0x22,0x22,0x28,0x20, + 0xD7,0xF6,0xB6,0xEE,0x6E,0xC8,0xF8,0xC8,0xD6,0xF6,0xB6,0xEE,0xB9,0x23,0x02,0x02, + 0xD6,0xF6,0xB7,0xE6,0x08,0x8A,0x08,0xA2,0xF7,0xF6,0xB6,0xEE,0xDB,0x5A,0xFF,0xBF, + 0xD7,0xF6,0xB6,0xEE,0x1B,0x29,0x2C,0x00,0xD7,0xF6,0xD6,0xEE,0xAA,0x22,0xAA,0xAA, + 0xD7,0xF6,0xF7,0xEE,0x28,0x08,0x20,0xAA,0xF6,0xF6,0xB7,0xEE,0xA7,0xBE,0xAB,0xAB, + 0xD6,0xF6,0xF7,0xEE,0x2A,0x2A,0x20,0x82,0xD6,0xF6,0xF8,0xEE,0x08,0x80,0x28,0xA8, + 0xD6,0xF6,0xB6,0xEE,0xEE,0x68,0xF8,0x6C,0xD6,0xF6,0x96,0xEE,0xBB,0xEF,0xAF,0x0F, + 0xD6,0xF6,0x96,0xEE,0xFF,0xFE,0xF2,0xC2,0xD6,0xF6,0xB6,0xEE,0xFD,0xF7,0xBD,0xBB, + 0xD7,0xF6,0xB6,0xEE,0x7D,0xFF,0xAD,0xEE,0xD6,0xF6,0xB6,0xEE,0xB5,0xBD,0xBB,0xB6, + 0xF7,0xF6,0xD7,0xF6,0xDF,0xFD,0xDD,0xFD,0xF7,0xF6,0xD7,0xF6,0xDD,0xBF,0x3A,0x8D, + 0xF7,0xF6,0xD7,0xF6,0xEA,0xF8,0xDA,0xFE,0xF6,0xF6,0xD7,0xF6,0xB5,0xFB,0xFF,0xED, + 0xF7,0xF6,0xD7,0xF6,0x79,0x6B,0xFB,0x9B,0xD7,0xF6,0xF7,0xEE,0x00,0x80,0x0E,0x02, + 0xF7,0xF6,0x96,0xEE,0xAA,0x2A,0x8A,0xA2,0xF7,0xFE,0x76,0xEE,0x6A,0xE0,0xEA,0xEA, + 0xF4,0xDD,0x42,0x41,0x58,0x78,0x78,0x78,0x03,0x39,0xC1,0x38,0xAA,0x1D,0x24,0xBA, + 0x64,0x49,0x02,0x41,0x3F,0xAB,0x2F,0x65,0x84,0x51,0x23,0x49,0xE2,0xA2,0xA9,0xF5, + 0x64,0x49,0xE2,0x40,0xF8,0x5A,0xFB,0x7E,0x43,0x49,0x03,0x41,0xFF,0xBB,0x2D,0x29, + 0xC5,0x59,0x44,0x49,0x35,0x2D,0x09,0x0A,0x27,0x6A,0x84,0x51,0xAD,0xAF,0x2A,0x3B, + 0x27,0x6A,0xA4,0x59,0x08,0x88,0xA8,0x7E,0x67,0x72,0x85,0x59,0x20,0x2A,0xAD,0xAD, + 0xA8,0x7A,0x46,0x6A,0x83,0xAA,0xA5,0xF5,0xA8,0x7A,0x47,0x6A,0x82,0x8A,0xEF,0x7F, + 0x88,0x72,0x47,0x72,0xB0,0xBA,0xCD,0xB5,0x88,0x72,0x06,0x6A,0xA0,0xAF,0x97,0xAB, + 0x67,0x72,0x26,0x6A,0xA6,0x02,0x2B,0xEF,0x67,0x72,0x26,0x6A,0x80,0xF0,0x68,0xD8, + 0x67,0x72,0x06,0x62,0xB0,0xBF,0xFD,0xFF,0xA7,0x7A,0xE5,0x61,0x0A,0xAD,0xAB,0xFF, + 0xC8,0x7A,0x67,0x72,0xAB,0xAE,0xAB,0x0D,0xE9,0x82,0x87,0x7A,0x0B,0xBF,0xEF,0xF7, + 0x2A,0x8B,0x88,0x7A,0x0A,0xBE,0xFF,0xD5,0xE9,0x8A,0x46,0x72,0xA0,0xE0,0x7A,0x5E, + 0x67,0x7A,0xA4,0x61,0xE0,0xF8,0x7E,0x5F,0xE5,0x69,0x83,0x59,0xBC,0xE7,0xCF,0x2E, + 0x26,0x72,0xC5,0x69,0xAD,0x3D,0x3D,0x2A,0x68,0x7A,0xE6,0x69,0xEA,0xF8,0x6A,0x7E, + 0x06,0x72,0x64,0x61,0xE0,0x72,0x72,0x5A,0x84,0x69,0x22,0x59,0x2A,0x27,0x37,0xBF, + 0x06,0x7A,0x63,0x61,0x0B,0x2F,0xAD,0xBF,0x47,0x82,0x06,0x7A,0xAF,0xA6,0xF5,0x75, + 0x67,0x8A,0x06,0x82,0xC0,0xCA,0x69,0xCB,0x47,0x82,0x26,0x82,0xB2,0xDD,0x95,0x55, + 0xE9,0x92,0x47,0x82,0xAD,0xAB,0x2D,0x2F,0x29,0x9B,0xA8,0x8A,0x27,0xB7,0xFB,0xFF, + 0xB6,0xF6,0x6B,0xA3,0x2D,0x2D,0x2D,0x2D,0x17,0xFF,0xD7,0xFE,0xAD,0xBD,0xAD,0xBF, + 0xF7,0xFE,0x18,0xF7,0xBE,0xFA,0xFE,0xFE,0x18,0xFF,0xF7,0xF6,0xAF,0x89,0xAB,0xAB, + 0x17,0xFF,0xF7,0xF6,0x82,0x8A,0x2A,0xB6,0x18,0xFF,0x17,0xF7,0xEA,0xAA,0xA2,0xAA, + 0x38,0xFF,0xF7,0xF6,0xAE,0xBA,0x2F,0xBF,0x38,0xFF,0x17,0xF7,0xFF,0xAE,0xAA,0xFF, + 0x38,0xFF,0x18,0xFF,0x2A,0xAA,0xBB,0xEB,0x38,0xFF,0x18,0xFF,0xA2,0xAA,0xFA,0xD5, + 0x18,0xFF,0x38,0xF7,0x08,0x02,0xC0,0xAA,0x38,0xFF,0xD7,0xF6,0x6A,0xEA,0x78,0x57, + 0xD7,0xF6,0xB6,0xEE,0xE0,0xA8,0xA8,0xAA,0xD7,0xF6,0xB6,0xEE,0xAF,0x0A,0x08,0x02, + 0xD7,0xF6,0xB6,0xF6,0xAB,0xEA,0xEA,0x5C,0xB6,0xF6,0x75,0xEE,0xA2,0xA0,0xA8,0xD8, + 0x96,0xEE,0x55,0xEE,0xE0,0xE0,0xF8,0xF7,0xB6,0xF6,0x30,0xCD,0x7A,0x7E,0xEA,0x00, + 0x75,0xEE,0xAE,0xBC,0xD7,0xB7,0x2A,0x00,0x76,0xEE,0xD3,0xDD,0x2D,0x0B,0x00,0x08, + 0x75,0xEE,0xB2,0xD5,0x58,0xE2,0xA0,0x00,0x14,0xE6,0x71,0xCD,0xF5,0xDF,0xF6,0xF8, + 0x76,0xEE,0xD3,0xD5,0x0B,0x2D,0xB5,0xB5,0xF7,0xF6,0x55,0xE6,0x2A,0x8B,0x2B,0xBD, + 0xF7,0xF6,0xD7,0xF6,0x8A,0xAB,0xEF,0x95,0xF8,0xF6,0xD7,0xF6,0xAA,0x9D,0x3E,0xFA, + 0xD8,0xFE,0xF7,0xF6,0xDD,0x5D,0x75,0xFD,0xF7,0xF6,0xD7,0xF6,0xAA,0x88,0x80,0xFC, + 0xF7,0xF6,0xD7,0xF6,0xEC,0xB2,0xD0,0x5D,0xF7,0xF6,0xD7,0xF6,0x88,0x82,0xFD,0x55, + 0xF7,0xF6,0xB7,0xF6,0xA0,0xFA,0xD7,0xDB,0xF7,0xF6,0xB7,0xF6,0x7A,0x7F,0xDF,0xBF, + 0xF7,0xF6,0xB6,0xEE,0x5F,0x55,0x95,0xAA,0xF7,0xF6,0xB6,0xEE,0xF5,0xFB,0xAA,0x2A, + 0xF7,0xF6,0xD7,0xF6,0x5D,0xF5,0xAA,0xA0,0x18,0xFF,0xD7,0xF6,0x75,0xBF,0xEB,0xEB, + 0xF7,0xF6,0xD7,0xF6,0xAD,0x02,0x00,0x80,0xF8,0xFE,0xF7,0xF6,0xFF,0xFF,0x5D,0x55, + 0xF8,0xF6,0xD8,0xF6,0x00,0x20,0xF8,0xAE,0xF8,0xF6,0xD7,0xF6,0x80,0xEE,0xFC,0x8A, + 0xF8,0xF6,0xD8,0xF6,0x00,0x86,0xAE,0xFE,0xF7,0xF6,0xD8,0xF6,0x2E,0xAF,0xFF,0x5A, + 0xF8,0xF6,0xD7,0xF6,0xE0,0x80,0xCA,0xAD,0xF8,0xF6,0xD7,0xF6,0x7F,0xFF,0xFD,0xA9, + 0xF8,0xF6,0xD7,0xF6,0x59,0x7F,0x6E,0x5A,0xD7,0xF6,0xD8,0xEE,0xAA,0xA2,0xAA,0x2A, + 0xF7,0xF6,0xB7,0xEE,0x0A,0x3B,0x2F,0xBF,0x18,0xFF,0xB7,0xEE,0xFA,0xFA,0x62,0xFA, + 0xB7,0xEE,0x75,0xEE,0xFA,0xD8,0x78,0xFC,0x76,0xEE,0x96,0xE6,0x08,0x02,0x8A,0x0F, + 0x96,0xEE,0x55,0xEE,0x8A,0xEE,0xFF,0xDF,0xB7,0xEE,0x56,0xEE,0xEB,0xAF,0x2D,0xAF, + 0x96,0xEE,0xF4,0xDD,0x60,0x60,0xE0,0xC0,0xD3,0xDD,0x10,0xBD,0x3D,0xA5,0x26,0x27, + 0x96,0xEE,0xF4,0xDD,0x2B,0x2D,0xAD,0x2F,0xB7,0xF6,0x76,0xEE,0xFE,0xEA,0xFA,0x7A, + 0x96,0xEE,0x35,0xE6,0xF2,0xEA,0xFC,0x7A,0x14,0xDE,0x72,0xCD,0x5C,0x5C,0x58,0x78, + 0x92,0xCD,0x51,0xCD,0xFF,0x3E,0xEF,0x55,0x92,0xD5,0x31,0xC5,0xE3,0xFA,0xDE,0x5F, + 0xB2,0xD5,0x10,0xC5,0xFB,0xAF,0xAF,0x25,0xF3,0xDD,0x92,0xCD,0xB5,0xAD,0x2F,0x2B, + 0x14,0xDE,0xD3,0xDD,0x0F,0xAF,0xAB,0xC2,0x55,0xE6,0xF4,0xDD,0xBD,0xB7,0x37,0x97, + 0x96,0xEE,0x55,0xE6,0x2D,0x2D,0x8B,0xAD,0x96,0xEE,0x76,0xEE,0x7C,0x6B,0xFB,0xFF, + 0x75,0xEE,0x55,0xE6,0x58,0xBA,0xE8,0xFA,0x96,0xEE,0x34,0xE6,0xFD,0xAF,0x3F,0xAB, + 0xF7,0xF6,0xB6,0xEE,0xAB,0xEB,0xEB,0xFE,0xF7,0xF6,0xB6,0xEE,0xFA,0xFE,0xFF,0xF7, + 0xD7,0xF6,0xD6,0xEE,0xAA,0x22,0xAA,0xAA,0xD7,0xF6,0xF6,0xEE,0x00,0x22,0xA8,0x2A, + 0xF7,0xF6,0xB6,0xEE,0xEF,0xFE,0xAA,0xCA,0xD7,0xF6,0xB6,0xEE,0x8A,0x2A,0x08,0x83, + 0xD7,0xF6,0xF6,0xEE,0x08,0x82,0x08,0x38,0xD7,0xF6,0xF7,0xEE,0x80,0x08,0x22,0x82, + 0xD7,0xF6,0xF6,0xEE,0xE8,0xA0,0x20,0x08,0xD7,0xF6,0xF7,0xEE,0x88,0x22,0x20,0xA2, + 0xF7,0xF6,0xD7,0xF6,0xB7,0xFD,0xFF,0x7F,0xF6,0xF6,0xD7,0xF6,0xEF,0xFD,0xD7,0x57, + 0xD7,0xF6,0xB5,0xEE,0xE0,0xA0,0xA8,0xE8,0xD7,0xF6,0xB6,0xEE,0xAA,0x6A,0xEA,0xEE, + 0xD6,0xF6,0xB6,0xEE,0xEB,0xB5,0x9F,0xB2,0xD7,0xF6,0xB6,0xEE,0x55,0xF7,0x76,0xDF, + 0xD6,0xF6,0xB6,0xEE,0xFE,0x57,0xFE,0xA3,0xD6,0xF6,0xB6,0xEE,0x3F,0xAB,0x29,0xAD, + 0xF7,0xF6,0xB6,0xEE,0xAA,0xAA,0xAF,0xEB,0xF7,0xF6,0xD7,0xF6,0x89,0x97,0x5D,0x5D, + 0xF7,0xF6,0xD7,0xF6,0xFF,0x6F,0x6C,0x7D,0xF7,0xF6,0xD7,0xF6,0xF5,0x5F,0x75,0xBD, + 0xF7,0xF6,0xD7,0xF6,0x3E,0xBA,0xAB,0xBB,0xF7,0xF6,0xD7,0xF6,0xFA,0xA2,0x4C,0xEA, + 0xF7,0xF6,0xD7,0xF6,0x5E,0xFA,0x5E,0x6A,0xF7,0xF6,0xB6,0xEE,0xCA,0xEA,0xEA,0x7A, + 0x34,0xDE,0xE5,0x59,0x78,0x70,0x60,0x60,0x43,0x41,0xC2,0x38,0x5E,0xFE,0x7C,0x7A, + 0x23,0x49,0x81,0x30,0x0A,0x2B,0xAD,0xAF,0x64,0x51,0x03,0x41,0xAF,0x8F,0xA5,0x3D, + 0x85,0x51,0x02,0x41,0x5F,0xFA,0xAE,0x02,0xC5,0x61,0x43,0x49,0xF5,0xB9,0xAA,0x0A, + 0x06,0x62,0x84,0x59,0xE5,0xBF,0x2F,0x02,0xE6,0x61,0xA5,0x59,0xA2,0xE0,0xE0,0xBC, + 0xC5,0x59,0x64,0x59,0x80,0x88,0xAA,0x3A,0xE6,0x61,0xA5,0x59,0x0E,0xBD,0x79,0x5A, + 0x26,0x6A,0xA5,0x59,0x02,0xAA,0xE9,0xA7,0x47,0x72,0xE6,0x61,0x03,0xA2,0xAA,0xED, + 0x47,0x6A,0x06,0x62,0xEA,0xFF,0xFB,0xFF,0x68,0x72,0xE5,0x61,0x0A,0x2B,0xAB,0xB5, + 0x88,0x72,0x05,0x62,0xE2,0xF0,0x7A,0xDF,0x47,0x6A,0x06,0x62,0xF0,0x70,0xDD,0x57, + 0x26,0x6A,0x05,0x62,0xAC,0xBA,0x57,0x7D,0x67,0x72,0xE5,0x61,0xBA,0x2E,0xED,0xF7, + 0xC9,0x7A,0x26,0x6A,0x2D,0xAF,0xBB,0xF5,0xE9,0x82,0x47,0x72,0x8E,0xAE,0x77,0x55, + 0x88,0x7A,0xE6,0x61,0x00,0xA8,0xEE,0x5F,0x47,0x72,0xA4,0x59,0xE8,0xEA,0x7A,0x7F, + 0x05,0x6A,0x83,0x59,0x7F,0xF7,0xBF,0x2F,0x47,0x7A,0xA4,0x61,0xB5,0xBF,0x2A,0x02, + 0x68,0x7A,0x26,0x72,0x7D,0x7F,0x7B,0x70,0x26,0x72,0xC5,0x69,0x78,0x78,0x78,0x70, + 0xC5,0x69,0xE3,0x50,0xE8,0xFC,0x7E,0xDE,0x44,0x59,0x03,0x59,0x22,0x03,0x9A,0xAF, + 0xA5,0x69,0x44,0x61,0x0A,0x2B,0x2F,0xFD,0x06,0x7A,0xA5,0x69,0x02,0xAB,0x1F,0xB9, + 0x87,0x8A,0x27,0x82,0x7D,0xF5,0xF5,0x27,0x87,0x8A,0x26,0x7A,0x5D,0xDB,0xF3,0xFE, + 0xC8,0x8A,0x47,0x82,0xBD,0xBF,0xAD,0x29,0x29,0x93,0x87,0x82,0x9F,0x75,0x37,0x37, + 0x96,0xF6,0xEC,0xAB,0x2D,0x2D,0x29,0x09,0xF7,0xFE,0xD7,0xF6,0x0A,0x08,0x02,0x03, + 0xF7,0xFE,0x17,0xF7,0xEE,0xEA,0xEE,0xE8,0xF7,0xFE,0x18,0xF7,0xEF,0xAE,0xFF,0xBB, + 0x17,0xFF,0xF7,0xF6,0x9E,0xB5,0xBD,0xAB,0xF7,0xFE,0x18,0xF7,0x9B,0x5B,0xBF,0xBF, + 0x17,0xFF,0xF7,0xF6,0x2B,0xAE,0xAE,0xEB,0x17,0xFF,0xF7,0xF6,0xA0,0xBF,0xB7,0xDF, + 0x17,0xFF,0xF8,0xF6,0x00,0xAA,0xEF,0xAF,0x18,0xFF,0xF7,0xF6,0x22,0x0A,0x02,0x0A, + 0x38,0xFF,0xD7,0xF6,0xA8,0xF2,0x7A,0x7E,0xF7,0xF6,0xB6,0xEE,0xF0,0xF8,0xFA,0xFF, + 0xD7,0xF6,0xB6,0xEE,0x29,0xAB,0xFA,0xFE,0xB6,0xF6,0xD7,0xEE,0xFE,0xBE,0xAE,0xEF, + 0xD6,0xF6,0x96,0xEE,0x7A,0xFE,0x7F,0x5E,0x96,0xEE,0x92,0xD5,0xA0,0xA8,0xEA,0x5A, + 0xD7,0xF6,0x71,0xCD,0x2A,0xAB,0x0F,0x2D,0x18,0xFF,0xD7,0xFE,0xBD,0xAF,0x2E,0xAA, + 0x18,0xFF,0x96,0xF6,0x5E,0x7A,0xE8,0xA2,0xD7,0xF6,0x75,0xEE,0x55,0x5E,0x5F,0x5C, + 0x75,0xEE,0x55,0xEE,0x98,0x38,0xB8,0x78,0x55,0xEE,0xB2,0xD5,0xFC,0x70,0xE0,0x80, + 0x34,0xE6,0xB2,0xD5,0x2B,0x3D,0x35,0xAF,0xB6,0xF6,0x14,0xDE,0x2F,0x2F,0xBD,0xED, + 0xF7,0xF6,0x96,0xF6,0x2A,0x2B,0x2F,0x2D,0xF7,0xF6,0xD7,0xF6,0x7E,0xAF,0xEB,0x6B, + 0xF7,0xF6,0xD7,0xF6,0xAD,0xFE,0xE8,0xA3,0xF7,0xF6,0xD7,0xF6,0xFE,0x5B,0x6B,0xEA, + 0xF7,0xF6,0xD7,0xF6,0x75,0xFF,0xA9,0x0F,0xF7,0xF6,0xD7,0xF6,0x75,0xFB,0xFE,0xD7, + 0xF7,0xF6,0xD7,0xF6,0x55,0xF5,0xBD,0xCF,0xF8,0xF6,0xD7,0xF6,0xD5,0x2D,0x01,0x0A, + 0xF7,0xF6,0xD7,0xF6,0x5C,0x76,0x54,0x5C,0xF7,0xF6,0xD7,0xF6,0x95,0x57,0xB5,0xA5, + 0xF7,0xF6,0xD7,0xF6,0xB8,0xAE,0xE6,0xE2,0xF7,0xF6,0xB7,0xF6,0x00,0x2C,0x2E,0x82, + 0xD7,0xF6,0xF7,0xEE,0xAB,0x8B,0xAA,0xAC,0xF7,0xF6,0xD7,0xF6,0xAA,0x2B,0x8E,0xFA, + 0xF7,0xF6,0xD7,0xF6,0x08,0x22,0x02,0xBA,0xF7,0xF6,0xD8,0xF6,0xAA,0xB8,0xA8,0x88, + 0xF7,0xF6,0xD7,0xF6,0xFE,0xBA,0xA2,0x20,0xF7,0xF6,0xD7,0xF6,0x78,0xAA,0x80,0x20, + 0xF7,0xF6,0xD8,0xF6,0x8A,0x8A,0x00,0x80,0xD8,0xFE,0xF8,0xF6,0xD5,0x55,0x7D,0xF5, + 0xF7,0xF6,0xD7,0xF6,0xE4,0x6A,0x60,0x7A,0xD7,0xF6,0xB7,0xEE,0x8A,0xBA,0xDF,0xD6, + 0xB7,0xF6,0x18,0xEF,0xA8,0xA8,0xAA,0xA8,0xF8,0xF6,0xB7,0xF6,0xE2,0xC0,0xC0,0xC2, + 0xB6,0xEE,0x76,0xEE,0x7C,0x5E,0x7E,0x5E,0xB6,0xEE,0x56,0xE6,0xEB,0x7B,0xEB,0x2F, + 0x96,0xEE,0x55,0xEE,0xDF,0xBA,0x08,0x00,0x96,0xF6,0x76,0xEE,0x2D,0xAB,0xE8,0xA2, + 0xB7,0xF6,0x14,0xDE,0x60,0x6A,0x6A,0x72,0xF4,0xDD,0x51,0xC5,0x17,0xB7,0x37,0xB7, + 0x97,0xEE,0x14,0xDE,0xBD,0xAD,0x25,0x2D,0x96,0xEE,0x55,0xEE,0xA0,0xE8,0xE0,0xFA, + 0x75,0xEE,0x35,0xE6,0xF8,0xBA,0xE8,0xAE,0x35,0xE6,0x72,0xCD,0x7C,0x58,0x58,0x58, + 0x72,0xCD,0x31,0xC5,0xBE,0x5E,0x58,0xD7,0x52,0xCD,0xD0,0xBC,0xE0,0xFB,0x7E,0x7A, + 0xB2,0xD5,0xCF,0xBC,0x2B,0xAF,0x25,0x2D,0x34,0xE6,0xD2,0xD5,0xFD,0xB5,0xBD,0x2D, + 0x14,0xE6,0x34,0xDE,0xA8,0xBF,0xAF,0xAF,0x55,0xE6,0xF3,0xDD,0xBD,0xBE,0xBF,0xAF, + 0x96,0xEE,0x55,0xE6,0xBD,0xED,0x0D,0xAF,0x96,0xEE,0x76,0xEE,0x79,0x39,0xAF,0x8B, + 0x75,0xEE,0x55,0xE6,0xF8,0xE8,0x82,0xA0,0x96,0xEE,0x55,0xE6,0xAF,0xAF,0xB7,0xBF, + 0xD6,0xF6,0xB7,0xEE,0xB0,0x82,0xA8,0x2A,0xD7,0xF6,0xB6,0xEE,0xFA,0xEE,0xAA,0xA2, + 0xD6,0xF6,0xB7,0xEE,0x8B,0x2E,0x8A,0xA8,0xD6,0xF6,0xB7,0xEE,0x80,0xF0,0x82,0x28, + 0xD7,0xF6,0xB6,0xEE,0x2B,0xAA,0xAA,0xAC,0xD7,0xF6,0xB6,0xEE,0x02,0x02,0x00,0x8E, + 0xD7,0xF6,0xF6,0xEE,0xA8,0x28,0x00,0x20,0xF7,0xF6,0xD7,0xF6,0x5F,0xFF,0xFF,0xF5, + 0xD7,0xF6,0xF7,0xEE,0x22,0x00,0x82,0xA8,0xF7,0xF6,0xD7,0xF6,0xF5,0xBB,0xBE,0xAD, + 0xF7,0xF6,0xD7,0xF6,0xFF,0xFF,0x2F,0xAD,0xF7,0xF6,0xD7,0xF6,0xBA,0xA9,0xAB,0xE8, + 0xD7,0xF6,0xF6,0xEE,0x2A,0x02,0x08,0x2A,0xD6,0xF6,0xB7,0xEE,0x2A,0x2A,0xAC,0xAE, + 0xD6,0xF6,0xB7,0xEE,0xA2,0x2A,0xAA,0x2A,0xD7,0xF6,0xB6,0xEE,0xBF,0xBE,0x88,0x80, + 0xB6,0xF6,0xD6,0xEE,0xEF,0xAB,0xBB,0xED,0xB6,0xF6,0xD7,0xEE,0x8B,0xAB,0xFE,0xEF, + 0xF6,0xF6,0xD7,0xF6,0x75,0xF5,0xED,0xAD,0xF7,0xF6,0xD7,0xF6,0xDD,0xF7,0xDD,0x57, + 0xF7,0xF6,0xD7,0xF6,0x5F,0xE9,0xE3,0x7D,0xF7,0xF6,0xD7,0xF6,0xAD,0xBA,0xEB,0x6E, + 0xF7,0xF6,0xD7,0xF6,0xFA,0xAF,0xEA,0x0C,0xF7,0xF6,0xD7,0xF6,0xAF,0xA8,0xEE,0xEA, + 0xF7,0xF6,0xD7,0xF6,0x6A,0x5E,0x5D,0x9D,0xF7,0xF6,0xB6,0xEE,0x7A,0xEA,0xAB,0xAA, + 0x75,0xEE,0x09,0x7B,0x70,0x70,0x60,0xE0,0xE4,0x59,0xC2,0x38,0x5E,0x5E,0x7A,0xF8, + 0x64,0x51,0xC2,0x38,0xDD,0xA5,0xBF,0x2A,0xE5,0x61,0xE2,0x40,0xBD,0xBD,0x2B,0x2E, + 0x06,0x6A,0x84,0x51,0xF5,0xBF,0xAA,0x80,0x26,0x6A,0xC5,0x59,0x9D,0x09,0xAB,0x80, + 0x27,0x72,0x05,0x62,0xE9,0x8A,0x89,0xCA,0x26,0x6A,0xC6,0x61,0x64,0xC8,0xE8,0xA2, + 0x06,0x62,0xA4,0x59,0x5B,0x7E,0xBE,0xE8,0xE5,0x61,0xA5,0x59,0xBF,0xFA,0xAF,0x8A, + 0x27,0x6A,0xE6,0x61,0xE1,0x3F,0x09,0x09,0x47,0x6A,0x06,0x62,0x97,0xD7,0xE2,0x00, + 0x47,0x6A,0xE5,0x61,0xF7,0x5F,0x7C,0xF8,0x26,0x6A,0xC4,0x59,0x2F,0xCF,0xFF,0x96, + 0x06,0x6A,0xC5,0x59,0xBC,0xFE,0xBB,0xFA,0x05,0x6A,0xC5,0x59,0x2A,0xE9,0xFA,0xFA, + 0x26,0x6A,0xC5,0x59,0xA2,0xFD,0xF7,0x5D,0x47,0x6A,0xE5,0x61,0x4B,0xAD,0xF5,0x5D, + 0x47,0x6A,0xA4,0x59,0x0E,0xFA,0xEE,0x9E,0x26,0x6A,0xC4,0x59,0x88,0xC2,0x7B,0x57, + 0x06,0x6A,0xA4,0x59,0xE8,0xAE,0xF6,0xFF,0xE5,0x69,0x83,0x59,0xDE,0xBA,0xBE,0x0E, + 0x67,0x7A,0xC4,0x61,0xB5,0xAD,0x2D,0x0B,0xC8,0x8A,0x47,0x7A,0x5F,0xF7,0xAD,0x8A, + 0xA8,0x82,0x47,0x7A,0x7B,0x7F,0xE8,0x80,0x68,0x7A,0x64,0x61,0xFA,0x7A,0x78,0xF8, + 0x65,0x61,0xE2,0x50,0xB4,0xF6,0xFE,0xAC,0x85,0x61,0x23,0x59,0x55,0xE5,0xFD,0x8B, + 0xA4,0x69,0x43,0x59,0xB5,0x15,0xBF,0x3B,0x67,0x82,0xC5,0x71,0xBD,0xA9,0x29,0x09, + 0xA8,0x8A,0x47,0x82,0xFD,0x2D,0x8F,0x22,0xC8,0x8A,0x67,0x82,0x77,0xFA,0xAB,0xEA, + 0xA8,0x8A,0x26,0x7A,0x0A,0x80,0xAA,0x7E,0x2D,0xAC,0x26,0x72,0xBF,0xB7,0xB5,0x25, + 0xD7,0xFE,0xAF,0xBC,0x2D,0x29,0x09,0x0B,0x17,0xFF,0xD8,0xF6,0xEB,0x8B,0xAA,0x02, + 0x18,0xFF,0xF7,0xF6,0xFF,0xCF,0xA3,0x82,0x17,0xFF,0xF7,0xF6,0xFE,0xF7,0xBD,0xBF, + 0x18,0xFF,0xF7,0xF6,0x8B,0x2A,0xAA,0x2A,0xF7,0xFE,0x18,0xF7,0xE5,0xFF,0xEF,0xFF, + 0x17,0xFF,0xF7,0xF6,0xEB,0xFE,0x7E,0x5E,0xF7,0xFE,0xF7,0xF6,0x5F,0xFF,0xFD,0xDF, + 0x17,0xFF,0xD7,0xF6,0xAF,0x0B,0x2B,0x0B,0x18,0xFF,0xD7,0xF6,0x00,0x80,0x68,0x58, + 0xF7,0xF6,0xB6,0xEE,0xB8,0x5E,0x57,0x77,0xB6,0xF6,0xD7,0xEE,0xAA,0xEB,0xEB,0xFA, + 0x18,0xFF,0xB6,0xEE,0xF7,0xF7,0xFF,0x2B,0x38,0xFF,0xB6,0xEE,0x77,0xFD,0xBF,0x02, + 0x18,0xFF,0x96,0xEE,0x57,0xFF,0xAA,0x00,0xD7,0xF6,0xB2,0xD5,0x7E,0xF8,0xE0,0xA8, + 0xD7,0xF6,0xB2,0xD5,0x0D,0x2B,0x0A,0x0B,0xF8,0xFE,0x18,0xF7,0x88,0x20,0x28,0xAA, + 0x17,0xFF,0xD8,0xF6,0xAB,0xA5,0xFB,0x2A,0x18,0xFF,0x76,0xEE,0x5E,0x7C,0x7A,0x78, + 0x75,0xEE,0x55,0xE6,0x5E,0xF8,0xE8,0xB8,0x75,0xEE,0x34,0xEE,0xEA,0xEA,0xEA,0xAA, + 0x35,0xE6,0xD2,0xD5,0xB6,0xBE,0xE0,0xA0,0x75,0xEE,0x14,0xDE,0x29,0xAF,0xAF,0x95, + 0xF8,0xFE,0x55,0xE6,0x2B,0x2F,0xA9,0xAD,0xF7,0xF6,0xD7,0xF6,0x89,0xBE,0xBF,0xAB, + 0xF7,0xF6,0xD7,0xF6,0xEA,0xE2,0xE2,0x0A,0xF7,0xF6,0xD7,0xF6,0x6E,0xDD,0x7F,0x80, + 0xF7,0xF6,0xD7,0xF6,0xAD,0xA5,0xA9,0x05,0xF7,0xF6,0xD7,0xF6,0xB7,0xAF,0x6D,0xD7, + 0xF7,0xF6,0xD7,0xF6,0xAA,0x57,0x55,0x55,0xF7,0xF6,0xD7,0xF6,0xE8,0x5E,0x5D,0x5F, + 0xF7,0xF6,0xD7,0xF6,0x5F,0x7D,0xFF,0x7F,0xF7,0xF6,0xD7,0xF6,0xBF,0xFD,0x7F,0xFF, + 0xD7,0xF6,0xF7,0xEE,0xAE,0x82,0xA8,0xEA,0xF7,0xF6,0xD7,0xF6,0xEB,0xE9,0xE9,0x5E, + 0xF7,0xF6,0xD7,0xF6,0xAB,0xBA,0xAE,0x2E,0xF7,0xF6,0xD7,0xF6,0x25,0xA3,0xE2,0x7C, + 0xF7,0xF6,0xD7,0xF6,0xAE,0x0A,0x2A,0x7B,0x18,0xFF,0xD7,0xF6,0xAA,0xAB,0xEF,0x55, + 0xF7,0xF6,0xD7,0xEE,0x20,0xAC,0xD4,0xDD,0xF7,0xF6,0xD7,0xF6,0xA8,0xAA,0xB9,0x3D, + 0xF7,0xF6,0xD7,0xF6,0x88,0xEA,0xAE,0x88,0xF7,0xF6,0xD7,0xF6,0xEA,0x78,0x5E,0x7F, + 0xF7,0xF6,0xB7,0xEE,0xFA,0xFA,0x7E,0x5F,0xD7,0xF6,0x96,0xEE,0xAA,0xBA,0xBF,0xB7, + 0xD7,0xF6,0xB7,0xEE,0x0A,0x22,0xAF,0x55,0xF7,0xF6,0xB7,0xEE,0xC2,0xEA,0xFB,0xAF, + 0xD7,0xF6,0x75,0xE6,0x5F,0xFE,0x7A,0xDC,0xB6,0xEE,0x96,0xEE,0x75,0x75,0xFD,0xE5, + 0x96,0xEE,0x76,0xEE,0x00,0xFC,0xDC,0x9C,0x96,0xEE,0x36,0xEE,0x28,0x2A,0x3A,0x2A, + 0x97,0xF6,0xF4,0xDD,0x68,0x60,0x48,0x60,0xF4,0xDD,0x51,0xC5,0xB6,0xBE,0x3F,0x36, + 0x96,0xEE,0x14,0xDE,0xAD,0xAF,0xAD,0xAD,0x96,0xEE,0x55,0xE6,0x7A,0x68,0x7E,0x5A, + 0x75,0xEE,0x36,0xE6,0xAA,0xAA,0xFA,0xDF,0x55,0xE6,0x52,0xCD,0x78,0x78,0x68,0x78, + 0x52,0xCD,0xAF,0xBC,0x88,0xA0,0xEA,0x7E,0x11,0xC5,0xAF,0xBC,0xF8,0x76,0xDB,0xF5, + 0xD3,0xDD,0xCF,0xBC,0xAD,0x2D,0x2D,0x2D,0x34,0xE6,0xD2,0xD5,0x2D,0x29,0x22,0x0B, + 0x55,0xE6,0x14,0xE6,0xEB,0xAA,0xAA,0xEA,0x54,0xE6,0x14,0xE6,0xB7,0xB7,0xB5,0xA9, + 0x96,0xEE,0x34,0xE6,0x8A,0xAB,0x2E,0xA9,0xB6,0xF6,0x76,0xEE,0xEF,0xED,0xAB,0xAF, + 0x95,0xEE,0x55,0xE6,0x5E,0x5E,0xDE,0xDE,0xB7,0xF6,0x55,0xE6,0xBD,0xAD,0x2B,0x0B, + 0xD6,0xF6,0xB6,0xEE,0xA2,0xFA,0xE8,0x8A,0xB6,0xF6,0xD7,0xEE,0xBF,0xBF,0xBF,0xF7, + 0xB6,0xF6,0xD7,0xEE,0xFF,0xFB,0xFB,0xBF,0xD7,0xF6,0xB6,0xEE,0x2A,0x8E,0xB8,0xAC, + 0xB6,0xF6,0xD7,0xEE,0x6D,0xFF,0xFF,0xFF,0xD6,0xF6,0xB6,0xEE,0xE8,0x0A,0x2A,0x02, + 0xD7,0xF6,0xF6,0xEE,0x80,0x22,0x0A,0x2A,0xD7,0xF6,0xF6,0xEE,0x20,0x02,0xC8,0xA0, + 0xD7,0xF6,0xB7,0xEE,0x02,0x08,0x28,0x08,0xD7,0xF6,0xF7,0xEE,0xA8,0xA0,0x20,0x80, + 0xF7,0xF6,0xD7,0xF6,0xA1,0xB5,0xB5,0x55,0xF7,0xF6,0xD7,0xF6,0xDB,0xDA,0xD0,0x5F, + 0xF7,0xF6,0xD7,0xF6,0x5A,0xDE,0x56,0xD7,0xF7,0xF6,0xD7,0xF6,0x55,0x5F,0xFE,0x95, + 0xD6,0xF6,0xB7,0xEE,0x20,0x22,0x28,0xA0,0xD7,0xF6,0xF6,0xEE,0x20,0xA2,0x22,0xA2, + 0xF7,0xF6,0xB6,0xEE,0xDA,0x7E,0xEE,0xEA,0xD7,0xF6,0xB6,0xEE,0xBF,0xBA,0xB2,0xEB, + 0xF8,0xF6,0xD7,0xF6,0x85,0xB5,0xF5,0xFD,0xF7,0xF6,0xD7,0xF6,0x5B,0xBE,0xB5,0xF9, + 0xF7,0xF6,0xD7,0xF6,0xFB,0x3A,0xAE,0xAC,0xF7,0xF6,0xD7,0xF6,0xEA,0xE8,0xEA,0xEF, + 0xF7,0xF6,0xD7,0xF6,0x87,0xED,0xED,0xDF,0xF7,0xF6,0xD7,0xF6,0x8E,0xBB,0xAF,0xEA, + 0xF7,0xF6,0xD7,0xF6,0xB7,0x94,0xD4,0xF8,0xF7,0xFE,0xD7,0xF6,0x7B,0x6E,0xFE,0x57, + 0xB6,0xF6,0x4D,0xAC,0x60,0xE0,0x60,0x78,0x29,0x83,0x43,0x49,0x5E,0x7C,0xF8,0xEA, + 0x25,0x6A,0x43,0x49,0xD5,0xFB,0xAA,0x80,0x46,0x6A,0xA4,0x59,0x7D,0xFF,0x2F,0x0B, + 0x67,0x72,0xC5,0x61,0xBD,0xEA,0xA8,0x02,0x67,0x72,0x06,0x6A,0x7F,0xD7,0x37,0x22, + 0x88,0x7A,0xE5,0x61,0xFD,0xFB,0xC8,0x80,0x67,0x72,0x06,0x6A,0x7E,0xEF,0xEB,0xB0, + 0x26,0x62,0xC5,0x59,0xFF,0xB8,0xFE,0x6E,0x06,0x62,0xA4,0x59,0xEA,0x62,0xBA,0xFF, + 0x68,0x72,0xC5,0x59,0xAD,0xAF,0x2D,0xA5,0xC8,0x7A,0x67,0x72,0xFD,0xB5,0xBD,0x2D, + 0xA8,0x7A,0x06,0x6A,0x7A,0xE8,0x40,0xE0,0x26,0x6A,0xC5,0x59,0x37,0xDE,0x5E,0x5E, + 0xE6,0x61,0xA5,0x59,0x6E,0x94,0x5E,0x1B,0x06,0x62,0xC5,0x59,0xDF,0x3D,0x25,0x80, + 0x05,0x62,0xC5,0x59,0xFB,0xBA,0xFE,0xBC,0x06,0x62,0xC5,0x59,0xE8,0xA7,0x8B,0xEA, + 0x06,0x62,0xC5,0x61,0x3B,0x0B,0x82,0x53,0xC4,0x59,0x63,0x51,0x80,0x60,0xE0,0xFA, + 0xE5,0x69,0x83,0x51,0xFF,0xDD,0xFD,0x3F,0xC9,0x82,0xA4,0x61,0xFD,0xBD,0x0F,0x0B, + 0x4A,0x93,0x67,0x7A,0x75,0xFF,0xAB,0x22,0x4B,0x9B,0xA8,0x82,0xF5,0xEB,0x0A,0x00, + 0x2A,0x9B,0xA8,0x82,0xD7,0xFE,0xFA,0xBC,0xC9,0x8A,0xA5,0x69,0x7A,0x7A,0xE0,0x80, + 0xC8,0x8A,0x85,0x61,0x55,0xFF,0xAB,0x00,0x88,0x82,0x64,0x61,0xF5,0xFF,0xFA,0xF8, + 0x67,0x7A,0xC5,0x69,0x55,0xD5,0x37,0x3F,0xE9,0x92,0x46,0x7A,0xC5,0x29,0x2B,0x2F, + 0x09,0x93,0x67,0x82,0xFA,0xF8,0x7A,0x5E,0xA8,0x8A,0x05,0x72,0xA0,0xEA,0xE8,0x7E, + 0x46,0x7A,0xE5,0x69,0xA0,0xA8,0x3E,0xB5,0xB4,0xDD,0x67,0x7A,0xB5,0x2D,0x2D,0x0B, + 0xF7,0xFE,0xF4,0xDD,0x2D,0x0F,0x0B,0x02,0xF7,0xFE,0x18,0xF7,0xBE,0xFE,0xBE,0xF8, + 0x18,0xFF,0xF7,0xF6,0xA2,0xE0,0xF2,0xBF,0x18,0xFF,0xF7,0xF6,0xAA,0x8B,0xAA,0xEF, + 0x18,0xFF,0xF7,0xF6,0xAA,0x2A,0x2A,0x8B,0x17,0xFF,0xF7,0xF6,0x7A,0xFA,0xFA,0xEA, + 0x17,0xFF,0xF7,0xF6,0xFE,0xF5,0x5F,0xDF,0x18,0xFF,0xF7,0xF6,0xDD,0x55,0x95,0xBB, + 0x17,0xFF,0xD7,0xF6,0x8A,0xEA,0x7A,0x7A,0xF7,0xF6,0xB6,0xEE,0xF8,0xFA,0xBF,0xBB, + 0xD6,0xF6,0xB7,0xEE,0xEB,0x82,0x08,0xAA,0xD6,0xF6,0x96,0xEE,0x08,0x00,0x22,0xEF, + 0x18,0xFF,0x96,0xEE,0x0A,0x2A,0x3E,0xB5,0x38,0xFF,0x18,0xFF,0x0B,0x09,0x0B,0x01, + 0x38,0xFF,0xF7,0xF6,0xE0,0x60,0x6A,0xF8,0xF8,0xF6,0x55,0xE6,0x5E,0xFE,0xB8,0xA8, + 0xF8,0xFE,0x96,0xE6,0x2D,0xAD,0x2F,0x2A,0x18,0xFF,0xF8,0xF6,0xAB,0xED,0xAF,0xFD, + 0x18,0xFF,0xF8,0xF6,0xFF,0xF9,0xEF,0xEB,0x18,0xFF,0x97,0xF6,0x6A,0xE8,0xA2,0xA0, + 0xD7,0xF6,0x55,0xE6,0x77,0xDF,0x5E,0x78,0x75,0xEE,0x55,0xE6,0xAF,0xB7,0x7F,0x5F, + 0x55,0xE6,0x14,0xE6,0x70,0x60,0x00,0x00,0x35,0xE6,0xF4,0xDD,0x0B,0x29,0x2F,0x38, + 0xB6,0xF6,0x34,0xE6,0x09,0x2F,0x89,0xAD,0xF7,0xF6,0xB7,0xF6,0x8A,0xA2,0x83,0x2D, + 0x17,0xF7,0xB6,0xEE,0xAB,0xA9,0xAF,0xEE,0xF7,0xFE,0x18,0xF7,0xAA,0xAA,0xAA,0xA0, + 0x18,0xFF,0xD7,0xF6,0xFD,0xFF,0xFA,0xEA,0xF7,0xF6,0xD7,0xF6,0x75,0x5E,0xD8,0x7E, + 0xF7,0xF6,0xB7,0xEE,0xFB,0xA3,0xAB,0xFF,0xD7,0xF6,0xF7,0xEE,0x0A,0x80,0x00,0x00, + 0xF7,0xF6,0xD7,0xF6,0x5F,0xDF,0x7D,0xD5,0xF7,0xF6,0xD7,0xF6,0xEA,0xFB,0xFB,0x59, + 0xD7,0xF6,0xF7,0xEE,0xEA,0xA8,0x82,0x00,0xD7,0xF6,0xF7,0xEE,0x8A,0x8E,0xA2,0xE8, + 0xD7,0xF6,0xF7,0xEE,0xAA,0x2A,0x8A,0xBA,0xD7,0xF6,0xF8,0xEE,0x08,0x00,0xF2,0xEA, + 0x18,0xF7,0xD7,0xF6,0x55,0x97,0xAA,0xAE,0xF8,0xFE,0xD7,0xEE,0xFF,0xAA,0x82,0xAA, + 0x18,0xF7,0xD7,0xF6,0xFF,0xAB,0xAB,0xEB,0x18,0xF7,0xD7,0xF6,0xAF,0xBE,0xFE,0xFA, + 0xF7,0xF6,0xD7,0xF6,0x80,0x40,0xF0,0xDF,0xF7,0xF6,0xB7,0xEE,0xEA,0xEE,0x7F,0xFE, + 0xD7,0xF6,0x76,0xE6,0xA8,0xFA,0xFA,0x68,0xB6,0xEE,0x76,0xE6,0x2A,0xBF,0xBF,0xAB, + 0xD7,0xF6,0x96,0xEE,0x56,0x9D,0x2D,0x2B,0xD7,0xF6,0xF7,0xEE,0xA0,0x20,0x20,0x08, + 0xD7,0xF6,0x76,0xE6,0x5C,0xFF,0xDE,0x5E,0x96,0xEE,0x55,0xE6,0x0A,0x28,0xFE,0x7A, + 0x96,0xEE,0x55,0xE6,0xA8,0x2A,0xAF,0x95,0x96,0xEE,0x76,0xEE,0xFD,0xFB,0x3D,0x25, + 0x96,0xEE,0xF4,0xDD,0x48,0x60,0xE0,0x60,0xF4,0xDD,0x52,0xC5,0x3F,0x37,0x37,0xBF, + 0x96,0xEE,0x14,0xDE,0xAD,0x29,0xAD,0x3D,0xB6,0xF6,0x56,0xE6,0x7F,0xFC,0x7B,0x7E, + 0x35,0xEE,0x56,0xE6,0xFB,0xFB,0xFF,0xF7,0x35,0xE6,0x31,0xCD,0x60,0xE0,0x40,0x60, + 0x10,0xC5,0xAF,0xBC,0xFC,0x74,0xDC,0x76,0xD0,0xBC,0x6D,0xB4,0xA2,0xEC,0x7A,0xDE, + 0xF3,0xDD,0xCF,0xBC,0x2D,0x2D,0x0D,0x2D,0x54,0xE6,0xD2,0xDD,0x2F,0x2F,0xB9,0x2B, + 0x55,0xE6,0xF3,0xDD,0x8A,0x68,0x6A,0xFE,0x55,0xE6,0x14,0xDE,0xBB,0xB5,0x35,0xBD, + 0x75,0xEE,0x55,0xE6,0x2D,0x37,0xA9,0xC5,0xB6,0xF6,0x35,0xE6,0x8A,0x2A,0xAF,0xED, + 0x96,0xEE,0x35,0xE6,0xA8,0xAE,0x2E,0x27,0xD7,0xF6,0x75,0xE6,0x2D,0xAF,0x2B,0x2A, + 0xD7,0xF6,0xB6,0xEE,0xAC,0xAC,0x2F,0x0A,0xD7,0xF6,0xF6,0xEE,0x2A,0x0A,0x00,0xA2, + 0xD6,0xF6,0xB6,0xEE,0xAE,0x2A,0xA2,0xE0,0xD6,0xF6,0xB7,0xEE,0xE2,0xAE,0xAB,0x2A, + 0xD6,0xF6,0xB6,0xEE,0xA3,0xA8,0xAA,0x22,0xD6,0xF6,0xD7,0xEE,0x2A,0xAA,0x8A,0xA8, + 0xD7,0xF6,0xB6,0xEE,0x08,0x26,0x0F,0x00,0xF7,0xF6,0xB6,0xEE,0x6A,0xEE,0xAA,0xBB, + 0xD7,0xF6,0xF6,0xEE,0xA0,0x82,0x8A,0x0A,0xD7,0xF6,0xF8,0xEE,0x02,0x0A,0xA0,0x80, + 0xF7,0xF6,0xD7,0xF6,0x7E,0x5B,0x7A,0xFE,0xD7,0xF6,0xD6,0xEE,0xAA,0x8A,0x8C,0x2A, + 0xD7,0xF6,0xB6,0xEE,0x28,0xA8,0xAA,0xFA,0xF7,0xF6,0xB6,0xEE,0xAA,0xEB,0xFF,0xE7, + 0xD6,0xF6,0xB7,0xEE,0x20,0x02,0xA8,0xE2,0xF7,0xF6,0xD7,0xF6,0xED,0xAD,0xFD,0x7D, + 0xF7,0xF6,0xD7,0xF6,0x56,0x77,0xDD,0x7B,0xD7,0xF6,0xB6,0xEE,0xAA,0xB2,0x02,0x00, + 0xF7,0xF6,0xD7,0xF6,0x83,0xA2,0x8B,0x02,0xF7,0xF6,0xD7,0xF6,0xDF,0xFA,0x2A,0x88, + 0xF7,0xF6,0xD7,0xF6,0xFE,0x6A,0xE2,0xEE,0xF7,0xF6,0xD7,0xF6,0x6B,0xA6,0xFA,0xAF, + 0xF7,0xF6,0xD7,0xF6,0xBF,0x8F,0x2B,0xB8,0xF7,0xF6,0xD7,0xF6,0xF0,0xE2,0x6A,0xEA, + 0xF7,0xFE,0xD7,0xF6,0xFA,0x5F,0x55,0xDF,0xF7,0xFE,0x76,0xEE,0xE2,0xE8,0x6A,0x6A, + 0x55,0xEE,0x6A,0x93,0x70,0x78,0x5E,0x5E,0xE8,0x82,0x66,0x72,0x54,0xFE,0xEA,0xB8, + 0xA7,0x7A,0x05,0x62,0xDE,0xEA,0xAA,0xF8,0xA8,0x82,0x45,0x6A,0xF5,0x2F,0x0B,0x22, + 0xE9,0x8A,0x47,0x72,0xBD,0xAA,0x2A,0x02,0x09,0x8B,0x66,0x72,0x5F,0xFE,0x20,0x00, + 0x0A,0x8B,0x67,0x72,0xDD,0xBB,0xB8,0xE8,0xE9,0x82,0x47,0x72,0x5E,0x7E,0x28,0x8A, + 0xA8,0x7A,0x06,0x62,0x55,0x7A,0x88,0x80,0x47,0x6A,0xA4,0x59,0x57,0xDC,0x5C,0x70, + 0x06,0x6A,0x84,0x51,0x39,0xAB,0xA9,0xA9,0xA8,0x7A,0xE5,0x61,0x0B,0x0B,0x03,0xBD, + 0xA8,0x7A,0xE5,0x61,0xA0,0xE8,0xEC,0x7E,0x26,0x6A,0xA5,0x59,0xF8,0x9E,0xBE,0xFE, + 0xE5,0x61,0xA5,0x59,0x1E,0xD9,0xD8,0xFF,0x06,0x62,0xA4,0x59,0x8A,0x0A,0xFB,0xFD, + 0x47,0x6A,0xC5,0x59,0xA2,0x0A,0xFF,0x7D,0x06,0x62,0xC5,0x61,0x7A,0xCC,0xFE,0xFE, + 0x26,0x6A,0xC5,0x59,0x5F,0xFD,0xFC,0x5B,0x06,0x6A,0x84,0x59,0x9B,0x2A,0x02,0x00, + 0x87,0x7A,0xC4,0x61,0xD7,0x2F,0xAA,0x0A,0x09,0x93,0x26,0x72,0xAD,0x2B,0x2A,0xAA, + 0xAD,0xA3,0x0A,0x93,0xB7,0xBD,0xAD,0x0F,0xED,0xAB,0x4B,0x9B,0x7D,0xFF,0xAA,0x80, + 0x6B,0xA3,0xC8,0x8A,0x5C,0x5C,0x78,0xE0,0x4A,0x9B,0xA8,0x8A,0xB9,0x09,0x0F,0xAF, + 0x4A,0x9B,0xE9,0x92,0x6B,0xC2,0xA0,0xFF,0x8C,0xA3,0x26,0x7A,0x5F,0x7A,0xAA,0x0A, + 0xCC,0xAB,0x26,0x72,0xD5,0xFF,0xEA,0x80,0xC8,0x8A,0x66,0x82,0x0B,0x0B,0xFA,0xF4, + 0xC9,0x8A,0x26,0x72,0xF8,0xFE,0xFB,0x57,0x67,0x7A,0xC4,0x61,0xE8,0xE8,0x7E,0x77, + 0x11,0xCD,0xE5,0x69,0xD5,0xB5,0xB5,0x25,0xD7,0xFE,0x6F,0xBC,0x2D,0x2B,0x0B,0x02, + 0x18,0xFF,0xD7,0xFE,0xAD,0xAB,0xAA,0x2A,0x17,0xFF,0xF8,0xF6,0xAF,0xEA,0xE3,0xEA, + 0xF8,0xFE,0x17,0xF7,0xEA,0xBA,0xBA,0xBA,0x17,0xFF,0xF7,0xF6,0xBD,0xEF,0xAF,0xAB, + 0x17,0xFF,0xF7,0xF6,0x8B,0xA6,0xAA,0x7E,0x17,0xFF,0xF7,0xF6,0xFA,0xD6,0x77,0xD5, + 0x18,0xFF,0xF7,0xF6,0xF7,0xF7,0xAD,0xAB,0x18,0xFF,0xB6,0xEE,0x08,0x80,0xE8,0x7A, + 0xF7,0xF6,0x96,0xEE,0x80,0xE8,0xFE,0xDF,0xD7,0xF6,0x96,0xEE,0xA0,0xBE,0x5F,0x57, + 0xB6,0xEE,0x55,0xEE,0x00,0xE8,0x7A,0x5F,0x96,0xEE,0xB2,0xD5,0x20,0xA2,0xFA,0x7A, + 0x18,0xFF,0xF3,0xD5,0xAF,0x2D,0x2D,0x29,0x38,0xFF,0x18,0xFF,0x2B,0x8B,0x2F,0xAF, + 0x38,0xFF,0xF8,0xF6,0x6A,0xEA,0xC0,0x80,0x18,0xFF,0xB7,0xEE,0x7E,0xDA,0xFA,0xFC, + 0xF8,0xFE,0xD7,0xF6,0x9D,0xBF,0xA5,0xB5,0x18,0xFF,0xF8,0xF6,0xFF,0xBE,0xAB,0xAB, + 0x18,0xFF,0xF8,0xF6,0xEA,0xAE,0xB2,0xAA,0x18,0xFF,0xF8,0xF6,0xFF,0xAF,0xFE,0xF2, + 0xF8,0xFE,0x75,0xEE,0x58,0x58,0x68,0xE0,0x96,0xEE,0x35,0xE6,0x7E,0xFE,0xBE,0xF8, + 0x76,0xEE,0x55,0xE6,0x57,0xF7,0xEC,0xFF,0x55,0xEE,0x35,0xE6,0x5E,0xF8,0xDC,0xF8, + 0x96,0xEE,0x35,0xE6,0x2F,0x3F,0xAD,0xEF,0xF7,0xFE,0x96,0xEE,0xA9,0x2F,0xAD,0xAD, + 0xF7,0xF6,0xD7,0xF6,0x94,0xBA,0xAA,0x82,0xD7,0xFE,0xF7,0xF6,0x77,0x5F,0xFD,0xF7, + 0x18,0xFF,0xD7,0xF6,0xEA,0xAA,0xAB,0xAF,0x18,0xF7,0xD7,0xF6,0x7F,0xDE,0xFE,0xA2, + 0xF7,0xF6,0xB7,0xEE,0xFA,0xAA,0x80,0x00,0xD7,0xF6,0xF7,0xEE,0x00,0x00,0x8A,0xFA, + 0xF7,0xF6,0xD7,0xEE,0xB7,0xEF,0xF7,0x28,0xF7,0xF6,0xD7,0xF6,0x5F,0x7A,0xE2,0xB2, + 0x38,0xF7,0xD7,0xF6,0x55,0x7D,0xFF,0xBF,0x18,0xFF,0xD7,0xF6,0xFD,0xBB,0xB2,0xF2, + 0xD9,0xFE,0xF7,0xF6,0xF5,0x55,0xF5,0xD5,0xD8,0xFE,0xF8,0xF6,0xDD,0x77,0x75,0x57, + 0x17,0xFF,0xF8,0xF6,0x7D,0xFD,0xFD,0x77,0xF8,0xFE,0xF7,0xF6,0x77,0xDD,0xD7,0x5D, + 0xF7,0xF6,0xD7,0xF6,0x00,0x20,0x08,0x22,0xF7,0xF6,0xD7,0xF6,0x88,0xC2,0xE8,0xEC, + 0xF7,0xF6,0xD7,0xF6,0xDF,0xF7,0xDD,0xD5,0xD7,0xF6,0xB6,0xEE,0xF8,0xE8,0xF8,0xFF, + 0xB7,0xEE,0x76,0xE6,0xE0,0xFA,0x78,0xE0,0xD7,0xF6,0x75,0xE6,0xBF,0xAD,0x3D,0xA9, + 0xF7,0xF6,0xB6,0xEE,0xF7,0xBF,0xBB,0xAA,0xF7,0xF6,0xB6,0xEE,0xFA,0xFA,0xFA,0xEA, + 0xB7,0xF6,0x75,0xEE,0x7E,0xF8,0xFC,0x5F,0x96,0xEE,0x35,0xE6,0xE8,0xA8,0x88,0x22, + 0x76,0xEE,0x55,0xE6,0x2B,0x02,0x00,0x00,0x96,0xEE,0x76,0xEE,0x85,0xB4,0x9F,0xF5, + 0x76,0xEE,0xF3,0xDD,0x60,0x60,0x40,0xE0,0xF4,0xDD,0x52,0xCD,0x37,0x3E,0x3F,0x2F, + 0x76,0xEE,0x14,0xDE,0x2D,0xAD,0xAD,0x2D,0x96,0xEE,0x14,0xE6,0xAA,0xEA,0xE0,0xFA, + 0x55,0xE6,0xF4,0xDD,0xA2,0xEA,0xFE,0xFE,0x14,0xE6,0x52,0xCD,0x60,0xC0,0xE0,0xC0, + 0x11,0xC5,0x6E,0xB4,0xFE,0xF8,0x78,0x5C,0xCF,0xBC,0x4D,0xAC,0xFE,0xBF,0x3F,0xB7, + 0x13,0xDE,0x0F,0xC5,0xAD,0x2D,0x2D,0x29,0x54,0xE6,0x14,0xDE,0xB5,0xBD,0xAF,0xAA, + 0x55,0xE6,0x14,0xE6,0xFF,0xDA,0x7A,0xFA,0x55,0xE6,0x14,0xDE,0xB9,0xEF,0x2B,0x0F, + 0x55,0xEE,0x35,0xE6,0x3A,0xFF,0xFA,0x28,0x55,0xE6,0x14,0xDE,0x08,0xBF,0xFF,0xA8, + 0xB6,0xEE,0x35,0xE6,0xB5,0xA5,0x2F,0x2B,0xD6,0xF6,0x96,0xEE,0xA9,0xAB,0x8A,0xBE, + 0xB6,0xF6,0xF7,0xEE,0xFA,0xFE,0xAA,0xAE,0xD7,0xF6,0xF6,0xEE,0x22,0x0A,0x00,0x08, + 0xD7,0xF6,0xB6,0xEE,0x28,0xAA,0x8E,0xAB,0xD6,0xF6,0xB6,0xEE,0xA2,0x82,0xA2,0xEA, + 0xD6,0xF6,0xB5,0xEE,0x02,0xAA,0xAE,0xA5,0xD6,0xF6,0xB6,0xEE,0x00,0x82,0x2C,0xAA, + 0xD7,0xF6,0xF7,0xEE,0x28,0x20,0x20,0x00,0xD6,0xF6,0xB7,0xEE,0x82,0x2A,0xAA,0x20, + 0xF6,0xF6,0xD7,0xF6,0x7D,0x7F,0x5A,0x5F,0xD6,0xF6,0xD7,0xEE,0x2A,0xAA,0xAA,0xAA, + 0xD7,0xF6,0xF6,0xEE,0x22,0x00,0x02,0x08,0xF7,0xF6,0xB6,0xEE,0xBE,0xBF,0xAF,0xAE, + 0xD7,0xF6,0xB6,0xEE,0xBE,0xAA,0xF8,0xE2,0xD6,0xF6,0xB6,0xEE,0x8F,0xFF,0xAF,0xAF, + 0xD6,0xF6,0xB6,0xEE,0x88,0x28,0x8B,0x2D,0xF7,0xF6,0xB6,0xEE,0xAA,0xBA,0xEF,0xBF, + 0xD7,0xF6,0xF7,0xEE,0x88,0x08,0xC0,0x02,0xF7,0xF6,0xD7,0xF6,0x8F,0xBE,0xDE,0xA9, + 0xF7,0xF6,0xD7,0xF6,0x08,0x2A,0x0A,0x0A,0x17,0xFF,0xD7,0xF6,0xFE,0xAA,0xFA,0xFF, + 0xD7,0xFE,0xF7,0xF6,0xDD,0xDD,0x55,0x57,0xF7,0xF6,0xD6,0xF6,0xB7,0x3A,0x21,0x00, + 0xF7,0xF6,0xD7,0xF6,0xA8,0xA8,0x22,0x28,0xF7,0xF6,0xD7,0xF6,0xEA,0xFE,0x60,0x78, + 0xF7,0xFE,0xD7,0xF6,0xFF,0xBD,0xDF,0xDF,0xF7,0xF6,0x13,0xE6,0x60,0x68,0x68,0x62, + 0xEF,0xC4,0xA6,0x7A,0xF8,0x78,0x78,0x78,0xC7,0x82,0x46,0x72,0xB8,0xF8,0x56,0x5F, + 0x87,0x7A,0x26,0x72,0x2A,0xAB,0xFA,0x7D,0xA8,0x7A,0x47,0x72,0x00,0xAB,0x9D,0x5D, + 0xE9,0x82,0x46,0x72,0x0A,0x2A,0xBF,0xF5,0x4A,0x8B,0x67,0x72,0xA2,0xAB,0x7D,0x55, + 0xE9,0x8A,0x06,0x6A,0xA8,0xE8,0xFB,0x5F,0xA8,0x7A,0x05,0x62,0x88,0xAA,0xBA,0x7F, + 0xA8,0x7A,0x06,0x62,0xA8,0xFE,0x5E,0x5F,0x27,0x6A,0x84,0x51,0xE0,0xBA,0xBF,0xDE, + 0xE5,0x61,0x64,0x51,0x0A,0xAA,0xAC,0xA5,0x05,0x62,0x84,0x59,0x02,0x7B,0xFF,0xD7, + 0xE5,0x61,0xA4,0x59,0x8A,0xDF,0xB9,0xF5,0xE5,0x61,0x84,0x59,0xA2,0xAA,0xB8,0xBB, + 0xE5,0x61,0xA4,0x59,0xE5,0xAA,0x82,0xAA,0x06,0x62,0xA5,0x59,0x5F,0xD5,0xBE,0x8E, + 0xE5,0x61,0xA5,0x59,0x53,0x2B,0x09,0x02,0x26,0x6A,0xC5,0x59,0xEF,0xB9,0xCB,0x0A, + 0x67,0x72,0xC5,0x59,0x5F,0xED,0xAA,0xA2,0xA8,0x82,0xE5,0x61,0xDD,0xF7,0xBB,0x02, + 0x09,0x93,0x66,0x72,0xD5,0xBD,0x2A,0x0E,0x2A,0x93,0xC8,0x8A,0x9F,0x83,0x08,0x28, + 0xAC,0xA3,0x0A,0x93,0x0D,0x2B,0x0D,0x2B,0x4E,0xBC,0xCC,0xAB,0x7D,0x0F,0xAF,0x29, + 0x6E,0xBC,0x6B,0xA3,0x5F,0xFE,0xA8,0x00,0x2D,0xB4,0x0A,0x93,0x55,0x5F,0x7A,0xB0, + 0x2A,0x9B,0xC8,0x8A,0xBF,0xFE,0x57,0xF8,0x6B,0xA3,0xC9,0x8A,0x0B,0x2D,0x3F,0xA5, + 0xED,0xB3,0x4A,0x9B,0x83,0xAA,0xFF,0xD5,0x2A,0x9B,0x67,0x82,0xD4,0x58,0x78,0xF0, + 0x87,0x82,0x26,0x72,0x7A,0xEA,0x7E,0x2A,0x4A,0x93,0xC5,0x69,0x57,0xDF,0xB5,0x2F, + 0x56,0xEE,0xC9,0x82,0x35,0x2D,0x0B,0x0B,0xD7,0xFE,0x35,0xEE,0x09,0x03,0x02,0x00, + 0x18,0xFF,0xF7,0xFE,0xFD,0xBD,0xBD,0xA5,0x18,0xFF,0xF8,0xF6,0xEE,0x7E,0xD8,0xBA, + 0x17,0xFF,0xF7,0xF6,0xEF,0xEB,0xF7,0xFA,0x18,0xFF,0xF7,0xF6,0xBA,0x8E,0xEB,0x8E, + 0x17,0xFF,0xD7,0xF6,0xAA,0xBA,0xFA,0xFE,0x17,0xFF,0xD7,0xF6,0xBF,0xB6,0x3A,0xAB, + 0x18,0xFF,0xB6,0xEE,0x82,0xA0,0xA8,0x72,0xF7,0xF6,0x96,0xEE,0xF8,0xFA,0x5E,0x57, + 0x75,0xEE,0xB6,0xE6,0xAD,0xAA,0xAE,0xEB,0xB6,0xEE,0x75,0xEE,0xFF,0x7F,0x7F,0x00, + 0xB6,0xF6,0x54,0xE6,0x7F,0xFF,0xEB,0x80,0x75,0xEE,0xD3,0xD5,0x5A,0x5E,0x9E,0x28, + 0x18,0xFF,0x34,0xDE,0x0D,0x0F,0x03,0x02,0x39,0xFF,0x18,0xFF,0xBF,0xBF,0xBB,0xAF, + 0x39,0xFF,0x18,0xFF,0xC2,0x00,0x02,0xC2,0x18,0xF7,0xD7,0xF6,0x56,0x5E,0x78,0xF8, + 0xF8,0xF6,0xD7,0xF6,0xA5,0x29,0xA3,0x0A,0x18,0xFF,0xF8,0xF6,0xAF,0xED,0xAF,0xA9, + 0x18,0xFF,0xF8,0xF6,0xBA,0x7F,0xDD,0xEF,0x18,0xFF,0xF8,0xF6,0x6A,0xFF,0x7D,0x7D, + 0xF8,0xF6,0xB7,0xF6,0x60,0x80,0x20,0x00,0xD7,0xF6,0x55,0xE6,0x57,0x5E,0x7C,0x78, + 0x76,0xEE,0x55,0xE6,0xEB,0x8F,0x1F,0xEB,0x55,0xEE,0x35,0xE6,0x78,0x70,0xF0,0xE8, + 0x76,0xEE,0x14,0xDE,0x2A,0x2A,0xAF,0xA9,0xD7,0xF6,0x55,0xEE,0x0B,0x0B,0x2D,0xAF, + 0x18,0xF7,0xB6,0xEE,0xCA,0xA2,0xFB,0xAD,0xF7,0xF6,0xD7,0xF6,0x2B,0x8D,0xA5,0xBE, + 0xD7,0xFE,0xF8,0xF6,0x57,0x5D,0x97,0x55,0x18,0xFF,0xF8,0xF6,0xED,0xAD,0xFD,0xED, + 0xF7,0xF6,0xD8,0xF6,0x2A,0xB8,0x70,0xB0,0x18,0xFF,0xD7,0xF6,0x3D,0xA7,0xB7,0x57, + 0x18,0xFF,0xF8,0xF6,0x5F,0x7F,0xFF,0xBD,0x18,0xFF,0xD7,0xF6,0xFE,0xFF,0xEA,0xA8, + 0xF7,0xF6,0xD7,0xF6,0x08,0x2E,0xAA,0x22,0x18,0xFF,0xF7,0xF6,0x75,0x55,0x75,0xD7, + 0xF7,0xFE,0xF8,0xF6,0x75,0xDD,0x7F,0xF7,0x18,0xFF,0xF8,0xF6,0x75,0x55,0x7F,0x7F, + 0x18,0xFF,0xD7,0xF6,0xAB,0xEA,0xFB,0xDF,0xF7,0xF6,0xD7,0xF6,0x00,0x00,0x00,0xAC, + 0xF7,0xF6,0xD7,0xF6,0x28,0x22,0xAC,0xEE,0xF7,0xF6,0xD7,0xF6,0x6C,0x7E,0xD7,0x59, + 0xD7,0xF6,0xB6,0xEE,0x00,0xC8,0xE0,0xC0,0xD7,0xF6,0x96,0xEE,0xAB,0x8B,0xEE,0x7F, + 0xB6,0xEE,0x75,0xE6,0xE8,0xAE,0xEC,0xDF,0xD7,0xF6,0x96,0xEE,0x0D,0x2D,0x25,0xAD, + 0xF7,0xF6,0xB7,0xEE,0xAA,0xE8,0xFA,0xEF,0xF7,0xF6,0xB6,0xEE,0xAA,0xEB,0xFA,0xFB, + 0xB7,0xF6,0x55,0xE6,0x7E,0xD6,0x76,0x5C,0x96,0xEE,0x76,0xEE,0x89,0xFF,0x7D,0xD5, + 0x76,0xEE,0x55,0xE6,0x88,0xE0,0xF0,0xFE,0x96,0xEE,0x55,0xE6,0xAB,0xBB,0xEF,0xFF, + 0x76,0xEE,0xD3,0xDD,0xE0,0xE0,0xE0,0x60,0xF3,0xDD,0x72,0xCD,0xBF,0xAF,0x2F,0x3F, + 0x76,0xEE,0xF4,0xDD,0x2D,0x2D,0x0B,0x2D,0x76,0xEE,0x14,0xE6,0xF8,0xB8,0x68,0x70, + 0x34,0xE6,0xF4,0xDD,0xEC,0x68,0xFA,0xB7,0x15,0xE6,0x92,0xD5,0x60,0x48,0x6A,0x62, + 0x10,0xC5,0xEC,0xA3,0xE8,0xF8,0xFC,0x7C,0xF0,0xC4,0xEC,0x9B,0xAF,0x2F,0x3D,0x25, + 0x34,0xE6,0x51,0xCD,0xAD,0x2D,0x3D,0x2F,0x55,0xE6,0x14,0xE6,0xAF,0x89,0x23,0x23, + 0x54,0xE6,0x14,0xDE,0xFA,0x5E,0xDA,0xFC,0xB7,0xF6,0x34,0xE6,0xF5,0xAD,0xA9,0x09, + 0xB6,0xF6,0x55,0xE6,0xD5,0xFF,0xEA,0x70,0x76,0xEE,0x55,0xE6,0xD7,0x1F,0x2F,0x2B, + 0xB6,0xEE,0x76,0xEE,0xAD,0x2F,0xAA,0xAA,0xB6,0xF6,0x96,0xEE,0xCA,0xCB,0x7E,0xDE, + 0xD7,0xF6,0xB6,0xEE,0x0A,0x31,0x22,0xBA,0xD6,0xF6,0xB6,0xEE,0xB8,0xFE,0xA2,0x80, + 0xD6,0xF6,0xD7,0xEE,0xAA,0xA2,0xAA,0xAA,0xD6,0xF6,0xB7,0xEE,0xEA,0xA8,0x2C,0x28, + 0xF6,0xF6,0xB7,0xEE,0xBD,0xFE,0xFA,0xEA,0xD7,0xF6,0xB6,0xEE,0xA2,0xE2,0x82,0xA8, + 0xD6,0xF6,0xB6,0xEE,0x22,0x0A,0x8B,0xA8,0xF7,0xF6,0xB6,0xEE,0xBA,0xFE,0xAB,0xAF, + 0xF7,0xF6,0xB6,0xEE,0xBA,0xEF,0xAA,0xAA,0xD6,0xF6,0xF8,0xEE,0x88,0x28,0x00,0x22, + 0xF5,0xF6,0xD7,0xF6,0x57,0xDF,0xF5,0xFD,0xD6,0xF6,0xD7,0xEE,0xAA,0xA2,0xAA,0x28, + 0xD6,0xF6,0xB6,0xEE,0xFE,0x6E,0x60,0xF0,0xD6,0xF6,0xB6,0xEE,0x6F,0x7F,0xF9,0x9B, + 0xD6,0xF6,0xB6,0xEE,0x8F,0xEF,0xBE,0xAE,0xD7,0xF6,0xB6,0xEE,0xAA,0xA8,0xBA,0xFF, + 0xF6,0xF6,0xB6,0xEE,0xEB,0xEB,0xAF,0xAF,0xF7,0xF6,0xB6,0xEE,0xAA,0xBA,0xAD,0xBB, + 0xF6,0xF6,0xD6,0xF6,0xF6,0xFF,0xDD,0xF5,0xF6,0xF6,0xD6,0xF6,0xAA,0xA2,0xBB,0x79, + 0xF7,0xF6,0xD7,0xF6,0x20,0xAA,0xAE,0xF5,0xF7,0xF6,0xD7,0xF6,0x80,0x28,0xA0,0xAA, + 0xF7,0xFE,0xF7,0xF6,0xFD,0xDF,0x7F,0x7D,0xD7,0xFE,0xF7,0xF6,0xF5,0xFD,0xFD,0xBD, + 0xF7,0xFE,0xD6,0xF6,0xD8,0xEA,0xFF,0x5E,0xB6,0xF6,0x51,0xCD,0xC0,0x60,0x40,0x60, + 0x4D,0xAC,0xA6,0x7A,0x58,0x5C,0x5C,0x5C,0xE7,0x82,0x45,0x6A,0x55,0x57,0xFD,0x8A, + 0xA7,0x7A,0x26,0x6A,0x7D,0x77,0x7A,0x78,0x67,0x72,0xC5,0x61,0x0A,0xBA,0x6E,0xEF, + 0x47,0x72,0xE6,0x61,0x02,0xEA,0xF5,0x85,0x46,0x6A,0xE5,0x61,0xBC,0xDF,0x7B,0xD7, + 0x46,0x6A,0xE5,0x61,0x9F,0x3F,0xAF,0xAA,0x46,0x6A,0x26,0x6A,0x06,0x68,0x9E,0x76, + 0x46,0x6A,0xC4,0x59,0xE8,0xF8,0xFA,0x5E,0xE5,0x59,0x43,0x51,0x6E,0xE0,0xE8,0xEA, + 0x84,0x59,0x03,0x49,0x82,0x6A,0xAA,0xA0,0x84,0x59,0x23,0x49,0x2E,0x3D,0x25,0x8A, + 0xC6,0x61,0x64,0x51,0xD5,0xBD,0x8B,0x0B,0x06,0x62,0x85,0x59,0xFF,0xFF,0xBA,0x2E, + 0x06,0x62,0xA5,0x59,0xFB,0xB5,0xFE,0xE8,0x26,0x6A,0xC5,0x61,0xEB,0xFF,0x0F,0x29, + 0x47,0x72,0xC5,0x59,0x7D,0xD7,0xAB,0x2A,0xC8,0x7A,0x06,0x62,0xF5,0xFF,0xFD,0x8F, + 0xE9,0x8A,0x46,0x72,0xF5,0xBD,0x2D,0x2A,0x2A,0x93,0xC8,0x82,0xF5,0xFF,0x2E,0x0B, + 0x2A,0x93,0xE8,0x8A,0x36,0x2B,0xAC,0xAA,0x6B,0x9B,0x09,0x93,0xFF,0xFF,0xEB,0x2B, + 0x8B,0xA3,0x2A,0x9B,0x29,0x2B,0x0B,0x02,0x6E,0xBC,0xAC,0xAB,0x2D,0xA5,0xAD,0xAD, + 0xCF,0xCC,0x4E,0xBC,0xF7,0xAD,0xAF,0x0F,0xCF,0xCC,0xCC,0xAB,0x7E,0xEA,0xA8,0xA0, + 0x0D,0xB4,0x2A,0x93,0x5F,0x7A,0xF8,0xE8,0x4A,0x93,0xE9,0x8A,0xAF,0xEF,0xFA,0xF8, + 0x2A,0x93,0x87,0x82,0x00,0xEA,0x6E,0x7E,0xE9,0x8A,0xC5,0x69,0xA0,0xEA,0x7E,0x57, + 0x09,0x8B,0xE5,0x69,0xFF,0xDD,0xB5,0x3D,0x12,0xE6,0xE8,0x82,0xF5,0xB5,0x2D,0x0B, + 0xD7,0xFE,0x72,0xD5,0x2D,0x0B,0x02,0x00,0x18,0xFF,0xD7,0xFE,0xBF,0xEB,0xAA,0xAA, + 0x18,0xFF,0xF7,0xFE,0x8D,0xAB,0xA5,0x2D,0x18,0xFF,0xF7,0xF6,0xA2,0x80,0xA8,0xFA, + 0x17,0xFF,0xF8,0xF6,0xAA,0x7A,0xAE,0xAA,0xF7,0xFE,0x18,0xF7,0xEF,0xFE,0xFF,0xAF, + 0x17,0xFF,0xD7,0xF6,0x7A,0xFA,0xEA,0xEA,0x17,0xFF,0xB6,0xEE,0x22,0x0A,0xE2,0x6A, + 0xF7,0xF6,0x96,0xEE,0x60,0x5C,0xDF,0xF7,0xF7,0xF6,0x96,0xEE,0x55,0xF5,0xFD,0x0B, + 0x17,0xFF,0x96,0xEE,0xFD,0xAF,0x8A,0x00,0x38,0xFF,0xD7,0xF6,0xD5,0xFB,0xAA,0x8A, + 0x18,0xFF,0xB6,0xF6,0x7E,0xFE,0xE2,0xF0,0xF7,0xF6,0x75,0xEE,0x9D,0xB7,0x37,0x37, + 0x38,0xFF,0xF8,0xFE,0xAF,0xAB,0xAA,0x8A,0x39,0xFF,0x18,0xFF,0xBF,0xF5,0x2D,0x29, + 0x39,0xFF,0x18,0xFF,0xC2,0xE8,0xE0,0xB0,0x18,0xFF,0xF8,0xF6,0x56,0x78,0x50,0xD0, + 0xF8,0xF6,0xD7,0xF6,0x88,0xAA,0xB8,0xA2,0x18,0xFF,0xF8,0xF6,0xFD,0xF5,0xD5,0xDD, + 0x18,0xFF,0xF8,0xF6,0xED,0xA5,0xAB,0xAF,0x18,0xFF,0xF8,0xF6,0xEB,0xAE,0x2A,0xBA, + 0x18,0xFF,0xF8,0xF6,0xFA,0xDA,0xB2,0xAA,0x18,0xFF,0x55,0xE6,0x7A,0xFA,0xE0,0xA8, + 0x75,0xEE,0x55,0xE6,0xBF,0xFD,0xDF,0x70,0x75,0xEE,0x35,0xE6,0xEA,0xFF,0xAF,0x9A, + 0x76,0xEE,0x35,0xE6,0xAD,0xEF,0x2F,0xAB,0xB6,0xF6,0x55,0xE6,0xAD,0xAD,0xBF,0x0F, + 0xF7,0xF6,0xB6,0xF6,0x8F,0xA9,0xED,0xAD,0xF7,0xF6,0xD7,0xF6,0xFA,0x7B,0xFF,0xBF, + 0x18,0xFF,0xD7,0xF6,0xAA,0xAB,0xEB,0xAF,0x18,0xFF,0xF8,0xF6,0xEB,0xED,0xF5,0x55, + 0x18,0xFF,0xF8,0xF6,0x57,0x56,0x5F,0x5F,0xF8,0xF6,0xD7,0xF6,0xDE,0xFA,0xA2,0x20, + 0xF8,0xF6,0xD7,0xF6,0x00,0xA2,0xAA,0x2B,0x18,0xFF,0xD7,0xF6,0xAA,0xBF,0xBF,0xBF, + 0x18,0xFF,0xF7,0xF6,0x5D,0x77,0x7E,0xFD,0xF7,0xF6,0xD7,0xF6,0x00,0xA0,0xF2,0xA0, + 0x18,0xFF,0xD7,0xF6,0xAE,0xBE,0xEB,0x7F,0x18,0xFF,0xF7,0xF6,0xFF,0xED,0x77,0xD5, + 0x18,0xF7,0xD7,0xF6,0xDE,0xFA,0x7E,0xFF,0xF7,0xF6,0xD7,0xF6,0xBC,0xEE,0x2E,0x9E, + 0xF7,0xF6,0xD7,0xF6,0xA8,0xAA,0xAE,0x8A,0xD7,0xF6,0xF7,0xEE,0x2A,0xA2,0x02,0x00, + 0xD7,0xF6,0xB6,0xEE,0xCA,0xEB,0xE3,0xEB,0xB6,0xEE,0x96,0xEE,0xE0,0xC0,0x78,0x56, + 0x96,0xEE,0x75,0xEE,0x9E,0xB8,0xC2,0x6A,0xD7,0xF6,0x76,0xEE,0xAB,0x0B,0xEF,0xAD, + 0xD7,0xF6,0xB6,0xEE,0xEA,0xEB,0xAB,0x3A,0xD7,0xF6,0xB6,0xEE,0x8B,0xFB,0x63,0x74, + 0x96,0xEE,0x14,0xDE,0xF8,0xFC,0xFC,0x58,0x96,0xEE,0x35,0xE6,0x2B,0xAB,0x8F,0xAD, + 0x75,0xEE,0x56,0xE6,0xE8,0xA2,0x2B,0x2A,0x96,0xEE,0x55,0xEE,0xB7,0x9D,0x2F,0x8B, + 0x96,0xEE,0xF4,0xDD,0x60,0x72,0x68,0xE0,0x14,0xDE,0x72,0xCD,0xB7,0x2F,0x35,0xB7, + 0x76,0xEE,0xF3,0xDD,0x2D,0xAF,0x2B,0x2B,0x75,0xEE,0x35,0xE6,0x72,0x7A,0x5A,0x7A, + 0x14,0xE6,0xD3,0xDD,0xE8,0xFA,0x7E,0x56,0x14,0xE6,0x93,0xD5,0x62,0x6A,0xEF,0x7B, + 0xF0,0xC4,0x8B,0x93,0xFC,0xFC,0x7C,0xF8,0x72,0xD5,0xEC,0x9B,0x35,0x25,0x2D,0x2B, + 0x55,0xEE,0x92,0xD5,0xBD,0xAD,0x2D,0xAD,0x96,0xEE,0x34,0xE6,0xFD,0x2A,0x0A,0x02, + 0x96,0xEE,0x34,0xE6,0x57,0xF4,0x80,0x00,0xB7,0xF6,0x55,0xE6,0x09,0x29,0xEA,0xFF, + 0xB6,0xEE,0x14,0xE6,0xB0,0xFA,0xFE,0xD6,0x96,0xEE,0xF4,0xDD,0x2A,0x0A,0xAA,0x75, + 0x96,0xEE,0x35,0xE6,0x20,0x00,0x82,0x09,0xB6,0xF6,0x55,0xE6,0xAA,0xEA,0x7E,0x7F, + 0xD6,0xF6,0xB6,0xEE,0xBE,0x2B,0x2A,0xAA,0xF7,0xF6,0xD7,0xF6,0x7C,0x9F,0x55,0x55, + 0xD7,0xF6,0xD6,0xEE,0xAB,0xAA,0x88,0xAA,0xD6,0xF6,0xD7,0xEE,0xAA,0xAA,0x8A,0x8A, + 0xD6,0xF6,0xB6,0xEE,0x80,0xA2,0xAB,0x0B,0xF6,0xF6,0xB7,0xEE,0xFA,0xFE,0xBA,0xAB, + 0xD6,0xF6,0xF8,0xEE,0x00,0xA2,0x02,0x02,0xD6,0xF6,0xB6,0xE6,0x88,0x32,0x02,0x00, + 0xD6,0xF6,0xF8,0xEE,0x08,0x82,0x20,0x22,0xD7,0xF6,0xD6,0xEE,0xAA,0xA2,0xA8,0xA3, + 0xB5,0xF6,0xF6,0xEE,0xFA,0xEA,0xBF,0xAA,0xD6,0xF6,0xD6,0xEE,0x38,0xA8,0xAA,0xA8, + 0xD6,0xF6,0xB6,0xEE,0xF2,0xE2,0x70,0x78,0xD6,0xF6,0xB6,0xEE,0xAA,0xAF,0x9D,0x57, + 0xD6,0xF6,0xB6,0xEE,0xEF,0x96,0xFE,0xAA,0xD6,0xF6,0xB6,0xEE,0xFE,0xEE,0xEB,0xFE, + 0xD6,0xF6,0xB6,0xF6,0xA8,0x0B,0x8D,0xAF,0xD6,0xF6,0xB6,0xEE,0x80,0x00,0x80,0xA3, + 0xF6,0xF6,0xB6,0xEE,0xAA,0x9E,0xBF,0xEF,0xF6,0xF6,0xB6,0xEE,0xAA,0xDA,0xBF,0xEF, + 0xD6,0xF6,0xF7,0xEE,0x88,0x80,0x20,0xA8,0xF7,0xF6,0xD6,0xF6,0xFA,0xFA,0xED,0xF7, + 0xF7,0xF6,0xD6,0xF6,0x38,0x96,0xEB,0xFA,0xF7,0xFE,0xD7,0xF6,0xAA,0xAF,0xFF,0x74, + 0xF7,0xFE,0x75,0xEE,0xA2,0xAA,0xEA,0x7E,0x54,0xEE,0x29,0x83,0x80,0xE0,0xE0,0x78, + 0xEC,0xA3,0xE5,0x61,0xF8,0xFA,0xFE,0x57,0xC8,0x7A,0x64,0x51,0x00,0xA0,0xFB,0x57, + 0xA8,0x7A,0x63,0x51,0xA0,0xE8,0xFF,0xD5,0x26,0x6A,0x84,0x51,0xA0,0xA8,0xBB,0xD5, + 0x06,0x62,0xA5,0x59,0x02,0x22,0xBB,0xDD,0x26,0x6A,0x84,0x51,0xAA,0x82,0x8E,0x6F, + 0x26,0x6A,0x23,0x41,0xA0,0x8A,0xFA,0x5F,0xE5,0x59,0x43,0x49,0x00,0xFA,0x7E,0x55, + 0xC5,0x59,0x43,0x49,0x2A,0xAA,0xFE,0xFD,0xA4,0x51,0x64,0x51,0xB0,0xE8,0xAF,0x7D, + 0xC5,0x61,0x43,0x49,0xDF,0xFF,0x2F,0x0F,0xA8,0x7A,0x84,0x59,0x55,0xFF,0xAB,0x2E, + 0x47,0x72,0xA5,0x59,0x55,0xFE,0xA8,0x00,0x27,0x6A,0xC5,0x59,0xB7,0xAF,0x98,0x90, + 0x47,0x6A,0xE5,0x61,0x79,0xF2,0x20,0xAA,0x06,0x6A,0xC5,0x61,0xA7,0x3A,0x9A,0xAC, + 0xA8,0x7A,0x06,0x6A,0xF7,0xB5,0x8D,0x2F,0x8B,0xA3,0x67,0x72,0xFD,0xAF,0xAB,0x0B, + 0xCC,0xA3,0xE9,0x8A,0x55,0xFF,0xAA,0x20,0xAB,0xA3,0xC9,0x8A,0xFD,0xAE,0xCA,0x00, + 0x8B,0xA3,0x09,0x93,0x55,0xEF,0xFB,0x78,0x8B,0xA3,0x2A,0x9B,0x39,0x3F,0x2D,0xA9, + 0xAB,0xA3,0x6A,0xA3,0xAE,0x9A,0xDC,0x55,0x2D,0xBC,0x8B,0xA3,0x2B,0x25,0xAD,0xF5, + 0xCF,0xCC,0xCC,0xAB,0x2A,0xAF,0x37,0xFD,0xCF,0xCC,0x2D,0xBC,0x78,0xE8,0x7A,0x77, + 0x2E,0xBC,0x4A,0x9B,0xF8,0xF8,0x78,0x5E,0x29,0x93,0x46,0x7A,0x80,0xFC,0xFA,0x5E, + 0xC8,0x8A,0xE5,0x69,0xE0,0xFA,0x56,0x5F,0x46,0x72,0xA4,0x61,0xDE,0x5F,0xAA,0x0A, + 0xF3,0xE5,0xA7,0x7A,0xD5,0xB5,0x25,0x2D,0xD6,0xF6,0x10,0xCD,0x2D,0x2B,0x02,0x02, + 0x18,0xFF,0xB6,0xFE,0xAB,0x8A,0x2A,0x22,0x17,0xFF,0xF8,0xFE,0xAF,0xB9,0xAB,0x22, + 0x17,0xFF,0xF8,0xF6,0xAA,0xA2,0xA8,0x08,0x17,0xFF,0xF8,0xF6,0xEA,0xA0,0x82,0x82, + 0xF7,0xFE,0x18,0xF7,0xFF,0xEF,0xBF,0xFA,0x17,0xFF,0xF7,0xF6,0x5B,0xFD,0xFF,0xEF, + 0x17,0xFF,0xD7,0xF6,0xAA,0xE2,0xEA,0x7A,0xF7,0xF6,0x96,0xEE,0xE8,0x78,0xBF,0xAF, + 0xF7,0xF6,0xB6,0xEE,0x7D,0x2F,0x0A,0x00,0x18,0xFF,0xD7,0xF6,0xBD,0x0B,0x02,0x00, + 0x38,0xFF,0x18,0xFF,0xB5,0xAD,0xAD,0x8D,0x38,0xFF,0x18,0xFF,0x0A,0x02,0x02,0x00, + 0x38,0xFF,0xF4,0xDD,0xA0,0xE8,0x78,0x78,0xF7,0xFE,0xD3,0xD5,0x2B,0x27,0x2D,0x2D, + 0x38,0xFF,0x18,0xFF,0xED,0x7D,0xFD,0xFD,0x39,0xFF,0x18,0xFF,0x2F,0xAE,0xBF,0xBD, + 0x38,0xFF,0x19,0xFF,0xE8,0xF8,0xFA,0x6A,0x18,0xFF,0xF8,0xF6,0xA8,0xF8,0x72,0xDA, + 0x18,0xFF,0xD7,0xF6,0xFF,0xAB,0xAF,0xBF,0x18,0xFF,0xF8,0xF6,0xEE,0xBA,0x0A,0x6A, + 0x18,0xFF,0xF8,0xF6,0xFF,0xFE,0xAA,0xBD,0x18,0xFF,0xF8,0xF6,0xFE,0x9F,0xAF,0x8A, + 0x18,0xFF,0xF8,0xF6,0xAF,0x2B,0x8E,0x0A,0x18,0xFF,0xD7,0xF6,0x7A,0xE2,0xEA,0xEA, + 0xF7,0xFE,0x55,0xE6,0x5F,0x5E,0xFA,0xF8,0x75,0xEE,0x55,0xE6,0x55,0x7F,0xFA,0x02, + 0x55,0xEE,0x75,0xE6,0x80,0x82,0xBE,0xAB,0xB6,0xF6,0x54,0xE6,0x2F,0x29,0x2B,0xAB, + 0xF7,0xF6,0xB7,0xF6,0xAF,0x0F,0xA5,0x3D,0xF8,0xF6,0xD7,0xF6,0xEB,0x6E,0x60,0x60, + 0xF7,0xF6,0xD8,0xF6,0x02,0x02,0xAB,0xBD,0xD6,0xFE,0xF8,0xF6,0x55,0x5D,0xDD,0x5F, + 0xF8,0xF6,0xD8,0xF6,0x00,0xAE,0xBE,0xAA,0xF8,0xF6,0xD7,0xF6,0xAA,0x8B,0xB3,0x82, + 0xF7,0xF6,0xD7,0xF6,0x88,0xA8,0x82,0x00,0xF7,0xF6,0xD7,0xF6,0x08,0xE0,0xC8,0x00, + 0xF7,0xF6,0xD7,0xF6,0x00,0x8A,0x8F,0xBF,0xF7,0xF6,0xD7,0xF6,0x20,0x00,0x0A,0x3B, + 0xF7,0xF6,0xD7,0xF6,0xCA,0xC8,0xE2,0x28,0xF7,0xFE,0xD7,0xF6,0x2D,0x2D,0x2B,0xBA, + 0xF7,0xF6,0xD7,0xF6,0xA8,0xA8,0xE8,0xFA,0xF7,0xF6,0xD7,0xF6,0xDE,0xDF,0x7E,0x56, + 0xF7,0xF6,0xD7,0xF6,0xEB,0x4A,0xDD,0x55,0xF7,0xF6,0xB7,0xEE,0x8F,0xBF,0xDE,0xFE, + 0xD7,0xF6,0x96,0xEE,0xE8,0xEC,0x7E,0x7F,0xB6,0xEE,0x55,0xE6,0xF8,0xFA,0x7A,0x5F, + 0x96,0xEE,0x55,0xE6,0xBB,0xBD,0xBD,0x35,0xD7,0xF6,0x96,0xEE,0xAD,0x2D,0x0F,0x3B, + 0xD7,0xF6,0xB6,0xF6,0xB2,0xDF,0xD8,0xEA,0xD7,0xF6,0x96,0xEE,0xA8,0xAA,0xEB,0xE8, + 0x96,0xEE,0xF4,0xDD,0x78,0x78,0x5C,0x5A,0x76,0xEE,0xF4,0xDD,0x03,0x2B,0x2D,0xAF, + 0x75,0xEE,0x55,0xE6,0x88,0xA2,0x88,0xA2,0x96,0xEE,0x75,0xEE,0xBF,0xD7,0x7D,0x55, + 0x76,0xEE,0xD3,0xD5,0x60,0xF8,0x60,0x68,0xF4,0xDD,0x92,0xD5,0xAF,0x27,0x2D,0x3F, + 0x55,0xEE,0xF4,0xDD,0x0B,0x2B,0x29,0xA7,0x76,0xEE,0x35,0xE6,0x7A,0x7A,0x62,0x6B, + 0x35,0xE6,0xD3,0xDD,0x56,0x7E,0xE2,0xE8,0x15,0xE6,0xB3,0xD5,0x7B,0x6A,0x62,0x68, + 0x31,0xC5,0x0D,0xA4,0xDC,0x7C,0xBC,0xAA,0x92,0xD5,0xAF,0xB4,0x2D,0x2D,0x09,0xAF, + 0x55,0xEE,0x92,0xD5,0x3F,0x35,0x95,0xFD,0x96,0xF6,0xF4,0xDD,0x00,0x22,0xAA,0xF5, + 0x96,0xEE,0xD3,0xDD,0xA0,0xEA,0xFF,0x5F,0x35,0xE6,0x92,0xD5,0x80,0xBA,0xDF,0x55, + 0xF4,0xDD,0x52,0xCD,0x00,0xAA,0xFB,0xFD,0xF4,0xDD,0x92,0xD5,0x8F,0xAF,0xAD,0x0D, + 0x76,0xEE,0xF3,0xDD,0x0D,0xA5,0xAD,0xAD,0x76,0xEE,0x35,0xE6,0xE8,0xFC,0x57,0x55, + 0xD6,0xF6,0xB6,0xEE,0xAA,0xAA,0x08,0x83,0xF6,0xF6,0xB7,0xEE,0xFB,0xEB,0xAA,0xAF, + 0xD6,0xF6,0xB6,0xEE,0x2B,0x83,0x02,0x08,0xD6,0xF6,0xD7,0xEE,0x8A,0xAA,0xAA,0x2A, + 0xD6,0xF6,0xD7,0xEE,0xA2,0x8A,0xA8,0xAA,0xF6,0xF6,0xD6,0xF6,0xBD,0xCB,0x7D,0x55, + 0xD6,0xF6,0xB6,0xEE,0x38,0x00,0x2A,0x38,0xF6,0xF6,0xD6,0xF6,0xF5,0xF5,0xDD,0xFD, + 0xD6,0xF6,0xD7,0xEE,0x8A,0xA8,0x2A,0xA8,0xD6,0xF6,0xB6,0xEE,0xAA,0x8A,0x30,0x00, + 0xF6,0xF6,0xB6,0xEE,0xFF,0xFF,0xEE,0xAA,0xD6,0xF6,0xD6,0xEE,0x2A,0x22,0xAA,0xAA, + 0xD6,0xF6,0xB6,0xEE,0xB6,0x2E,0xA2,0xFA,0xD6,0xF6,0xB6,0xEE,0x9F,0xDF,0xE7,0xA5, + 0xB6,0xF6,0xD6,0xEE,0xEB,0xAA,0xBA,0x2A,0xD6,0xF6,0xB6,0xEE,0xFA,0x63,0xAF,0xBD, + 0xD7,0xF6,0xB6,0xF6,0xFB,0xEB,0xEA,0xF7,0xD6,0xF6,0xB6,0xEE,0x29,0xFB,0xAF,0xAB, + 0xD6,0xF6,0xB6,0xEE,0x0A,0x0A,0x28,0xBA,0xD6,0xF6,0xB6,0xEE,0x08,0x28,0xA8,0xA3, + 0xD6,0xF6,0xB6,0xEE,0x00,0xA2,0xA8,0xA2,0xF6,0xF6,0xB5,0xEE,0xAA,0xBA,0xEE,0xFA, + 0xF6,0xF6,0xB5,0xEE,0x2A,0xAB,0x3F,0xFF,0xF6,0xF6,0xB7,0xF6,0xE8,0xFA,0xFE,0xFE, + 0xD7,0xF6,0x75,0xEE,0x6A,0x68,0xC0,0xC0,0xF3,0xDD,0xE8,0x82,0x78,0x78,0x78,0x78, + 0x46,0x6A,0xA4,0x51,0x7E,0x56,0x5C,0x58,0x84,0x51,0x23,0x41,0x77,0xBE,0x7A,0xA0, + 0x63,0x49,0xE2,0x38,0x02,0xA8,0xDF,0x56,0x84,0x51,0xC2,0x30,0x0A,0x2E,0xEF,0x55, + 0x84,0x51,0xC2,0x30,0x00,0x02,0xBF,0xFD,0xA4,0x51,0x03,0x39,0xA0,0xFB,0xD7,0x55, + 0x84,0x51,0xE2,0x38,0xE2,0xDB,0xD5,0x57,0x43,0x49,0xE2,0x38,0x82,0xB6,0xFD,0x75, + 0x44,0x49,0xC2,0x38,0x22,0xAF,0xAD,0xAB,0x84,0x51,0x23,0x49,0xA9,0xAD,0x3F,0xF9, + 0x67,0x72,0x84,0x59,0xBD,0x2D,0x2D,0x2F,0xE8,0x82,0x67,0x72,0xBD,0x29,0x8B,0xAB, + 0xA8,0x7A,0x47,0x72,0xFC,0x7E,0x7C,0xF2,0x47,0x6A,0xC5,0x61,0xBC,0xA8,0xF8,0x5C, + 0x26,0x6A,0xC5,0x59,0xEC,0x7F,0xFB,0xEB,0x26,0x6A,0xC5,0x61,0xBE,0xAD,0xA9,0xAA, + 0xC8,0x82,0x26,0x6A,0x3D,0x2D,0x2F,0xB7,0xCC,0xA3,0xC9,0x82,0x0B,0x0B,0xA9,0xA5, + 0x0D,0xB4,0xAC,0xA3,0xA2,0x2A,0x2F,0x9D,0x4E,0xBC,0xED,0xAB,0x5F,0xFE,0x2F,0x8F, + 0x4D,0xBC,0x4A,0x9B,0x5F,0xFA,0xC0,0x80,0xCC,0xAB,0x2A,0x9B,0xF7,0x5E,0x7E,0xB0, + 0x8B,0xA3,0x29,0x9B,0x6F,0x75,0xFB,0x80,0x8B,0xA3,0xE8,0x8A,0x2A,0xAF,0xFF,0x55, + 0xEC,0xAB,0x09,0x93,0x0A,0xAB,0xAF,0xFD,0x0D,0xB4,0x6A,0x9B,0x0A,0xAF,0xBF,0x75, + 0xEC,0xAB,0xC8,0x8A,0xE0,0xF8,0x7A,0x5F,0xC8,0x8A,0x26,0x72,0xFC,0xFE,0xDF,0x57, + 0xC9,0x8A,0xE6,0x69,0x5D,0x7F,0x8A,0x0B,0x4D,0xB4,0x26,0x72,0xD5,0xBD,0x3D,0x2F, + 0xB6,0xFE,0xAB,0x9B,0xAD,0x2D,0x2A,0x0A,0x18,0xFF,0x96,0xF6,0x29,0x2F,0x8B,0x2A, + 0x18,0xFF,0xF7,0xFE,0xBD,0xBD,0xA5,0xA7,0x18,0xFF,0x17,0xF7,0xAA,0xA8,0xA0,0x20, + 0x18,0xFF,0xF6,0xEE,0xA8,0x22,0x08,0xA0,0xF7,0xFE,0x18,0xF7,0xDF,0xFF,0xFF,0xEF, + 0x17,0xFF,0xF7,0xF6,0x9E,0xBA,0x88,0xAA,0x17,0xFF,0xD7,0xF6,0xAA,0x82,0xE0,0x68, + 0xF7,0xF6,0xD7,0xF6,0x70,0x58,0x57,0x5F,0xF8,0xFE,0xD6,0xEE,0xB5,0xAB,0xAE,0x8B, + 0x38,0xFF,0xF7,0xF6,0xF5,0xBF,0xAD,0xAB,0x38,0xFF,0x18,0xFF,0xD5,0xAB,0x0A,0x02, + 0x59,0xFF,0x18,0xFF,0xAD,0xAA,0xAA,0x2A,0x38,0xFF,0x96,0xEE,0x80,0x80,0x40,0xF0, + 0xD7,0xF6,0xF4,0xDD,0x78,0x7E,0xFE,0xFE,0x18,0xFF,0x14,0xDE,0x2D,0x2D,0x0F,0x8F, + 0x38,0xFF,0x18,0xFF,0xFD,0xFD,0x7D,0x55,0x39,0xFF,0x18,0xFF,0xAD,0xAD,0xAF,0x7D, + 0x39,0xFF,0x18,0xFF,0x6E,0xFE,0xDE,0x5F,0x18,0xFF,0xF8,0xF6,0x5F,0x5A,0xD6,0xDE, + 0x18,0xFF,0xF8,0xF6,0x95,0xB5,0x9D,0xDD,0x18,0xFF,0xF8,0xF6,0xD6,0xFA,0xFE,0x7F, + 0x18,0xFF,0xF8,0xF6,0xA9,0xAB,0x77,0xF7,0x18,0xFF,0xF8,0xF6,0x80,0x80,0xAA,0xAB, + 0x18,0xFF,0xF7,0xF6,0x8E,0x8B,0x82,0x82,0x18,0xFF,0xF7,0xF6,0xFE,0xEA,0xFA,0xFF, + 0xF7,0xF6,0xB7,0xF6,0x52,0x70,0x78,0x78,0xB6,0xF6,0x76,0xEE,0x57,0x5E,0x7C,0xFA, + 0x96,0xEE,0x76,0xEE,0x55,0xBD,0x69,0xCA,0xB6,0xF6,0x55,0xE6,0xA9,0xAB,0xAB,0x2E, + 0xF7,0xF6,0x96,0xEE,0xAF,0xB9,0x2F,0x2B,0x18,0xFF,0xD7,0xF6,0xFF,0xEB,0xBF,0xAF, + 0xF7,0xF6,0xD7,0xF6,0x3B,0xAF,0x2F,0x28,0x18,0xFF,0xF7,0xF6,0x55,0x55,0xF7,0x7F, + 0xF8,0xF6,0xD7,0xF6,0x2A,0xA8,0x08,0x00,0xD7,0xFE,0xF7,0xF6,0x57,0xD7,0x55,0x55, + 0xF7,0xF6,0xD7,0xF6,0x88,0x0A,0x22,0xAA,0x18,0xFF,0xD7,0xF6,0xFA,0xFB,0xFB,0xF9, + 0xF7,0xF6,0xD7,0xF6,0x96,0xFE,0xAA,0xA2,0xF7,0xF6,0xD7,0xF6,0xD7,0x5D,0x55,0x58, + 0xF7,0xF6,0xD7,0xF6,0x88,0x2B,0xEF,0x2C,0xF7,0xF6,0xD7,0xF6,0xB4,0xD4,0xFE,0xFA, + 0xF7,0xF6,0xD7,0xF6,0xAF,0xAF,0xED,0xD7,0xF7,0xF6,0x97,0xEE,0xA8,0xAA,0x80,0xEA, + 0xD7,0xF6,0xB7,0xEE,0x08,0x02,0x82,0xAC,0xD7,0xF6,0x96,0xEE,0xA8,0xA0,0xE8,0xFA, + 0xB7,0xF6,0x55,0xEE,0xA0,0xE8,0xE2,0x7E,0x75,0xEE,0x35,0xE6,0xB0,0xA8,0xEE,0xFF, + 0x96,0xEE,0x55,0xE6,0x3D,0x0D,0x0B,0x0B,0xD7,0xF6,0xB7,0xF6,0x8D,0x35,0xE9,0xFD, + 0xD7,0xF6,0xB6,0xF6,0x38,0xF8,0xE2,0x77,0xD7,0xF6,0x76,0xEE,0xA8,0xAA,0xE8,0x7A, + 0x76,0xEE,0xD4,0xD5,0xD8,0x5C,0x7E,0x5A,0x55,0xEE,0xD4,0xDD,0x2F,0xAD,0xAD,0xBD, + 0x75,0xEE,0x55,0xE6,0x09,0x2F,0x37,0x05,0x96,0xEE,0x75,0xEE,0xFF,0xEE,0x77,0x57, + 0x76,0xEE,0xD3,0xD5,0x68,0x70,0x60,0xFA,0xF4,0xDD,0x92,0xCD,0x37,0x3D,0x37,0x3F, + 0x55,0xEE,0xF4,0xDD,0x2F,0x29,0x29,0x2D,0x55,0xEE,0x35,0xE6,0xE2,0x68,0xEA,0x8A, + 0x55,0xEE,0xB3,0xDD,0xFA,0x7E,0x7E,0xF0,0xF4,0xDD,0x92,0xD5,0x4A,0x7A,0x4A,0xC2, + 0x72,0xCD,0xCF,0xBC,0x56,0xF6,0xBE,0xF8,0x92,0xD5,0xF0,0xBC,0xAD,0x2F,0x2F,0x2F, + 0xB3,0xDD,0x72,0xD5,0x2D,0xBD,0xDF,0x7D,0xB3,0xDD,0x51,0xCD,0xA0,0x6C,0xFA,0x5F, + 0xB2,0xD5,0x31,0xCD,0xA8,0xFF,0x77,0x55,0x72,0xCD,0x31,0xCD,0x80,0x8A,0x2B,0x3D, + 0xB3,0xDD,0x51,0xCD,0xB5,0xBF,0x2F,0x2B,0xF4,0xE5,0xB3,0xD5,0xBF,0xB7,0xFF,0x35, + 0x55,0xE6,0xF4,0xDD,0x2D,0xAD,0x2F,0xEB,0x55,0xE6,0x14,0xE6,0xFE,0xAE,0x2F,0x2B, + 0xD6,0xF6,0xB6,0xF6,0xE2,0xEA,0xBE,0x7E,0xD6,0xF6,0xB6,0xEE,0x22,0xE2,0xA0,0x2A, + 0xD6,0xF6,0xB6,0xEE,0x02,0x88,0x22,0x08,0xD6,0xF6,0xF8,0xEE,0x88,0x20,0xAA,0x28, + 0xD6,0xF6,0xB7,0xEE,0xA2,0xA8,0x00,0x02,0xF7,0xF6,0xD6,0xF6,0xF7,0xE7,0x7F,0x5D, + 0xB6,0xF6,0xF6,0xEE,0xAB,0xEF,0xAB,0xAF,0xF6,0xF6,0xB6,0xEE,0x8A,0xA2,0xAA,0xBF, + 0xF6,0xF6,0xB6,0xEE,0xFE,0xBE,0xBA,0xAA,0xD6,0xF6,0xB6,0xEE,0x82,0xA0,0x8A,0x28, + 0xD6,0xF6,0xF7,0xEE,0xA8,0x80,0x02,0x80,0xF6,0xF6,0xB6,0xEE,0xFA,0xBA,0xBF,0xFE, + 0xD6,0xF6,0xB6,0xEE,0xEE,0xBA,0x2A,0x00,0xD6,0xF6,0xB6,0xEE,0xB7,0x7B,0xEA,0x00, + 0xD6,0xF6,0xB6,0xEE,0xFF,0xEB,0x8A,0x22,0xD6,0xF6,0xB6,0xF6,0xDD,0xEE,0x68,0xA8, + 0xB6,0xF6,0xD6,0xEE,0x82,0xAA,0xE8,0xFE,0xB6,0xF6,0xD5,0xEE,0xAA,0xAA,0xF8,0xEA, + 0xB6,0xF6,0xD6,0xEE,0xEE,0xBA,0xA8,0xF8,0xB6,0xF6,0xD6,0xEE,0xFF,0xEB,0xAA,0x8E, + 0xD6,0xF6,0xB6,0xEE,0x0A,0x23,0x8B,0x0A,0xD6,0xF6,0xF6,0xEE,0x22,0x02,0xA8,0x80, + 0xF7,0xF6,0xB6,0xEE,0xBF,0xAE,0xAA,0xEA,0xD6,0xF6,0xB7,0xF6,0xB8,0xBA,0xBE,0xBC, + 0xD7,0xF6,0x34,0xE6,0xC0,0xE0,0x60,0x68,0x71,0xCD,0x86,0x72,0xF0,0x70,0x78,0x78, + 0x46,0x6A,0x64,0x49,0xF8,0x78,0x5A,0x5E,0xA4,0x51,0x02,0x39,0xE8,0xFA,0x7A,0x7F, + 0x02,0x39,0xA1,0x28,0xF8,0xE0,0xEA,0x56,0xC2,0x30,0x81,0x28,0xF8,0xA8,0xA8,0x00, + 0x03,0x39,0xA2,0x28,0xAB,0x8F,0x6F,0xE7,0xE3,0x38,0xC2,0x30,0x2F,0xEB,0x79,0x7D, + 0x03,0x39,0xC2,0x30,0xA7,0x2B,0x0B,0x85,0x23,0x41,0xE2,0x38,0x57,0xD6,0xAB,0x0A, + 0x44,0x49,0x03,0x39,0xE9,0xB9,0xAB,0xA9,0xE5,0x61,0x43,0x49,0xD5,0x35,0xA5,0x35, + 0x09,0x93,0xA5,0x59,0xBD,0xAF,0xAB,0x2B,0xE9,0x8A,0x87,0x7A,0xFF,0x5B,0x7A,0x60, + 0xA7,0x82,0xC5,0x61,0xA0,0xFA,0x77,0x5E,0x26,0x6A,0x63,0x49,0xF8,0xFA,0xFF,0x57, + 0xE5,0x59,0x02,0x41,0x02,0xA2,0xBF,0xF7,0x06,0x6A,0x84,0x51,0x02,0xAB,0xAF,0xB5, + 0x87,0x7A,0xE6,0x61,0x0F,0x2F,0xA9,0x2D,0x4B,0x93,0x67,0x72,0x0B,0x2B,0xBD,0xF5, + 0x8B,0x9B,0xA8,0x82,0x08,0xAA,0xAF,0xF5,0x0C,0xAC,0x09,0x93,0x08,0x2F,0xBF,0xF5, + 0x2D,0xBC,0x8B,0xA3,0x82,0x02,0x2A,0xA9,0x2D,0xB4,0xAB,0xA3,0x7C,0xFA,0xFA,0x7A, + 0xCC,0xAB,0x6A,0x9B,0x6B,0x6A,0xE8,0xBE,0x6A,0xA3,0xC8,0x8A,0xFA,0x78,0xE0,0xC8, + 0x49,0x9B,0xA7,0x82,0x0A,0xAB,0xFB,0x5F,0x4A,0x9B,0x87,0x7A,0xA0,0xFA,0x7F,0x56, + 0x09,0x93,0x46,0x7A,0x60,0xEA,0xAA,0xAB,0x0A,0x93,0x27,0x72,0x7D,0xF7,0xAA,0x02, + 0x09,0x93,0x68,0x7A,0x35,0xA7,0x2B,0x02,0xEF,0xC4,0x09,0x8B,0x3D,0x25,0x2D,0xAD, + 0xB6,0xFE,0x51,0xD5,0x0B,0x0B,0x09,0x0D,0x18,0xFF,0xD7,0xFE,0xEB,0xAB,0x29,0xAF, + 0x18,0xFF,0xF7,0xFE,0xAB,0x7E,0x7A,0x7E,0x18,0xFF,0xF7,0xFE,0x0A,0x09,0xAB,0xAA, + 0x17,0xFF,0xF8,0xF6,0x22,0x82,0x0A,0x02,0x17,0xFF,0xF8,0xF6,0xB8,0xE8,0x20,0x80, + 0x18,0xFF,0xD7,0xF6,0x28,0x80,0x80,0x78,0xF7,0xF6,0xD7,0xF6,0xE0,0xE8,0xFE,0x77, + 0xF7,0xF6,0xD7,0xF6,0xF9,0xAD,0xBD,0xA7,0x18,0xFF,0xD7,0xF6,0xAF,0xAD,0xBF,0xAF, + 0x38,0xFF,0xF7,0xFE,0xBB,0xAF,0x09,0x02,0x59,0xFF,0x39,0xFF,0xF5,0xF5,0xED,0xFB, + 0x59,0xFF,0x18,0xFF,0x8A,0xAA,0xEA,0x7E,0x18,0xFF,0x96,0xEE,0x70,0x78,0x58,0x5E, + 0x96,0xEE,0x55,0xE6,0x5E,0x7A,0xFA,0xFA,0x18,0xFF,0x76,0xEE,0x2D,0x29,0x8F,0x0B, + 0x18,0xFF,0x19,0xF7,0x22,0x88,0x82,0x22,0x39,0xFF,0x18,0xFF,0xF9,0xED,0xB9,0x9D, + 0x39,0xFF,0x18,0xFF,0x7F,0x7E,0x5E,0x7E,0x18,0xFF,0xF8,0xF6,0xFE,0xEA,0xA8,0x2A, + 0x18,0xFF,0xF8,0xF6,0xFF,0xFA,0xBF,0x77,0xF7,0xFE,0xF8,0xF6,0x7F,0xDF,0x7F,0x75, + 0x18,0xFF,0xF8,0xF6,0xA9,0xC9,0xB9,0xBB,0xF8,0xFE,0x18,0xF7,0x5E,0xFE,0xFE,0xEE, + 0x18,0xFF,0xF7,0xEE,0x22,0x0A,0x22,0xA8,0x18,0xFF,0xF7,0xF6,0x76,0x7E,0xF8,0x78, + 0xF7,0xF6,0xB7,0xEE,0xFA,0x7A,0x7C,0xFC,0x96,0xF6,0xB6,0xEE,0x2B,0xAD,0xFE,0xFD, + 0xB7,0xF6,0x96,0xEE,0x55,0x77,0xF8,0xF8,0xD6,0xF6,0x75,0xEE,0xF5,0xDD,0xF7,0xBF, + 0xD7,0xF6,0x96,0xEE,0x03,0x0B,0x2F,0x2B,0x18,0xFF,0xD7,0xF6,0xAF,0xAA,0xAB,0xE9, + 0xF7,0xF6,0xD7,0xF6,0xA8,0xA8,0xA8,0xA8,0x18,0xFF,0xD7,0xF6,0xAA,0x8B,0x2B,0xAD, + 0x18,0xFF,0xD7,0xF6,0xFE,0xFA,0xB8,0x28,0x18,0xF7,0xD7,0xF6,0xEF,0xFF,0xFE,0xA8, + 0x18,0xF7,0xD7,0xF6,0xF7,0xFF,0xBB,0xAB,0x18,0xFF,0xD7,0xF6,0xF5,0xFF,0xAE,0xBE, + 0x18,0xFF,0xD7,0xF6,0xEE,0xAE,0xFE,0xFE,0xD8,0xFE,0xF7,0xF6,0xF5,0xFD,0xF5,0xF5, + 0xF7,0xF6,0xD7,0xF6,0x28,0xAA,0xAF,0xEA,0xF7,0xF6,0xB6,0xEE,0xA0,0xEA,0x7C,0x7E, + 0xF7,0xF6,0x96,0xEE,0xAA,0x2B,0xBF,0xD5,0xD7,0xF6,0x96,0xEE,0xA0,0xF8,0x5E,0x5F, + 0xB6,0xEE,0x76,0xEE,0x28,0xAA,0xDB,0x5D,0xB6,0xF6,0x35,0xE6,0x80,0xAA,0xFA,0x7F, + 0x96,0xEE,0x35,0xE6,0x68,0xEE,0xFF,0xFF,0x96,0xEE,0x35,0xE6,0xBD,0xAB,0xAB,0x0A, + 0x76,0xF6,0x96,0xEE,0x7E,0x7F,0x5F,0xDD,0xD7,0xF6,0xB7,0xF6,0xED,0xAB,0xDB,0xC3, + 0xB6,0xF6,0x96,0xEE,0x6C,0xFE,0xB7,0xF6,0xB6,0xF6,0x76,0xEE,0x7B,0xFF,0xEA,0x82, + 0x56,0xEE,0xB3,0xD5,0x58,0x78,0x7C,0xD8,0x35,0xE6,0xD3,0xD5,0x35,0x2D,0xAB,0xBF, + 0x76,0xEE,0x35,0xE6,0x0D,0x2D,0xA5,0xB5,0x76,0xEE,0x55,0xE6,0xE0,0xE0,0xE0,0x73, + 0x55,0xE6,0xB2,0xD5,0xE0,0x70,0x68,0x70,0xF3,0xDD,0xB2,0xD5,0x35,0xA7,0xB5,0x95, + 0x55,0xEE,0xF4,0xDD,0xA9,0x29,0xAD,0xBB,0x76,0xEE,0xD3,0xDD,0x8A,0x8A,0xAA,0xDF, + 0x55,0xEE,0xD3,0xDD,0x68,0xFA,0xE2,0xEB,0x14,0xE6,0xB3,0xD5,0x7F,0x62,0xE2,0xEA, + 0x72,0xCD,0x8F,0xB4,0xE8,0xF8,0xFC,0xDE,0x72,0xD5,0xD0,0xBC,0x2B,0x2B,0xA9,0x2D, + 0x92,0xD5,0x52,0xCD,0xB2,0xEF,0xFF,0xDF,0x72,0xCD,0x31,0xCD,0xC8,0xF2,0x42,0x5A, + 0x71,0xCD,0x31,0xC5,0x55,0xFE,0xBD,0x35,0xB3,0xD5,0x31,0xC5,0xAD,0xAB,0xAF,0x0A, + 0xB3,0xD5,0x92,0xD5,0xC9,0xC1,0xB9,0xDD,0xF4,0xDD,0x92,0xD5,0x2F,0xAE,0xA7,0x3B, + 0x14,0xE6,0xD3,0xDD,0x00,0x0A,0xEF,0x5B,0x75,0xEE,0xF4,0xDD,0x2B,0xAF,0xAF,0xBD, + 0xB6,0xF6,0x50,0xC5,0x00,0x00,0x82,0xB5,0xD6,0xF6,0x55,0xEE,0x08,0x0A,0x8A,0xA9, + 0xD6,0xF6,0xB6,0xEE,0x28,0xA2,0xAA,0xFE,0xD6,0xF6,0xB6,0xEE,0x02,0x80,0xA3,0xE2, + 0xD6,0xF6,0xB6,0xEE,0xAA,0xAA,0xA8,0xAA,0xD6,0xF6,0xD7,0xEE,0xAA,0x2A,0x8A,0x20, + 0xF8,0xF6,0xD6,0xF6,0x77,0x7D,0xE5,0xBD,0xF7,0xF6,0xB6,0xEE,0xBF,0xEE,0xBA,0xEA, + 0xF6,0xF6,0xB6,0xEE,0xAA,0xAB,0xEB,0xFF,0xD6,0xF6,0xD6,0xEE,0xA8,0x2A,0xAA,0xAA, + 0xD6,0xF6,0xF6,0xEE,0x00,0xA0,0x8A,0xA0,0xD6,0xF6,0xF7,0xEE,0x08,0x88,0x08,0x02, + 0xD6,0xF6,0xF6,0xEE,0x88,0x00,0x80,0xA2,0xF7,0xF6,0xD6,0xF6,0xE7,0xA5,0xB5,0xD5, + 0xF7,0xF6,0xD6,0xF6,0x55,0x75,0xF7,0x5F,0xD6,0xF6,0xD6,0xF6,0x00,0x00,0x00,0x00, + 0xF7,0xF6,0xD6,0xF6,0x55,0x55,0x75,0xFD,0xD6,0xF6,0xB6,0xEE,0x3B,0x83,0x8B,0x80, + 0xD6,0xF6,0xB6,0xF6,0x0C,0x8A,0x88,0x00,0xD6,0xF6,0xB6,0xF6,0x9A,0x9A,0x3A,0xBE, + 0xD6,0xF6,0xB6,0xEE,0x08,0x28,0x2A,0xBA,0xD6,0xF6,0xB6,0xEE,0x00,0x28,0x2A,0x02, + 0xD6,0xF6,0xB6,0xF6,0x20,0xE0,0x60,0xB8,0xF7,0xF6,0xB6,0xF6,0xFA,0xDF,0x7F,0xDF, + 0xD6,0xF6,0xB2,0xD5,0xE0,0x60,0x60,0x68,0xCE,0xBC,0x05,0x62,0x78,0x78,0x78,0x58, + 0xC5,0x59,0x23,0x41,0xE8,0xE8,0x5C,0xEE,0x43,0x41,0xE2,0x30,0xC0,0xE0,0xFE,0x78, + 0x02,0x31,0xA1,0x28,0x7A,0x78,0xD8,0x5E,0xE2,0x28,0x81,0x28,0xE2,0xFE,0xFA,0xF7, + 0xC1,0x28,0x80,0x28,0x28,0x28,0xFB,0xBF,0x03,0x31,0xA2,0x28,0x2B,0x2F,0xB9,0xEB, + 0x02,0x31,0xC2,0x30,0x07,0xAF,0xAD,0xAF,0x23,0x41,0xE2,0x30,0x0A,0x2B,0xA9,0xE9, + 0x43,0x49,0x03,0x41,0x8B,0x02,0x23,0x29,0x26,0x6A,0x64,0x51,0xB5,0x2D,0x2D,0x2D, + 0x09,0x8B,0x66,0x7A,0x0D,0x09,0x09,0x29,0x29,0x93,0xA7,0x82,0xDA,0xF8,0xE8,0x70, + 0x87,0x7A,0xA5,0x59,0x58,0x5C,0x5C,0x7C,0x85,0x59,0x03,0x41,0xF8,0x7E,0x77,0x5F, + 0x23,0x49,0xE2,0x38,0x2C,0xAF,0xDE,0xFE,0xC6,0x61,0xE2,0x38,0x0A,0xAF,0xFF,0xF5, + 0x46,0x6A,0x64,0x51,0x0A,0x2B,0xAD,0xBD,0xA8,0x7A,0x06,0x62,0x0B,0xBF,0xF7,0xFD, + 0xC9,0x82,0x26,0x6A,0x22,0xA2,0xB7,0xF5,0x2A,0x93,0x87,0x7A,0x0A,0x0A,0xAF,0xBD, + 0xEC,0xAB,0x09,0x93,0x2B,0xAF,0xAD,0xB5,0xEC,0xAB,0xAC,0xAB,0x78,0x72,0x3E,0x3D, + 0xCC,0xAB,0x6A,0xA3,0xFF,0xED,0xAC,0xFC,0xAB,0xA3,0xE9,0x8A,0xEA,0xE8,0xE0,0x78, + 0xE8,0x8A,0x67,0x7A,0xF8,0x78,0x7E,0x7F,0x87,0x7A,0x46,0x7A,0xBA,0xF6,0x7F,0xA7, + 0x29,0x93,0x67,0x7A,0xB9,0x3D,0xB5,0xAD,0xEC,0xAB,0x0A,0x93,0x7D,0xAF,0x0B,0x03, + 0xAB,0xA3,0x29,0x93,0x75,0x7F,0xEA,0x88,0x6D,0xB4,0x09,0x8B,0x3D,0x35,0x35,0xB7, + 0xD7,0xFE,0x4D,0xB4,0x0B,0x0B,0xAB,0xD5,0xF7,0xFE,0xD3,0xDD,0x00,0x00,0x0A,0x2D, + 0x17,0xFF,0xF8,0xFE,0xDB,0xFE,0xB7,0xF5,0x18,0xFF,0xF8,0xFE,0xAB,0xAE,0xFF,0xA7, + 0x18,0xFF,0xF7,0xFE,0x0A,0x0B,0x2A,0xBE,0x38,0xFF,0xF7,0xF6,0xAA,0xEA,0xFB,0x5F, + 0x18,0xFF,0xB6,0xEE,0xE8,0xFA,0xFA,0x7F,0xD7,0xF6,0xB6,0xEE,0x00,0xA0,0xE2,0xFA, + 0xF7,0xF6,0xB6,0xEE,0xAA,0xFB,0x6D,0xDD,0x39,0xFF,0xB6,0xEE,0xBF,0x2D,0x2D,0x0F, + 0x59,0xFF,0x38,0xFF,0xB5,0xFD,0xAB,0xEE,0x59,0xFF,0x39,0xFF,0xEB,0xEE,0xFA,0x5F, + 0x38,0xFF,0xD7,0xF6,0xC0,0xE0,0xF0,0x68,0xD6,0xEE,0x76,0xEE,0xFC,0xFE,0xFE,0xF7, + 0x96,0xEE,0x55,0xE6,0xD8,0x9C,0xB6,0x37,0x18,0xFF,0x96,0xEE,0x01,0x0B,0x29,0x8B, + 0x18,0xFF,0xF8,0xF6,0x82,0x0A,0x0A,0x22,0x39,0xFF,0x18,0xFF,0x95,0xB5,0xB5,0xFD, + 0x39,0xFF,0x18,0xFF,0x7A,0x7E,0x7A,0x7E,0x18,0xFF,0xF8,0xF6,0xAE,0xBA,0xAA,0xEA, + 0x18,0xFF,0xF8,0xF6,0xDF,0x5E,0x58,0x5E,0x18,0xF7,0xD7,0xF6,0xBF,0xAE,0x2B,0xAA, + 0x18,0xFF,0xF8,0xF6,0xAB,0xEE,0xA9,0xFD,0x18,0xFF,0xF8,0xF6,0xBB,0xDE,0xAE,0xAA, + 0x18,0xFF,0xF8,0xF6,0xAA,0xBF,0xBE,0xAA,0x18,0xFF,0xF8,0xF6,0x58,0x7A,0xEA,0xFE, + 0xF7,0xF6,0xB7,0xF6,0xFE,0xE0,0xE0,0xA0,0xD7,0xF6,0xB6,0xEE,0xEF,0xB5,0x35,0x87, + 0xD7,0xF6,0x96,0xEE,0xFA,0xE0,0xA0,0x20,0xD7,0xF6,0x96,0xEE,0x97,0x9F,0xBE,0xAA, + 0xD7,0xF6,0x96,0xEE,0xAB,0xBF,0xBB,0xB8,0x18,0xFF,0xB6,0xEE,0xAB,0xAF,0xAD,0x2D, + 0xF8,0xFE,0xF7,0xF6,0x5F,0x5F,0xDE,0x5F,0x18,0xF7,0xB7,0xF6,0x0A,0x2A,0x2E,0xAA, + 0x18,0xFF,0xF7,0xF6,0x28,0x28,0x0A,0xAF,0x18,0xFF,0xF8,0xF6,0xA8,0xA0,0xE8,0xB8, + 0x18,0xFF,0xF7,0xF6,0x7E,0x5D,0x7D,0xEA,0x17,0xFF,0xF8,0xF6,0xFD,0xDD,0xDF,0xB7, + 0x18,0xFF,0xD7,0xF6,0xFE,0xDE,0xDA,0xEA,0xF8,0xFE,0xF7,0xF6,0xFF,0xFB,0xFF,0xF7, + 0xF7,0xF6,0xD7,0xF6,0x6F,0xDE,0x5E,0x56,0xD7,0xF6,0x96,0xEE,0xF8,0xEA,0xA8,0xBA, + 0xB7,0xF6,0x96,0xEE,0x77,0xEB,0x80,0xA0,0x97,0xEE,0x76,0xEE,0xD8,0x5C,0x5C,0xDC, + 0x96,0xEE,0x76,0xEE,0x55,0xA5,0x9F,0xFE,0x96,0xEE,0x35,0xE6,0x7E,0xF8,0xB2,0xAA, + 0x96,0xEE,0x55,0xEE,0xD5,0xBD,0x2B,0xAA,0x96,0xEE,0x76,0xEE,0xAD,0x3B,0x00,0xA3, + 0xB6,0xF6,0x76,0xEE,0xAB,0x89,0xAF,0x3F,0xD7,0xF6,0x96,0xEE,0x22,0xAB,0x6B,0x7F, + 0xB6,0xF6,0x76,0xEE,0xAE,0x2A,0xBA,0xF7,0xB6,0xF6,0x96,0xEE,0xA2,0x8A,0xE2,0x63, + 0x76,0xEE,0xD3,0xD5,0x5C,0x58,0x7E,0x5C,0x14,0xE6,0xD3,0xD5,0xAB,0x2D,0x2F,0xA5, + 0x55,0xEE,0x14,0xE6,0x0B,0x8B,0x8B,0x09,0x75,0xEE,0x35,0xE6,0xF3,0xBF,0xBF,0xAB, + 0x75,0xEE,0xB2,0xD5,0x78,0x78,0x7E,0x7A,0xF3,0xDD,0x92,0xD5,0x35,0xAD,0xB5,0xBD, + 0x34,0xE6,0xD3,0xDD,0x8B,0xEB,0x7B,0x7B,0xD4,0xDD,0x30,0xC5,0x28,0xBC,0xFC,0x57, + 0x14,0xE6,0x71,0xCD,0x00,0x2B,0xAD,0xF5,0x14,0xE6,0x92,0xD5,0xE0,0xCA,0xE2,0x4A, + 0x51,0xCD,0x2D,0xAC,0xF8,0xFC,0xFC,0xDC,0x72,0xD5,0xD0,0xBC,0x8D,0x2D,0xAD,0x2D, + 0x72,0xCD,0x10,0xC5,0xE0,0xA0,0x88,0x60,0x51,0xCD,0x11,0xC5,0xB3,0x8F,0xBF,0xF9, + 0x71,0xCD,0x31,0xC5,0xAD,0x3F,0xED,0xF7,0xB3,0xD5,0x72,0xD5,0x95,0xAD,0xEF,0xA5, + 0xB3,0xD5,0x51,0xD5,0xBA,0x22,0x22,0x0A,0x14,0xE6,0xB3,0xD5,0x9D,0xAD,0xBF,0xAD, + 0xF4,0xDD,0xB3,0xDD,0xB8,0x38,0xB2,0xDE,0x35,0xE6,0xD3,0xDD,0x2B,0xAF,0xDB,0x77, + 0xCE,0xBC,0xE8,0x82,0x2B,0xF5,0x55,0x55,0x14,0xE6,0x29,0x8B,0x02,0xBF,0x75,0x55, + 0x95,0xEE,0x8A,0x93,0x00,0x02,0xBD,0x55,0x95,0xEE,0x4D,0xAC,0x00,0x00,0x0A,0xB5, + 0xB6,0xF6,0x13,0xDE,0x00,0x00,0x00,0x0D,0xD6,0xF6,0xB6,0xF6,0x08,0xAA,0x8A,0x75, + 0x17,0xFF,0xB6,0xF6,0xFF,0xFF,0x9D,0xD7,0xD7,0xF6,0xB6,0xF6,0x00,0x08,0xAA,0xAE, + 0xD7,0xF6,0xB6,0xF6,0xAC,0x2A,0xAB,0x08,0xF7,0xFE,0xD6,0xF6,0x55,0x55,0xFD,0xB7, + 0xF7,0xF6,0xD6,0xF6,0xB5,0x9F,0x5B,0x7F,0xF7,0xF6,0xD6,0xF6,0x57,0x57,0x37,0xF5, + 0xF7,0xF6,0xD6,0xF6,0xFB,0x7A,0x7E,0x7A,0xF7,0xFE,0xD6,0xF6,0x55,0xF5,0xB7,0xFD, + 0xF6,0xF6,0xD6,0xF6,0x5D,0x7D,0x6A,0x5A,0xF7,0xF6,0xD6,0xF6,0xD5,0xD7,0x57,0x5F, + 0xF6,0xFE,0xD6,0xF6,0xE7,0xFF,0x57,0x59,0xF6,0xF6,0xB7,0xF6,0xAA,0xEB,0xAF,0xFF, + 0xF7,0xF6,0xD6,0xF6,0xA5,0xAF,0x3E,0xFF,0xF7,0xFE,0xD6,0xF6,0x55,0x57,0x5F,0xF7, + 0xD6,0xF6,0xB6,0xF6,0xBC,0xAA,0xA0,0x08,0xD6,0xF6,0xB6,0xF6,0x8E,0xA7,0xAF,0x0A, + 0xD6,0xF6,0xB6,0xF6,0xEC,0xF8,0x88,0x20,0xD6,0xF6,0xB6,0xF6,0xAB,0xEB,0xCA,0xAA, + 0xB6,0xF6,0xB3,0xD5,0x60,0x60,0x60,0x60,0x6E,0xB4,0x63,0x49,0xF8,0x78,0x78,0x78, + 0x84,0x49,0x23,0x41,0xE0,0xF0,0x78,0x7A,0x43,0x41,0xE2,0x30,0x78,0xF8,0x7E,0xF5, + 0xE2,0x30,0x81,0x28,0xEA,0x6A,0x58,0x78,0xA1,0x28,0x40,0x20,0x08,0x22,0xBC,0xB7, + 0xC2,0x28,0x81,0x20,0xBF,0x25,0x25,0x0D,0xE2,0x30,0xA1,0x28,0x0A,0x0B,0xAD,0x3F, + 0x03,0x31,0xC2,0x30,0xEA,0xFA,0xFB,0xE9,0x02,0x39,0xC2,0x30,0x8F,0xAF,0xAB,0x8A, + 0x44,0x49,0xE2,0x38,0x09,0x0F,0xAF,0x2D,0x26,0x72,0x64,0x51,0x2D,0x3D,0x0D,0x2D, + 0x29,0x93,0x87,0x7A,0x29,0x0D,0xBF,0xB5,0x2A,0x93,0xA8,0x82,0xE8,0xB2,0x78,0x6A, + 0x88,0x7A,0x44,0x49,0xF8,0x78,0x78,0x7A,0x44,0x49,0xE2,0x38,0xB8,0x78,0x78,0x5C, + 0x02,0x39,0xC2,0x38,0xAC,0xB6,0xD7,0xDF,0x44,0x49,0xE3,0x38,0x2D,0x27,0x2D,0x29, + 0x05,0x62,0x43,0x49,0x8B,0x3D,0xB5,0xFD,0x26,0x6A,0xA5,0x51,0x0A,0xAB,0xA5,0x2D, + 0x87,0x72,0x06,0x62,0x3B,0xAF,0x0D,0xBF,0x09,0x8B,0x66,0x72,0x3D,0xBD,0xED,0xFF, + 0x29,0x93,0xC8,0x82,0x0E,0x2E,0xFD,0xB5,0xAB,0xAB,0xE8,0x8A,0x03,0x2B,0xAD,0x95, + 0xAB,0xA3,0x4A,0x9B,0x2A,0xA0,0xEA,0x75,0x6A,0x9B,0xC8,0x82,0xE0,0xE0,0x78,0x7E, + 0xA8,0x82,0x47,0x72,0xEA,0xFA,0xFE,0xDE,0xC8,0x8A,0x46,0x7A,0xB7,0xBD,0x0F,0x0B, + 0x4A,0x93,0xA8,0x82,0xAD,0x2B,0x2B,0x2B,0x0C,0xAC,0x4A,0x9B,0x0F,0x0B,0x2B,0xAD, + 0x2C,0xB4,0x8B,0x9B,0x5E,0x68,0x68,0x6A,0x2A,0x93,0x66,0x72,0xA0,0x78,0x78,0x78, + 0x6A,0x93,0x06,0x6A,0x0A,0xEF,0xF5,0xD5,0xF4,0xE5,0x87,0x7A,0x0B,0xBF,0xF5,0x55, + 0xB6,0xF6,0x86,0x72,0x00,0x0A,0xBF,0xD5,0xD7,0xFE,0xCE,0xBC,0x00,0x02,0x0B,0x2D, + 0x18,0xFF,0xD7,0xFE,0xA2,0x22,0xA3,0xEF,0xF7,0xFE,0x96,0xF6,0x80,0xF0,0x7A,0xFA, + 0xB6,0xF6,0xD6,0xE6,0x88,0x88,0x08,0x20,0xD6,0xF6,0xB6,0xEE,0xAA,0xCF,0xE9,0x7F, + 0x18,0xFF,0xB6,0xEE,0xD5,0x95,0xBD,0x2D,0x59,0xFF,0xF7,0xFE,0xAD,0x2B,0x22,0x8A, + 0x59,0xFF,0x38,0xFF,0xEA,0xFE,0xFF,0x7B,0x59,0xFF,0x18,0xFF,0xAE,0xFA,0xFA,0xEE, + 0x38,0xFF,0x56,0xEE,0xE0,0xE8,0xEA,0x78,0x96,0xEE,0x55,0xE6,0xC8,0xAA,0xEB,0xFF, + 0xB6,0xF6,0x34,0xE6,0x3F,0xAF,0xBF,0x35,0x18,0xFF,0xD7,0xF6,0xBD,0x2D,0xA5,0xAD, + 0x18,0xFF,0xF8,0xF6,0x0E,0x22,0x0A,0x23,0x38,0xFF,0x19,0xFF,0xBF,0xEB,0xBD,0xAD, + 0x39,0xFF,0x18,0xFF,0x5E,0xDF,0xDE,0x7E,0x18,0xFF,0xF8,0xF6,0xE2,0xE0,0xAA,0xB8, + 0x18,0xFF,0xF8,0xF6,0x77,0x57,0x5D,0x5D,0x18,0xFF,0xF8,0xF6,0x5F,0x7F,0xEF,0xEF, + 0x18,0xFF,0xF8,0xF6,0xED,0xFB,0xBB,0xFD,0x18,0xFF,0xF8,0xF6,0xEA,0xEB,0xE9,0xF7, + 0x18,0xFF,0xF8,0xF6,0xAA,0xAA,0xEF,0xAA,0x18,0xFF,0xF8,0xF6,0xFE,0xDE,0xFE,0x5E, + 0xF8,0xF6,0xD7,0xF6,0x60,0x70,0x5C,0x79,0xD7,0xF6,0xB7,0xEE,0x2F,0x0B,0x2A,0x0E, + 0xF8,0xF6,0xB6,0xEE,0x6E,0xEA,0x8A,0xAA,0xF7,0xF6,0xB6,0xEE,0x9F,0xBB,0xAA,0xB2, + 0xD7,0xF6,0xB6,0xEE,0x7E,0xE8,0x2A,0x0A,0xF7,0xFE,0xD6,0xEE,0x2D,0x2F,0xBD,0xAF, + 0x18,0xFF,0xF7,0xF6,0x7F,0x77,0xFF,0x7B,0x18,0xF7,0xD7,0xF6,0xBF,0xFF,0xAF,0xAE, + 0xF8,0xFE,0x18,0xF7,0xFE,0xFE,0xFF,0xFA,0x18,0xFF,0xF7,0xF6,0xEE,0xBB,0xAE,0xAF, + 0x18,0xFF,0xF7,0xF6,0xAA,0xAA,0x20,0xA2,0x18,0xFF,0xF7,0xF6,0xE7,0x97,0xD6,0xF7, + 0x18,0xFF,0xF7,0xF6,0x7D,0x5E,0x76,0x6F,0xD7,0xFE,0xF7,0xF6,0xF7,0xFF,0xDF,0xF7, + 0xF7,0xF6,0x96,0xEE,0xA8,0xBA,0xFA,0x7E,0xD7,0xF6,0x96,0xEE,0xBA,0xFA,0xFA,0xFF, + 0xB6,0xF6,0x96,0xEE,0xC0,0xE0,0xDB,0x5F,0x96,0xEE,0x76,0xEE,0x88,0x20,0xA3,0xAD, + 0x96,0xEE,0x76,0xEE,0xFD,0x6E,0x76,0x5F,0x75,0xEE,0x55,0xE6,0x2A,0xE8,0x7A,0xEE, + 0x76,0xEE,0x55,0xE6,0xCC,0xE7,0xB5,0xF5,0x76,0xEE,0x55,0xE6,0x00,0x8B,0x22,0x2A, + 0xB6,0xF6,0x76,0xEE,0xAF,0x89,0xAD,0x2D,0xB6,0xF6,0x76,0xEE,0xAA,0xE2,0xFA,0x6A, + 0x96,0xF6,0x76,0xEE,0x3E,0x0B,0x09,0x2B,0xB6,0xF6,0x76,0xEE,0x8A,0xC2,0xCA,0x48, + 0x55,0xE6,0x92,0xCD,0x78,0x5C,0x5C,0x5A,0x15,0xE6,0x92,0xD5,0x2F,0xAB,0xAD,0xB5, + 0x55,0xEE,0xF4,0xE5,0x2A,0xAF,0x09,0x2B,0x76,0xEE,0x55,0xEE,0xDD,0xF5,0xD9,0x5F, + 0x55,0xEE,0xB2,0xD5,0x78,0x78,0x6A,0x78,0xD3,0xDD,0x92,0xD5,0x0B,0x29,0x2E,0x2B, + 0x14,0xE6,0xB2,0xD5,0x63,0x63,0x6A,0x62,0x92,0xD5,0xF0,0xBC,0xFE,0xDE,0x7E,0x5C, + 0x92,0xD5,0xEF,0xC4,0x2B,0xBD,0xB5,0xFF,0xD4,0xDD,0x71,0xCD,0xCA,0x8F,0xCF,0x85, + 0x51,0xCD,0x2D,0xAC,0xDC,0x5C,0xDE,0xDC,0x51,0xCD,0xAF,0xB4,0x89,0x21,0xA9,0x2D, + 0x51,0xCD,0xD0,0xBC,0xE0,0xFA,0xF6,0xDE,0x51,0xCD,0xF0,0xC4,0x9F,0x2D,0x2F,0xA9, + 0x71,0xD5,0x31,0xC5,0x9B,0xAD,0x3F,0x9F,0x92,0xD5,0x52,0xCD,0x2A,0x8B,0x2B,0xAF, + 0xB3,0xD5,0x92,0xD5,0xDF,0x35,0x25,0x95,0xF3,0xDD,0xB3,0xD5,0xAD,0xC9,0xFB,0xFF, + 0xD3,0xDD,0xB2,0xD5,0x3D,0xAD,0x7D,0xFD,0xD3,0xDD,0x71,0xCD,0x08,0xE8,0x78,0x5E, + 0xE8,0x82,0xA7,0x7A,0x0E,0x80,0x3A,0x98,0x08,0x83,0xC8,0x82,0x28,0xAE,0xCB,0x0F, + 0x28,0x8B,0xC7,0x7A,0x0A,0xBB,0xEF,0xDF,0xEB,0x9B,0xC7,0x7A,0x2B,0xFF,0x7F,0xD7, + 0x91,0xD5,0x08,0x83,0x0A,0xFD,0x55,0x55,0x75,0xEE,0x49,0x8B,0x00,0x2B,0xF5,0x55, + 0x95,0xEE,0xE8,0x82,0x00,0x00,0x2A,0xBD,0xD6,0xF6,0x50,0xCD,0x00,0x02,0x2A,0xBD, + 0xD6,0xF6,0x54,0xEE,0x00,0x08,0x82,0xAD,0xD6,0xF6,0xB6,0xF6,0x28,0x22,0x0A,0x8D, + 0xF7,0xF6,0xB6,0xF6,0xAE,0x2F,0xEF,0xBF,0xF7,0xFE,0xB6,0xF6,0xBB,0xBA,0xFE,0x7A, + 0xD6,0xF6,0xB6,0xF6,0x00,0x80,0xA3,0xAA,0x16,0xF7,0xB6,0xF6,0xEF,0xDD,0xFF,0x55, + 0xF7,0xFE,0xD6,0xF6,0x7F,0x5D,0xD5,0x5D,0xF6,0xF6,0xD6,0xF6,0x7D,0xD5,0xFD,0x77, + 0xF7,0xF6,0xD6,0xF6,0x56,0xFE,0x5E,0x57,0xD6,0xF6,0xB6,0xF6,0xE0,0xB0,0x00,0x00, + 0xF7,0xFE,0xB6,0xF6,0xBB,0xFF,0xFB,0xAA,0xD7,0xF6,0xD6,0xF6,0xFD,0xF5,0xFF,0xEE, + 0xD7,0xF6,0xD6,0xF6,0xAD,0xBF,0xBD,0xF5,0xB6,0xFE,0xF7,0xF6,0xFA,0xFB,0xEE,0x7A, + 0xF6,0xF6,0xD6,0xF6,0x57,0xB7,0xEF,0xAB,0xB7,0xFE,0xF6,0xF6,0xBA,0xAF,0xFF,0xEF, + 0xD6,0xF6,0xB3,0xD5,0x60,0xE8,0xC0,0xC0,0xEF,0xBC,0x43,0x49,0x78,0x78,0x78,0x78, + 0x64,0x49,0x02,0x39,0xFC,0xFE,0x7B,0xFE,0x23,0x41,0xE2,0x38,0x7D,0x6E,0xF8,0xE0, + 0x23,0x39,0x80,0x28,0x7E,0xFA,0xAA,0x22,0x03,0x39,0x60,0x20,0xD5,0xFF,0xBA,0x20, + 0x02,0x31,0x81,0x20,0xAD,0xA1,0xBA,0xA8,0x02,0x39,0xC2,0x30,0xBD,0xAB,0xAF,0xAB, + 0x23,0x39,0xC2,0x30,0x7D,0xEF,0xEA,0xCB,0x03,0x39,0xC2,0x30,0x2E,0xB7,0xA7,0xFB, + 0x84,0x59,0xE3,0x38,0xBD,0xAD,0x37,0x25,0x87,0x7A,0x64,0x59,0xAD,0x2D,0x2F,0x2F, + 0xE9,0x8A,0x87,0x7A,0x09,0xA9,0xA9,0xF5,0xE9,0x8A,0x05,0x6A,0x80,0x80,0xE2,0x7B, + 0x47,0x72,0xE3,0x38,0xF0,0xE8,0xF8,0x7F,0x24,0x41,0xA1,0x30,0xF0,0xFA,0x7C,0xFE, + 0xE2,0x38,0xC2,0x30,0xFD,0x2D,0x39,0xBB,0x44,0x49,0xC2,0x38,0x8F,0x2F,0xAF,0x6D, + 0xA5,0x51,0x81,0x28,0x02,0xAA,0xFE,0x5D,0xA5,0x51,0x61,0x28,0x00,0xAA,0xDF,0x75, + 0xE5,0x61,0xA2,0x30,0x00,0xAB,0x7D,0x55,0x46,0x6A,0xE3,0x40,0x00,0x0A,0xBD,0xD5, + 0xE8,0x8A,0x84,0x51,0x02,0x8A,0xAF,0xBD,0x29,0x93,0x87,0x7A,0x2A,0xAB,0xBF,0xB5, + 0x4A,0x9B,0xC8,0x82,0x02,0xAB,0x7F,0x55,0x2A,0x93,0x67,0x7A,0x60,0x60,0xEE,0xEE, + 0xA8,0x82,0x46,0x7A,0x93,0xBF,0xB5,0xAA,0x09,0x8B,0x87,0x7A,0x65,0x3F,0x2F,0xAD, + 0x4A,0x93,0xE9,0x8A,0xAF,0xA3,0xEA,0x7F,0x6A,0x9B,0xC8,0x82,0x2A,0xAF,0x37,0xBD, + 0xCC,0xA3,0xE9,0x8A,0xA0,0xEE,0x7E,0x5F,0x4B,0x93,0xA8,0x82,0x78,0xE8,0x62,0x6F, + 0x87,0x7A,0x06,0x6A,0xD7,0xD8,0x78,0xF8,0x67,0x72,0xC5,0x61,0x0A,0xAE,0x5F,0x7A, + 0x86,0x7A,0xE6,0x61,0x2A,0xA7,0xBD,0xD5,0x54,0xEE,0x29,0x8B,0x0D,0x3D,0x2D,0xB5, + 0xD7,0xFE,0x54,0xEE,0x82,0xAB,0xAF,0xB5,0xB6,0xF6,0x96,0xEE,0x28,0xFA,0x3C,0x0A, + 0xD6,0xF6,0x95,0xEE,0xEF,0xBF,0xEA,0xC0,0xF7,0xF6,0x96,0xEE,0x7E,0xFE,0xBF,0x35, + 0x38,0xFF,0xB6,0xF6,0x2D,0x0B,0x02,0x02,0x59,0xFF,0x39,0xFF,0xAD,0xED,0xFF,0x5D, + 0x58,0xFF,0x39,0xFF,0x5B,0xD7,0xDF,0x75,0x39,0xFF,0xF7,0xFE,0xC0,0xE8,0xF8,0x68, + 0xF8,0xFE,0x75,0xEE,0x58,0x5C,0x5E,0x5F,0x75,0xEE,0x35,0xE6,0xE2,0xE0,0xE2,0xEA, + 0xD7,0xF6,0x34,0xE6,0x35,0xBD,0xBD,0x3D,0x18,0xFF,0xD7,0xF6,0xA9,0xA9,0x2B,0xAB, + 0x18,0xFF,0xF8,0xF6,0x2B,0x2F,0x2F,0x3F,0x38,0xFF,0x19,0xFF,0xEF,0xEB,0x6B,0xFD, + 0x39,0xFF,0x18,0xFF,0xFF,0xFD,0xFD,0xDD,0x18,0xFF,0xF8,0xF6,0xF8,0xA0,0xB0,0xF0, + 0x18,0xFF,0xF8,0xF6,0xDA,0x6A,0xBE,0xF7,0x18,0xFF,0xF8,0xF6,0xFD,0x77,0x57,0x77, + 0xF7,0xFE,0xF8,0xF6,0xEF,0xAF,0xAD,0xFF,0x18,0xFF,0xF8,0xF6,0xBF,0xDB,0xF5,0xF7, + 0x18,0xFF,0xF8,0xF6,0xBA,0x77,0x5F,0xDF,0x18,0xFF,0xD7,0xF6,0xE8,0xBA,0x7E,0x6E, + 0xF8,0xF6,0xD7,0xF6,0x75,0x76,0x5D,0xEF,0xF8,0xF6,0xB6,0xEE,0xA7,0x2F,0x2A,0xAA, + 0xF7,0xF6,0xD7,0xF6,0xAF,0xBF,0xAB,0xF8,0xF7,0xF6,0xD7,0xF6,0xBA,0xAB,0xAB,0xEA, + 0xF7,0xF6,0xD7,0xF6,0x57,0xEF,0xAB,0xA3,0xF8,0xF6,0xD7,0xF6,0xA5,0xA7,0x22,0x0A, + 0x18,0xFF,0xF8,0xF6,0x6A,0xAB,0x8F,0xFF,0x17,0xFF,0xF7,0xF6,0x75,0x57,0x75,0x5F, + 0x18,0xFF,0xF7,0xF6,0xBB,0xFD,0xBD,0xFF,0x18,0xFF,0xF7,0xF6,0xB7,0xBD,0xAF,0xAB, + 0x18,0xFF,0xF8,0xF6,0xBA,0xEE,0xFE,0xBA,0x18,0xFF,0xF7,0xF6,0xDF,0x7F,0xEA,0xEA, + 0xD7,0xFE,0x18,0xF7,0xBF,0xAB,0xAB,0xAF,0xF7,0xF6,0x98,0xEE,0x88,0xA0,0xAA,0xBA, + 0xD7,0xF6,0x96,0xEE,0xE8,0xAA,0x78,0x7E,0xB6,0xF6,0x76,0xEE,0xA8,0xAA,0xEA,0xFA, + 0x96,0xEE,0x56,0xEE,0x00,0x80,0x8A,0xFF,0x96,0xEE,0x55,0xE6,0xAB,0xA8,0xFA,0xFF, + 0x96,0xEE,0x55,0xE6,0xA8,0xBA,0xAF,0xFE,0x75,0xEE,0x35,0xE6,0xA2,0xE0,0xB8,0xFF, + 0x55,0xEE,0x76,0xE6,0xA0,0xAA,0xA8,0xAA,0x96,0xEE,0x55,0xE6,0xBD,0xBD,0xBF,0xAF, + 0xB6,0xF6,0x76,0xEE,0x29,0x23,0xAB,0x2B,0xB6,0xF6,0x76,0xEE,0xF8,0xE8,0xEA,0xFA, + 0xB6,0xF6,0x76,0xEE,0xAD,0xBB,0xAD,0x2F,0xB7,0xF6,0x55,0xE6,0xA0,0xE2,0xC0,0x48, + 0x35,0xE6,0x52,0xCD,0xF8,0xDC,0xDE,0x5A,0xF4,0xDD,0x51,0xCD,0x2A,0xA9,0x3D,0xAD, + 0x55,0xEE,0xD3,0xDD,0x0A,0x8B,0x2F,0xA9,0x75,0xEE,0x35,0xE6,0xFA,0xBE,0xFB,0xDB, + 0x35,0xEE,0xB3,0xD5,0x78,0x58,0x7C,0x7C,0xF4,0xDD,0x92,0xD5,0xAB,0x2F,0x2D,0xAF, + 0x14,0xE6,0xD3,0xDD,0x62,0xE2,0xA2,0xE2,0xF3,0xDD,0x11,0xC5,0x7E,0x7A,0xF8,0xA0, + 0x71,0xCD,0x10,0xC5,0xFD,0x7F,0xD6,0xD8,0xB3,0xD5,0x10,0xC5,0x89,0xAB,0xFD,0xAD, + 0x30,0xC5,0x4D,0xAC,0x5C,0x5C,0x5E,0x54,0x31,0xCD,0x8E,0xB4,0x29,0x8B,0x0D,0x0D, + 0x31,0xCD,0xD0,0xBC,0xFF,0x9E,0xAA,0xA8,0x31,0xC5,0xF0,0xC4,0x0F,0x2B,0xBB,0xEB, + 0x51,0xCD,0x11,0xC5,0x28,0xB2,0xBB,0xFE,0x92,0xD5,0x51,0xCD,0xAB,0xEB,0xAD,0xFD, + 0xB3,0xD5,0x72,0xCD,0x2B,0x27,0xAF,0x35,0xD3,0xDD,0xB3,0xD5,0x8E,0xEB,0xAF,0x09, + 0xD3,0xDD,0x92,0xD5,0xEE,0x66,0x78,0x68,0x92,0xD5,0x30,0xCD,0xB8,0x5E,0xFF,0xD7, + 0x08,0x83,0xC7,0x7A,0xBC,0xB6,0x96,0xDF,0x08,0x83,0xC8,0x7A,0x2A,0xFA,0x5C,0xBA, + 0x29,0x8B,0xC8,0x7A,0xFE,0x7F,0xB6,0x8E,0x08,0x83,0xC8,0x82,0xF6,0xE6,0xF2,0xBE, + 0x08,0x83,0xC7,0x7A,0xAA,0x85,0xEF,0x18,0x08,0x83,0xC7,0x82,0x02,0xA3,0x2F,0x0E, + 0x8A,0x93,0xE8,0x82,0x0B,0x77,0x55,0x57,0xCE,0xBC,0x08,0x83,0x2B,0xF5,0x55,0x55, + 0x14,0xE6,0x28,0x8B,0x02,0xAF,0xD5,0x55,0x96,0xEE,0x29,0x8B,0x00,0x02,0xBF,0xD5, + 0xB6,0xF6,0x4E,0xAC,0x00,0x00,0x0A,0xBD,0xD6,0xF6,0xF3,0xE5,0x00,0x00,0x0A,0xAD, + 0xD6,0xF6,0xB5,0xF6,0xA8,0xAA,0xAA,0xF5,0xD6,0xF6,0xB6,0xF6,0xF7,0xFF,0xFD,0x77, + 0xD6,0xF6,0xB6,0xF6,0xA2,0xEE,0x7B,0xF9,0xD6,0xF6,0xB6,0xF6,0x0C,0x2B,0x8A,0xE8, + 0xD7,0xFE,0xD6,0xF6,0xD7,0xDF,0x7D,0xD7,0xF7,0xFE,0xD6,0xF6,0xEF,0xED,0xE9,0xFD, + 0xF7,0xFE,0xD6,0xF6,0xFF,0xDF,0x7F,0xDF,0xF6,0xFE,0xD7,0xF6,0xFD,0xF5,0x57,0x5D, + 0xF7,0xFE,0xD6,0xF6,0x55,0x5F,0x5F,0x7F,0xF7,0xFE,0xB6,0xF6,0xAF,0xAF,0xBF,0xBF, + 0xF6,0xFE,0xD6,0xF6,0xAF,0xBB,0x95,0xF7,0xF7,0xFE,0xB6,0xF6,0xBE,0xEE,0xDE,0xFE, + 0xD6,0xF6,0x54,0xEE,0x60,0xC0,0xA0,0x80,0xF2,0xDD,0xC4,0x59,0x78,0x58,0x78,0xF8, + 0x84,0x49,0x02,0x39,0xDF,0x5F,0xFF,0xF0,0x43,0x41,0xE2,0x38,0x2A,0x0B,0xA5,0xBF, + 0x84,0x49,0x23,0x39,0x59,0x8A,0xAB,0xFD,0x64,0x49,0x02,0x39,0x5F,0xBE,0xA8,0x2A, + 0x85,0x49,0xE2,0x30,0x57,0x57,0x7A,0xE8,0x43,0x41,0xE2,0x30,0x75,0xFD,0xAA,0xA0, + 0x23,0x41,0xE2,0x38,0xED,0xBB,0x7B,0x5C,0x03,0x39,0xC2,0x38,0xBA,0xBC,0xB8,0x28, + 0xE5,0x69,0x23,0x41,0xB5,0xB5,0xAD,0xAD,0x47,0x7A,0xC4,0x61,0x09,0x29,0x03,0x83, + 0x67,0x7A,0x06,0x72,0x00,0xA0,0xA8,0x43,0x46,0x72,0x84,0x59,0x80,0xC8,0xEA,0x7E, + 0x84,0x59,0xE3,0x38,0x58,0xE8,0x68,0xE8,0x24,0x41,0xC2,0x38,0x55,0x7A,0xA2,0x60, + 0x03,0x39,0xC2,0x30,0xFF,0xBF,0x7F,0x65,0xE2,0x38,0xA1,0x28,0x5A,0xF8,0xFA,0x78, + 0xC2,0x30,0x61,0x28,0x7A,0xBE,0xBA,0xA8,0xA2,0x30,0x82,0x28,0xE5,0x0F,0x0B,0x02, + 0xC2,0x38,0xA2,0x30,0x29,0x28,0x3F,0x25,0x44,0x49,0xE3,0x38,0xBD,0xAF,0xAD,0x95, + 0xC5,0x61,0x23,0x49,0x09,0xBD,0xD5,0xDD,0xC8,0x82,0x84,0x59,0x0B,0x2F,0xAD,0xB5, + 0xC8,0x82,0x67,0x7A,0x2C,0xAA,0xBD,0xF5,0x09,0x93,0x87,0x82,0xFF,0xF7,0xAD,0x25, + 0xE9,0x8A,0x87,0x7A,0xFB,0x0A,0xCB,0x60,0xE8,0x8A,0x88,0x7A,0xAF,0xB1,0xDD,0x7D, + 0xE9,0x8A,0x87,0x7A,0x00,0x0B,0xF7,0xF6,0x2A,0x93,0xC9,0x82,0x29,0x2D,0xB9,0x15, + 0x2A,0x93,0x46,0x72,0xE8,0x78,0x78,0x78,0x29,0x8B,0x06,0x6A,0x8A,0xFD,0xD5,0x75, + 0x87,0x7A,0xE5,0x69,0xE8,0xBA,0x2F,0xBD,0xC8,0x82,0xC5,0x61,0x7F,0xE2,0xA2,0x0A, + 0x67,0x72,0xC5,0x61,0xD5,0xD7,0xFE,0x80,0x6E,0xB4,0x26,0x72,0x2D,0xB5,0xF5,0xDD, + 0x96,0xF6,0xCC,0xA3,0x02,0x0B,0x2D,0xB5,0xD7,0xFE,0x96,0xF6,0x2D,0x0A,0x0A,0x2D, + 0xF7,0xFE,0x96,0xEE,0x6A,0x78,0xFA,0xAA,0x38,0xFF,0x95,0xEE,0xAD,0x29,0x0B,0x02, + 0x58,0xFF,0x39,0xFF,0x75,0x5D,0x57,0x57,0x39,0xFF,0x18,0xFF,0x00,0x00,0x00,0x3A, + 0x39,0xFF,0x18,0xFF,0x80,0xA0,0xF8,0xFA,0x59,0xFF,0xB6,0xEE,0x6A,0x6A,0x7A,0x7E, + 0x96,0xEE,0x55,0xEE,0xD8,0x7E,0x76,0x57,0x76,0xEE,0x35,0xE6,0xE2,0x68,0x5A,0x5E, + 0xD7,0xF6,0x35,0xE6,0x25,0x2D,0x2D,0x3F,0x18,0xFF,0xF8,0xF6,0x37,0x9B,0xA9,0xED, + 0x18,0xFF,0xF8,0xF6,0x3F,0x2E,0x2E,0x0E,0x39,0xFF,0x18,0xFF,0x7F,0x79,0xBF,0x9E, + 0x18,0xFF,0x3A,0xF7,0x80,0x02,0x22,0x2A,0x18,0xFF,0xF8,0xF6,0xE8,0xF2,0xE8,0xFA, + 0x18,0xFF,0xF8,0xF6,0x76,0x5D,0xF7,0x77,0x18,0xFF,0xF8,0xF6,0x7F,0x66,0x77,0xF5, + 0x17,0xFF,0xF8,0xF6,0x7F,0x77,0xFD,0xFD,0x17,0xFF,0xF8,0xF6,0xF7,0xED,0xDF,0x7F, + 0x17,0xFF,0xF8,0xF6,0xFF,0xF7,0x5D,0xF7,0x18,0xFF,0xF7,0xF6,0x57,0x75,0x6F,0x5F, + 0xF7,0xF6,0xD7,0xF6,0x7A,0x62,0xE0,0xEC,0xF7,0xF6,0xD7,0xF6,0x35,0xAD,0x5D,0xF9, + 0xF7,0xF6,0xD7,0xF6,0xEA,0xEA,0xF7,0x6F,0xF8,0xF6,0xD7,0xF6,0xAF,0x9D,0x0D,0x0D, + 0x17,0xFF,0xF8,0xF6,0xD5,0xF5,0xDF,0xDB,0x18,0xFF,0xF8,0xF6,0x57,0x7D,0xBD,0xF7, + 0x18,0xFF,0xF8,0xF6,0xEF,0xF9,0xFB,0x3D,0x18,0xFF,0xF7,0xF6,0x5D,0x5A,0x7E,0xEA, + 0x18,0xFF,0xF7,0xF6,0xED,0xB9,0xED,0x97,0x18,0xFF,0xF8,0xF6,0xAA,0xAB,0xFD,0xFF, + 0x18,0xFF,0xF7,0xF6,0xAE,0x82,0xAE,0xFE,0xF8,0xFE,0x18,0xF7,0xBF,0x2B,0x2F,0x2E, + 0xF8,0xF6,0xD7,0xF6,0xF0,0x52,0x58,0x5A,0xD7,0xF6,0x97,0xEE,0xE0,0x68,0xE0,0xA8, + 0xB7,0xF6,0x76,0xEE,0xA0,0xF0,0xFC,0x7A,0x96,0xEE,0x76,0xEE,0xB8,0x68,0xF8,0x5F, + 0x96,0xEE,0x55,0xE6,0x7E,0x5E,0xFA,0xBA,0x76,0xEE,0x35,0xE6,0xAF,0xFF,0xFF,0xC0, + 0x76,0xEE,0x35,0xE6,0xFA,0x5F,0x57,0xFF,0x55,0xE6,0x35,0xE6,0x9E,0xD8,0x02,0x83, + 0x75,0xEE,0x55,0xE6,0xD9,0xDD,0xFF,0x5D,0x96,0xEE,0x55,0xE6,0xBD,0xB7,0x37,0xAD, + 0x96,0xF6,0xB7,0xEE,0xE8,0xFE,0xEE,0xBA,0xB7,0xF6,0x76,0xEE,0xE8,0xFC,0xFE,0x5F, + 0xB6,0xF6,0x96,0xEE,0xE5,0xAD,0xCD,0xFD,0xB6,0xF6,0x55,0xE6,0x6A,0x7A,0x72,0x7A, + 0xF4,0xDD,0x72,0xCD,0x5C,0x5C,0x5C,0x78,0xD3,0xDD,0x72,0xCD,0x25,0x3D,0xAF,0xE9, + 0x35,0xE6,0xD3,0xDD,0x2B,0x2B,0x2D,0xAD,0x55,0xEE,0x14,0xE6,0xEA,0xEA,0xEB,0xAF, + 0x35,0xE6,0xB3,0xD5,0x5A,0xDA,0x7A,0x78,0xF4,0xDD,0xB3,0xD5,0xBD,0x2D,0x39,0x2F, + 0x14,0xE6,0xD3,0xDD,0xF3,0xA8,0xE2,0x60,0xF4,0xDD,0x92,0xD5,0xE2,0xAA,0x80,0x80, + 0xD3,0xDD,0x31,0xCD,0x5E,0xFE,0xA8,0x00,0x92,0xD5,0xF0,0xBC,0xBF,0xF7,0x78,0x60, + 0x10,0xC5,0x4E,0xAC,0x5C,0x5E,0x56,0x57,0x32,0xCD,0x8F,0xB4,0x2D,0x2D,0x0D,0x09, + 0x52,0xCD,0x11,0xC5,0x5A,0xDA,0xDE,0x7C,0x31,0xC5,0xD0,0xC4,0xAA,0x28,0x2B,0x0A, + 0x51,0xCD,0x10,0xC5,0xEA,0xAA,0xDA,0xEF,0x72,0xD5,0x51,0xCD,0xAD,0x35,0x55,0x55, + 0xB3,0xD5,0x72,0xCD,0x15,0x2B,0x3D,0xBD,0x34,0xE6,0xD3,0xDD,0xEB,0xA9,0xC9,0xED, + 0xD3,0xDD,0x10,0xC5,0xA0,0xE0,0xE0,0x78,0x51,0xCD,0x10,0xC5,0xBC,0xBF,0xF5,0xFF, + 0xE8,0x82,0xC8,0x7A,0xDA,0x9E,0x80,0xC2,0xE8,0x82,0xA7,0x7A,0xDA,0x2F,0x06,0x3F, + 0x08,0x83,0xC8,0x7A,0xBE,0xEF,0xED,0xA7,0xE8,0x82,0xC8,0x7A,0x28,0x3F,0x65,0x7A, + 0x08,0x83,0xA7,0x7A,0x68,0xE2,0x8F,0xF5,0x08,0x83,0xC7,0x82,0xEF,0x7A,0xEF,0x77, + 0x09,0x8B,0xA7,0x7A,0xBB,0xB7,0x3D,0xFF,0x08,0x8B,0xC8,0x82,0xAC,0x7C,0xCF,0xEF, + 0x29,0x8B,0xC7,0x82,0xA7,0xEB,0xE9,0x75,0x29,0x8B,0xA7,0x7A,0x89,0x6A,0xF9,0x5A, + 0x2C,0xA4,0xC8,0x82,0x2F,0xFD,0x55,0x55,0x90,0xD5,0x07,0x83,0x0A,0xBD,0x55,0x55, + 0x54,0xEE,0x49,0x8B,0x00,0x2A,0xB5,0x55,0x96,0xF6,0x8A,0x9B,0x00,0x00,0x2B,0xF5, + 0xB6,0xF6,0x72,0xD5,0x00,0x00,0x0A,0xBD,0xD6,0xF6,0x76,0xF6,0xA0,0x8A,0x2A,0xB5, + 0xD6,0xF6,0xB6,0xF6,0x29,0xBD,0xFF,0x55,0xF7,0xF6,0xB6,0xF6,0xEB,0xFF,0xFF,0xD5, + 0xB7,0xFE,0xD6,0xF6,0xD5,0xD5,0x77,0xDD,0xF7,0xFE,0xB6,0xF6,0xBF,0xAB,0xAF,0xFB, + 0xF7,0xFE,0xD7,0xF6,0x55,0x57,0x7F,0x55,0xF7,0xFE,0xB6,0xF6,0x9E,0xBF,0xAE,0xBA, + 0xD6,0xFE,0xF7,0xF6,0xEA,0xFE,0xFB,0xEA,0xF7,0xFE,0xD7,0xF6,0x77,0x5F,0x7D,0x7B, + 0xB6,0xFE,0xD6,0xF6,0x95,0xB5,0x57,0x55,0xB5,0xF6,0x29,0x83,0x78,0x78,0x78,0xE8, + 0x46,0x6A,0x44,0x49,0x5F,0xFE,0xDC,0xDC,0xA5,0x51,0x02,0x41,0xDF,0xFC,0xA2,0xC8, + 0x84,0x51,0x23,0x41,0x55,0x55,0xDF,0x80,0x84,0x51,0x03,0x39,0xF7,0xFD,0xAF,0x02, + 0x85,0x49,0x03,0x41,0xFA,0x7B,0x6A,0xF8,0x44,0x41,0xE2,0x38,0x8A,0xAB,0xFB,0xDF, + 0x23,0x41,0xC2,0x38,0xEC,0xAE,0x29,0x29,0x44,0x49,0xE2,0x38,0xFD,0xBF,0xBE,0x3B, + 0xE5,0x69,0x23,0x49,0x2F,0xBD,0xBF,0x2B,0x67,0x7A,0xE5,0x69,0xAB,0x8B,0x2D,0xAB, + 0x47,0x72,0xE4,0x69,0x6E,0x7E,0x7E,0xE0,0xE5,0x69,0x44,0x51,0xF8,0xF8,0x78,0x78, + 0x64,0x51,0x04,0x41,0xF8,0xDE,0xEA,0xE2,0x44,0x49,0xE3,0x38,0x7A,0xDC,0xF2,0x68, + 0x03,0x39,0xC2,0x30,0xAB,0xA8,0xF8,0x57,0x03,0x39,0xA1,0x30,0x68,0xEA,0xEF,0x83, + 0xE2,0x30,0x81,0x28,0xEF,0xBE,0xFA,0x78,0xC2,0x30,0x81,0x28,0xB7,0xFA,0x7A,0x75, + 0xC2,0x30,0x81,0x28,0x2B,0x3E,0xB5,0xE5,0x44,0x49,0xA2,0x30,0xBF,0xAF,0xBF,0x2D, + 0x84,0x59,0x03,0x41,0xAF,0x27,0x35,0xB7,0xA9,0x82,0x85,0x59,0x3D,0x3F,0x2F,0x29, + 0xE9,0x82,0x67,0x7A,0x75,0x7F,0xAA,0x02,0x09,0x8B,0x67,0x72,0x0F,0xAF,0x9F,0x57, + 0x0A,0x93,0x87,0x7A,0xC0,0xEA,0xE3,0xD5,0xC8,0x82,0x67,0x72,0x2B,0x1F,0x2E,0xB3, + 0xE9,0x82,0x88,0x82,0x9E,0xFE,0x8E,0x8B,0xE9,0x82,0x87,0x7A,0x3A,0xEA,0x68,0x70, + 0xE9,0x8A,0xC5,0x61,0xA8,0xAA,0xFE,0x5F,0x47,0x72,0xA5,0x59,0x68,0x58,0x5F,0x57, + 0x67,0x72,0xA5,0x61,0x3D,0x25,0x2D,0x0D,0x08,0x8B,0x86,0x7A,0xBD,0xAD,0x2A,0xA9, + 0xE8,0x82,0x67,0x7A,0xFE,0xEA,0x6A,0xE8,0xC8,0x82,0x27,0x72,0x2F,0xB7,0xAF,0x2E, + 0x2E,0xA4,0xC9,0x82,0x3F,0x95,0xD5,0x55,0x76,0xEE,0x0A,0x8B,0x02,0x2F,0xAD,0xF5, + 0x38,0xFF,0x14,0xE6,0x2A,0x8A,0x0B,0x2D,0x39,0xFF,0x18,0xFF,0x89,0x2B,0x2A,0xA2, + 0x39,0xFF,0x38,0xFF,0xA2,0xAA,0xA8,0xAA,0x39,0xFF,0x18,0xFF,0xAA,0xAC,0xBA,0xFC, + 0x38,0xFF,0x18,0xFF,0x7A,0x7A,0xEE,0xFA,0x18,0xFF,0x75,0xEE,0x68,0x78,0x7C,0x5C, + 0x76,0xEE,0x55,0xE6,0x76,0x5F,0x2E,0xAE,0x76,0xEE,0x14,0xDE,0xF2,0xFA,0xFA,0xDE, + 0xD7,0xF6,0x55,0xE6,0x2D,0x2D,0x2B,0x09,0xF8,0xFE,0x18,0xF7,0xEC,0xB8,0xAC,0xEA, + 0x18,0xFF,0xF8,0xF6,0x2F,0x3D,0x05,0x29,0x39,0xFF,0x18,0xFF,0x9F,0xFF,0x5D,0xDD, + 0x18,0xFF,0x39,0xF7,0x2A,0x82,0x22,0x02,0x18,0xFF,0xF8,0xF6,0xEA,0xAE,0xAA,0xA2, + 0x18,0xFF,0xF8,0xF6,0xD5,0x7F,0x7A,0xEF,0xF8,0xFE,0x18,0xF7,0xA8,0xA8,0xAA,0x82, + 0x18,0xFF,0xF8,0xF6,0xF7,0x7D,0x5F,0x7F,0x19,0xFF,0xF7,0xF6,0x7F,0x5F,0x75,0x75, + 0xF8,0xFE,0x18,0xF7,0xAA,0xEA,0x8A,0x2A,0x18,0xFF,0xD7,0xF6,0xEA,0x7A,0xFB,0x7E, + 0x38,0xFF,0xD7,0xF6,0x77,0xFD,0xDD,0xFD,0xF7,0xF6,0xD7,0xF6,0x3A,0xBA,0xEA,0xE2, + 0xF7,0xF6,0xD7,0xF6,0x7E,0xD6,0xD5,0xDD,0x18,0xFF,0xD7,0xF6,0xBD,0xAF,0xAF,0xFF, + 0x18,0xFF,0xD7,0xF6,0xAA,0xAE,0xAF,0xFF,0xF8,0xFE,0x17,0xEF,0xAA,0x82,0x22,0x2A, + 0x18,0xFF,0xF8,0xF6,0xBD,0x3D,0xAF,0x2D,0x18,0xFF,0xF7,0xF6,0xE8,0x6A,0x52,0x6A, + 0xF7,0xF6,0xD7,0xF6,0x28,0x0C,0x0F,0x0E,0xF8,0xFE,0x18,0xF7,0xFF,0x7E,0xEE,0xBA, + 0x18,0xFF,0xF8,0xF6,0xFE,0xF6,0xD7,0xDF,0x18,0xFF,0xD7,0xF6,0xA2,0x7A,0xAA,0xEA, + 0xF8,0xF6,0x97,0xEE,0xA8,0x80,0xA8,0xEA,0xD7,0xF6,0x96,0xEE,0xAA,0xE8,0xFE,0x5A, + 0xB7,0xF6,0x76,0xEE,0xFA,0xFE,0x5F,0xD7,0x96,0xEE,0x55,0xE6,0xFA,0xBC,0xFA,0x82, + 0x76,0xEE,0x55,0xE6,0x00,0x20,0xBE,0xD7,0x96,0xEE,0x55,0xEE,0x80,0x80,0xB5,0xFD, + 0x96,0xEE,0x55,0xE6,0x7B,0xC0,0xA2,0xFA,0x96,0xEE,0x55,0xE6,0x55,0x7F,0xCA,0xAB, + 0x55,0xEE,0x35,0xE6,0xB9,0x7A,0xB8,0x20,0x96,0xEE,0x55,0xE6,0xBD,0x95,0x25,0x2F, + 0xB7,0xF6,0x76,0xEE,0xFB,0xFB,0x7A,0x78,0x96,0xEE,0x76,0xEE,0xDA,0x7B,0x7F,0xD5, + 0x96,0xEE,0x75,0xEE,0xA2,0x3D,0x2B,0x03,0xB7,0xF6,0x35,0xE6,0xFA,0xEA,0x72,0x62, + 0x14,0xDE,0x51,0xCD,0x7C,0x5C,0x5E,0x5E,0xB3,0xD5,0x51,0xCD,0x2F,0xAD,0xB5,0xBB, + 0x35,0xEE,0xB3,0xD5,0x2D,0x3D,0x3D,0xBD,0x34,0xE6,0x14,0xE6,0xE0,0xC0,0xC2,0xE7, + 0x14,0xE6,0xB2,0xD5,0x78,0xE8,0x78,0x70,0x34,0xE6,0xB3,0xD5,0xBD,0xA7,0xBD,0x2D, + 0x35,0xE6,0xD3,0xDD,0x72,0xFE,0x5C,0x5C,0xF4,0xDD,0xD3,0xDD,0xFB,0x3D,0xAD,0xF2, + 0xF4,0xE5,0xD3,0xDD,0x60,0xFA,0x77,0x55,0xB3,0xDD,0x11,0xC5,0x78,0xE0,0x60,0x70, + 0xD0,0xBC,0x2D,0xA4,0xDE,0xDC,0x5C,0x5C,0x51,0xCD,0x6E,0xAC,0x29,0x2D,0x05,0xBD, + 0x31,0xCD,0xD0,0xBC,0xB8,0xF8,0xE8,0x5A,0x31,0xC5,0xAF,0xB4,0x0A,0xAF,0x9F,0xDF, + 0x51,0xCD,0x10,0xC5,0xFE,0xBB,0x77,0xF9,0x72,0xD5,0x31,0xC5,0x37,0x39,0xAE,0xBF, + 0x92,0xD5,0x51,0xCD,0xAB,0xFA,0x6A,0x7E,0xD3,0xDD,0xF0,0xC4,0x02,0xEA,0xFF,0x5F, + 0x72,0xD5,0xF0,0xBC,0xFC,0xD6,0x55,0xD5,0x72,0xCD,0x10,0xC5,0xBF,0xBF,0xA9,0x2A, + 0xC8,0x7A,0x87,0x7A,0x00,0x88,0x40,0x03,0xE8,0x82,0xA7,0x7A,0xBF,0xB2,0xA9,0x8B, + 0xE8,0x82,0xA8,0x7A,0x78,0xAC,0xEB,0xBF,0xE8,0x82,0xA7,0x7A,0x24,0x08,0xEF,0xAD, + 0xE8,0x82,0xC7,0x7A,0x3B,0x6B,0x9E,0x2B,0x09,0x8B,0xC7,0x82,0xA7,0x9E,0xDB,0x5F, + 0x08,0x8B,0xA7,0x7A,0xFE,0xEF,0xE4,0xB7,0xE8,0x82,0xA7,0x82,0xB8,0x80,0x8A,0xFC, + 0xE8,0x82,0xA7,0x82,0xEB,0x28,0x0A,0x32,0x08,0x8B,0xC7,0x82,0xDF,0xFF,0xA9,0xBF, + 0x08,0x8B,0xA7,0x7A,0xBF,0xBE,0x36,0xFC,0x08,0x8B,0xC7,0x82,0x29,0xE8,0xEA,0xA3, + 0x08,0x8B,0xC7,0x82,0xA0,0x7A,0xAB,0xEB,0x49,0x93,0xA7,0x7A,0x0E,0xAF,0xFE,0xFB, + 0xF0,0xC4,0x09,0x8B,0x2B,0xD5,0x55,0x55,0x34,0xE6,0x29,0x8B,0x02,0xAF,0xD5,0x55, + 0x96,0xF6,0x8A,0x93,0x00,0x0A,0xAF,0x55,0x96,0xF6,0x8E,0xB4,0x00,0x00,0x0A,0xB5, + 0xB6,0xF6,0x14,0xE6,0x00,0x00,0x08,0xAD,0xD6,0xF6,0x95,0xF6,0x23,0x22,0x23,0xA5, + 0xD7,0xF6,0xB6,0xF6,0xFA,0xFE,0xD8,0x9E,0xB6,0xFE,0xD6,0xF6,0x57,0xFF,0xDF,0xFD, + 0xF7,0xFE,0xB6,0xF6,0xAA,0xAF,0xFA,0x7F,0xD7,0xF6,0xB6,0xF6,0xC0,0x80,0x0B,0xEB, + 0xF6,0xFE,0xB7,0xF6,0xBB,0xAB,0xAB,0xEF,0xD6,0xF6,0xAE,0xB4,0x78,0x68,0xE0,0xA0, + 0x8E,0xB4,0xA4,0x59,0x57,0x56,0x5E,0x58,0xA5,0x51,0x64,0x49,0x82,0x9F,0x9D,0xD7, + 0xE5,0x59,0x84,0x51,0xED,0xF9,0xD7,0x57,0xE6,0x59,0x84,0x51,0x6F,0x7E,0x68,0x63, + 0xA5,0x51,0x44,0x41,0x7A,0xF2,0x58,0x7E,0x44,0x41,0x03,0x41,0xDA,0xB8,0x3C,0xBC, + 0x44,0x49,0x03,0x41,0x7D,0x6E,0xE8,0x8F,0xC5,0x61,0x03,0x41,0xDD,0x95,0xBF,0x2A, + 0x67,0x7A,0xC5,0x61,0xF5,0x35,0x29,0x0A,0xC8,0x8A,0x26,0x72,0xF5,0x8B,0xAA,0x28, + 0xC9,0x8A,0x06,0x6A,0x5B,0x6A,0x78,0xB8,0x27,0x72,0x84,0x51,0x5E,0x7A,0x78,0xF0, + 0x64,0x51,0x24,0x49,0xFA,0xF7,0xD4,0xAC,0x64,0x51,0xE2,0x38,0xFA,0x7C,0x7A,0xEC, + 0xE3,0x38,0xA2,0x30,0xBE,0xDC,0x5F,0xFA,0x03,0x39,0xC2,0x30,0x8B,0xAB,0x89,0xA9, + 0x03,0x39,0x82,0x28,0x6A,0xFA,0xE2,0xCA,0xA2,0x30,0x82,0x28,0xD5,0x55,0x57,0x5C, + 0xE2,0x30,0x82,0x28,0xFF,0xF5,0xB5,0x3D,0x43,0x41,0xA1,0x30,0x29,0xAD,0xAF,0xAF, + 0xA5,0x59,0x23,0x41,0xB5,0xAD,0x3D,0x0D,0xA9,0x82,0xA5,0x59,0x2D,0x2D,0xAB,0xAB, + 0xC9,0x82,0x06,0x6A,0x00,0xA8,0xFE,0x7B,0xA8,0x7A,0xE4,0x61,0xF8,0xFA,0x7F,0x55, + 0x67,0x7A,0xC4,0x61,0x0A,0xBF,0xF5,0xFF,0x88,0x7A,0xE5,0x69,0x00,0x02,0x0B,0xBD, + 0xC9,0x82,0x46,0x72,0x82,0x2A,0xAF,0x97,0xE9,0x82,0x84,0x51,0x80,0xAA,0xFA,0x7E, + 0x06,0x6A,0x02,0x49,0xA8,0xE8,0xFF,0x57,0xE6,0x61,0x43,0x51,0xAA,0xFD,0xBD,0x35, + 0x47,0x72,0xA4,0x59,0x0D,0x2D,0x2F,0x0A,0xA8,0x82,0x46,0x72,0x03,0xB5,0xED,0xAD, + 0xC9,0x8A,0xA8,0x7A,0xEB,0xEF,0xA9,0x87,0xC9,0x82,0x67,0x7A,0xB7,0xFC,0xFE,0x5E, + 0xA8,0x82,0x46,0x72,0x02,0xAA,0x2B,0x89,0x8B,0x9B,0x68,0x7A,0x2F,0x2D,0xAD,0xBD, + 0xD6,0xF6,0x8A,0x93,0x0B,0x0F,0x2D,0x95,0x39,0xFF,0xB6,0xF6,0x00,0x20,0x82,0x89, + 0x39,0xFF,0x18,0xFF,0x20,0x0A,0x8B,0x8B,0x38,0xFF,0x18,0xFF,0xDE,0x9E,0xBE,0xBE, + 0x38,0xFF,0xF7,0xF6,0xA0,0xEA,0x6A,0x7A,0xB6,0xF6,0x55,0xE6,0xF0,0xF8,0x78,0xFA, + 0x55,0xEE,0x75,0xE6,0x0A,0x02,0xA0,0xA0,0x55,0xEE,0x35,0xE6,0xD7,0xDE,0xAC,0xB8, + 0xF8,0xFE,0x76,0xEE,0x2D,0x2D,0x29,0x0F,0x18,0xFF,0xD7,0xF6,0xFA,0xFA,0xFA,0xE8, + 0x38,0xFF,0xF8,0xF6,0xB7,0xB5,0xB5,0xAD,0x18,0xFF,0x38,0xF7,0x20,0x0A,0x2A,0x2A, + 0x18,0xFF,0xF8,0xF6,0x28,0xA8,0xF8,0xBA,0x18,0xFF,0xF8,0xF6,0xEA,0xBA,0xAE,0xAB, + 0xF8,0xFE,0x18,0xF7,0xAA,0xBA,0xEB,0xBB,0xF8,0xFE,0x18,0xF7,0x82,0xAA,0xA8,0xAC, + 0x18,0xFF,0xF8,0xF6,0x7F,0x5F,0xDA,0x5F,0xD8,0xFE,0xF7,0xF6,0xF7,0xF7,0x7D,0xDF, + 0xD7,0xFE,0xF8,0xF6,0xF7,0xFF,0xDD,0x75,0xD8,0xFE,0xF7,0xF6,0xFD,0xFD,0x77,0x55, + 0x18,0xFF,0xD7,0xF6,0xAF,0xBB,0xFF,0xDF,0xD8,0xFE,0xF7,0xF6,0xBD,0xF5,0x77,0x5F, + 0x18,0xFF,0xD7,0xF6,0xDD,0x5D,0x7F,0xFA,0xF7,0xF6,0xD7,0xF6,0x2B,0x25,0xB7,0x37, + 0xF8,0xFE,0xF7,0xF6,0xFF,0xFF,0xFB,0xBF,0x18,0xFF,0xF8,0xF6,0x6D,0xDF,0xF5,0xFF, + 0x18,0xFF,0xF8,0xF6,0xAD,0x0B,0x8F,0xAF,0x18,0xFF,0xF8,0xF6,0x60,0x7A,0xEE,0xEB, + 0xD8,0xFE,0xF7,0xF6,0x5D,0x75,0xF5,0xFF,0x18,0xFF,0xD7,0xF6,0xA2,0xAA,0xF7,0xB7, + 0xF7,0xF6,0xD8,0xF6,0xA0,0xA0,0xE2,0xEA,0xF8,0xF6,0xD7,0xF6,0x82,0x7B,0x5F,0x57, + 0xF8,0xF6,0xB7,0xF6,0x7A,0xFA,0x77,0x5F,0xB7,0xF6,0x76,0xEE,0xF8,0xB8,0xEC,0xFE, + 0x96,0xEE,0x76,0xEE,0xD9,0xD7,0x5F,0xD5,0x96,0xEE,0x76,0xEE,0x68,0x7A,0x57,0x55, + 0x75,0xEE,0x35,0xE6,0xE2,0xBC,0xAE,0xAE,0x75,0xEE,0x35,0xE6,0xAA,0xBB,0xB6,0xFF, + 0x75,0xEE,0x55,0xE6,0x8A,0xAA,0xFF,0x56,0x76,0xEE,0x35,0xE6,0x2A,0xEE,0x9F,0xD7, + 0x76,0xEE,0x55,0xE6,0x95,0xBD,0x0D,0xA3,0xB7,0xF6,0x76,0xEE,0xA5,0x2B,0xA9,0xAB, + 0xB7,0xF6,0x76,0xEE,0xFA,0xF8,0xEA,0x5E,0xB6,0xF6,0x55,0xEE,0xFD,0xAF,0x2B,0x2A, + 0xB6,0xF6,0x96,0xEE,0xFD,0xFE,0x8A,0xA6,0xB6,0xF6,0x14,0xDE,0xE2,0xE0,0xEA,0x7A, + 0xF4,0xDD,0x31,0xCD,0xF8,0xF8,0x78,0x5E,0xB3,0xDD,0x31,0xCD,0x2B,0x2B,0xAF,0xF5, + 0x15,0xE6,0x92,0xD5,0x2F,0xAB,0xAD,0xBD,0x35,0xE6,0xD3,0xDD,0x82,0x8A,0xEE,0x7E, + 0x14,0xE6,0xB3,0xD5,0x70,0xD8,0xEA,0xEA,0x14,0xE6,0xB3,0xD5,0x2F,0x2D,0x2F,0x0F, + 0x14,0xE6,0xD3,0xDD,0xF8,0x7C,0xDA,0xDA,0xF4,0xDD,0x92,0xD5,0x80,0x80,0xC2,0x68, + 0xD3,0xDD,0x31,0xC5,0x00,0x80,0xAA,0x55,0x92,0xD5,0xD0,0xBC,0x60,0xF0,0xFE,0xFF, + 0xEF,0xBC,0x0D,0xA4,0x5A,0x7E,0xFC,0xF8,0xF0,0xC4,0x4D,0xAC,0x2D,0x2D,0x25,0x35, + 0x31,0xCD,0xB0,0xB4,0xFA,0xF0,0xF8,0x7A,0xCF,0xBC,0x8F,0xB4,0x36,0x0E,0x2F,0x17, + 0x31,0xC5,0xF0,0xC4,0x23,0x89,0x09,0x05,0x72,0xCD,0x31,0xCD,0xAD,0x29,0x3D,0x3B, + 0x71,0xCD,0x31,0xCD,0xAA,0xE8,0xFA,0x56,0x51,0xCD,0xF0,0xBC,0x58,0x56,0xDD,0xF7, + 0x52,0xCD,0xD0,0xBC,0x35,0x2F,0xBA,0xAA,0x92,0xD5,0x31,0xC5,0xBF,0xAF,0x8B,0xAD, + 0xE8,0x82,0x86,0x7A,0x89,0x8A,0xE8,0xA2,0x08,0x83,0x87,0x7A,0xC3,0x6E,0x6B,0xEA, + 0xE8,0x82,0x87,0x7A,0x6E,0xCF,0xEF,0xFE,0xE8,0x82,0x86,0x7A,0x2D,0xBD,0xAB,0xBA, + 0xE8,0x82,0x87,0x7A,0x02,0x90,0x00,0x8B,0xE7,0x82,0xA7,0x7A,0xBF,0xBC,0xFE,0xFA, + 0xC8,0x82,0xA8,0x7A,0x0E,0x40,0xD2,0x05,0xE8,0x82,0xA7,0x7A,0xD5,0xAB,0x2A,0x28, + 0xE8,0x82,0xA6,0x82,0x0F,0xC0,0xE0,0xF0,0x08,0x8B,0xA7,0x7A,0x28,0x5E,0xFA,0xBA, + 0x09,0x8B,0xC7,0x82,0x5E,0xCB,0x79,0x5A,0x08,0x8B,0xA7,0x7A,0xAB,0x3F,0xFE,0xBD, + 0x08,0x83,0xA7,0x82,0x2A,0xBE,0xFE,0x9F,0xE8,0x82,0xC8,0x82,0x20,0x22,0x6B,0xDF, + 0x08,0x8B,0xC8,0x82,0x8B,0xB5,0xA9,0x2D,0x08,0x8B,0xC8,0x82,0x28,0x2A,0x3A,0x5F, + 0x49,0x8B,0xC8,0x82,0xA8,0xFF,0xDA,0xDF,0x0C,0x9C,0xC7,0x82,0x2B,0xFF,0xF5,0x5D, + 0xD3,0xDD,0x29,0x8B,0x0A,0xF5,0x55,0x55,0x75,0xEE,0x29,0x8B,0x00,0x0B,0xFD,0x55, + 0xB6,0xF6,0xCB,0xA3,0x00,0x00,0xAB,0xF5,0xD6,0xF6,0x92,0xD5,0x00,0x08,0x8A,0xBD, + 0xD6,0xF6,0x75,0xF6,0x08,0x8A,0xAB,0xBD,0xD7,0xFE,0x96,0xF6,0xAA,0xAE,0x9E,0xFB, + 0xD7,0xFE,0xB6,0xF6,0xEA,0xFF,0xEB,0xEB,0xB7,0xF6,0x34,0xE6,0x60,0xC0,0xA0,0x80, + 0x55,0xEE,0x87,0x72,0x5E,0x78,0x78,0xE0,0x66,0x6A,0x43,0x49,0xF7,0xD5,0x56,0x5C, + 0xA5,0x59,0x43,0x49,0xA0,0x80,0xEA,0xD5,0xC5,0x51,0x64,0x49,0x8A,0xAA,0xFE,0x75, + 0x85,0x51,0x64,0x49,0x7A,0x68,0xD5,0xEF,0x84,0x51,0x23,0x41,0x77,0x7F,0xFE,0x8E, + 0xC5,0x59,0x23,0x41,0xFD,0x2F,0xAB,0x2A,0xA8,0x82,0x84,0x51,0xF5,0xBD,0xAF,0x2B, + 0x09,0x93,0x46,0x72,0xBD,0x2D,0x0B,0x0A,0x09,0x93,0xA8,0x8A,0xD7,0x6E,0xE2,0xE0, + 0xC9,0x8A,0x26,0x72,0xF8,0xFE,0x58,0xD8,0x47,0x7A,0xA4,0x61,0x5C,0x7A,0x7C,0xB0, + 0xC5,0x69,0x44,0x49,0xDF,0x7F,0xBA,0xA0,0xA5,0x59,0x44,0x49,0x55,0xFF,0xBF,0x2A, + 0xE6,0x69,0xE2,0x40,0x5F,0xFE,0xAA,0x2A,0xC5,0x59,0x03,0x41,0x55,0x55,0x5E,0xE8, + 0x03,0x41,0xC2,0x30,0xE8,0x7A,0xFF,0x2E,0x44,0x41,0xA2,0x30,0x55,0xF7,0xAA,0x0A, + 0x85,0x51,0x81,0x30,0xFD,0xBF,0x2F,0x0A,0x64,0x49,0x03,0x41,0xBD,0x2E,0xAA,0x02, + 0xC5,0x61,0x44,0x49,0x37,0xAF,0x2A,0xAB,0x27,0x6A,0x84,0x51,0x82,0xEB,0xFF,0x57, + 0x06,0x6A,0xA4,0x59,0x80,0xEF,0xB5,0xB5,0xE5,0x61,0xA4,0x61,0xDE,0x7B,0xEA,0xA8, + 0xE5,0x61,0xA4,0x61,0x2E,0x39,0x29,0x09,0x26,0x6A,0xC5,0x61,0x97,0x9F,0x2B,0x2F, + 0x87,0x7A,0x06,0x62,0xAB,0x7B,0x83,0x8A,0x67,0x72,0x23,0x49,0x78,0x78,0x5E,0x5E, + 0x63,0x51,0xE2,0x40,0xF7,0xF7,0xBD,0x27,0x26,0x6A,0x02,0x49,0x2D,0x2F,0x2B,0x0B, + 0x67,0x72,0x26,0x72,0xFF,0x52,0xFA,0xDE,0x88,0x7A,0xE5,0x69,0xA0,0x8B,0xF7,0xFF, + 0xC9,0x8A,0x05,0x6A,0x0A,0x2B,0x3D,0x25,0x4A,0x9B,0x46,0x72,0x57,0x5E,0xFA,0xE2, + 0x88,0x7A,0x05,0x6A,0x0F,0xB5,0xFD,0xBA,0x2A,0x8B,0x67,0x7A,0x2D,0x39,0xBD,0x3D, + 0x8E,0xBC,0x2A,0x8B,0x3D,0xBD,0xD5,0x55,0x18,0xFF,0x6E,0xB4,0x02,0x0B,0x09,0x2D, + 0x38,0xFF,0x18,0xFF,0xED,0xED,0x7D,0xD5,0x38,0xFF,0x18,0xFF,0x5F,0xDF,0x55,0x55, + 0x18,0xFF,0x96,0xF6,0xE0,0xE0,0x68,0x78,0x96,0xF6,0x55,0xEE,0x5C,0xDE,0x77,0xD7, + 0x75,0xEE,0x55,0xEE,0xF5,0xFD,0x7B,0x7D,0x75,0xEE,0x35,0xE6,0xB7,0x97,0x97,0x2F, + 0xF8,0xFE,0x96,0xEE,0x2D,0x2D,0x0D,0x2D,0xF8,0xFE,0x18,0xF7,0xB8,0xAA,0x2E,0xAE, + 0x18,0xFF,0xF8,0xF6,0x29,0x0E,0x0D,0xAF,0x18,0xFF,0x38,0xF7,0x28,0x28,0x80,0x02, + 0x18,0xFF,0xF8,0xF6,0xAA,0xEE,0xBA,0xBE,0x18,0xFF,0xF8,0xF6,0xAA,0xAA,0xE8,0xDE, + 0x18,0xFF,0xF8,0xF6,0x7A,0x7E,0xDF,0xEF,0xF7,0xFE,0xF8,0xF6,0xBF,0xFF,0x7F,0xFF, + 0xD7,0xFE,0xF8,0xF6,0xF5,0xF7,0xD7,0x77,0x18,0xFF,0xD7,0xF6,0xBF,0xAB,0xEB,0xAB, + 0xD7,0xFE,0xF8,0xF6,0x75,0xFD,0xE5,0xE7,0xD7,0xFE,0xF7,0xF6,0x57,0xDD,0xF7,0xFD, + 0xF7,0xF6,0xB7,0xF6,0x2E,0x28,0x2A,0xA8,0x18,0xFF,0xD7,0xF6,0xAE,0xEB,0xFB,0xEF, + 0xD7,0xFE,0xF7,0xF6,0x75,0xFD,0xFF,0xFD,0xF7,0xF6,0xD7,0xF6,0x7E,0x3E,0x8A,0x0A, + 0x18,0xFF,0xF7,0xF6,0x55,0x75,0x7F,0xFF,0x18,0xFF,0xF8,0xF6,0xEF,0x2F,0xB5,0xB7, + 0x18,0xFF,0xF8,0xF6,0x6B,0x78,0xFA,0xFE,0x17,0xFF,0xF8,0xF6,0x6B,0xFF,0xFD,0x77, + 0xF8,0xF6,0xD7,0xF6,0xA8,0xBA,0xA8,0xCE,0xF8,0xF6,0xD7,0xF6,0x8A,0xA8,0xAA,0xBE, + 0xF8,0xF6,0xD7,0xF6,0xC8,0xA2,0x6A,0x7A,0x18,0xF7,0xB7,0xF6,0x7F,0x7F,0xDE,0x7F, + 0xD7,0xF6,0x96,0xEE,0x7A,0x5F,0x5F,0x7E,0x96,0xEE,0x76,0xEE,0xDA,0x58,0x7F,0xF9, + 0x96,0xEE,0x55,0xEE,0xFE,0xEA,0xAE,0xEA,0x76,0xEE,0x55,0xE6,0x20,0x80,0x20,0xE8, + 0x75,0xEE,0x34,0xE6,0xF8,0xFA,0xAA,0xEA,0x75,0xEE,0x35,0xE6,0xBF,0xFE,0xFE,0xEA, + 0x75,0xEE,0x34,0xE6,0xFE,0xA8,0x02,0x2A,0x75,0xEE,0x34,0xE6,0x9F,0xBA,0xA2,0x80, + 0x76,0xEE,0x55,0xE6,0xAF,0x0C,0xB7,0x25,0x96,0xEE,0x76,0xEE,0x22,0x26,0x2E,0xBB, + 0x96,0xEE,0x55,0xE6,0xF8,0xEA,0xEA,0xAA,0x96,0xEE,0x55,0xEE,0x0A,0x02,0x29,0x2F, + 0xB6,0xF6,0x96,0xEE,0xFB,0x7F,0x7D,0x55,0x96,0xEE,0x14,0xDE,0x60,0x70,0xE0,0xE0, + 0xD3,0xDD,0x30,0xC5,0x76,0xFC,0xE8,0xF0,0x71,0xCD,0x30,0xCD,0x09,0xE2,0xAA,0xDC, + 0xF3,0xDD,0x51,0xCD,0x2F,0xA9,0x2D,0xB9,0xF4,0xDD,0xB3,0xD5,0x80,0xE0,0x80,0x02, + 0xF4,0xDD,0x92,0xD5,0x83,0xAA,0xFA,0x60,0x14,0xE6,0xB3,0xD5,0x2D,0x0F,0xA9,0xB5, + 0x14,0xE6,0x10,0xC5,0x20,0xA0,0xFA,0x5E,0xB3,0xD5,0xF0,0xC4,0x80,0x78,0x57,0x77, + 0x30,0xC5,0xF0,0xBC,0x58,0xFF,0x55,0x55,0x30,0xC5,0xD0,0xBC,0xFE,0x36,0x9F,0xDF, + 0x31,0xCD,0x2D,0xAC,0x7A,0x78,0xE0,0x80,0xCF,0xBC,0xEC,0xA3,0x2B,0x2D,0x3F,0x2F, + 0x31,0xCD,0xB0,0xBC,0xFA,0x40,0xA2,0xCB,0xCF,0xBC,0x4E,0xAC,0x3E,0x37,0x97,0xBF, + 0x51,0xCD,0xF0,0xC4,0xA5,0x29,0x89,0x29,0x51,0xCD,0x11,0xC5,0x0A,0x22,0xA9,0xCE, + 0x52,0xCD,0xD0,0xBC,0xE8,0xE8,0x7C,0xDF,0x52,0xCD,0xCF,0xBC,0xF7,0x9F,0xAD,0x8B, + 0x72,0xCD,0x11,0xC5,0xB7,0xBD,0x9F,0x3F,0x72,0xCD,0x51,0xCD,0x29,0x3D,0xB5,0xBD, + 0xC8,0x82,0x25,0x6A,0x20,0xAA,0xAF,0xD7,0xE8,0x82,0x66,0x72,0xA2,0x83,0x8A,0xFD, + 0xC7,0x82,0x87,0x7A,0xB8,0x2A,0x2A,0x2E,0x07,0x83,0xC8,0x82,0x5F,0x7B,0xFF,0x7E, + 0xE8,0x82,0xA7,0x7A,0xAB,0x8B,0x89,0x23,0x08,0x8B,0xA7,0x7A,0xF7,0xB7,0xBF,0xBA, + 0x09,0x8B,0xA7,0x7A,0x8F,0xC6,0xDE,0x5F,0xE8,0x82,0xA7,0x82,0xFB,0x75,0xAB,0xA3, + 0xE8,0x82,0x87,0x7A,0xE0,0x2A,0x0A,0x28,0x08,0x8B,0xA7,0x7A,0xEF,0xBF,0xFA,0x5C, + 0xE8,0x82,0x86,0x7A,0x20,0xA8,0x80,0xC1,0xE8,0x82,0xA7,0x7A,0xDE,0xAA,0x3A,0xE8, + 0x09,0x8B,0xA8,0x7A,0x7F,0xCF,0xAB,0xAF,0x08,0x8B,0xC8,0x82,0xBF,0xB3,0xE3,0x6A, + 0x08,0x8B,0xA7,0x82,0xAF,0xE2,0xAA,0xDA,0x09,0x8B,0xC8,0x82,0xD5,0xD7,0x2B,0xC5, + 0xC8,0x8A,0xE8,0x82,0xFD,0x59,0x5F,0xF7,0x08,0x8B,0xC8,0x82,0xBB,0xAA,0xFA,0x7A, + 0xE8,0x82,0xC8,0x82,0xD8,0xB8,0xAA,0x7B,0x09,0x8B,0xC8,0x82,0x22,0x83,0x0A,0xF9, + 0x8A,0x93,0xE8,0x82,0x2F,0xFD,0x5D,0x55,0x10,0xCD,0x09,0x8B,0x2B,0xF5,0x55,0x55, + 0x54,0xEE,0x09,0x8B,0x02,0xAF,0xD5,0x55,0x95,0xF6,0x4A,0x93,0x00,0x02,0xAF,0xD5, + 0xB6,0xF6,0xAE,0xBC,0x00,0x00,0x0A,0xBD,0xB7,0xF6,0x14,0xE6,0x00,0x00,0x00,0x8D, + 0x96,0xF6,0xF0,0xBC,0x70,0xE0,0xC0,0x80,0xD0,0xBC,0x44,0x49,0x5E,0x5E,0x58,0x78, + 0x43,0x49,0x03,0x41,0xA2,0xB8,0xEE,0xFF,0x63,0x49,0x03,0x49,0x0A,0xBA,0xEB,0x09, + 0xA5,0x51,0x43,0x49,0xCA,0xAE,0xBD,0xEB,0xA5,0x59,0x64,0x51,0x55,0x6D,0xB7,0x35, + 0x26,0x6A,0x84,0x51,0xA5,0xAF,0x29,0x0F,0x09,0x8B,0x26,0x72,0x3D,0x2D,0x29,0x2F, + 0x4A,0x9B,0xE8,0x8A,0xA9,0x02,0x0A,0xA3,0x2A,0x9B,0xA8,0x8A,0x78,0x78,0x60,0xF2, + 0xA8,0x8A,0x47,0x7A,0xD4,0xFA,0x7A,0xF8,0x67,0x82,0xE5,0x69,0xFA,0xF2,0x7E,0x7F, + 0x06,0x72,0xA5,0x61,0x56,0xA8,0xCA,0x0A,0x27,0x72,0xA5,0x61,0x95,0x2A,0x0A,0x22, + 0x67,0x7A,0xC5,0x61,0x57,0xFF,0xBE,0x2E,0x27,0x6A,0xA5,0x59,0x76,0x7E,0x78,0x60, + 0xA5,0x59,0x03,0x41,0xDE,0xA8,0x20,0xF8,0xA5,0x51,0x03,0x41,0xF7,0xA8,0xB8,0x5F, + 0xA6,0x51,0x24,0x49,0x2F,0xAA,0xAE,0xFD,0xA5,0x51,0x23,0x49,0xAE,0xAC,0xEE,0x7F, + 0x84,0x51,0x23,0x49,0x20,0xA2,0xEB,0xFD,0xA5,0x59,0x43,0x49,0x3F,0xFF,0xFF,0xAD, + 0x06,0x62,0x84,0x59,0x2F,0xAD,0x2F,0x8B,0x67,0x72,0xC5,0x61,0x7D,0x7B,0xC2,0x22, + 0x26,0x6A,0xA4,0x59,0xED,0xF7,0x76,0x68,0x67,0x72,0xC5,0x61,0xAB,0xAB,0x2D,0x29, + 0x67,0x72,0xA4,0x59,0x80,0xA0,0x70,0x7C,0xC4,0x59,0xE2,0x38,0xF8,0x5C,0x5E,0x57, + 0xC5,0x61,0xE2,0x38,0xBF,0x35,0x3D,0x2D,0x67,0x7A,0xC5,0x61,0x2D,0x0F,0x8B,0xAB, + 0x88,0x7A,0x26,0x72,0xBE,0x8E,0xEB,0x5E,0x67,0x7A,0xE6,0x69,0xB8,0xE8,0xFA,0xDF, + 0xC8,0x8A,0x06,0x72,0x2D,0x25,0x2F,0x2B,0x2A,0x93,0xC8,0x8A,0x4B,0xFB,0x7D,0xC3, + 0xE9,0x8A,0x67,0x7A,0x56,0xF8,0xBC,0xA8,0xE9,0x8A,0x88,0x82,0x29,0xB7,0xD7,0x5F, + 0x0A,0x8B,0xA8,0x82,0x3A,0x3F,0x35,0x55,0x76,0xF6,0x8B,0x9B,0x2D,0x2D,0xF5,0xD5, + 0xF8,0xFE,0x31,0xD5,0x00,0x00,0x02,0x09,0x18,0xFF,0xF8,0xFE,0x7A,0x57,0x7D,0x55, + 0xF8,0xFE,0x75,0xE6,0xE0,0xF0,0xF0,0x78,0x55,0xEE,0x75,0xE6,0x8A,0xEB,0xAA,0x20, + 0x75,0xEE,0x55,0xEE,0xD9,0xFF,0xFF,0xE5,0x96,0xEE,0x35,0xE6,0x97,0x2F,0xBB,0x2F, + 0xF8,0xFE,0x96,0xF6,0x2D,0x2F,0x09,0x0B,0x18,0xFF,0xF8,0xF6,0xDB,0x7B,0x7B,0x7A, + 0x18,0xFF,0xF8,0xF6,0x2F,0xA9,0x2B,0x0D,0x18,0xFF,0xF8,0xF6,0x00,0x08,0xA0,0xE0, + 0x18,0xFF,0xF8,0xF6,0xBA,0xAA,0xFA,0xEE,0x18,0xFF,0xF8,0xF6,0xFF,0x7E,0x5E,0x7F, + 0x18,0xFF,0xF8,0xF6,0xFF,0xDD,0xEF,0xED,0xF7,0xFE,0xF8,0xF6,0xFF,0x7E,0xFF,0xFF, + 0xD8,0xFE,0xF7,0xF6,0x57,0x5F,0xD7,0x7F,0x18,0xFF,0xF8,0xF6,0x6F,0x55,0x75,0xD5, + 0xF8,0xF6,0xD7,0xF6,0xBA,0xFC,0xDC,0xBA,0xF7,0xF6,0xD7,0xF6,0xAA,0x2A,0x0B,0xAA, + 0x18,0xFF,0xF7,0xF6,0x57,0x5D,0xBF,0xBB,0x17,0xFF,0xF8,0xF6,0x55,0xDD,0xFF,0xFD, + 0x18,0xFF,0xF8,0xF6,0xFF,0xFD,0xFF,0x77,0x18,0xFF,0xF8,0xF6,0xFF,0x7A,0xBD,0xFF, + 0xF8,0xFE,0xF7,0xF6,0xDB,0xFF,0xFF,0xAE,0x18,0xFF,0xF8,0xF6,0xBB,0xFA,0xFA,0xFF, + 0x18,0xFF,0xF8,0xF6,0x7F,0x7D,0x7F,0x9B,0xD7,0xFE,0xF8,0xF6,0xDD,0xFD,0xF5,0xD5, + 0xF8,0xF6,0xD7,0xF6,0x8E,0x9C,0xFE,0x2A,0xF8,0xF6,0xD7,0xF6,0xAA,0xB2,0xF8,0xB2, + 0xF7,0xF6,0x98,0xF6,0xA0,0xAA,0xE8,0xAA,0xD7,0xF6,0x96,0xEE,0xE0,0xAE,0x6A,0xFE, + 0x96,0xF6,0x76,0xEE,0x88,0xD8,0x54,0xB2,0x95,0xEE,0x56,0xE6,0xCA,0xFB,0xFF,0xFE, + 0x76,0xEE,0x55,0xEE,0x00,0xA7,0xD7,0xA5,0x76,0xF6,0x55,0xE6,0xFF,0xFF,0x7C,0x78, + 0x76,0xEE,0x35,0xE6,0xBA,0xEA,0xB2,0xFA,0x36,0xEE,0x55,0xE6,0x55,0xDF,0xD7,0xBA, + 0x75,0xEE,0x35,0xE6,0xF6,0xFF,0x3F,0xB5,0x76,0xEE,0x55,0xE6,0xF3,0x23,0xB3,0xFF, + 0x96,0xEE,0x55,0xE6,0xAD,0xBB,0xAF,0x2F,0x96,0xEE,0x76,0xEE,0x78,0xFE,0x7F,0x6B, + 0x96,0xEE,0x76,0xEE,0x65,0x7D,0x5F,0x7D,0x95,0xEE,0x76,0xEE,0x55,0x55,0x7B,0x99, + 0x96,0xEE,0x76,0xEE,0xB5,0x55,0x75,0x7A,0x96,0xEE,0x34,0xE6,0xE2,0x68,0xFE,0x7E, + 0x14,0xE6,0x71,0xCD,0x5E,0xFA,0xF8,0xE8,0xF4,0xDD,0x51,0xCD,0x57,0x7F,0xAA,0x2A, + 0xD3,0xDD,0x51,0xCD,0x2D,0x2E,0x2A,0x8A,0x14,0xDE,0xB3,0xD5,0x8A,0xAB,0xEF,0xAF, + 0x14,0xE6,0x92,0xD5,0x78,0x7A,0xEA,0x6A,0xD3,0xDD,0x92,0xD5,0x01,0x81,0xA3,0x42, + 0x72,0xD5,0xCF,0xBC,0xF8,0x68,0xFC,0x5E,0x10,0xC5,0xCF,0xBC,0xB8,0xF3,0x72,0x56, + 0xF0,0xC4,0xCF,0xBC,0x81,0x8D,0x75,0xE6,0x10,0xC5,0xAF,0xBC,0x3B,0xAE,0x9B,0x9E, + 0x91,0xD5,0xF0,0xC4,0xEB,0xEF,0xAD,0x2B,0x51,0xCD,0x6E,0xB4,0xD7,0x5E,0x5E,0x78, + 0x31,0xCD,0xAF,0xBC,0xE3,0xCB,0x8B,0xAD,0xAF,0xBC,0x2D,0xAC,0x36,0x9E,0xBC,0x54, + 0x51,0xCD,0xAF,0xBC,0x29,0x2B,0x0F,0x2D,0x71,0xCD,0x31,0xC5,0xAA,0xEA,0xFF,0x7D, + 0x31,0xCD,0xCF,0xBC,0xDA,0xFE,0x2E,0x2A,0x72,0xCD,0xF0,0xC4,0xAD,0x2F,0xAA,0x2A, + 0x72,0xCD,0x51,0xCD,0x5D,0x5E,0x16,0x7C,0x71,0xCD,0x51,0xCD,0x1D,0xF7,0xE4,0xEA, + 0x87,0x7A,0x25,0x6A,0x7E,0xEE,0xEE,0xAA,0xA7,0x7A,0x25,0x6A,0xBD,0xFD,0xFD,0x2E, + 0xC7,0x7A,0x45,0x6A,0x2E,0xD7,0xF5,0xDF,0xC7,0x7A,0x25,0x6A,0x02,0x2B,0xF7,0xF5, + 0xE8,0x82,0x45,0x72,0x2A,0x0B,0xAF,0xFD,0xE8,0x82,0x86,0x7A,0xAA,0xB0,0x2A,0xBD, + 0xE8,0x82,0xA7,0x7A,0xFA,0x60,0xC8,0xFD,0xE8,0x82,0x87,0x7A,0xA3,0x89,0xCA,0x82, + 0xE8,0x82,0x87,0x7A,0x08,0x20,0xAA,0x62,0xE8,0x82,0x86,0x7A,0x70,0xF0,0xBA,0xEB, + 0xE8,0x82,0xA7,0x7A,0x49,0xF9,0xF9,0xEB,0xE8,0x8A,0xA7,0x7A,0x92,0x2A,0xBE,0xAF, + 0xE8,0x82,0xA7,0x7A,0x2B,0xAF,0x56,0xA6,0xE8,0x82,0xC7,0x82,0x07,0xA1,0x05,0xAD, + 0xC8,0x8A,0xE8,0x82,0xB5,0xF5,0x95,0xEC,0x08,0x8B,0xC8,0x82,0xEB,0xEA,0xE9,0xDF, + 0x09,0x8B,0xC8,0x82,0x7B,0xFB,0xFD,0x2E,0x09,0x8B,0xC8,0x82,0x7F,0xFB,0xA9,0x37, + 0xE8,0x8A,0xC8,0x82,0xEB,0x45,0x86,0x04,0x08,0x8B,0xC8,0x82,0x35,0xA5,0xFE,0xBE, + 0x09,0x8B,0xC8,0x82,0xEA,0xF2,0xFF,0xA7,0x09,0x8B,0xC8,0x82,0x3E,0x93,0xFB,0x7C, + 0x29,0x8B,0xE8,0x82,0xA7,0x5D,0x69,0xA9,0x29,0x8B,0xE8,0x82,0x0F,0x8F,0x6F,0x7F, + 0xEC,0xA3,0x09,0x8B,0x0F,0x75,0x55,0x55,0xB3,0xDD,0x09,0x8B,0x0A,0xBD,0x55,0x55, + 0x55,0xEE,0x29,0x8B,0x00,0xAA,0xFD,0x55,0x32,0xCD,0x84,0x51,0x78,0x78,0x7A,0x7F, + 0x43,0x49,0xE2,0x38,0xBF,0xD4,0xBE,0x0A,0x84,0x51,0x03,0x41,0xAD,0xFD,0xEF,0x6A, + 0xA4,0x51,0x23,0x41,0x8B,0x8B,0xBE,0xF7,0xA5,0x59,0x43,0x49,0x2E,0x3E,0x2F,0x2D, + 0x26,0x72,0xC5,0x61,0x3D,0xBD,0xBD,0xB5,0xC8,0x8A,0x26,0x72,0x0F,0x0B,0xAD,0xB5, + 0x2A,0x9B,0xA7,0x82,0x02,0x2B,0xAD,0xAD,0x29,0x9B,0xC9,0x8A,0x6A,0xAA,0x20,0x0A, + 0x0A,0x9B,0x47,0x7A,0x7E,0xFC,0xF8,0xF8,0x67,0x7A,0x06,0x72,0xDD,0xEF,0xEF,0x2C, + 0x87,0x82,0xE6,0x69,0x5D,0x7E,0xFA,0xE2,0x47,0x7A,0xE5,0x69,0x1D,0xB5,0xD7,0xF7, + 0x88,0x7A,0x26,0x72,0x2E,0xA3,0x0F,0xED,0x88,0x82,0x05,0x62,0x78,0xF8,0x7E,0x57, + 0xE6,0x61,0x43,0x49,0x5E,0x70,0xC0,0x80,0x84,0x51,0xC2,0x38,0xDF,0x5E,0xFA,0xA0, + 0x44,0x49,0x03,0x41,0xFD,0x75,0xA9,0xA8,0x64,0x49,0x03,0x41,0xE3,0xBF,0xE7,0x9B, + 0x85,0x51,0x03,0x41,0x95,0xFF,0xAF,0x0A,0xA5,0x59,0x43,0x49,0x2D,0x2D,0x2E,0x2F, + 0x26,0x6A,0xC5,0x59,0xB9,0xAD,0xAD,0xED,0x87,0x72,0x06,0x6A,0xBB,0xFF,0x9F,0x3B, + 0xA8,0x7A,0x26,0x6A,0x7F,0xFB,0xAA,0x02,0x67,0x72,0x06,0x62,0x2B,0x2A,0x88,0x78, + 0x67,0x72,0x63,0x51,0x78,0x58,0x5E,0x5F,0x43,0x49,0xC2,0x38,0xDA,0x5A,0xF8,0xF8, + 0xE5,0x61,0x23,0x41,0x2D,0xAD,0xAD,0xB5,0x26,0x72,0xA5,0x59,0x02,0x2B,0xA7,0x75, + 0x27,0x72,0xC5,0x61,0xE8,0xE8,0xFE,0xA9,0x27,0x72,0xA5,0x61,0x9F,0x95,0x1F,0x9E, + 0xE9,0x8A,0x47,0x7A,0x2D,0xA9,0x2D,0x89,0x4A,0x93,0xA8,0x82,0x8A,0xFA,0x7B,0x5F, + 0xC9,0x8A,0x47,0x7A,0x68,0xEA,0xAB,0xA5,0xA8,0x82,0x67,0x7A,0xAB,0x0B,0x2F,0xA2, + 0x29,0x93,0x88,0x7A,0x7D,0xFF,0xFE,0xE2,0x4A,0x93,0x88,0x7A,0x0F,0x3D,0xD5,0xD5, + 0xB6,0xF6,0x09,0x8B,0x0B,0x2F,0xAD,0xB5,0xD7,0xFE,0xD3,0xDD,0x00,0x00,0x02,0x09, + 0xD7,0xFE,0x55,0xEE,0x68,0x78,0x58,0xDA,0x76,0xEE,0x55,0xEE,0xFF,0xBB,0xBB,0x69, + 0x75,0xEE,0x15,0xEE,0x2A,0xA2,0xA8,0xE2,0x96,0xEE,0x55,0xEE,0x37,0x2D,0x05,0x2D, + 0xF8,0xFE,0xB6,0xF6,0x29,0x2D,0x0D,0x2D,0x18,0xFF,0xF8,0xF6,0x7E,0xFF,0xFF,0xDB, + 0x39,0xFF,0xF8,0xFE,0xBD,0xBD,0xEF,0x29,0x39,0xFF,0x18,0xFF,0x5F,0x6F,0x7F,0x5F, + 0x18,0xFF,0xF8,0xF6,0xAA,0xA8,0xA2,0xAA,0x18,0xFF,0xF8,0xF6,0xFB,0xEB,0x92,0x5E, + 0x18,0xFF,0xF8,0xF6,0xD7,0x77,0xDF,0xFF,0xD7,0xFE,0xF8,0xF6,0x77,0xDD,0xF5,0xF5, + 0xF8,0xF6,0xD7,0xF6,0xAC,0xEA,0xE8,0xEA,0xF8,0xF6,0xD7,0xF6,0xA2,0x8A,0xAB,0xAE, + 0xF7,0xF6,0xD7,0xF6,0xAA,0x0E,0xAA,0xAA,0x18,0xFF,0xD7,0xF6,0xBF,0xBB,0xBB,0xAA, + 0xF7,0xFE,0x18,0xF7,0xAE,0xBE,0xBA,0xAA,0x18,0xFF,0xF7,0xF6,0xFF,0xF7,0xFF,0x7E, + 0xD8,0xFE,0xF7,0xF6,0x55,0xF5,0xDD,0xFD,0xF7,0xFE,0xF8,0xF6,0xFF,0xFF,0xFF,0xEF, + 0x19,0xFF,0xF7,0xF6,0xDF,0xFF,0xDD,0xFD,0x18,0xFF,0xF7,0xF6,0xFF,0x7D,0xED,0xFF, + 0x18,0xFF,0xF8,0xF6,0xFA,0xFE,0x7F,0x7F,0xD7,0xFE,0xF8,0xF6,0x95,0xD5,0x55,0x75, + 0xF7,0xF6,0xD8,0xF6,0x2A,0xA8,0xA8,0xAA,0xF7,0xF6,0xD7,0xF6,0xB8,0xDB,0xE7,0xF6, + 0xF7,0xF6,0xB7,0xF6,0x7E,0x7E,0x5E,0x5F,0xB7,0xF6,0x76,0xEE,0xAA,0xEB,0xE2,0xFA, + 0x96,0xEE,0x55,0xEE,0xA0,0xC8,0xE2,0xEB,0x76,0xEE,0x56,0xE6,0x88,0xAC,0xA0,0x00, + 0x76,0xEE,0x56,0xEE,0x20,0x02,0xAA,0xA2,0x76,0xEE,0x15,0xE6,0xC8,0x2A,0xA2,0x82, + 0x76,0xEE,0x35,0xE6,0xFA,0xEA,0xF2,0xFA,0x55,0xEE,0x14,0xDE,0xFA,0xE8,0xF8,0xFA, + 0x55,0xE6,0x14,0xDE,0x0B,0x0B,0x2F,0x85,0x76,0xEE,0x55,0xE6,0xEF,0x2A,0x29,0xBD, + 0x96,0xEE,0x76,0xEE,0xBD,0x7F,0xDD,0xF7,0x96,0xEE,0x76,0xEE,0x6D,0xA7,0x25,0x3F, + 0x96,0xEE,0x76,0xEE,0x7D,0xF5,0xFB,0xF8,0x96,0xEE,0x76,0xEE,0xFB,0xBA,0xFF,0xFF, + 0x96,0xF6,0x76,0xEE,0xEF,0xEB,0x8B,0xEB,0x96,0xEE,0x14,0xE6,0x6A,0x6A,0xE8,0x68, + 0x14,0xE6,0xD4,0xDD,0xDA,0x08,0x0A,0x28,0x34,0xE6,0xF4,0xDD,0x5D,0x7F,0xFB,0xCA, + 0x14,0xE6,0xD3,0xDD,0x55,0x57,0x7B,0xE2,0xF4,0xDD,0xB3,0xDD,0x8B,0x0A,0xAF,0xA8, + 0x14,0xE6,0x92,0xD5,0x6A,0x7A,0xAA,0xA0,0xF4,0xDD,0xF0,0xC4,0xEA,0xEA,0x78,0x78, + 0x10,0xC5,0x8E,0xB4,0xA8,0xBC,0xFA,0xDE,0xCF,0xBC,0xAF,0xBC,0x00,0xF2,0xFE,0xAC, + 0xEF,0xBC,0x8E,0xB4,0xE3,0xF7,0x5F,0x74,0xD0,0xC4,0x4D,0xAC,0xA2,0xEA,0xFE,0xD7, + 0x51,0xCD,0xCF,0xBC,0x09,0x05,0x8D,0xA5,0x51,0xCD,0x8E,0xB4,0x78,0xE0,0xA0,0x80, + 0x31,0xCD,0xCF,0xBC,0x25,0xE5,0xF5,0xFF,0xF0,0xBC,0xEC,0xA3,0xDE,0xFC,0x5E,0xF8, + 0x31,0xCD,0x8F,0xB4,0x09,0x0D,0x09,0x09,0x51,0xCD,0x10,0xC5,0x8B,0xFE,0xAC,0x7A, + 0x72,0xCD,0xF0,0xC4,0xB7,0xA7,0x2D,0xAA,0x92,0xD5,0x31,0xC5,0xAD,0xEF,0xEC,0x2E, + 0x93,0xD5,0x51,0xCD,0xD7,0x5F,0x5F,0xFA,0x71,0xCD,0x51,0xCD,0xF3,0xFB,0xF6,0x7E, + 0x86,0x7A,0x46,0x72,0xA8,0xA6,0xEE,0xA8,0x86,0x7A,0x46,0x72,0x28,0xAB,0x2B,0xAA, + 0xA7,0x7A,0x45,0x72,0xDF,0x5F,0xEA,0x62,0x86,0x7A,0x45,0x72,0x68,0x60,0x60,0x43, + 0x86,0x72,0x25,0x72,0xFE,0x9F,0xAA,0xA0,0x87,0x7A,0x46,0x72,0x03,0xBB,0x7E,0x8F, + 0xC8,0x82,0x25,0x6A,0x2B,0xAB,0xDF,0x57,0xA7,0x82,0x05,0x6A,0x00,0x00,0x0B,0xBD, + 0xE8,0x82,0x87,0x7A,0xEE,0x2B,0xBB,0x75,0xE8,0x82,0xA7,0x7A,0xEF,0xAB,0xA9,0x29, + 0xE8,0x82,0x87,0x7A,0xEB,0x7A,0x88,0x0E,0xE8,0x82,0xA8,0x82,0x03,0x82,0xAA,0x28, + 0xE8,0x82,0x88,0x82,0x2A,0xA2,0x28,0xB8,0x09,0x8B,0xA7,0x7A,0xFF,0xDE,0xBE,0xE8, + 0xE8,0x82,0xA7,0x7A,0xAB,0xE2,0xC3,0x89,0xE8,0x82,0xA8,0x82,0xA8,0x8A,0xAC,0xEB, + 0xE8,0x82,0xC8,0x82,0x0A,0xFF,0x2B,0x2A,0x09,0x83,0xA7,0x7A,0x2E,0xBF,0x9E,0xFA, + 0x09,0x8B,0xC8,0x82,0x3A,0x77,0xE3,0xF0,0x08,0x8B,0xC8,0x82,0x7A,0x6D,0xF5,0x95, + 0x09,0x8B,0xC8,0x82,0xC1,0xCF,0xAB,0xD4,0x08,0x8B,0xC8,0x82,0x5E,0x7E,0xFA,0x7F, + 0x08,0x8B,0xC7,0x82,0x82,0x01,0xCB,0xBF,0x29,0x8B,0xC8,0x82,0xF5,0x6F,0xA8,0xEB, + 0x09,0x8B,0xC9,0x82,0xBF,0x02,0x38,0xFE,0x09,0x8B,0xC8,0x82,0x00,0xB0,0xBE,0x96, + 0x29,0x8B,0xC8,0x7A,0xFC,0xFA,0xFA,0x7E,0xC9,0x82,0x84,0x51,0x78,0x68,0xF8,0x78, + 0x63,0x49,0x23,0x49,0xEF,0x2E,0x6C,0xF0,0x84,0x51,0x43,0x49,0xEB,0xBE,0xAF,0xDD, + 0x84,0x51,0x44,0x49,0xF5,0x5F,0xBE,0x3A,0xC5,0x61,0x64,0x51,0xBD,0x35,0xAF,0xAF, + 0xE6,0x69,0xA5,0x61,0x38,0xAF,0xB9,0x29,0xA8,0x82,0xE5,0x69,0xAD,0xBF,0x2D,0x29, + 0xE9,0x92,0xA8,0x82,0x89,0xB9,0xBB,0xAA,0x09,0x93,0xA8,0x8A,0x88,0xFA,0xFD,0x77, + 0xEA,0x92,0x67,0x82,0xE8,0xFA,0xFE,0x7E,0x67,0x7A,0x26,0x72,0x1E,0x1A,0x58,0x77, + 0x67,0x7A,0x26,0x72,0xE0,0x00,0x3C,0xD5,0x46,0x72,0x06,0x72,0xE5,0xDE,0x34,0x9C, + 0x67,0x7A,0x06,0x6A,0xFD,0xEE,0xAE,0x0A,0x46,0x72,0xE5,0x61,0x5E,0xFA,0x7E,0x5C, + 0x06,0x6A,0xA5,0x59,0xFA,0xF0,0x72,0x55,0xA5,0x59,0x23,0x49,0x7A,0x68,0x5A,0x7A, + 0x23,0x49,0xE3,0x40,0x28,0xF0,0xE8,0xB2,0x64,0x49,0x03,0x41,0xBD,0x9D,0x2F,0xB9, + 0x64,0x49,0x23,0x49,0x35,0xAD,0xAF,0xFE,0x84,0x59,0x23,0x49,0x9A,0xAA,0x2A,0x2A, + 0x05,0x62,0xA5,0x59,0x3F,0xBF,0xB5,0xDD,0x88,0x72,0xC5,0x59,0x2B,0x27,0xAF,0xAD, + 0x88,0x72,0x46,0x72,0xBE,0xB2,0xE2,0xC2,0x67,0x72,0xA4,0x59,0xE2,0x68,0x7A,0x7A, + 0xA4,0x59,0x43,0x49,0xE0,0xE8,0xF8,0x7E,0x64,0x51,0x02,0x41,0xDC,0xDC,0xFA,0xEF, + 0xA5,0x59,0x23,0x49,0xBD,0xAF,0xBD,0x3B,0x47,0x72,0x84,0x59,0xF5,0xD5,0xBD,0x2F, + 0x27,0x72,0xC6,0x69,0xA5,0xB7,0xAA,0x88,0xA8,0x82,0x06,0x6A,0xD5,0xF5,0xB5,0x0A, + 0x09,0x93,0x67,0x7A,0xED,0xFF,0xAE,0xA2,0xC9,0x8A,0x26,0x72,0xE0,0x7A,0x78,0xFA, + 0x88,0x82,0x26,0x72,0x2F,0x9D,0xFF,0xFB,0xE9,0x8A,0x87,0x82,0xAB,0x83,0x09,0x25, + 0x4A,0x93,0xC8,0x82,0x62,0x6A,0xEB,0x55,0xC9,0x82,0x67,0x7A,0xB7,0xDF,0x7A,0x78, + 0x0C,0x9C,0xA8,0x82,0x2D,0xFD,0xFD,0xF5,0xB6,0xF6,0x4A,0x93,0x0B,0xAD,0xF5,0x55, + 0x76,0xF6,0x11,0xC5,0x00,0x80,0x2B,0xAD,0x76,0xEE,0x55,0xEE,0xFE,0xB5,0xB5,0xB5, + 0x76,0xEE,0x55,0xEE,0xE8,0xAE,0x7E,0x5E,0xD7,0xF6,0x55,0xEE,0xBD,0xA7,0xAF,0xA5, + 0x18,0xFF,0xB7,0xF6,0xAD,0x2F,0xAF,0x2B,0x18,0xFF,0xD7,0xF6,0xBA,0xF8,0xFA,0xBE, + 0x39,0xFF,0xF8,0xF6,0x87,0xAD,0xAD,0xAD,0x18,0xFF,0x38,0xF7,0x22,0x88,0x02,0x08, + 0x18,0xFF,0xF8,0xF6,0xAA,0xA8,0xE2,0xAA,0x18,0xFF,0xF8,0xF6,0xFE,0xFA,0xFF,0xFE, + 0x18,0xFF,0xF8,0xF6,0xFE,0x79,0xEB,0xDF,0xD7,0xFE,0xF8,0xF6,0xDD,0x57,0xDD,0xFF, + 0xF8,0xF6,0xD7,0xF6,0xEA,0xB2,0xBE,0xBA,0xF7,0xF6,0xD7,0xF6,0xAE,0x9E,0x3E,0xA7, + 0xF7,0xF6,0xD7,0xF6,0xE3,0x88,0xAA,0x8A,0xF8,0xFE,0xF7,0xF6,0xFF,0xFF,0xF9,0xFF, + 0xD7,0xFE,0xF7,0xF6,0x5F,0x57,0x57,0x7F,0xF7,0xFE,0x18,0xF7,0x2E,0x0B,0xAA,0xFF, + 0xF8,0xFE,0x17,0xEF,0x28,0xA2,0xA2,0xAA,0x17,0xFF,0xF8,0xF6,0xFD,0x57,0x5F,0xFB, + 0x18,0xFF,0xF8,0xF6,0xAB,0xFE,0xB9,0xDE,0x18,0xFF,0xF8,0xF6,0xFF,0xEE,0xAA,0xAA, + 0x18,0xFF,0xF8,0xF6,0x7E,0xDA,0x5E,0xD7,0xD8,0xFE,0xF7,0xF6,0xD7,0xF7,0x9D,0xBD, + 0xF7,0xF6,0xB7,0xEE,0xAA,0xFE,0x5F,0x77,0xD7,0xF6,0x96,0xEE,0x00,0xAA,0xEF,0xDF, + 0xD7,0xF6,0x76,0xEE,0xA8,0xE2,0xEB,0xFF,0xB7,0xF6,0x55,0xE6,0xE8,0xFC,0xFC,0xFE, + 0x76,0xEE,0x55,0xE6,0x8E,0xAE,0xA8,0x00,0x96,0xEE,0x76,0xEE,0x7D,0x75,0xD5,0x55, + 0x76,0xEE,0x56,0xEE,0xBE,0xF4,0x9E,0xFA,0x75,0xEE,0x56,0xEE,0xD5,0xF5,0xAD,0xBB, + 0x76,0xEE,0x35,0xE6,0xFA,0xFA,0x82,0xA0,0x55,0xEE,0x14,0xE6,0xF2,0xF8,0x20,0x00, + 0x55,0xEE,0x14,0xDE,0xAF,0xDF,0xBE,0xB0,0x75,0xEE,0x35,0xE6,0xAB,0x2B,0x2B,0xAD, + 0x96,0xEE,0x76,0xEE,0xBF,0x2F,0x8F,0xEF,0xB6,0xF6,0x75,0xEE,0xAF,0xBF,0xBA,0x2A, + 0x96,0xEE,0x55,0xE6,0xFC,0x7B,0xB8,0x28,0x96,0xEE,0x55,0xE6,0x2B,0xAF,0x2B,0x00, + 0x95,0xEE,0x76,0xEE,0x6B,0xFB,0xF2,0xE2,0x96,0xEE,0x14,0xE6,0xE8,0xE0,0x62,0xF8, + 0x34,0xE6,0xF4,0xDD,0xF0,0xF8,0xFF,0xD7,0x14,0xE6,0xF4,0xDD,0x02,0xBA,0xFB,0x5D, + 0x14,0xE6,0xD3,0xDD,0xA0,0xBE,0xD7,0xD6,0xD3,0xE5,0xF4,0xDD,0x5D,0xDD,0xEF,0xFF, + 0x14,0xE6,0xD3,0xD5,0x02,0x02,0xE2,0x68,0xB3,0xD5,0xAF,0xBC,0xF0,0x78,0x58,0x5E, + 0xCF,0xBC,0x8E,0xB4,0xB8,0xA8,0xDF,0xED,0xAF,0xBC,0x4D,0xAC,0x00,0xA8,0xFA,0x58, + 0xAF,0xBC,0x0C,0xA4,0xA8,0xEA,0xEE,0x7F,0x8F,0xB4,0x0D,0xA4,0x2E,0xBD,0xB5,0xB5, + 0x11,0xC5,0x6F,0xB4,0x2A,0x2B,0x2D,0xAF,0x72,0xD5,0x10,0xC5,0xAA,0xAF,0x0D,0x35, + 0xB3,0xD5,0xF0,0xC4,0x5F,0x7E,0x7A,0xAA,0xF0,0xC4,0x0D,0xA4,0x58,0x58,0xD8,0xD8, + 0x31,0xCD,0x6E,0xB4,0x09,0x29,0x8D,0x89,0x31,0xCD,0xF0,0xC4,0xD0,0xF2,0x80,0x02, + 0x72,0xCD,0x31,0xCD,0xB5,0x0D,0x2D,0x2F,0x92,0xD5,0x51,0xCD,0xBF,0xEA,0xFB,0xFF, + 0x92,0xD5,0x51,0xCD,0xA3,0xDA,0xDE,0xAC,0x71,0xD5,0x51,0xCD,0xF8,0xF8,0xEC,0x30, + 0xA7,0x7A,0x46,0x7A,0xBB,0x28,0x92,0x82,0xA7,0x7A,0x45,0x72,0xEA,0x10,0xAA,0xAA, + 0xA7,0x7A,0x45,0x72,0xAA,0x85,0xAA,0xA2,0xA7,0x7A,0x45,0x6A,0xFE,0xDC,0xB2,0xAA, + 0xA7,0x7A,0x66,0x72,0x69,0xE9,0xA6,0x9A,0xA7,0x7A,0x46,0x72,0xAB,0xBA,0x6B,0x8F, + 0xA7,0x7A,0x46,0x72,0x57,0x5B,0xF7,0xD7,0x87,0x7A,0x46,0x72,0x55,0x6B,0xFA,0xA2, + 0x66,0x72,0x25,0x6A,0x9F,0x7E,0x5B,0x28,0xA7,0x7A,0x25,0x6A,0x0A,0xAD,0xFD,0xFF, + 0xC7,0x82,0x25,0x6A,0x00,0x8A,0xBF,0x57,0xE8,0x8A,0x66,0x72,0x8A,0xA0,0xEE,0xF5, + 0xE8,0x82,0xA7,0x7A,0xEC,0x1D,0xBD,0x55,0x08,0x8B,0xA7,0x7A,0xFF,0xDF,0xAB,0xBA, + 0xE8,0x82,0xA7,0x82,0x09,0x0B,0xC2,0x9F,0xE8,0x82,0xA7,0x7A,0xAA,0xBD,0xEB,0xA3, + 0x09,0x83,0xA7,0x7A,0xE8,0xFA,0xBF,0xBB,0xE9,0x82,0xC8,0x82,0x0F,0xD5,0x5B,0x42, + 0x09,0x8B,0xA7,0x7A,0xE2,0xEA,0xD8,0xDF,0xE8,0x8A,0xA7,0x7A,0x2B,0xBB,0x3D,0xAF, + 0xE8,0x8A,0xC8,0x82,0xBC,0x96,0xEE,0xFC,0x08,0x8B,0xC8,0x82,0x77,0xD4,0x5D,0xB7, + 0x09,0x8B,0xC8,0x82,0x95,0xD8,0xF8,0xFF,0x09,0x8B,0xA7,0x82,0xBE,0xFA,0xF8,0xDE, + 0xE8,0x8A,0xA8,0x82,0xBA,0xEA,0xAB,0x0A,0x09,0x8B,0xA7,0x82,0xBC,0xBB,0x6B,0xAB, + 0x08,0x83,0xA7,0x7A,0xFF,0x7F,0xFF,0xF8,0xA7,0x7A,0x84,0x51,0xF8,0x7A,0x78,0x5E, + 0xA4,0x59,0x23,0x41,0x78,0xFA,0xFF,0x57,0x84,0x49,0x23,0x49,0xAB,0x2D,0x9C,0xFD, + 0xC5,0x59,0x64,0x51,0xBA,0xBF,0x3B,0xFD,0xC5,0x61,0x84,0x59,0x3E,0xBF,0xAB,0xBB, + 0x26,0x72,0xC5,0x61,0xA5,0xAB,0x09,0x09,0xE8,0x8A,0x26,0x72,0xBD,0xAF,0x0F,0xAB, + 0xE9,0x92,0xA8,0x8A,0x2B,0x83,0xAA,0xEC,0xC8,0x92,0x46,0x7A,0xE8,0xF8,0xFE,0x7E, + 0x88,0x82,0x05,0x72,0xB0,0xDE,0x7F,0xFE,0x46,0x7A,0xE5,0x69,0xEA,0xBA,0x7F,0xEC, + 0x26,0x72,0xC5,0x69,0x00,0x0A,0x3E,0xDE,0x26,0x72,0xC5,0x61,0x88,0xE8,0xFA,0xBF, + 0x26,0x72,0x84,0x59,0x00,0xFE,0xFB,0x7E,0x26,0x72,0x84,0x59,0xE8,0xBE,0x5F,0x5D, + 0xA5,0x59,0x23,0x49,0xAA,0xFC,0x78,0xEA,0x64,0x51,0x02,0x49,0x48,0xEA,0xCF,0x80, + 0x84,0x51,0x03,0x49,0xDD,0xBB,0xEA,0x2A,0x64,0x49,0x23,0x49,0xFF,0x5C,0xDF,0x97, + 0x43,0x49,0x02,0x49,0x28,0xE8,0xEA,0x00,0xC5,0x59,0x23,0x49,0xAF,0x2D,0xBF,0x09, + 0x27,0x6A,0xA4,0x59,0xFD,0xBD,0xA9,0x2E,0x47,0x6A,0xE5,0x61,0x8D,0x02,0xB0,0xFF, + 0x67,0x72,0xE5,0x61,0x80,0xF2,0x7B,0xDD,0x46,0x72,0xC5,0x61,0x7E,0xE2,0xAA,0xFA, + 0xA5,0x59,0x43,0x49,0x7E,0xD8,0x50,0x70,0xA5,0x59,0x02,0x41,0xFF,0xB7,0x2F,0x0B, + 0xC5,0x61,0x44,0x51,0xAD,0xAB,0xA2,0x08,0x67,0x7A,0xA5,0x61,0x2D,0x0D,0xBD,0xB9, + 0x87,0x82,0x26,0x72,0x5F,0x57,0xAF,0x81,0x2A,0x93,0x26,0x72,0xAD,0x2D,0x2D,0xAF, + 0x2A,0x93,0xC7,0x8A,0xEA,0x60,0xE8,0x62,0xC8,0x8A,0x27,0x72,0xFE,0xF8,0xF8,0x58, + 0xE9,0x8A,0x47,0x7A,0xBD,0x35,0x2D,0x3D,0xE9,0x8A,0x46,0x72,0xBF,0xFE,0xF8,0x60, + 0xA8,0x82,0x06,0x6A,0x20,0x22,0xBA,0x5F,0xA8,0x7A,0xC5,0x61,0x88,0xAA,0xEE,0xD5, + 0xC8,0x82,0x06,0x6A,0x02,0x02,0x2B,0xB5,0x2A,0x8B,0x87,0x7A,0x2E,0x2E,0x3F,0x95, + 0xB3,0xDD,0x6B,0x93,0x0B,0x2D,0x35,0xF5,0x56,0xEE,0x93,0xDD,0x00,0x02,0x0B,0x09, + 0x76,0xEE,0x35,0xE6,0xBA,0xF8,0xB8,0xFE,0xB7,0xF6,0x55,0xEE,0x2D,0x2D,0x2D,0xAD, + 0xF7,0xFE,0xB7,0xF6,0x02,0x0B,0x03,0x8B,0xD6,0xFE,0xF8,0xF6,0xFD,0xD5,0x7D,0xFD, + 0x18,0xFF,0xF8,0xF6,0x02,0x0A,0x0D,0x2D,0x18,0xFF,0xF8,0xF6,0x00,0x80,0x80,0xA0, + 0x18,0xFF,0xF8,0xF6,0x82,0xA0,0xCA,0xAA,0x18,0xFF,0xF8,0xF6,0xFF,0xD7,0xFD,0x7F, + 0x18,0xFF,0xF8,0xF6,0x5E,0x5B,0xDF,0xD5,0xD7,0xFE,0xF8,0xF6,0x5B,0x5F,0x57,0x75, + 0xF7,0xF6,0xD8,0xF6,0x9C,0xA0,0x2A,0xAA,0xD7,0xFE,0xF7,0xF6,0xDF,0xDD,0xDF,0xFF, + 0xD8,0xFE,0xF7,0xF6,0x57,0x5D,0x5F,0xFF,0x18,0xFF,0xF7,0xF6,0x55,0xD5,0xFF,0xFD, + 0x18,0xFF,0xF7,0xF6,0x57,0xDD,0x36,0xAF,0x18,0xFF,0xF8,0xF6,0xE3,0xAA,0xEC,0xFA, + 0x18,0xFF,0xF8,0xF6,0xAF,0xAB,0xAB,0xAB,0x18,0xFF,0xF8,0xF6,0xFF,0xDE,0xFF,0xEA, + 0x18,0xFF,0xF8,0xF6,0xFF,0x7F,0x5F,0xFE,0x18,0xFF,0xD8,0xF6,0xAA,0xBA,0xF2,0xFA, + 0xF8,0xF6,0xD7,0xF6,0x20,0xB8,0xFB,0x5F,0xF8,0xF6,0xB7,0xEE,0xA0,0xCA,0xEE,0x5E, + 0xD7,0xF6,0x96,0xEE,0x78,0xFA,0xFE,0xFE,0xB6,0xF6,0x76,0xEE,0xFA,0xEE,0xFA,0xDE, + 0x96,0xEE,0x55,0xE6,0xE8,0xEA,0x78,0x7E,0x96,0xEE,0x55,0xE6,0xEA,0xFA,0xAF,0x2D, + 0x96,0xEE,0x76,0xEE,0xFD,0xFD,0xE7,0x7B,0x76,0xEE,0x55,0xEE,0x30,0xA0,0x20,0xAE, + 0x76,0xEE,0x56,0xEE,0xFB,0xAA,0xF8,0xBC,0x76,0xEE,0x55,0xEE,0xAF,0xB7,0xEA,0xE8, + 0x76,0xEE,0x55,0xEE,0x82,0x80,0x3B,0x2D,0x76,0xEE,0x55,0xEE,0xD7,0x52,0x68,0x98, + 0x55,0xEE,0x35,0xE6,0x58,0x72,0xE0,0x20,0x55,0xEE,0x14,0xE6,0x0B,0x15,0x9F,0x9C, + 0x96,0xEE,0x35,0xEE,0xA2,0xAB,0xFF,0xE7,0xB7,0xF6,0x34,0xE6,0x82,0xAE,0x7F,0x55, + 0xB7,0xF6,0x35,0xE6,0x2A,0xAE,0xFD,0x55,0x96,0xEE,0x55,0xEE,0x20,0xA0,0xD7,0xD5, + 0x96,0xEE,0x55,0xEE,0x22,0x2E,0x2F,0x2A,0x96,0xF6,0xF3,0xDD,0x68,0x68,0x68,0xF8, + 0x14,0xE6,0xD3,0xDD,0xB7,0xEF,0xAB,0xAA,0x14,0xE6,0xD3,0xDD,0xFF,0xDB,0xE6,0xFB, + 0x14,0xE6,0xD3,0xDD,0xF7,0x75,0xF5,0xAE,0x14,0xE6,0xF4,0xDD,0x79,0xC3,0xE9,0x6B, + 0xF4,0xE5,0x31,0xCD,0x80,0xE0,0x70,0x70,0x31,0xC5,0xAF,0xBC,0x58,0x5F,0xB7,0xFE, + 0xF0,0xC4,0x8E,0xB4,0x57,0xFB,0xAE,0x82,0xF0,0xC4,0x4D,0xAC,0xDE,0xFF,0xEA,0xE2, + 0xAF,0xBC,0x0C,0xA4,0x5F,0xF6,0x88,0x00,0x8E,0xB4,0xAB,0x9B,0xBF,0x2E,0x28,0xA8, + 0xD0,0xBC,0x8E,0xB4,0xE3,0xAB,0xFB,0xBF,0x31,0xC5,0x8E,0xB4,0x2A,0xAD,0xFD,0xD7, + 0x71,0xCD,0x6E,0xB4,0x00,0x80,0xFF,0x5F,0x10,0xC5,0x2C,0xAC,0x78,0xDC,0x57,0x95, + 0x31,0xCD,0x8E,0xB4,0x29,0x89,0x0B,0x0B,0x31,0xCD,0x10,0xC5,0x3C,0x17,0xD7,0xAF, + 0x92,0xD5,0x31,0xCD,0x8F,0x2D,0xA7,0xA5,0x92,0xD5,0x51,0xCD,0xBB,0x18,0xBA,0xAE, + 0x92,0xD5,0x51,0xCD,0xAA,0xEF,0x8E,0xF2,0x92,0xD5,0x51,0xCD,0x9E,0xDE,0xFB,0xE2, + 0xC7,0x7A,0x66,0x72,0x89,0xCB,0xFF,0xFF,0xA7,0x7A,0x86,0x7A,0x92,0xA2,0x9E,0x0B, + 0xA7,0x7A,0x66,0x72,0xA0,0xF0,0x38,0xF8,0x67,0x7A,0x86,0x72,0x5D,0x5B,0xDB,0x75, + 0xC7,0x7A,0x86,0x72,0x55,0xF7,0xEB,0xDF,0xA7,0x7A,0x66,0x72,0x2A,0x0A,0x28,0x3E, + 0xA7,0x7A,0x67,0x72,0x7A,0xFE,0xFF,0x88,0x86,0x7A,0x65,0x6A,0x02,0x08,0xB2,0x82, + 0xA7,0x7A,0x45,0x72,0xF7,0xD7,0xBB,0x2C,0x87,0x7A,0x46,0x72,0x7E,0x68,0xAA,0x8A, + 0x87,0x7A,0x46,0x72,0xFF,0xA3,0x08,0x08,0x86,0x7A,0x66,0x72,0xA5,0xFB,0xED,0xFF, + 0x86,0x7A,0x46,0x72,0x02,0x5F,0x57,0x7E,0xC8,0x82,0x25,0x6A,0x22,0xAF,0xBF,0xDF, + 0xE8,0x82,0x45,0x72,0x0A,0x80,0xAF,0x7D,0xE8,0x82,0x87,0x7A,0xA0,0x82,0xA2,0x3F, + 0xE9,0x8A,0xC8,0x82,0x2D,0x37,0xDF,0xDE,0xE8,0x8A,0xC8,0x82,0x62,0xC4,0x6A,0xAE, + 0x09,0x8B,0xC8,0x82,0x59,0xF3,0xED,0x16,0xE8,0x8A,0xA8,0x82,0xAF,0x2B,0xFE,0xC8, + 0xE8,0x8A,0xA7,0x82,0x3C,0x28,0x20,0xED,0xE8,0x8A,0xC8,0x82,0xB0,0xC8,0xE2,0xC1, + 0xE8,0x8A,0xC8,0x82,0x78,0x5E,0x40,0xBA,0x09,0x93,0xA7,0x82,0xDF,0xAE,0x2A,0xE6, + 0xE8,0x8A,0xA7,0x82,0x29,0x00,0x82,0x0B,0xE8,0x8A,0xC8,0x82,0x0B,0xDE,0xA6,0xE8, + 0xE8,0x82,0x66,0x72,0xE0,0x70,0x74,0x7A,0x66,0x72,0x84,0x51,0x58,0x5E,0x5A,0x78, + 0x64,0x51,0xE2,0x40,0xFC,0xF6,0x7E,0xFE,0x44,0x49,0xE2,0x38,0x02,0x3F,0xBF,0x57, + 0x84,0x51,0xE2,0x38,0x82,0x2F,0xFF,0xD5,0xA4,0x59,0x02,0x41,0x02,0x2B,0x2F,0x0D, + 0x46,0x72,0xC5,0x61,0x0D,0x0D,0x2F,0xA5,0xC8,0x8A,0x25,0x72,0x0B,0x0D,0xAF,0x25, + 0x29,0x93,0xA7,0x82,0xFB,0xBB,0x09,0xAF,0x09,0x93,0x67,0x82,0x5E,0xEA,0xA0,0xE8, + 0x88,0x82,0x06,0x72,0xEA,0xE0,0xFA,0x7C,0x67,0x7A,0x26,0x72,0x72,0xF2,0xCD,0xAD, + 0x47,0x7A,0xA4,0x61,0x7A,0x7A,0xA0,0xE8,0xE6,0x69,0x44,0x51,0x0A,0xEA,0xD8,0x7E, + 0xE5,0x69,0x43,0x51,0xA0,0xA3,0x6B,0xD5,0xA5,0x61,0x23,0x49,0xE8,0xEB,0x7B,0x5A, + 0x85,0x51,0x03,0x49,0x2A,0xBF,0xDD,0x7F,0x85,0x51,0x03,0x49,0xAA,0x0F,0xFF,0xBD, + 0x64,0x49,0x23,0x49,0xA2,0x88,0x80,0x63,0x84,0x51,0x02,0x41,0xF7,0xDF,0xFF,0x2F, + 0xA5,0x51,0x43,0x49,0xD5,0xD5,0xA7,0x88,0x06,0x62,0x84,0x51,0x25,0xBD,0xED,0x5D, + 0x06,0x62,0x64,0x51,0x20,0xB8,0xEB,0xFD,0x06,0x62,0x84,0x51,0x20,0xAB,0xA7,0xD5, + 0x06,0x62,0xA5,0x51,0xAB,0xAF,0xCF,0xDD,0x06,0x62,0x84,0x51,0x40,0xCA,0xEB,0x5F, + 0xA5,0x59,0x23,0x49,0xFA,0xFE,0x9F,0x3F,0x06,0x6A,0x64,0x51,0xB5,0xF5,0xBB,0x8B, + 0xE5,0x69,0xC5,0x61,0x5E,0x7F,0x7D,0xAE,0x67,0x7A,0xC5,0x61,0x5F,0xF5,0xBD,0x0B, + 0xA8,0x82,0x47,0x7A,0x25,0x25,0xF7,0x7A,0xE9,0x8A,0x47,0x72,0x2A,0x2A,0xBD,0xDD, + 0xE9,0x8A,0x88,0x82,0xE0,0x5A,0x58,0xCB,0xA8,0x82,0x27,0x72,0x58,0x7E,0xBC,0xFA, + 0x88,0x7A,0x26,0x72,0x2F,0xDF,0xF5,0xE5,0xA8,0x82,0xC4,0x61,0xA0,0xAA,0xEA,0x7A, + 0x06,0x6A,0xE2,0x40,0xA0,0xA8,0xFA,0x7E,0xC6,0x61,0x23,0x49,0x2A,0x0F,0x2D,0xB5, + 0x47,0x72,0xA5,0x59,0x0A,0xAF,0xDF,0xF5,0xC8,0x82,0xE5,0x61,0x0A,0x2F,0x2D,0xAD, + 0x2E,0xAC,0x88,0x7A,0x2F,0x2F,0xBD,0xF5,0xF4,0xE5,0x6A,0x9B,0x02,0x0B,0x0F,0xB5, + 0x55,0xEE,0x52,0xD5,0x00,0x00,0xAA,0xBD,0xB7,0xFE,0x14,0xE6,0x2B,0x0B,0x2F,0x2D, + 0xF8,0xFE,0xB7,0xFE,0x0B,0x2B,0x2A,0x2B,0xF8,0xFE,0xB7,0xF6,0xA8,0xAA,0x3E,0x9E, + 0x18,0xFF,0xB8,0xF6,0x0A,0x0A,0x2A,0x8B,0x18,0xFF,0xF8,0xF6,0xA2,0x80,0x80,0x80, + 0x18,0xFF,0xF8,0xF6,0xA2,0x8E,0xFA,0xEA,0x17,0xFF,0xF8,0xF6,0x7E,0xFF,0xFF,0xFF, + 0xD8,0xFE,0xF7,0xF6,0x56,0x7F,0x77,0x75,0xF7,0xFE,0xF8,0xF6,0xFF,0xFF,0xEF,0xFB, + 0xF7,0xF6,0xD7,0xF6,0xAB,0x8B,0xE2,0xB0,0xF7,0xF6,0xD8,0xF6,0xA8,0x0E,0x2A,0x8E, + 0xF8,0xFE,0xF7,0xF6,0xFF,0xFF,0xBF,0xFF,0x18,0xFF,0xD7,0xF6,0xFF,0xEB,0xEA,0xAA, + 0x18,0xFF,0xF7,0xF6,0xFB,0xFD,0xFF,0x7F,0xF8,0xFE,0x18,0xF7,0xAE,0xAA,0xEA,0xBE, + 0x18,0xFF,0xF8,0xF6,0xFB,0xFE,0xFE,0xDF,0xF8,0xFE,0x18,0xF7,0xAA,0xB8,0xAA,0xAA, + 0x18,0xFF,0xF8,0xF6,0xFF,0x7F,0x5E,0x76,0x18,0xFF,0xD7,0xF6,0xFA,0xFA,0xFE,0xEF, + 0xF7,0xF6,0xD7,0xF6,0x76,0x7E,0xBF,0x77,0xD7,0xF6,0xB7,0xF6,0x7C,0x70,0xA0,0xF8, + 0xB7,0xF6,0x96,0xEE,0xE8,0xEE,0x78,0xF0,0x96,0xEE,0x76,0xEE,0xD8,0xF0,0x7B,0x56, + 0x75,0xEE,0x35,0xE6,0xF8,0x7E,0xEA,0xFA,0x75,0xEE,0x35,0xE6,0x0B,0xAB,0xBF,0xFD, + 0x55,0xEE,0x76,0xE6,0xBD,0x02,0x02,0x22,0x76,0xEE,0x55,0xEE,0xCE,0xDE,0xD5,0xD5, + 0x76,0xEE,0x55,0xEE,0xFF,0x87,0x3A,0xF2,0x75,0xEE,0x56,0xEE,0xFB,0xEF,0xF7,0x55, + 0x76,0xEE,0x55,0xEE,0xAD,0xBD,0xF9,0xB0,0x76,0xEE,0x55,0xEE,0x68,0xEB,0x2A,0xBE, + 0x76,0xEE,0x14,0xE6,0xEA,0xA0,0x2A,0x20,0x55,0xEE,0x14,0xE6,0xE0,0xF0,0xF0,0xF0, + 0x55,0xEE,0x14,0xE6,0xAB,0xF9,0xD5,0xFF,0x35,0xE6,0x14,0xE6,0xFA,0xD7,0xB4,0xF8, + 0x55,0xEE,0x14,0xE6,0xBB,0x3F,0xBB,0x3F,0x96,0xF6,0x55,0xE6,0x9D,0xAF,0x0B,0x22, + 0x96,0xF6,0x75,0xEE,0x89,0xAB,0xC0,0xE0,0x96,0xF6,0xF3,0xDD,0x78,0x5E,0x5C,0x5E, + 0x14,0xE6,0xD3,0xDD,0xAF,0x3F,0x95,0xAD,0x34,0xE6,0xF4,0xE5,0xDD,0x8B,0x8F,0xB7, + 0x35,0xE6,0xF3,0xDD,0xFE,0xEE,0xB8,0x7A,0x14,0xE6,0xF4,0xDD,0xB2,0x20,0x20,0xF9, + 0x14,0xE6,0x31,0xCD,0x78,0x68,0xF8,0x78,0x51,0xCD,0xF0,0xC4,0x5F,0x55,0x5C,0x7A, + 0xF0,0xC4,0xCF,0xBC,0x0A,0x03,0x69,0x42,0xF0,0xC4,0xAF,0xBC,0xEA,0xEF,0xF4,0x77, + 0xD0,0xC4,0xAE,0xB4,0xBD,0x2F,0x2A,0x83,0xCF,0xBC,0xEC,0xA3,0xF8,0x58,0x78,0x60, + 0xCF,0xBC,0xEC,0xA3,0x82,0xAB,0xAF,0xAD,0xAF,0xBC,0x2D,0xAC,0xA8,0xEE,0x7F,0x5F, + 0x8E,0xB4,0xEC,0xA3,0xA0,0xEB,0xFE,0x77,0xCF,0xBC,0xEC,0x9B,0xBF,0xBD,0x3F,0x3D, + 0x31,0xCD,0xD0,0xBC,0x2D,0x2B,0x8B,0x8E,0x31,0xCD,0x10,0xC5,0x24,0xF4,0xD7,0x6B, + 0x72,0xD5,0x10,0xC5,0x2B,0x2B,0xFD,0xFF,0x72,0xD5,0x31,0xCD,0xA8,0xA2,0xA4,0xFF, + 0x92,0xD5,0x31,0xCD,0xAA,0x83,0xFE,0xDB,0x92,0xD5,0x31,0xCD,0xA2,0xFA,0xAD,0xF9, + 0xA7,0x7A,0x45,0x6A,0x28,0xAF,0x3F,0xD5,0xC7,0x7A,0x65,0x6A,0x2A,0xBA,0xAE,0xDB, + 0xA7,0x7A,0x66,0x72,0xA8,0xEA,0xAA,0xED,0xA7,0x7A,0x86,0x72,0x56,0xBF,0xA2,0xC2, + 0xC7,0x7A,0x86,0x72,0xFF,0x7E,0xFB,0xAB,0xC7,0x7A,0x66,0x72,0xB7,0xB3,0xBB,0xDE, + 0xA7,0x7A,0x87,0x72,0xAA,0x38,0xBA,0xBE,0xC8,0x82,0x66,0x72,0xE5,0xBF,0x0B,0xAA, + 0xA7,0x7A,0x66,0x72,0xFF,0xE2,0xF0,0x0A,0xC7,0x82,0x66,0x72,0xFE,0xE2,0xEB,0xB6, + 0xA7,0x7A,0x46,0x72,0x8E,0xEB,0xAA,0x9A,0xA7,0x7A,0x66,0x72,0xD3,0xD7,0xBB,0xAE, + 0x87,0x7A,0x45,0x72,0x6A,0xB8,0x28,0x00,0x87,0x7A,0x45,0x72,0x7B,0xE3,0x72,0xC0, + 0x86,0x7A,0x45,0x72,0xFD,0x25,0xFB,0xDF,0x87,0x7A,0x25,0x6A,0x3F,0xB7,0xA7,0xA2, + 0xC8,0x82,0x45,0x72,0x03,0x27,0xF5,0xF7,0xE8,0x8A,0x46,0x72,0x88,0xAA,0x3F,0x55, + 0xE8,0x8A,0x66,0x72,0x2A,0xA0,0xAA,0xBD,0xE8,0x82,0xA7,0x82,0x8A,0x6F,0x89,0xBB, + 0xE8,0x82,0xA7,0x7A,0x77,0x6D,0x2B,0xAA,0x08,0x8B,0xA7,0x82,0xFD,0xF5,0xBF,0x1E, + 0xE8,0x8A,0xC8,0x82,0xFB,0x5E,0xEB,0x62,0x08,0x8B,0xA7,0x82,0xA6,0x8B,0xAB,0x6D, + 0xE8,0x82,0xA8,0x82,0xAC,0xBB,0xFA,0xFA,0xE8,0x82,0x87,0x7A,0x6A,0x68,0x2A,0x02, + 0xE8,0x82,0x86,0x72,0x7F,0xEA,0xFC,0xE8,0xA7,0x7A,0x83,0x51,0x7E,0x78,0x78,0x78, + 0x43,0x49,0xE2,0x38,0xFE,0xFC,0x7A,0xFC,0x03,0x41,0xE2,0x38,0xFE,0x9E,0x5D,0x77, + 0xE2,0x38,0x81,0x30,0xAA,0xDA,0xAA,0xAC,0x64,0x51,0xC2,0x38,0x0F,0x2D,0xF5,0x55, + 0xE5,0x69,0x03,0x49,0x02,0x0A,0xAF,0xBD,0x87,0x82,0xA4,0x61,0x2B,0xAF,0xF5,0x55, + 0x09,0x93,0x26,0x72,0x2A,0x2B,0xFF,0xD5,0x09,0x93,0x27,0x7A,0xE8,0x6A,0xDF,0x57, + 0x88,0x82,0x06,0x72,0xFE,0xDD,0x9E,0x22,0x67,0x7A,0x06,0x6A,0xEF,0xFF,0x7E,0x58, + 0x06,0x6A,0xC5,0x69,0x68,0x5C,0x7F,0x97,0x26,0x72,0x84,0x59,0x57,0x7F,0xBA,0x0A, + 0xE5,0x69,0x43,0x51,0xF5,0xBF,0xBA,0xA0,0xC5,0x61,0x23,0x49,0x7E,0xFE,0xF8,0xE8, + 0x43,0x49,0x03,0x49,0xEA,0xAE,0xEC,0x9E,0x43,0x49,0x02,0x41,0x0D,0x8A,0x0A,0x00, + 0x64,0x49,0x23,0x49,0xEB,0xAB,0x3A,0x8A,0x85,0x51,0x23,0x41,0x2B,0x0E,0xBE,0x57, + 0xA5,0x59,0x03,0x41,0x80,0xA2,0xFE,0x75,0x64,0x49,0x23,0x41,0x00,0xF4,0x7F,0x65, + 0x84,0x51,0x23,0x41,0xF2,0xEF,0xBF,0xDD,0x84,0x51,0x23,0x41,0x0A,0x7E,0xDE,0xFF, + 0xA5,0x59,0x23,0x41,0x0A,0x2A,0xD7,0x55,0xC5,0x59,0x03,0x41,0xC8,0xFA,0xF5,0x55, + 0xE6,0x61,0x43,0x49,0xB5,0x3F,0x3D,0x2D,0x67,0x7A,0xE6,0x69,0xAF,0x0D,0xA8,0xB9, + 0x67,0x7A,0x06,0x6A,0x5F,0xEC,0x8B,0xA0,0xC8,0x82,0x26,0x72,0xBD,0xBD,0x2D,0xEA, + 0xEA,0x8A,0x47,0x72,0x7A,0xFA,0xE8,0xF8,0x67,0x7A,0xC6,0x69,0x8A,0xBB,0xF8,0x78, + 0xC9,0x8A,0xE5,0x69,0x8A,0xAB,0xDF,0x75,0x68,0x7A,0xC5,0x61,0x00,0x00,0x8A,0xFD, + 0x68,0x7A,0xC5,0x59,0x88,0xE0,0xEA,0x7E,0x47,0x72,0x03,0x49,0xA0,0xEA,0xFA,0x5F, + 0x64,0x51,0x02,0x41,0x58,0x7E,0xEE,0xBF,0xA5,0x59,0x03,0x49,0xAD,0x2D,0x2F,0x2F, + 0xE5,0x61,0x85,0x51,0xEF,0xA5,0x2B,0xAA,0x47,0x72,0xC4,0x61,0x09,0x8F,0xEE,0xBA, + 0xA8,0x7A,0x05,0x6A,0x0B,0xFF,0xF5,0xBD,0xAC,0xA3,0x46,0x72,0x2F,0xBD,0xFD,0xFF, + 0x11,0xCD,0x46,0x72,0x02,0xAF,0xFF,0x5F,0x93,0xDD,0x87,0x7A,0x00,0x2A,0xFF,0x55, + 0xB7,0xFE,0x6A,0x9B,0x00,0xAA,0xFF,0x55,0x97,0xF6,0x4D,0xB4,0x00,0x00,0xBF,0xD5, + 0xF8,0xFE,0x92,0xD5,0x00,0x02,0x0B,0x2D,0x18,0xFF,0xF8,0xFE,0xBF,0xBE,0xB7,0xD5, + 0x18,0xFF,0xF8,0xF6,0xEA,0xEA,0xBE,0xB7,0x18,0xFF,0xF8,0xF6,0xF7,0xFF,0xFA,0xAE, + 0xF8,0xFE,0xF7,0xF6,0xFF,0xBF,0xFF,0xFF,0x18,0xFF,0xD8,0xF6,0xEA,0xEE,0xFA,0x6E, + 0xF8,0xF6,0xD7,0xF6,0xA8,0xBE,0xAE,0xAE,0xF7,0xF6,0xD7,0xF6,0x3B,0xAB,0xAC,0x22, + 0xD8,0xFE,0x17,0xF7,0xEA,0xFA,0xBF,0xFF,0x18,0xFF,0xF7,0xF6,0xD7,0xBD,0xAF,0xAB, + 0x18,0xFF,0xF8,0xF6,0xFF,0xFA,0xEB,0xEA,0x18,0xFF,0xF8,0xF6,0xFE,0xFE,0xBF,0xF7, + 0x18,0xFF,0xF8,0xF6,0xFF,0x78,0xEA,0x6A,0xF8,0xFE,0x18,0xF7,0xAB,0xAE,0x8A,0xA8, + 0x18,0xFF,0xD8,0xF6,0xA9,0xAE,0xAE,0xEA,0xF7,0xF6,0xB7,0xF6,0xA0,0xE8,0x68,0x7A, + 0xD7,0xF6,0xB7,0xF6,0x00,0xA2,0xA9,0x0D,0xD7,0xF6,0xB7,0xF6,0xDC,0x55,0x76,0x56, + 0xB6,0xF6,0x96,0xEE,0xF8,0xFC,0x7E,0x56,0x96,0xEE,0x76,0xEE,0x5E,0xBA,0x80,0xA8, + 0x96,0xEE,0x55,0xE6,0x5F,0xFF,0xAE,0xA2,0x55,0xEE,0x35,0xE6,0xFE,0xFF,0xFE,0x18, + 0x76,0xEE,0x55,0xEE,0xEF,0xEA,0xAA,0x01,0x76,0xEE,0x55,0xEE,0xAD,0x29,0x00,0xA0, + 0xB5,0xF6,0x56,0xEE,0x5F,0xFF,0x7D,0xEF,0x76,0xEE,0x55,0xEE,0x95,0x55,0x7D,0xF7, + 0x76,0xEE,0x55,0xEE,0xFA,0xF8,0x27,0x37,0x76,0xEE,0x55,0xEE,0x9A,0xB2,0xBA,0xAA, + 0x76,0xEE,0x55,0xEE,0xF8,0x78,0xFB,0xD7,0x75,0xEE,0x15,0xE6,0xEA,0xAA,0xA8,0x08, + 0x55,0xEE,0x15,0xE6,0xFA,0xFE,0xFC,0xBE,0x55,0xEE,0x35,0xE6,0x5D,0xEB,0x2F,0x3F, + 0x55,0xEE,0x34,0xE6,0x15,0xE5,0xE0,0x40,0x96,0xF6,0x35,0xE6,0x03,0xAB,0x29,0xE5, + 0x96,0xF6,0x35,0xE6,0x88,0xF2,0xFA,0x7F,0x75,0xEE,0xD3,0xDD,0x58,0x7A,0x5E,0x56, + 0x14,0xE6,0xB3,0xD5,0xAB,0x3D,0xAF,0xDF,0x34,0xE6,0xF4,0xE5,0xFF,0xEB,0xAF,0xAD, + 0x35,0xE6,0xD3,0xDD,0x7A,0x7A,0x7A,0x8A,0x15,0xE6,0xB3,0xD5,0xBB,0xD5,0xF7,0xE8, + 0xD3,0xDD,0x30,0xCD,0xE0,0x60,0x78,0x60,0x51,0xCD,0xF0,0xC4,0xE8,0x7E,0x7F,0xFE, + 0x10,0xC5,0xAE,0xBC,0xFB,0xFF,0x5F,0xB8,0xF0,0xBC,0xAF,0xBC,0xD5,0x9E,0xA3,0xAE, + 0x10,0xC5,0xCF,0xBC,0xFB,0xF9,0xA9,0x92,0x31,0xCD,0x2D,0xAC,0x7A,0xE2,0x82,0x00, + 0x11,0xC5,0xAB,0x9B,0xB7,0xFF,0x7A,0x60,0x2D,0xAC,0x09,0x8B,0x80,0xAA,0xFF,0xF7, + 0xEC,0xA3,0x4A,0x8B,0xE8,0xFA,0xDF,0x55,0xD0,0xBC,0x8C,0x9B,0x2D,0x2D,0x0D,0x2D, + 0x10,0xC5,0xCF,0xBC,0x02,0x0B,0x0B,0x9D,0x10,0xC5,0xF0,0xC4,0x02,0x8C,0x76,0x67, + 0x51,0xCD,0xF0,0xC4,0xBA,0x2F,0x3F,0xBD,0x51,0xCD,0x31,0xCD,0x83,0xA7,0xD7,0xB7, + 0x72,0xD5,0x31,0xCD,0xA2,0xEF,0xDF,0x77,0x72,0xD5,0x30,0xCD,0xBB,0xEA,0xFE,0x55, + 0x46,0x6A,0x05,0x6A,0x2B,0xAB,0xAB,0xFF,0x86,0x72,0xE4,0x61,0x3E,0xB7,0xFF,0xFE, + 0xA7,0x7A,0x05,0x6A,0x8A,0xCF,0x7F,0x7D,0xA7,0x7A,0x05,0x62,0x82,0x22,0xAB,0xFD, + 0xA7,0x7A,0x46,0x6A,0x02,0x20,0xB2,0x3D,0xC7,0x7A,0x67,0x72,0xB4,0x9A,0xFC,0xEA, + 0xA7,0x7A,0x46,0x72,0x02,0x00,0xA2,0x60,0xC8,0x7A,0x66,0x72,0xF8,0xFA,0x7F,0xFB, + 0xC7,0x82,0x66,0x72,0xBF,0xA7,0x3F,0xBF,0xC7,0x7A,0x86,0x7A,0xD5,0x79,0x77,0xF7, + 0xA7,0x7A,0x46,0x72,0x9F,0xEE,0x80,0x28,0xA7,0x7A,0x66,0x72,0xBA,0xE7,0x1F,0x23, + 0xA7,0x7A,0x87,0x7A,0x3E,0x9C,0x9B,0xE9,0xA7,0x7A,0x66,0x72,0x7A,0x57,0xBC,0xB4, + 0x66,0x7A,0xA7,0x72,0x2E,0xBE,0xBE,0xAE,0xC7,0x82,0x46,0x72,0x5F,0xEF,0xAB,0x2B, + 0xA7,0x7A,0x66,0x72,0x5F,0xDE,0xDC,0xC2,0x87,0x7A,0x46,0x72,0x7A,0x78,0xFF,0xA3, + 0xA7,0x82,0x46,0x72,0xBD,0xD7,0xAF,0x8A,0xA7,0x82,0x46,0x72,0x22,0xBB,0x7F,0xF9, + 0xE8,0x8A,0x46,0x72,0x02,0xAE,0xF7,0x75,0x09,0x8B,0x66,0x72,0x82,0xAA,0xBB,0xD5, + 0x09,0x8B,0x87,0x7A,0x8A,0xEF,0xAF,0xFD,0xE8,0x82,0xA7,0x7A,0x7E,0x2F,0x0B,0x0B, + 0x29,0x8B,0xC8,0x82,0xD5,0x9D,0xBF,0xF2,0x08,0x8B,0xA7,0x7A,0xAA,0xA2,0xE0,0xDA, + 0xE8,0x82,0xA7,0x7A,0xE8,0xBF,0xAE,0xBE,0xC7,0x7A,0xA3,0x59,0x78,0xE0,0xA0,0x80, + 0x05,0x62,0xE2,0x40,0x5E,0x5E,0x5A,0xF8,0x03,0x41,0xE2,0x38,0x77,0x0E,0xBE,0xFD, + 0x02,0x41,0xA1,0x30,0xFE,0xFC,0xF6,0xFE,0xE2,0x38,0x81,0x30,0xAA,0xAF,0xFF,0xDB, + 0x44,0x51,0xA2,0x38,0x0B,0xAF,0xBD,0xF5,0x84,0x61,0xC2,0x40,0x00,0xAB,0xFF,0x55, + 0xC5,0x69,0x03,0x49,0x02,0xBB,0xDF,0xE5,0x47,0x7A,0x84,0x61,0x3B,0x3F,0x35,0x2D, + 0x88,0x82,0x26,0x72,0x8E,0xA7,0xAE,0x08,0xA8,0x82,0xC5,0x69,0x7E,0x7A,0xBA,0x00, + 0x88,0x82,0xE5,0x69,0x55,0x57,0xBF,0x28,0x67,0x7A,0xE5,0x69,0xBD,0x5D,0xB7,0x00, + 0xA8,0x82,0xE5,0x61,0x57,0xFF,0xAB,0x82,0x87,0x7A,0x63,0x51,0x5F,0x7E,0xFA,0xA8, + 0xA5,0x59,0x23,0x49,0xD7,0xFF,0xFA,0xE0,0x64,0x51,0x43,0x49,0x65,0xFA,0xF8,0x7D, + 0x64,0x51,0x03,0x41,0xA0,0xA2,0xF2,0x7E,0x23,0x49,0xC2,0x30,0xB8,0xFA,0x5A,0xFA, + 0x23,0x41,0xE2,0x38,0x2B,0x2B,0x8B,0xA5,0x64,0x49,0x03,0x41,0x3F,0xED,0xFA,0x7B, + 0x43,0x49,0xE3,0x38,0x28,0xA2,0xFA,0x7E,0x23,0x41,0xA1,0x30,0x80,0xFA,0x76,0x5F, + 0x03,0x41,0x81,0x28,0x28,0xAF,0xA5,0x25,0x44,0x49,0xC2,0x38,0xFF,0xF5,0xAF,0x0A, + 0xE6,0x61,0x03,0x41,0x29,0x3D,0x2F,0x2F,0x67,0x7A,0x06,0x6A,0x9D,0xBF,0xC2,0x63, + 0x67,0x7A,0x27,0x72,0x20,0x08,0xBF,0x75,0x68,0x7A,0x06,0x6A,0xA0,0xE0,0x6C,0xAA, + 0x47,0x7A,0xE5,0x69,0xA0,0xFE,0x5F,0x5E,0x06,0x72,0x84,0x59,0xE0,0xE8,0xFE,0x7E, + 0xE5,0x61,0x84,0x59,0x2D,0x35,0xFF,0xBD,0xE6,0x69,0x84,0x59,0x28,0x0A,0xFB,0x5E, + 0xE6,0x61,0x84,0x59,0xA0,0x80,0xAD,0x7D,0xA4,0x59,0x03,0x41,0xFE,0x7E,0x7C,0x7E, + 0x23,0x49,0x03,0x41,0x2B,0xD5,0xDF,0xDB,0x84,0x51,0x23,0x49,0xBD,0x25,0x25,0x25, + 0x47,0x72,0xA5,0x59,0xBD,0x09,0x2B,0x2B,0x47,0x72,0xA4,0x61,0xAA,0xF8,0x7C,0x5C, + 0x88,0x7A,0xE5,0x69,0x2B,0x0D,0x2D,0x25,0x0A,0x8B,0xA8,0x82,0xE5,0x8B,0x8B,0x2A, + 0xE9,0x8A,0x26,0x72,0xF2,0xEA,0x78,0x78,0x87,0x7A,0x05,0x6A,0x08,0x2F,0xBF,0xBD, + 0x4A,0x93,0x67,0x7A,0x0B,0x2F,0xF5,0xD5,0x2D,0xAC,0xC8,0x82,0x2F,0xBF,0xD5,0xF5, + 0xB7,0xF6,0xCC,0xA3,0x0B,0x2B,0x2D,0xAD,0xD8,0xFE,0x51,0xD5,0x00,0x00,0xA2,0x5F, + 0xD7,0xF6,0x72,0xD5,0x00,0x00,0x02,0xAD,0xF8,0xFE,0x96,0xEE,0x00,0x08,0x2A,0xFD, + 0xF8,0xFE,0xD7,0xF6,0xAA,0xA8,0xBB,0xA5,0xF8,0xFE,0xD7,0xF6,0xAA,0xAA,0xBE,0xAE, + 0xF8,0xFE,0xD7,0xF6,0xDB,0xFF,0xFA,0xDA,0xF8,0xFE,0xD7,0xF6,0xAA,0xAE,0xAF,0x9B, + 0xF8,0xFE,0xF7,0xF6,0xBF,0xEB,0xAA,0x82,0xD8,0xFE,0x17,0xF7,0xFF,0xEE,0xAA,0x8A, + 0x18,0xFF,0xF8,0xF6,0xEA,0xFE,0xBB,0xFF,0xF8,0xFE,0x18,0xF7,0xAA,0xAE,0x0A,0xA2, + 0xF8,0xFE,0x18,0xF7,0xBE,0xAA,0x00,0x00,0xF8,0xFE,0x18,0xF7,0xAA,0xAA,0x08,0x22, + 0x18,0xFF,0xD7,0xF6,0xEA,0xBA,0xFD,0xBB,0x18,0xFF,0xB7,0xF6,0x7F,0x7F,0x76,0x7F, + 0xD8,0xFE,0xB7,0xEE,0xAA,0xEA,0x7A,0x7F,0xB6,0xF6,0x96,0xEE,0xA8,0xEA,0xE0,0xEA, + 0xB6,0xF6,0x96,0xEE,0x5F,0xDE,0x7E,0x7B,0x96,0xEE,0x76,0xEE,0xA0,0x28,0x5D,0x5F, + 0x96,0xF6,0x76,0xEE,0x5A,0xF4,0xED,0xEF,0x96,0xF6,0x55,0xEE,0x55,0x7E,0xE2,0x80, + 0x76,0xEE,0x55,0xEE,0xA9,0xEF,0xE8,0xF0,0x75,0xEE,0x56,0xEE,0xAA,0xDF,0x55,0x97, + 0x97,0xF6,0x56,0xEE,0xFE,0xEE,0xEB,0xFE,0x76,0xEE,0x35,0xE6,0x8F,0x2E,0x0E,0x02, + 0x76,0xEE,0x55,0xEE,0x2D,0xF7,0xBE,0x00,0x76,0xEE,0x55,0xEE,0xFE,0xFC,0xFF,0xBE, + 0x76,0xEE,0x55,0xEE,0xDE,0xDB,0xAB,0xA2,0x76,0xEE,0x55,0xEE,0x0D,0x2E,0xBA,0xB6, + 0x75,0xEE,0x35,0xE6,0x76,0x5C,0xBC,0xEE,0x75,0xEE,0x34,0xEE,0xB5,0xAF,0xAB,0x22, + 0x75,0xEE,0x55,0xEE,0x62,0xC5,0x20,0xFA,0x55,0xEE,0x14,0xE6,0xAB,0xBF,0xFC,0x9A, + 0x75,0xEE,0x34,0xE6,0xE9,0xEB,0x7B,0x7F,0x14,0xE6,0xB3,0xD5,0xF8,0xF8,0x7C,0x78, + 0xF3,0xDD,0xB3,0xD5,0xD6,0xB7,0xED,0xAB,0x34,0xE6,0xD3,0xDD,0x2B,0x2D,0xAD,0xAD, + 0x35,0xEE,0x14,0xE6,0x2D,0x2B,0x2A,0x09,0x34,0xE6,0xF3,0xE5,0x78,0xB8,0x20,0x00, + 0x55,0xEE,0x51,0xCD,0x7F,0x7A,0x7A,0xE0,0x72,0xD5,0xF0,0xC4,0x5F,0xFB,0xFA,0xA8, + 0x31,0xC5,0xAF,0xBC,0xFE,0xDA,0xFC,0xFA,0x10,0xC5,0xD0,0xBC,0xF5,0xAD,0x8B,0x00, + 0x31,0xC5,0xF0,0xC4,0xB5,0xA5,0xA2,0x2A,0x52,0xCD,0x10,0xC5,0xE9,0x7F,0xBF,0x0A, + 0x31,0xCD,0x8F,0xBC,0x60,0x82,0x00,0x00,0xD0,0xBC,0xC8,0x82,0x5F,0x5E,0x7C,0x78, + 0x6B,0x93,0xA8,0x7A,0x3F,0xBD,0x35,0xB5,0xAF,0xBC,0x8B,0x93,0x09,0x29,0x0B,0x09, + 0xF0,0xC4,0xAE,0xB4,0x03,0x0B,0xEF,0xE7,0xF0,0xC4,0xCF,0xBC,0x28,0x60,0x8A,0xD8, + 0x30,0xCD,0xD0,0xBC,0x3B,0xAB,0xFF,0x7F,0x51,0xCD,0xF0,0xC4,0xAA,0x8B,0xEF,0xE5, + 0x51,0xCD,0xF0,0xC4,0xA8,0xEA,0xDF,0x7F,0x51,0xCD,0xF0,0xC4,0xAB,0xA3,0xFE,0x7E, + 0x45,0x6A,0xE4,0x69,0xEB,0xFF,0x6E,0xB8,0x45,0x6A,0x05,0x62,0xFF,0x7F,0xDF,0xAA, + 0x45,0x6A,0x05,0x6A,0x9A,0xFB,0xEA,0xBA,0x46,0x6A,0xE5,0x61,0x52,0x7A,0xBE,0xB8, + 0x66,0x6A,0x05,0x6A,0x2D,0xEF,0x55,0x76,0xA7,0x7A,0x05,0x62,0x0A,0xBB,0xF5,0xF5, + 0x87,0x7A,0x25,0x6A,0x02,0x00,0x2E,0x57,0xA7,0x7A,0x26,0x6A,0x80,0x00,0x2A,0xBD, + 0xC7,0x7A,0x87,0x7A,0xB5,0xFF,0x9D,0x57,0xA7,0x7A,0x87,0x7A,0x09,0xD3,0x14,0x13, + 0xC7,0x82,0x66,0x7A,0x7E,0xEB,0xEE,0xFA,0xA7,0x7A,0x67,0x7A,0x2A,0xB3,0xAB,0xBE, + 0xA7,0x7A,0x87,0x7A,0xAF,0xB7,0x27,0xB5,0xA7,0x7A,0x87,0x7A,0x57,0xF4,0xC3,0xAB, + 0xC7,0x82,0x66,0x72,0xBE,0xAF,0xAD,0xBE,0xA7,0x7A,0x66,0x7A,0x2D,0x88,0x00,0x0C, + 0xC7,0x82,0x87,0x7A,0x77,0xFC,0xEA,0xAE,0xA7,0x7A,0x46,0x72,0xAB,0x89,0x02,0x08, + 0xA7,0x7A,0x66,0x72,0x57,0xEE,0x88,0x02,0xA7,0x7A,0x66,0x72,0x77,0xFF,0xFA,0xF2, + 0xC7,0x82,0x46,0x72,0xDF,0xDF,0xFB,0xB8,0x86,0x7A,0x24,0x6A,0xA6,0x8A,0x8A,0xB0, + 0x87,0x7A,0x46,0x72,0x8D,0x6B,0x68,0xCB,0xE8,0x82,0x45,0x72,0x2B,0xAF,0xD7,0x5F, + 0x08,0x8B,0x66,0x72,0x02,0xA2,0xAF,0x57,0xE8,0x82,0xA7,0x7A,0xA0,0x00,0x0E,0x35, + 0xE8,0x82,0xA7,0x82,0x2F,0x08,0x20,0xE8,0xE8,0x82,0xA6,0x7A,0xEA,0xFA,0x02,0xCE, + 0xC7,0x7A,0x63,0x51,0x5A,0x58,0xE8,0x80,0xA4,0x59,0xC2,0x38,0xD7,0xD7,0x7E,0xF8, + 0xE2,0x40,0xC2,0x38,0x57,0x57,0x5E,0x60,0xE2,0x38,0x81,0x38,0x7A,0xFA,0xA8,0xA0, + 0xE3,0x40,0x81,0x38,0x2D,0x0F,0xAB,0x02,0x44,0x59,0xC2,0x40,0x95,0xB9,0x0B,0x2F, + 0xA5,0x61,0x23,0x51,0xBD,0xAF,0x2F,0x2B,0x47,0x7A,0xC5,0x69,0xBD,0x2D,0xA9,0x85, + 0xA8,0x82,0x47,0x7A,0x03,0x5B,0x7D,0xF5,0xC9,0x82,0x47,0x72,0xA2,0x7B,0x7D,0xBF, + 0x88,0x82,0x06,0x6A,0x08,0xE8,0x5F,0xEC,0xA8,0x82,0xC4,0x69,0x00,0x02,0xBD,0xB7, + 0xE9,0x8A,0x27,0x72,0x82,0x02,0xAF,0x7F,0x67,0x7A,0xC5,0x59,0xA8,0xDC,0x78,0xFE, + 0x27,0x6A,0x44,0x49,0x68,0xE0,0xEB,0x57,0x64,0x51,0xC2,0x38,0xA8,0xFC,0xFE,0x7F, + 0x23,0x41,0xC2,0x38,0xA0,0xAA,0x7D,0x5B,0x03,0x39,0xC2,0x38,0xAA,0xAF,0xAD,0xAD, + 0x03,0x41,0xE2,0x38,0x37,0xF6,0x32,0xBE,0x24,0x41,0xE3,0x38,0xC0,0xE2,0x7B,0x57, + 0xE3,0x38,0xA2,0x30,0xE0,0x48,0xAC,0x80,0xC2,0x38,0x81,0x30,0xDE,0xDF,0xCA,0x80, + 0x44,0x49,0xA1,0x30,0xB5,0xF5,0x3D,0x0B,0xA5,0x59,0x03,0x41,0xAD,0xAD,0x2F,0x0A, + 0xC6,0x61,0x64,0x51,0x25,0xBF,0xFE,0xFA,0x26,0x72,0x84,0x59,0x22,0x89,0xBD,0xB5, + 0x67,0x7A,0xE6,0x69,0xA9,0x0B,0x23,0xFD,0x88,0x82,0x26,0x72,0xE0,0xE0,0xFA,0xFD, + 0x26,0x72,0xA4,0x61,0xA0,0x88,0x80,0x7A,0xE6,0x69,0x84,0x59,0xD8,0xDA,0xD6,0x55, + 0xC5,0x59,0x84,0x59,0xB7,0xB5,0x2D,0x09,0xE6,0x61,0x85,0x59,0xFA,0xA3,0xEB,0xDE, + 0xA5,0x59,0x44,0x49,0xE8,0x80,0xE8,0x7E,0x64,0x51,0x03,0x41,0x68,0x7A,0x7A,0x7A, + 0x24,0x49,0xE3,0x40,0xAF,0xBF,0xFB,0xBF,0xE6,0x61,0x03,0x49,0xAD,0xA5,0xAF,0x2F, + 0x47,0x72,0xE6,0x61,0xA5,0xA3,0x8F,0xE3,0x68,0x7A,0xC5,0x61,0x5B,0xB7,0x2F,0x2F, + 0xA8,0x82,0x26,0x72,0xAD,0x8E,0x02,0x8A,0xC9,0x8A,0x26,0x72,0x02,0xA8,0xFE,0x7E, + 0x88,0x82,0x26,0x72,0x60,0xA2,0xAE,0x27,0xC8,0x8A,0x26,0x72,0x95,0x3E,0x0A,0x08, + 0x09,0x8B,0x66,0x7A,0xFD,0xAF,0xAE,0x2A,0x0A,0x8B,0xA8,0x82,0x2F,0x2E,0xAA,0x78, + 0x2E,0xB4,0x88,0x7A,0x0B,0xBF,0x55,0x55,0x4D,0xB4,0xA7,0x82,0x00,0xBE,0x75,0x55, + 0x31,0xCD,0x09,0x8B,0x2A,0xBF,0xFD,0x55,0x15,0xE6,0x2A,0x93,0x00,0x2A,0xAF,0xF5, + 0xD7,0xFE,0xD0,0xC4,0x00,0x0A,0x2B,0xFD,0xD7,0xFE,0x11,0xCD,0x00,0x00,0xAA,0xD5, + 0xD7,0xFE,0x94,0xDD,0x00,0x00,0x02,0xBD,0xF8,0xFE,0x96,0xF6,0xAA,0x2A,0xBB,0xF5, + 0xF8,0xFE,0xD7,0xF6,0x82,0xA0,0xA0,0x5B,0xF8,0xFE,0xB7,0xF6,0x32,0xA2,0x8A,0xFF, + 0xF8,0xFE,0xD7,0xF6,0x28,0x2E,0x8A,0xE5,0x18,0xFF,0xD7,0xF6,0xAA,0xBA,0xAB,0xFF, + 0xF8,0xFE,0xD8,0xF6,0xEA,0xAA,0xAA,0xB8,0xF8,0xFE,0xD7,0xF6,0x0A,0xA8,0x82,0xAA, + 0xF8,0xFE,0xB7,0xF6,0xA0,0xFA,0xE8,0x7A,0xD7,0xF6,0xB7,0xF6,0x7C,0xFE,0x5F,0x55, + 0xB7,0xF6,0x96,0xEE,0xE0,0xE8,0xF2,0x7A,0xB7,0xF6,0x76,0xEE,0xAA,0xFA,0x5B,0x7F, + 0x96,0xEE,0x55,0xEE,0x00,0x8A,0xDD,0xF7,0x76,0xEE,0x55,0xEE,0x20,0x00,0xA2,0xBF, + 0x55,0xF6,0x76,0xEE,0x55,0x5F,0x77,0xFE,0x96,0xF6,0x76,0xEE,0xE2,0xFF,0x7D,0x5D, + 0x76,0xEE,0x55,0xEE,0xE8,0xCA,0xB7,0x43,0x96,0xF6,0x56,0xEE,0xF5,0xFD,0xAF,0x2B, + 0x96,0xF6,0x56,0xEE,0x5E,0x7E,0xEA,0xE8,0x55,0xF6,0x76,0xEE,0x75,0x55,0x76,0xFE, + 0x96,0xF6,0x76,0xEE,0x7F,0xFE,0xEA,0x6A,0x56,0xF6,0x76,0xEE,0xF7,0xFD,0xDD,0xD5, + 0x75,0xEE,0x56,0xEE,0xA8,0x9A,0xFA,0xFB,0x76,0xEE,0x55,0xEE,0x26,0xFE,0xEA,0x28, + 0x76,0xEE,0x55,0xEE,0xFE,0xBE,0x3F,0xD5,0x75,0xEE,0x55,0xEE,0xFE,0x0C,0x80,0xCB, + 0x76,0xEE,0x34,0xE6,0xAA,0xBA,0x7E,0xFF,0x55,0xEE,0x14,0xE6,0xB2,0xA8,0xEA,0xAE, + 0x55,0xEE,0x34,0xE6,0x70,0x6B,0x61,0x7F,0x14,0xE6,0x92,0xD5,0xFC,0xF8,0x7E,0xDE, + 0xF3,0xDD,0xB3,0xD5,0x0B,0x2F,0xBD,0xB5,0x14,0xE6,0xD3,0xDD,0x2B,0x2E,0xBB,0xAD, + 0x55,0xEE,0xF4,0xDD,0xCB,0xAB,0x2F,0xB9,0x75,0xEE,0x34,0xE6,0x15,0xA5,0x0B,0xA2, + 0x75,0xEE,0x35,0xE6,0x60,0xEA,0xF6,0xB5,0x55,0xEE,0x93,0xD5,0x5F,0xFE,0xE0,0xA0, + 0xD3,0xDD,0xF0,0xC4,0x5F,0x7A,0xA8,0x80,0x72,0xCD,0x10,0xC5,0x9D,0xF5,0xBF,0xE0, + 0x51,0xCD,0x11,0xC5,0xBF,0xBE,0xA2,0x00,0x72,0xCD,0x51,0xCD,0xED,0x6D,0x9D,0x55, + 0x72,0xCD,0x31,0xCD,0x7F,0x5A,0xEA,0x8F,0x11,0xC5,0x2B,0x8B,0x78,0xE0,0xE0,0x80, + 0x4A,0x8B,0x67,0x72,0xBF,0xBE,0xBC,0xDC,0x8E,0xB4,0x09,0x83,0x0B,0x2F,0xFD,0xD5, + 0xAE,0xB4,0x8B,0x93,0x00,0xA8,0xAA,0xFD,0xD0,0xC4,0x6E,0xAC,0x2A,0xBB,0xAF,0x95, + 0xF0,0xC4,0xAF,0xBC,0xFA,0xDB,0xFD,0x75,0x31,0xCD,0xAF,0xBC,0x0F,0xAF,0xFF,0xF5, + 0x31,0xCD,0xCF,0xBC,0x2E,0xBE,0x6F,0xFD,0x10,0xC5,0xCF,0xBC,0xE0,0xA8,0xEF,0xD5, + 0x46,0x6A,0xE5,0x69,0x0A,0xBA,0x88,0xA0,0x46,0x6A,0x25,0x6A,0xF8,0xAA,0x35,0x17, + 0x46,0x72,0x05,0x62,0xDB,0xEF,0xAA,0x0A,0x66,0x72,0x05,0x6A,0xBA,0xFA,0x5E,0xF3, + 0x46,0x72,0x05,0x6A,0x7E,0xEF,0x5E,0x2A,0x46,0x72,0x05,0x6A,0xA9,0x2A,0x9A,0xC8, + 0x46,0x72,0x05,0x6A,0xF5,0x5A,0x73,0xF2,0x45,0x72,0xE4,0x69,0x2A,0xFE,0xFB,0xFA, + 0x87,0x7A,0x05,0x6A,0x2A,0xF5,0x75,0xFF,0xA7,0x82,0xE5,0x69,0x22,0x0A,0xFB,0xDF, + 0xA7,0x7A,0x26,0x72,0x20,0x00,0x8A,0xFD,0xC8,0x82,0x87,0x7A,0x57,0x6F,0xF5,0x9D, + 0xA7,0x7A,0x66,0x7A,0xC2,0x02,0x84,0x88,0xA7,0x7A,0x66,0x72,0x82,0xA8,0x8D,0x0E, + 0xC7,0x82,0x66,0x72,0x9B,0x1B,0xAB,0xE9,0xC7,0x7A,0x87,0x7A,0xF6,0x76,0x55,0xD7, + 0xA7,0x7A,0x86,0x7A,0x3E,0x25,0x3B,0xF5,0xC7,0x82,0x87,0x7A,0xDF,0xFB,0xAF,0xEB, + 0xA7,0x7A,0x45,0x72,0x0A,0xDA,0x8E,0x0B,0xA7,0x7A,0x45,0x72,0xA0,0xDE,0xEC,0x8A, + 0xA7,0x7A,0x87,0x7A,0xF8,0xBF,0xD5,0x35,0xA7,0x7A,0x87,0x7A,0xB7,0xDA,0xBE,0x2F, + 0xA7,0x82,0x46,0x72,0x70,0xB2,0x8A,0xB8,0xA7,0x7A,0x66,0x7A,0x56,0xE0,0xFE,0xB4, + 0xA7,0x7A,0x45,0x72,0x77,0xAF,0xAA,0x28,0xC7,0x82,0x66,0x72,0x25,0x5D,0xEF,0xFD, + 0xC8,0x82,0x66,0x72,0x03,0xB5,0x55,0xFF,0x08,0x8B,0x66,0x72,0xA8,0x2F,0xFD,0xDD, + 0xE8,0x82,0x65,0x72,0xE2,0x8A,0x2B,0xAD,0x86,0x72,0x03,0x49,0x7E,0xF8,0xE0,0x80, + 0xA4,0x59,0xE2,0x40,0x55,0x57,0x5E,0xF8,0x03,0x49,0xC2,0x40,0x7E,0x5A,0xF8,0x80, + 0x43,0x49,0xE3,0x40,0xDD,0x15,0xBD,0xF5,0x84,0x59,0x03,0x49,0xFD,0xAE,0xAA,0x8B, + 0x84,0x59,0xE2,0x48,0x0A,0xB7,0x5E,0x7E,0xE6,0x69,0xE3,0x48,0x0A,0xAF,0xFD,0x75, + 0x27,0x72,0x23,0x51,0x08,0xBF,0xF5,0xD5,0xA9,0x82,0x44,0x59,0x0A,0xAA,0xFF,0x5D, + 0x88,0x7A,0x85,0x61,0x00,0x08,0x8B,0xF5,0x88,0x82,0xC5,0x61,0xAA,0x00,0xA2,0x55, + 0x87,0x7A,0xC5,0x61,0xE2,0xE8,0x7A,0x55,0x06,0x6A,0x64,0x51,0x80,0xAE,0x5F,0x77, + 0xA5,0x59,0x03,0x41,0xFC,0xFE,0x57,0x57,0x23,0x41,0xE3,0x38,0x56,0xFA,0xFA,0xB5, + 0x03,0x39,0xC2,0x38,0xDE,0x5E,0xF8,0x28,0xE2,0x40,0x03,0x39,0x7A,0x76,0xD7,0xD5, + 0xE2,0x48,0x03,0x39,0x77,0xD7,0xFD,0x57,0x44,0x41,0xC2,0x38,0xF7,0xBA,0xAA,0xB2, + 0x03,0x39,0xA2,0x30,0xE8,0x7A,0xF0,0xE2,0xE2,0x38,0xA2,0x30,0xFD,0x37,0xFF,0xB9, + 0x44,0x49,0xC2,0x38,0x0B,0x29,0x09,0x29,0xC5,0x59,0x64,0x51,0x2B,0xC9,0x8D,0xA9, + 0xC5,0x69,0x64,0x51,0xFF,0xFF,0xFF,0x2E,0x06,0x72,0x64,0x59,0x89,0x0B,0xA9,0xFA, + 0xE5,0x69,0x84,0x59,0x00,0x00,0x08,0xDD,0x47,0x72,0xA4,0x61,0x8B,0xB7,0x97,0xD5, + 0x06,0x6A,0x64,0x59,0xE8,0xFA,0xFA,0x5E,0x85,0x59,0x64,0x51,0x0F,0xB8,0x98,0xEF, + 0xC5,0x61,0x64,0x51,0xC9,0xA7,0xBF,0xB5,0xE6,0x61,0x84,0x51,0x7F,0xE8,0x82,0xC2, + 0xA4,0x59,0x24,0x49,0xEA,0xE0,0xE8,0x7E,0x43,0x49,0x02,0x41,0x78,0xAE,0xAA,0xE2, + 0x64,0x51,0xE2,0x38,0xBD,0xAD,0x3F,0x2A,0xE6,0x61,0x44,0x49,0x2D,0x2B,0xAB,0xAF, + 0x47,0x72,0xC6,0x61,0xA2,0x8B,0x3F,0xF5,0x88,0x7A,0x26,0x6A,0xBD,0xEF,0xE8,0x01, + 0x88,0x82,0x26,0x72,0x8B,0xBA,0xDE,0xEA,0x88,0x82,0xE5,0x69,0xF0,0x7E,0xFF,0xD7, + 0x67,0x7A,0xE5,0x69,0x27,0x0D,0x88,0x02,0xE9,0x8A,0x47,0x72,0x2A,0x0F,0x2D,0xB5, + 0x2A,0x93,0xC9,0x8A,0x3B,0xAB,0xEF,0x6F,0x09,0x8B,0x67,0x7A,0xE8,0xA8,0xFA,0x5E, + 0x88,0x7A,0xE5,0x69,0xA8,0x78,0xBA,0xA7,0xC8,0x82,0x26,0x72,0x2B,0xBD,0xBF,0xBD, + 0xE9,0x8A,0x05,0x72,0x82,0xEA,0x5E,0x5E,0x6B,0x9B,0x47,0x72,0x2B,0x25,0xB5,0xF5, + 0x2D,0xAC,0x88,0x7A,0x00,0xFB,0x7F,0x5F,0x8B,0x9B,0x68,0x7A,0x08,0xDF,0x55,0x55, + 0x92,0xD5,0x88,0x7A,0x0B,0xBF,0xFD,0xD5,0x75,0xEE,0x6B,0x93,0x02,0xAB,0xFF,0x55, + 0xD7,0xFE,0x6B,0x93,0x00,0xAA,0xFF,0x55,0xB6,0xF6,0x6A,0x93,0x00,0xAA,0xFF,0xF5, + 0xB6,0xF6,0xCF,0xBC,0x00,0x0A,0xAF,0xA5,0xD7,0xF6,0xF4,0xE5,0x00,0x02,0x8A,0xFD, + 0xF8,0xFE,0x76,0xEE,0x80,0x02,0x2A,0xD5,0xF8,0xFE,0xB7,0xF6,0xE2,0xA8,0xAA,0xF5, + 0xD7,0xF6,0xB7,0xF6,0x78,0x78,0x58,0x75,0xB7,0xF6,0x96,0xEE,0x80,0x08,0xE8,0x7F, + 0xB6,0xF6,0x76,0xEE,0xAA,0xFE,0x7F,0x77,0x96,0xEE,0x55,0xEE,0xF0,0xF8,0x7A,0xBE, + 0x76,0xF6,0x55,0xE6,0xFB,0x2B,0x8A,0xAC,0x96,0xF6,0x55,0xEE,0xFF,0xFB,0xE8,0xFA, + 0x76,0xEE,0x35,0xEE,0xA8,0xE8,0xFA,0xFE,0x76,0xEE,0x35,0xEE,0x02,0x0F,0xAF,0xAA, + 0x96,0xF6,0x76,0xEE,0x75,0x5D,0xFD,0xB5,0x57,0xF6,0x75,0xEE,0x5F,0x5F,0xDD,0xFD, + 0x96,0xF6,0x56,0xEE,0xFA,0xAB,0x8B,0x8B,0x96,0xF6,0x56,0xEE,0xFD,0xEF,0xAA,0xEA, + 0x96,0xF6,0x76,0xEE,0xEF,0x3B,0x2F,0x8F,0xB6,0xF6,0x76,0xEE,0x7D,0xEF,0xEB,0x7F, + 0x76,0xEE,0x35,0xEE,0xA8,0xF0,0xB8,0xFA,0x75,0xEE,0x35,0xEE,0xAA,0x8D,0xFB,0xFF, + 0x76,0xEE,0x55,0xEE,0x55,0x55,0xE5,0x85,0x75,0xEE,0x35,0xEE,0xEE,0x88,0x22,0x23, + 0x75,0xEE,0x35,0xE6,0xFF,0xE3,0x20,0x80,0x55,0xEE,0x35,0xE6,0xEB,0xEA,0xEC,0xF4, + 0x55,0xEE,0xF4,0xDD,0xAA,0xC0,0xEA,0x6A,0xF3,0xDD,0x72,0xCD,0xDC,0xFA,0x7A,0x7E, + 0xD3,0xDD,0x72,0xCD,0x8F,0xB7,0xBF,0xAF,0x14,0xE6,0xB3,0xD5,0x0B,0x2F,0x2D,0xAB, + 0x34,0xE6,0xF4,0xDD,0x2B,0x8A,0xFF,0x77,0x55,0xEE,0xF4,0xDD,0x82,0xFF,0xFD,0xFD, + 0x76,0xEE,0x14,0xE6,0xAD,0xAF,0x2D,0x0F,0x96,0xF6,0x34,0xE6,0x7A,0xEA,0xA2,0x20, + 0x96,0xF6,0xF3,0xDD,0xDD,0xAA,0x82,0x08,0x96,0xF6,0x72,0xD5,0x5F,0xFA,0xE0,0x80, + 0x14,0xE6,0x51,0xCD,0x55,0x55,0x57,0xF8,0x72,0xD5,0x31,0xC5,0xEB,0xE7,0xEA,0xE8, + 0x72,0xD5,0x31,0xC5,0x2A,0xA3,0xAF,0xA6,0x72,0xCD,0xD0,0xBC,0x78,0xE8,0x80,0x82, + 0xD0,0xBC,0x67,0x72,0x5E,0x7C,0x78,0xC0,0xA8,0x7A,0xE6,0x61,0x8A,0x7F,0x5F,0xFE, + 0xAB,0x9B,0x05,0x62,0x0B,0xB5,0x55,0x55,0x6E,0xAC,0x47,0x72,0x02,0x0A,0xAB,0xF5, + 0xAF,0xBC,0xEC,0xA3,0x02,0x22,0xBB,0xE5,0xCF,0xBC,0x2E,0xAC,0x80,0x0A,0xBF,0x57, + 0xD0,0xBC,0x4E,0xAC,0x80,0x28,0xAA,0xA5,0x10,0xC5,0xAF,0xBC,0x9D,0x97,0x3B,0xA5, + 0x66,0x72,0x25,0x6A,0x6B,0xEA,0x7A,0xBA,0x46,0x72,0x05,0x6A,0x0D,0x82,0x00,0x2C, + 0x67,0x72,0x25,0x6A,0xE6,0xD3,0x6F,0xE7,0x66,0x72,0x25,0x6A,0x3A,0x1B,0x91,0x8F, + 0x46,0x72,0x05,0x6A,0xBA,0xFA,0xEE,0x40,0x26,0x6A,0x05,0x6A,0xA2,0x81,0x17,0xBD, + 0x46,0x72,0xE4,0x61,0xFE,0xFA,0xA2,0x2A,0x67,0x72,0xE5,0x69,0x9D,0xBF,0x2F,0xFE, + 0x46,0x72,0xE4,0x61,0xA8,0x8A,0x30,0x18,0x46,0x72,0x05,0x6A,0xFF,0xFD,0x6A,0x28, + 0x46,0x72,0x05,0x6A,0xA0,0x60,0xBE,0x3C,0x87,0x7A,0x05,0x6A,0x0B,0x57,0xD7,0xFF, + 0xA7,0x7A,0x05,0x6A,0x08,0xAA,0x67,0x57,0xA7,0x7A,0x05,0x6A,0x20,0x82,0xAB,0xBD, + 0xA7,0x82,0x46,0x72,0xC3,0x23,0x2A,0xB9,0xC7,0x82,0x87,0x7A,0xDD,0xF7,0xDF,0x79, + 0xC7,0x82,0x66,0x72,0x77,0xAE,0xEA,0xE3,0xC7,0x82,0x66,0x72,0x8B,0xAE,0xBB,0xDF, + 0xC7,0x82,0x87,0x7A,0x79,0xEA,0xE2,0x62,0xC7,0x82,0x66,0x72,0x29,0xAA,0xFF,0x7F, + 0xC7,0x82,0x87,0x7A,0xF7,0x6D,0xF9,0x7A,0xC8,0x82,0x66,0x7A,0xF9,0xBE,0xBA,0xA3, + 0xC7,0x82,0x67,0x7A,0xFF,0xAA,0x6A,0xFA,0xC8,0x82,0x87,0x7A,0xDD,0xDD,0x68,0xF6, + 0xA7,0x7A,0x86,0x7A,0x6D,0x83,0x0B,0x0E,0xC6,0x82,0x65,0x72,0xDE,0xEE,0xE8,0xB8, + 0xC7,0x82,0x66,0x72,0x56,0xFF,0xAB,0x8A,0xC7,0x82,0x66,0x72,0x77,0x7F,0xAA,0x2E, + 0xA7,0x7A,0x66,0x72,0xFD,0xFF,0x78,0xC0,0xA6,0x7A,0x66,0x72,0x5E,0x65,0xEB,0xE9, + 0x66,0x72,0x44,0x51,0x7E,0x78,0xE8,0xA0,0xA6,0x61,0xE3,0x40,0x7F,0xFA,0xE8,0xA8, + 0xA5,0x59,0x23,0x49,0x55,0x77,0xFF,0xFE,0x64,0x59,0x23,0x51,0x2E,0xBA,0xDA,0xE2, + 0x44,0x51,0x03,0x51,0x60,0x00,0xE0,0xA0,0x44,0x51,0xC2,0x40,0xFF,0x76,0xFE,0x2A, + 0x03,0x49,0xC2,0x40,0x2B,0x87,0xE7,0x0C,0x85,0x61,0x03,0x49,0xE2,0xFD,0xD9,0xFD, + 0xC6,0x61,0x24,0x49,0x2E,0xA7,0xBF,0xED,0xC6,0x61,0x24,0x49,0xA0,0xAA,0xFF,0x7F, + 0xA6,0x61,0x44,0x49,0x78,0x5E,0xFF,0xFB,0x85,0x51,0xE2,0x38,0x82,0xF8,0xDA,0x7E, + 0x03,0x41,0xA1,0x30,0x80,0xEA,0x7A,0x5F,0xE2,0x38,0xA2,0x30,0x0C,0x2B,0x2F,0x29, + 0x23,0x41,0xE3,0x38,0xF7,0xAA,0xAA,0xBA,0x44,0x41,0x03,0x41,0x55,0xF5,0x8B,0xE8, + 0x44,0x41,0x03,0x41,0xBF,0x3F,0x27,0x17,0x44,0x41,0xE2,0x38,0x6A,0xF0,0xE0,0xE0, + 0xC2,0x40,0x03,0x39,0xE7,0xAF,0xAD,0xFB,0x23,0x41,0xC2,0x38,0x65,0xBF,0x8D,0x0A, + 0x84,0x59,0x03,0x41,0x9D,0xA9,0x0F,0x0B,0xC5,0x61,0x64,0x51,0xBD,0x37,0x2A,0x2A, + 0x26,0x72,0xC5,0x61,0xE5,0xFF,0xFF,0x2F,0x06,0x72,0xA4,0x61,0x78,0x78,0x78,0xAE, + 0x06,0x72,0x84,0x59,0xF7,0xDF,0xFB,0x8A,0xE5,0x61,0xA4,0x61,0xF7,0x3D,0x2D,0xD7, + 0xC5,0x61,0x23,0x49,0xF8,0x78,0x78,0x68,0x85,0x51,0x03,0x49,0x0A,0xBB,0xFF,0xF5, + 0x64,0x51,0x23,0x49,0x20,0xB0,0xFD,0xB7,0xE6,0x61,0x64,0x51,0x83,0xBA,0xFD,0xD5, + 0x85,0x51,0x02,0x41,0x7E,0x5E,0x5C,0x78,0x43,0x49,0x03,0x41,0xA9,0xA5,0xAD,0xAD, + 0xA5,0x59,0x44,0x49,0x2D,0x0B,0x09,0xAD,0xA5,0x59,0x44,0x51,0xAA,0x6E,0x7C,0x58, + 0xE6,0x69,0x23,0x49,0x0A,0xBF,0xFF,0xFD,0x68,0x7A,0x85,0x59,0x02,0x0B,0x2D,0x2D, + 0xA9,0x8A,0x47,0x7A,0x7E,0x6A,0xF3,0xAF,0x88,0x82,0xC5,0x69,0xD5,0xFF,0xEA,0x80, + 0x67,0x7A,0x05,0x72,0x8B,0x2A,0x2B,0xE7,0xA8,0x82,0x26,0x6A,0x27,0x27,0xBA,0x7A, + 0xC9,0x8A,0x47,0x72,0x0A,0xAF,0xBB,0xA5,0xA8,0x82,0x46,0x72,0x60,0xE8,0x7E,0x57, + 0x88,0x82,0x06,0x6A,0xB7,0xB7,0xAF,0x0E,0xA8,0x82,0x47,0x7A,0xB5,0xFD,0xEA,0x80, + 0x88,0x7A,0x26,0x72,0x7C,0xFA,0xB8,0x88,0x88,0x82,0x26,0x72,0x29,0xAA,0xAE,0x82, + 0xC9,0x8A,0x47,0x7A,0xE2,0xFF,0x5D,0x77,0x88,0x7A,0x47,0x7A,0x3B,0x2B,0x0D,0x5E, + 0xA8,0x82,0x27,0x72,0x0A,0xB7,0x75,0x57,0xC9,0x82,0x06,0x6A,0x00,0xAA,0xFF,0xD5, + 0xC9,0x82,0x27,0x6A,0x80,0x2A,0x9F,0xD5,0xCC,0x9B,0x68,0x72,0x0F,0xAF,0xFD,0xD5, + 0xD0,0xBC,0x46,0x72,0x02,0x2A,0x7F,0x55,0x11,0xC5,0x46,0x72,0x00,0xBE,0xDD,0x55, + 0xF4,0xE5,0xC8,0x7A,0x02,0x2B,0xAF,0xF5,0x76,0xEE,0x4E,0xAC,0x00,0x00,0x0B,0xBD, + 0x96,0xF6,0xD3,0xDD,0x00,0x00,0xAA,0xAD,0x96,0xF6,0x55,0xEE,0x80,0x20,0xEF,0xFB, + 0x96,0xF6,0x56,0xEE,0xEA,0xFE,0x9F,0x5F,0x55,0xF6,0x76,0xEE,0x55,0x55,0xDD,0xFF, + 0x76,0xF6,0x35,0xE6,0xE0,0x7E,0xDB,0xFF,0x75,0xEE,0x34,0xE6,0xE0,0xD9,0xF7,0x57, + 0x55,0xEE,0x14,0xE6,0x88,0xAA,0xFE,0xFF,0x75,0xEE,0x34,0xE6,0xAB,0xEF,0xD5,0x55, + 0x96,0xF6,0x35,0xE6,0x2A,0xEA,0xAD,0xF5,0x75,0xEE,0x34,0xEE,0xA8,0xFA,0xFF,0x7F, + 0x96,0xF6,0x34,0xE6,0x8B,0xBB,0xF7,0x55,0x96,0xF6,0x34,0xE6,0x8A,0xAA,0xBF,0xF5, + 0x96,0xF6,0x35,0xE6,0x80,0xEA,0xFE,0x5D,0x75,0xEE,0x35,0xE6,0x88,0xFE,0xFF,0x55, + 0x75,0xEE,0x35,0xE6,0xBE,0x1A,0xAF,0xB5,0x76,0xEE,0x55,0xEE,0xDB,0xF8,0x8A,0x82, + 0x56,0xF6,0x96,0xEE,0xBE,0xFE,0xFF,0xFE,0x96,0xF6,0x76,0xEE,0x59,0xFE,0xBA,0x2A, + 0x96,0xF6,0x55,0xEE,0xFF,0xFE,0xFA,0xF8,0x55,0xEE,0x15,0xE6,0xFC,0xFC,0xB8,0xC0, + 0x55,0xEE,0xD3,0xDD,0x62,0x72,0xA8,0xA8,0xF3,0xDD,0x72,0xCD,0xFE,0xFE,0xFC,0x78, + 0xD3,0xDD,0x72,0xD5,0x0B,0x2A,0x2B,0x0D,0x14,0xE6,0xD3,0xDD,0xFD,0xDF,0xAF,0xBD, + 0x14,0xE6,0xD3,0xDD,0x9F,0x3F,0x2E,0x0A,0x55,0xEE,0x14,0xE6,0x7D,0x7F,0xFB,0xAB, + 0x75,0xEE,0x34,0xE6,0x2D,0xA9,0xA5,0x2B,0x96,0xEE,0x75,0xEE,0x8A,0xE5,0xAD,0x37, + 0x96,0xEE,0x76,0xEE,0x75,0xEF,0xFE,0xF6,0x96,0xEE,0x76,0xEE,0x57,0x55,0x5A,0x6C, + 0x55,0xEE,0x92,0xD5,0x78,0xE0,0x80,0x00,0xF4,0xDD,0x72,0xCD,0x55,0xFE,0xFA,0xE8, + 0xB3,0xDD,0x31,0xCD,0xF7,0xFE,0xEA,0x80,0x72,0xD5,0x51,0xCD,0x3C,0x2E,0x2F,0x23, + 0xB3,0xD5,0xED,0xA3,0x6A,0xE8,0xA8,0x00,0xB0,0xBC,0x27,0x6A,0x57,0x5E,0xFE,0xE8, + 0x89,0x7A,0xE6,0x61,0xDD,0xEE,0xAA,0x00,0x88,0x7A,0x06,0x6A,0x3D,0xFF,0xDE,0xA0, + 0xEC,0x9B,0x26,0x6A,0x0B,0x95,0xD5,0xD5,0x0E,0xA4,0x68,0x72,0x00,0xAA,0xFF,0x55, + 0x4E,0xAC,0x89,0x72,0x22,0x0A,0x2F,0x25,0x10,0xC5,0x8E,0xB4,0x2D,0xA9,0x0D,0xA9, + 0x66,0x72,0x26,0x6A,0x7A,0xA8,0x3A,0xF2,0x66,0x72,0x04,0x6A,0xA6,0xA3,0xFE,0xFA, + 0x66,0x72,0x25,0x6A,0xAA,0xAE,0xBB,0xFB,0x67,0x72,0x26,0x72,0xAF,0xAF,0x83,0x6E, + 0x67,0x72,0x05,0x6A,0xEE,0xAB,0x8B,0x89,0x66,0x72,0x05,0x6A,0x7A,0xFB,0xAF,0x28, + 0x66,0x72,0x05,0x6A,0xBB,0xA7,0xEE,0x32,0x66,0x72,0x05,0x6A,0xFF,0xAA,0xA8,0x9E, + 0x66,0x72,0x25,0x6A,0xDF,0xA3,0x62,0x7A,0x86,0x72,0x26,0x6A,0x5F,0x5F,0xFB,0xEB, + 0x46,0x72,0x05,0x6A,0x1E,0x2F,0xAB,0xAE,0x67,0x72,0x26,0x6A,0x9F,0xF7,0xBB,0x8F, + 0x67,0x72,0x05,0x6A,0x76,0xC7,0xEE,0xF8,0x67,0x72,0x05,0x6A,0xAD,0xFF,0xBB,0xB8, + 0x87,0x7A,0xE4,0x69,0x2D,0xAF,0xEA,0xEA,0xA7,0x7A,0x05,0x6A,0x02,0xAA,0xAD,0x7F, + 0xA7,0x7A,0x05,0x6A,0x00,0x00,0xBB,0xF5,0xA7,0x7A,0x66,0x72,0x8E,0x8A,0x0B,0x25, + 0xE8,0x82,0x86,0x7A,0xFB,0x55,0x5E,0x53,0xA7,0x82,0x87,0x7A,0x55,0x2F,0x2F,0xBB, + 0xC7,0x82,0x87,0x7A,0xFF,0x5E,0xF8,0xAA,0xA7,0x82,0x67,0x7A,0x8A,0xAE,0x3C,0xB0, + 0xC7,0x82,0x87,0x7A,0x6B,0xFA,0xFB,0xFA,0xC7,0x82,0x87,0x7A,0xCF,0x7B,0xFE,0x5F, + 0xC7,0x82,0x86,0x7A,0xBF,0xFB,0xFF,0x2E,0xC7,0x82,0x86,0x7A,0x6F,0xFF,0xB8,0x78, + 0xC7,0x82,0x86,0x7A,0x4E,0xEE,0xB7,0x35,0xC7,0x82,0xA7,0x7A,0xF5,0xB5,0xBE,0xED, + 0xA7,0x82,0x87,0x7A,0xB8,0xF3,0x88,0x0A,0xA7,0x82,0x86,0x72,0x7F,0xBC,0x22,0x00, + 0xA7,0x82,0x06,0x6A,0x7A,0xA2,0xA0,0x80,0x26,0x72,0x64,0x59,0x5E,0x5C,0x78,0xE0, + 0xC5,0x69,0x64,0x59,0x55,0x75,0xDF,0xAA,0xC5,0x61,0x23,0x51,0x7F,0xDB,0xAA,0x08, + 0xC5,0x69,0x23,0x51,0x7F,0x7B,0xA8,0xA8,0xC6,0x69,0x44,0x51,0x55,0xF5,0xBF,0x0B, + 0xA5,0x61,0x03,0x49,0x5F,0xEE,0xA0,0x80,0x85,0x59,0x23,0x49,0xAD,0xA2,0x28,0xE2, + 0x85,0x51,0x44,0x51,0x8B,0xA2,0xDC,0x56,0x85,0x51,0x23,0x49,0x7A,0xD8,0xFE,0xFF, + 0x85,0x51,0x03,0x39,0xC2,0xEA,0xFA,0x7F,0x24,0x41,0xA1,0x30,0xF8,0xF8,0xD6,0xD7, + 0xC2,0x30,0xA2,0x30,0x5F,0x35,0x25,0x08,0xE2,0x38,0xA2,0x30,0x2B,0xAB,0xA2,0xB2, + 0x44,0x41,0xE3,0x38,0x2F,0x2D,0xAF,0xFA,0x64,0x49,0x03,0x39,0xFC,0xDF,0x7F,0xF5, + 0x03,0x41,0xE2,0x38,0x28,0x60,0x78,0x6F,0x23,0x41,0xE2,0x38,0x80,0x2B,0xBD,0x0D, + 0x44,0x49,0xE2,0x38,0x75,0xAF,0xAA,0x22,0x85,0x51,0x03,0x41,0xEF,0x2D,0x8A,0xEA, + 0x84,0x51,0x23,0x49,0x3D,0xBF,0xF7,0xFD,0xC5,0x61,0x44,0x51,0x0A,0x3E,0x2D,0xFD, + 0x47,0x72,0xA5,0x61,0x0A,0x0A,0xAB,0xF9,0x68,0x7A,0xE5,0x69,0x55,0xB7,0x8F,0x09, + 0x68,0x7A,0xE5,0x69,0x5F,0xFE,0xE8,0xE0,0x06,0x6A,0x64,0x51,0xFE,0xFA,0x5C,0x5E, + 0xC5,0x61,0x03,0x41,0xE8,0xE8,0xFE,0xFF,0x44,0x49,0xE2,0x40,0x0E,0xBC,0x78,0xFE, + 0xA6,0x59,0x23,0x49,0xEF,0x8B,0xBD,0xA5,0x85,0x51,0x03,0x41,0x2A,0xBE,0x6A,0xF0, + 0xA5,0x51,0x03,0x41,0x78,0xFA,0xFF,0xD5,0x44,0x49,0x03,0x41,0x2D,0x0D,0x0A,0x2B, + 0x84,0x51,0x44,0x49,0xBF,0xBD,0x3F,0xCA,0x85,0x51,0x23,0x49,0x92,0xF2,0xE2,0x8A, + 0xC6,0x61,0x23,0x49,0xED,0xBF,0x3D,0x25,0x68,0x7A,0xC6,0x61,0x05,0x25,0xA5,0x2D, + 0x4A,0x93,0x68,0x7A,0xBF,0x2D,0xAD,0xAB,0x6B,0x9B,0xC9,0x8A,0x7F,0xEE,0xE0,0xEA, + 0xE9,0x8A,0x26,0x6A,0x7F,0xFA,0xE8,0xE2,0x26,0x72,0xE5,0x69,0x02,0xAE,0x06,0x94, + 0x67,0x72,0xE6,0x69,0x2B,0xAF,0xBD,0xBF,0x88,0x7A,0x26,0x72,0x9C,0xA5,0x37,0x3B, + 0x88,0x82,0x47,0x7A,0xAF,0xDE,0x82,0x00,0xC8,0x8A,0x67,0x7A,0xBA,0x3B,0xAF,0x95, + 0x09,0x93,0xA8,0x82,0x5D,0xBF,0xAA,0x2B,0x09,0x8B,0x67,0x7A,0xF7,0xFE,0xFA,0xA8, + 0x88,0x82,0x47,0x7A,0xFF,0x5E,0xFA,0x02,0x68,0x7A,0x27,0x72,0xB8,0xFD,0x7D,0xC3, + 0x68,0x7A,0x06,0x6A,0x57,0x5E,0xDB,0x2F,0x88,0x7A,0xE6,0x61,0x5F,0x5D,0x6E,0xA2, + 0x67,0x7A,0xC6,0x61,0xB7,0xBD,0xAB,0x2A,0x88,0x7A,0x26,0x6A,0x8B,0x86,0xAF,0x68, + 0x87,0x72,0x46,0x72,0xAC,0x82,0x3A,0xD5,0x67,0x72,0x26,0x6A,0x7E,0x7C,0xB0,0xA2, + 0xA8,0x7A,0xE6,0x61,0x0A,0xAB,0xF7,0x5F,0xF0,0xC4,0x88,0x72,0x2B,0xAD,0x95,0x55, + 0x35,0xEE,0x4A,0x93,0x02,0x0A,0x2B,0xBD,0x76,0xF6,0xD3,0xDD,0x00,0x22,0xAA,0x55, + 0x55,0xEE,0xF4,0xE5,0x00,0x00,0x8A,0x95,0x55,0xEE,0x15,0xE6,0x8A,0xE2,0x6C,0x7F, + 0x55,0xEE,0x14,0xE6,0xA2,0xA2,0x23,0xAF,0x15,0xEE,0x34,0xE6,0x79,0x7F,0x7D,0xBF, + 0x35,0xE6,0x14,0xE6,0xA0,0xB0,0x68,0x4F,0x34,0xE6,0xD4,0xE5,0xA0,0x2A,0x0A,0xBA, + 0x34,0xE6,0xF4,0xE5,0x08,0x08,0x96,0xBE,0x15,0xEE,0x34,0xE6,0x75,0xFF,0x7F,0xFF, + 0x35,0xE6,0xD3,0xDD,0xA2,0xFA,0xDE,0xF8,0x35,0xE6,0xD3,0xDD,0x2A,0xFB,0xFD,0xF7, + 0x14,0xE6,0xD3,0xDD,0xE8,0xFD,0xB5,0x2B,0x35,0xE6,0xF4,0xE5,0x03,0x2B,0x0B,0x3F, + 0x76,0xEE,0x35,0xE6,0x95,0xBD,0xAB,0xAF,0x96,0xF6,0x55,0xEE,0xEB,0xFF,0xAF,0xA5, + 0x76,0xF6,0x96,0xEE,0xE8,0xFE,0xBF,0xFB,0x96,0xF6,0x55,0xEE,0x88,0xEA,0x7A,0x5E, + 0x76,0xEE,0x35,0xE6,0xC0,0xAE,0xF5,0xDF,0x55,0xEE,0x35,0xE6,0xC0,0x62,0x8A,0x2B, + 0x55,0xEE,0xF4,0xDD,0x7A,0x7A,0xEA,0xE0,0x14,0xE6,0x72,0xCD,0x7F,0x7E,0xE8,0x00, + 0xD3,0xDD,0x72,0xCD,0x9D,0xDF,0xBE,0x08,0x14,0xE6,0xB2,0xDD,0xAF,0xA5,0x3D,0x0A, + 0x34,0xE6,0x14,0xE6,0x75,0xE5,0xF7,0x55,0x55,0xEE,0xF4,0xDD,0x8B,0xBB,0xBF,0xF7, + 0x75,0xEE,0x35,0xE6,0x0E,0x2F,0xBD,0xBD,0x96,0xEE,0x75,0xEE,0xED,0xFF,0x0A,0x0A, + 0xB6,0xF6,0x76,0xEE,0x7F,0xFB,0xFE,0xFE,0x96,0xEE,0x76,0xEE,0x7C,0xFE,0xFF,0xFE, + 0x96,0xEE,0x55,0xE6,0x7B,0xFA,0xA8,0xAA,0x75,0xEE,0xB2,0xD5,0x7F,0xD8,0xE8,0xE0, + 0xB3,0xDD,0xF3,0xD5,0xAA,0xEB,0xAB,0xAB,0xB3,0xDD,0x71,0xCD,0x7F,0x7C,0x5C,0xE0, + 0xD3,0xDD,0x71,0xCD,0x0A,0x0B,0x0F,0x25,0xF4,0xDD,0x2E,0xAC,0x78,0xA0,0x00,0x00, + 0xB3,0xD5,0xC9,0x7A,0x57,0xFA,0x80,0x00,0x10,0xC5,0xA8,0x7A,0x55,0x5D,0xFA,0x80, + 0x0D,0xA4,0x87,0x72,0x55,0x55,0xFE,0x80,0x8B,0x93,0x26,0x6A,0x5F,0xFD,0xBF,0x80, + 0xAF,0xB4,0xC9,0x7A,0x35,0x25,0x29,0x0B,0xF0,0xC4,0xAF,0xBC,0x09,0x29,0x0A,0x0E, + 0x66,0x72,0x25,0x6A,0x60,0xBA,0xD2,0xA0,0x87,0x72,0x46,0x72,0x5A,0x76,0x77,0xBA, + 0x66,0x72,0x26,0x72,0xBA,0xFF,0xEF,0xEA,0x86,0x72,0x26,0x72,0x7F,0xDF,0xED,0xD5, + 0x67,0x7A,0x26,0x6A,0xCD,0x8B,0xAC,0xAD,0x87,0x7A,0x25,0x6A,0xA5,0x9D,0xBA,0xBF, + 0x87,0x7A,0x04,0x6A,0xBB,0xFE,0xDA,0xA2,0x67,0x7A,0x25,0x6A,0x5F,0xC9,0x2F,0xBF, + 0x66,0x72,0x26,0x72,0x7D,0xFE,0x96,0xDE,0x66,0x72,0x05,0x6A,0x02,0xCA,0x27,0x01, + 0x66,0x72,0x26,0x6A,0xD6,0xAD,0xBE,0x88,0x66,0x72,0x26,0x6A,0xFF,0x3D,0xBE,0xAE, + 0x87,0x72,0x26,0x72,0xD7,0xD5,0xFF,0xFB,0x46,0x72,0x25,0x6A,0xA0,0x83,0x8A,0xEA, + 0x46,0x72,0x05,0x6A,0x82,0x0F,0x2B,0x3A,0x66,0x72,0x05,0x6A,0x6E,0xEC,0xD8,0xFE, + 0x45,0x72,0x05,0x6A,0x9D,0x90,0xC2,0x38,0x87,0x7A,0x04,0x6A,0x27,0xFF,0xDF,0x7F, + 0xA7,0x7A,0x04,0x6A,0xB0,0xBD,0xB7,0xED,0xA7,0x82,0x25,0x72,0x02,0xA0,0xFB,0x7E, + 0xA7,0x82,0x46,0x72,0x00,0xA8,0xA3,0xFD,0xA7,0x82,0x67,0x7A,0xAA,0x2A,0xFA,0x85, + 0xC8,0x82,0x86,0x7A,0xE5,0xAF,0xEA,0xDB,0xA7,0x82,0x66,0x7A,0x00,0x80,0x18,0x40, + 0xC7,0x82,0x86,0x7A,0x9E,0xBF,0x8C,0xAC,0xC7,0x82,0x87,0x7A,0xF8,0x0A,0xA2,0xD8, + 0xE8,0x8A,0x86,0x7A,0xB7,0x2F,0x3B,0xAF,0xE7,0x82,0xA7,0x82,0xDA,0xD6,0x75,0xDF, + 0xC7,0x82,0x86,0x7A,0xA6,0xF6,0xDC,0xFC,0xC8,0x82,0x87,0x82,0xBE,0x27,0x2F,0xA2, + 0xE8,0x8A,0x87,0x7A,0x5F,0x5F,0xEF,0xAB,0xA7,0x82,0xE5,0x69,0xF6,0xBE,0x28,0x28, + 0xE8,0x8A,0x26,0x72,0x55,0xEA,0x80,0xA0,0x87,0x82,0xE5,0x69,0x57,0xF7,0xA8,0x08, + 0xA7,0x7A,0xA5,0x61,0xD7,0xFE,0xAA,0xA2,0x47,0x72,0xA5,0x59,0xF7,0x7B,0x58,0x58, + 0xA5,0x59,0x44,0x51,0xE8,0xF0,0x78,0x5A,0x23,0x51,0x44,0x49,0x57,0xE7,0xDE,0x5F, + 0x44,0x49,0xE3,0x38,0x80,0x80,0x80,0x70,0x64,0x49,0xC2,0x30,0xE8,0xFF,0x7F,0x7F, + 0x23,0x41,0xA2,0x30,0x8A,0xEF,0xAD,0xAD,0x03,0x39,0xA1,0x30,0x55,0x5E,0xF8,0xFC, + 0x03,0x39,0xC2,0x30,0x55,0xD5,0x1D,0x29,0x24,0x39,0xC2,0x30,0x9F,0xBF,0xAE,0xB8, + 0x24,0x41,0x03,0x39,0x73,0xFD,0x85,0x57,0x03,0x39,0xA2,0x30,0xA8,0xD8,0xFC,0xF8, + 0x03,0x39,0xC2,0x38,0xCB,0xC5,0xB5,0xA7,0x65,0x49,0xE3,0x38,0xB5,0x3F,0x2D,0x25, + 0x85,0x51,0x44,0x49,0x5D,0x7F,0xDA,0xCF,0x64,0x51,0x23,0x41,0x62,0x63,0xEA,0xFF, + 0x64,0x51,0x24,0x49,0xA5,0xAF,0x3F,0x2D,0xA5,0x61,0x44,0x49,0xA5,0x35,0xAF,0xFE, + 0x06,0x6A,0x64,0x59,0x0B,0x0B,0xBF,0xD5,0x68,0x7A,0xC6,0x61,0x0B,0xAA,0xA9,0xAD, + 0x68,0x7A,0xC6,0x61,0x80,0xC0,0xEA,0xDF,0xE6,0x61,0x44,0x49,0x78,0x7C,0xFC,0x6E, + 0x44,0x49,0xC2,0x38,0xFF,0x5E,0x54,0xDC,0x03,0x41,0xE3,0x40,0x38,0x3D,0x1F,0xDA, + 0x85,0x51,0x03,0x41,0x2F,0x09,0x2B,0x2D,0xC6,0x59,0x03,0x41,0x7A,0xEA,0x28,0x22, + 0xC6,0x59,0x03,0x41,0x55,0x57,0x5A,0xA0,0x64,0x51,0x03,0x41,0x2B,0x2F,0x2D,0x8E, + 0xA5,0x59,0x23,0x49,0x28,0xE0,0xF6,0xD7,0x85,0x59,0x03,0x41,0xAA,0xE2,0xEF,0x7F, + 0xA6,0x59,0xE2,0x40,0x2F,0xBF,0xB7,0xF5,0x88,0x7A,0x85,0x59,0x2F,0x2B,0x0B,0xAD, + 0x29,0x8B,0xA8,0x82,0xAA,0x62,0xAF,0xF5,0x2A,0x93,0x86,0x7A,0x82,0xAA,0xEB,0x75, + 0xA8,0x82,0x05,0x6A,0xE8,0x78,0x58,0x78,0x26,0x6A,0x63,0x51,0x28,0xBA,0xBF,0xF7, + 0x47,0x72,0xA5,0x59,0x2A,0x23,0xAB,0xAD,0x47,0x72,0x06,0x6A,0x22,0xEE,0x8F,0x85, + 0x88,0x7A,0x26,0x72,0xE8,0xEF,0xF9,0x55,0xE9,0x8A,0x26,0x72,0xBF,0x3F,0x29,0xAD, + 0xE9,0x8A,0x88,0x82,0x22,0x20,0xA8,0x6E,0x2A,0x93,0xA8,0x82,0xAB,0x0B,0xBB,0xF5, + 0x0A,0x93,0xA8,0x82,0x7E,0x60,0x5E,0xFF,0xA8,0x82,0x68,0x7A,0x64,0xEE,0xF0,0x68, + 0x68,0x7A,0x26,0x72,0xAB,0xE8,0x50,0xF0,0x67,0x7A,0x06,0x6A,0x80,0x6E,0xF7,0xDF, + 0x88,0x7A,0x26,0x6A,0x2B,0x2B,0xBF,0xD5,0xA8,0x82,0x46,0x72,0x6A,0xE2,0xFF,0xF7, + 0x87,0x7A,0x26,0x6A,0x75,0xFF,0xF8,0xA2,0x67,0x6A,0x05,0x6A,0x0F,0xBB,0x97,0xB7, + 0x67,0x72,0xE6,0x61,0x72,0xA0,0x80,0xA2,0x87,0x72,0xE6,0x61,0x2E,0xBB,0xF7,0xFE, + 0xCC,0x9B,0x27,0x6A,0x2F,0xF7,0xF5,0x55,0xAF,0xBC,0x67,0x72,0x02,0xBF,0xF5,0x55, + 0x92,0xD5,0x2A,0x8B,0x02,0x2B,0xFD,0x55,0x14,0xE6,0xEC,0xA3,0x00,0x0A,0xAB,0xB5, + 0x35,0xEE,0x93,0xD5,0x02,0x08,0x2A,0xAD,0x34,0xEE,0x14,0xE6,0xF7,0x5E,0x78,0xEC, + 0x34,0xE6,0xD4,0xE5,0xA2,0xA2,0xAA,0xE0,0x14,0xE6,0xF4,0xE5,0x80,0xA2,0xFD,0xD5, + 0x14,0xE6,0xF4,0xE5,0x08,0x22,0xB6,0xA5,0x35,0xEE,0xD3,0xDD,0x22,0x0E,0xEE,0x9F, + 0x35,0xE6,0xF4,0xE5,0xAA,0xF8,0xDE,0xFF,0x34,0xE6,0xF4,0xDD,0x75,0xFA,0xFE,0xFE, + 0x14,0xE6,0xF4,0xDD,0x3F,0x37,0x35,0xD5,0x34,0xE6,0xF4,0xE5,0x3F,0xAF,0xFF,0xFF, + 0x55,0xEE,0x14,0xE6,0x8A,0xAB,0xAD,0xB9,0x96,0xF6,0x55,0xEE,0xAD,0xAF,0xD5,0xD5, + 0x97,0xF6,0x35,0xE6,0xA2,0xA8,0x6E,0x5F,0x76,0xEE,0x14,0xE6,0xE8,0xFA,0xF6,0xD5, + 0x55,0xEE,0x14,0xE6,0xA7,0x3F,0xBF,0xBF,0x55,0xEE,0x35,0xE6,0x2E,0x1C,0xDF,0xFF, + 0x55,0xEE,0x14,0xE6,0xFA,0xAC,0xFE,0x57,0x55,0xEE,0x14,0xE6,0xFF,0xE2,0xEF,0x55, + 0x55,0xEE,0xF4,0xDD,0x7F,0xAA,0x82,0xE8,0x35,0xE6,0xD3,0xDD,0xAD,0xAE,0xE8,0xB8, + 0x14,0xE6,0xF4,0xDD,0xE6,0xFA,0xA2,0x02,0x14,0xE6,0xD4,0xDD,0x0E,0x2B,0xA2,0xB6, + 0x55,0xE6,0x14,0xE6,0x29,0x2F,0x3D,0xAD,0x96,0xEE,0x55,0xE6,0x02,0x02,0x03,0x0D, + 0x96,0xEE,0x76,0xEE,0xCA,0xEA,0xA8,0xB8,0x76,0xF6,0x96,0xEE,0x9D,0xD7,0x95,0xF7, + 0x96,0xEE,0x76,0xEE,0x76,0x5F,0xFD,0x3B,0x96,0xEE,0x35,0xE6,0x7A,0x8A,0x80,0x08, + 0x96,0xEE,0xD3,0xDD,0x55,0x7E,0xFA,0xA8,0x35,0xE6,0x92,0xD5,0x5F,0x5F,0xFE,0xF0, + 0xD3,0xD5,0x72,0xD5,0x0D,0xAB,0xED,0x7F,0x14,0xE6,0xB3,0xD5,0xAA,0xAB,0x8D,0xB9, + 0x14,0xE6,0xB3,0xD5,0x7E,0x6A,0xAA,0xAB,0xF4,0xDD,0x51,0xD5,0x7E,0xAB,0xEA,0x80, + 0x92,0xD5,0x6F,0xB4,0x5E,0xA0,0x00,0x00,0xB2,0xD5,0x0D,0xA4,0x57,0xFF,0xEA,0xA8, + 0xAF,0xBC,0x0D,0xA4,0x2D,0x0A,0x2A,0x58,0xF0,0xC4,0x0D,0xA4,0x08,0x02,0x0A,0xBD, + 0x87,0x7A,0x25,0x6A,0xDF,0x1D,0xFB,0xFA,0x86,0x7A,0x25,0x6A,0x32,0xB9,0xEB,0xE7, + 0x66,0x72,0x05,0x72,0xA8,0xAE,0xAB,0xA9,0x66,0x72,0x06,0x72,0xAA,0x2A,0x02,0xE0, + 0x87,0x7A,0x46,0x72,0x55,0x15,0x97,0xEF,0x87,0x7A,0x25,0x6A,0xBD,0xBB,0x2B,0x7A, + 0x66,0x72,0x05,0x72,0x00,0x8C,0xA8,0x2A,0xA7,0x82,0x25,0x6A,0xEF,0xFB,0xFF,0x6A, + 0x86,0x72,0x26,0x72,0xFE,0xEE,0xFE,0x92,0x66,0x72,0x26,0x72,0x82,0xEB,0xAE,0xA2, + 0x66,0x72,0x26,0x72,0xA8,0xE2,0xE0,0x12,0x67,0x72,0x26,0x72,0xEE,0xBF,0x81,0x2B, + 0x66,0x72,0x25,0x72,0x76,0xBF,0x3F,0x5D,0x87,0x7A,0x25,0x6A,0x5F,0xDF,0xD2,0x38, + 0x66,0x72,0x05,0x6A,0xBE,0xEE,0xFE,0xB0,0x66,0x72,0xE5,0x69,0xA6,0x28,0xAA,0x82, + 0x66,0x72,0x05,0x72,0x2A,0x02,0x8E,0xAA,0x66,0x72,0x25,0x72,0xFE,0xD0,0xA8,0x9B, + 0x66,0x72,0x05,0x6A,0xEF,0xE8,0xFA,0xEE,0x46,0x72,0x05,0x6A,0xE0,0xA8,0x37,0x0A, + 0x66,0x72,0x25,0x6A,0xFA,0x5F,0x75,0x9F,0x87,0x7A,0x25,0x6A,0x8B,0xBD,0xF7,0x56, + 0xC7,0x82,0x05,0x6A,0x0A,0x2A,0xBB,0xF5,0xC7,0x82,0x45,0x72,0x02,0xA0,0xBB,0xFD, + 0xC8,0x82,0x66,0x7A,0xAA,0xAA,0x2B,0x2D,0xC8,0x82,0x86,0x7A,0x7E,0xF7,0xEC,0xB8, + 0xC7,0x82,0x87,0x7A,0x8B,0xAA,0x8B,0xBE,0xC8,0x82,0xA7,0x82,0x0F,0xCA,0xE8,0x33, + 0xE7,0x8A,0xA7,0x82,0xF5,0xF5,0xED,0x6A,0xE8,0x8A,0xA7,0x82,0xAB,0xEA,0xFB,0xFB, + 0xE8,0x8A,0xA7,0x82,0xBF,0xAD,0xEB,0x2B,0xE8,0x8A,0x66,0x7A,0x9F,0x7E,0xF8,0xE8, + 0xE8,0x8A,0x87,0x7A,0xA3,0x8B,0xED,0xCB,0xC8,0x8A,0x46,0x72,0xD6,0xFC,0xF8,0xA8, + 0xA7,0x7A,0x26,0x72,0xF2,0x78,0x7E,0x5E,0x26,0x72,0x44,0x51,0xF8,0x7A,0x7C,0x7A, + 0x64,0x51,0xE3,0x38,0x80,0x2A,0xEA,0x7A,0x64,0x51,0xE3,0x38,0x82,0xA8,0x5E,0x57, + 0x44,0x49,0xA1,0x28,0xF8,0xF8,0xDF,0x57,0xE3,0x38,0x81,0x28,0x8B,0x8F,0x9F,0xF5, + 0xE3,0x38,0xC2,0x30,0x39,0x3D,0x9D,0x59,0xE3,0x38,0xC2,0x28,0xA8,0xAA,0xDC,0xA7, + 0x23,0x39,0xC3,0x30,0x2D,0xAB,0xBE,0xBF,0x24,0x39,0xC2,0x30,0xFC,0xF6,0x7E,0x7E, + 0x03,0x39,0xC2,0x30,0xA2,0xDE,0x5D,0xF5,0xE2,0x38,0xC2,0x30,0x20,0x0A,0x2A,0x9D, + 0x03,0x39,0xE2,0x38,0x49,0x59,0xFD,0x97,0x64,0x49,0xE2,0x38,0x2D,0x3D,0xBD,0x2F, + 0x85,0x51,0x03,0x41,0x82,0xA0,0xA2,0x5E,0x64,0x49,0x23,0x49,0xF6,0x96,0xEB,0xAB, + 0x64,0x51,0x44,0x51,0xDD,0x9E,0x82,0x22,0xA5,0x59,0x44,0x51,0xFD,0xE9,0x0B,0x02, + 0xA5,0x59,0x65,0x59,0x95,0xDD,0x36,0x1A,0x27,0x72,0xA5,0x61,0x0D,0x0D,0x09,0x2F, + 0x07,0x6A,0x65,0x51,0x68,0x60,0xFC,0xF8,0x64,0x51,0x24,0x49,0x7B,0xFD,0xCF,0xF8, + 0x44,0x49,0xE3,0x40,0x57,0x7E,0xEA,0xF8,0x24,0x41,0xA2,0x30,0xA2,0xE2,0xFA,0xFE, + 0x85,0x51,0xC2,0x38,0xAF,0xB5,0xB5,0x2D,0xE6,0x59,0x84,0x51,0xA7,0xBD,0xFD,0x2A, + 0xE6,0x61,0x85,0x51,0xE2,0xF2,0x7B,0x5E,0x85,0x51,0x24,0x49,0xAE,0xC8,0xFE,0xDF, + 0x65,0x51,0x03,0x41,0x58,0x7A,0x6F,0x5F,0x23,0x49,0xE3,0x38,0xA0,0xFA,0xBB,0xBD, + 0xE3,0x40,0x02,0x39,0x0A,0x00,0x80,0xE2,0x46,0x72,0x23,0x49,0x29,0xF5,0xF5,0xD5, + 0x86,0x7A,0xC5,0x59,0x0A,0xAB,0xFD,0x55,0x66,0x72,0x64,0x51,0x80,0xE8,0xFF,0x5F, + 0x25,0x6A,0x64,0x51,0xA0,0xAB,0xF5,0xD5,0xC5,0x61,0x64,0x51,0x5C,0xFA,0xFD,0xFE, + 0xC6,0x61,0x64,0x51,0x0B,0xAD,0xFF,0xF7,0x06,0x6A,0x85,0x59,0x2A,0xB7,0xF5,0x55, + 0x26,0x72,0x84,0x59,0x28,0x2F,0xBD,0x95,0x88,0x7A,0xE5,0x69,0x0A,0x2A,0xAB,0xBD, + 0xA8,0x82,0x67,0x7A,0xA2,0xCB,0x61,0x6E,0xE9,0x8A,0x46,0x72,0x0A,0x09,0xA7,0x55, + 0xE9,0x8A,0x67,0x7A,0xA0,0x88,0xEB,0xFD,0xC9,0x8A,0x67,0x7A,0x9E,0xDF,0xAB,0xA2, + 0xE9,0x92,0x47,0x72,0x5F,0x6F,0xA2,0xA0,0xA8,0x7A,0x06,0x72,0xF7,0xF7,0xFE,0xF8, + 0x47,0x72,0xE5,0x69,0x3A,0xAE,0xFE,0xF5,0x67,0x7A,0xC5,0x61,0x00,0xBA,0x5F,0x5F, + 0x67,0x72,0xC5,0x61,0x00,0x0B,0xA5,0x55,0x87,0x72,0x06,0x6A,0xFE,0x82,0xCA,0xFD, + 0x67,0x72,0xE5,0x61,0xEA,0xE8,0xF2,0xD7,0x46,0x6A,0xC5,0x59,0xBA,0xB8,0x7C,0x5F, + 0x27,0x6A,0x84,0x59,0x00,0x0A,0xAA,0xDF,0x68,0x72,0xC5,0x61,0x0A,0x2E,0xFB,0x7D, + 0xC8,0x82,0x26,0x6A,0x00,0x2A,0xAF,0xA5,0xAF,0xBC,0xC8,0x7A,0x2D,0x2D,0xF5,0xF5, + 0xF4,0xE5,0xEC,0xA3,0x02,0x0A,0x0B,0xBD,0x35,0xEE,0xD3,0xE5,0x02,0x02,0x82,0x29, + 0x34,0xEE,0xF4,0xE5,0xE2,0xEA,0xFA,0xF2,0x14,0xE6,0xD3,0xDD,0xBE,0xFB,0xF8,0xFA, + 0xF4,0xE5,0xD3,0xDD,0x28,0x8A,0x2F,0x0B,0xF4,0xDD,0xB3,0xDD,0xE8,0x78,0x7E,0xB0, + 0x14,0xE6,0xB3,0xDD,0x2A,0x2B,0xAD,0xFE,0x14,0xE6,0xD3,0xDD,0xE8,0x7A,0xFA,0xFF, + 0xF4,0xE5,0xD3,0xDD,0xFE,0xFB,0x5B,0xDF,0x14,0xE6,0xD3,0xDD,0xCF,0xAD,0xD5,0xB5, + 0x34,0xE6,0xF3,0xE5,0x0B,0x2B,0x2F,0x2A,0x55,0xEE,0x35,0xE6,0x02,0x82,0x77,0x57, + 0x56,0xEE,0x14,0xE6,0xAC,0xDE,0xFE,0x55,0x35,0xE6,0x14,0xE6,0xFC,0x38,0x2F,0xBD, + 0x55,0xEE,0x14,0xE6,0xBE,0xAA,0x3E,0xFF,0x55,0xEE,0x35,0xE6,0xEE,0xBB,0x7E,0xF7, + 0x35,0xE6,0xD3,0xDD,0xF8,0x78,0x7A,0xA8,0x14,0xE6,0xD3,0xDD,0x2B,0x37,0xBF,0xAF, + 0xF4,0xE5,0x35,0xDE,0xAB,0x22,0xA0,0xFA,0x34,0xE6,0xF4,0xE5,0xFF,0xA9,0x2B,0x2B, + 0x35,0xE6,0xF4,0xDD,0xAF,0xEE,0x6E,0xFA,0x34,0xE6,0xF4,0xDD,0xF7,0xBF,0x2D,0xAF, + 0x76,0xEE,0x15,0xE6,0x3D,0xAF,0xBF,0xFD,0xB6,0xF6,0x56,0xE6,0xB9,0xAF,0xBB,0x0F, + 0xB6,0xF6,0x76,0xEE,0xF7,0xB5,0xBF,0xF8,0x76,0xF6,0x96,0xEE,0xDD,0xFD,0xFF,0xF5, + 0x76,0xF6,0x96,0xEE,0x5D,0xF7,0xFF,0x56,0x96,0xEE,0x76,0xEE,0x6A,0xFD,0xFA,0x70, + 0x96,0xEE,0x35,0xE6,0xEA,0xA8,0x22,0x88,0xB6,0xEE,0x14,0xE6,0x7F,0xFA,0xAA,0xAA, + 0x55,0xEE,0xB3,0xD5,0x57,0x5A,0xA0,0x00,0x35,0xE6,0x92,0xD5,0xBD,0xF5,0xFF,0xFC, + 0x14,0xE6,0xB3,0xD5,0x2E,0xAA,0x2F,0xAD,0x14,0xE6,0xD3,0xDD,0xFB,0xCA,0x6A,0xFA, + 0xF3,0xDD,0xB3,0xD5,0x7F,0xC2,0x08,0x20,0xF4,0xDD,0x51,0xCD,0x5E,0xE8,0x80,0x00, + 0xD3,0xDD,0x8F,0xB4,0x5E,0xEA,0x20,0x00,0x72,0xCD,0x6A,0x93,0xD7,0x5E,0xF8,0xC0, + 0x87,0x7A,0x46,0x72,0x7E,0x7A,0x5E,0x75,0x66,0x72,0x25,0x6A,0xE6,0x2A,0x0A,0x32, + 0x86,0x7A,0x46,0x72,0xF5,0xDB,0xBB,0x7A,0x66,0x72,0x25,0x72,0x3A,0xAA,0x20,0x2F, + 0x66,0x72,0x25,0x6A,0xE0,0x18,0xD2,0x3A,0x87,0x7A,0x26,0x6A,0x7E,0xEA,0xAF,0xEC, + 0x87,0x7A,0x46,0x72,0xD1,0x7B,0xEA,0x69,0x66,0x72,0x26,0x72,0x6A,0xAA,0x82,0x23, + 0x66,0x72,0x25,0x72,0xAE,0x3E,0x3F,0xEA,0x86,0x72,0x25,0x6A,0xEA,0xEF,0xF4,0xB7, + 0x87,0x7A,0x46,0x72,0xDD,0xFB,0xBF,0x8D,0x66,0x72,0x25,0x72,0xE0,0xCE,0x2C,0xAC, + 0x66,0x7A,0x25,0x6A,0x69,0xE9,0xB2,0x82,0x87,0x7A,0x46,0x72,0x9F,0xE5,0x45,0xFD, + 0x87,0x7A,0x25,0x6A,0xDA,0x8B,0xCD,0xAB,0x87,0x7A,0x25,0x6A,0xEF,0xFA,0x9A,0xD8, + 0x67,0x72,0x26,0x72,0xA3,0x36,0xDE,0x98,0x66,0x72,0x05,0x6A,0xAA,0xC0,0xE8,0xF8, + 0x66,0x72,0x25,0x72,0x4A,0xCB,0xCA,0xCB,0x46,0x72,0x25,0x6A,0x87,0x2B,0x01,0x03, + 0x87,0x7A,0x25,0x6A,0x57,0x77,0x6B,0xF2,0x66,0x72,0x05,0x6A,0x7B,0xE2,0xA0,0x0A, + 0x67,0x7A,0x05,0x6A,0x2D,0x2B,0xAA,0x2A,0x67,0x7A,0x26,0x72,0x7E,0xFE,0xBE,0xC8, + 0x87,0x7A,0x25,0x72,0x07,0xBF,0xFF,0xFF,0xA8,0x82,0x25,0x72,0x0A,0x2D,0xF7,0x9F, + 0xC8,0x82,0x26,0x72,0x2A,0x0A,0xEB,0x67,0xC7,0x82,0x66,0x7A,0xAC,0xB8,0xAB,0xAD, + 0xC8,0x82,0xA7,0x82,0xC0,0xD7,0xD5,0x5F,0xE8,0x8A,0xA7,0x82,0x7B,0xEA,0xB2,0xF5, + 0x09,0x93,0xA7,0x82,0x8F,0x8B,0xFB,0xDB,0x09,0x93,0xC8,0x8A,0x5F,0xAD,0x3F,0x2F, + 0x29,0x93,0xC8,0x8A,0x7D,0x7E,0x6E,0x72,0xC9,0x8A,0x06,0x6A,0xA8,0xA8,0xE0,0x78, + 0x67,0x7A,0xA4,0x59,0xE8,0xFA,0xFA,0x5F,0xE5,0x61,0x23,0x49,0x68,0x78,0x7E,0x5F, + 0x24,0x49,0xC2,0x30,0xE8,0xF8,0x7C,0x5D,0x03,0x39,0xA2,0x30,0xBF,0xFF,0xFF,0x55, + 0xC2,0x30,0x82,0x28,0xC0,0x68,0x7E,0xF7,0xC2,0x30,0x81,0x28,0x25,0x25,0x2D,0x2D, + 0xE2,0x30,0xA2,0x28,0xFE,0xF6,0xF7,0xF7,0x03,0x31,0xA2,0x28,0xBE,0x1F,0xBF,0xB7, + 0x03,0x39,0xA2,0x28,0xAA,0xA8,0xAA,0x5B,0xE3,0x30,0x82,0x28,0x20,0x2A,0xB6,0xAE, + 0xE3,0x30,0xA2,0x30,0x80,0xDE,0xFE,0xDF,0xE2,0x30,0xA2,0x30,0x1D,0xFF,0xFF,0xF5, + 0x23,0x41,0xC2,0x30,0xB5,0x95,0x35,0xB5,0xA6,0x51,0x24,0x41,0xBD,0x8B,0x81,0xEB, + 0x64,0x49,0xE3,0x40,0x58,0x7A,0x5E,0x57,0x44,0x49,0xE3,0x40,0x03,0x29,0x29,0x2D, + 0x85,0x59,0x44,0x51,0xEB,0xAA,0xF5,0x83,0xA5,0x59,0x64,0x51,0x0A,0xA6,0x77,0x55, + 0xC5,0x61,0x44,0x49,0xBC,0x28,0x3A,0xAD,0x27,0x72,0xC5,0x61,0x8D,0xE9,0xA9,0xFD, + 0xE6,0x61,0x65,0x51,0xFF,0x7E,0x78,0x5A,0x65,0x51,0xE2,0x38,0xA8,0xE8,0xBC,0x5F, + 0x64,0x49,0xE3,0x38,0x78,0x6A,0xFA,0xEB,0x24,0x41,0xC3,0x38,0x5F,0xFD,0xA7,0x2F, + 0xA6,0x59,0x03,0x41,0x25,0xAD,0xAB,0x8F,0xE7,0x61,0x44,0x49,0x02,0x0A,0xFF,0x55, + 0xE7,0x61,0x64,0x49,0xEA,0x20,0xA3,0xF5,0x85,0x51,0x24,0x41,0x7E,0xE8,0x78,0x5C, + 0x44,0x49,0xE3,0x38,0x7E,0xDC,0xDC,0xFE,0x44,0x49,0xC2,0x30,0xF7,0xFE,0xAA,0x82, + 0x65,0x49,0xE3,0x38,0xFD,0xFD,0xCB,0x82,0x44,0x49,0x03,0x41,0x2F,0x3F,0xBD,0xEF, + 0xC6,0x59,0x24,0x49,0x8A,0xA3,0xAB,0xAD,0xA5,0x59,0x43,0x49,0xE2,0x7A,0x5C,0x58, + 0x85,0x51,0x23,0x49,0xED,0xFF,0xB7,0xD7,0x85,0x51,0x23,0x49,0x00,0xE0,0xDA,0x5F, + 0x84,0x51,0x43,0x49,0xA8,0xE8,0xEB,0xD7,0xC5,0x61,0x44,0x51,0xAF,0x2F,0x2F,0xAD, + 0x26,0x6A,0x84,0x59,0x9F,0xAA,0xAA,0x7D,0x88,0x7A,0xA5,0x59,0x0B,0x2A,0x0F,0xAD, + 0xA8,0x82,0x06,0x72,0xA0,0xA2,0xAA,0x5E,0x68,0x7A,0xE6,0x69,0x8A,0xAA,0xDE,0xDF, + 0xC9,0x8A,0x46,0x7A,0xB7,0x2D,0x25,0x8D,0xC9,0x8A,0x87,0x82,0x20,0xE0,0xE0,0xFC, + 0xE9,0x8A,0x67,0x82,0x02,0x02,0xAB,0xDA,0xEA,0x8A,0x47,0x7A,0x5C,0x7C,0xE2,0xAA, + 0x88,0x82,0x26,0x72,0x55,0xBF,0xF8,0xA8,0x67,0x7A,0xC5,0x61,0x5F,0xB2,0xC0,0xE0, + 0x07,0x6A,0xA5,0x59,0x7F,0x7E,0xD8,0x6C,0x06,0x6A,0x64,0x51,0x02,0xFE,0x7F,0x57, + 0xE5,0x61,0x64,0x51,0x00,0xAB,0xBD,0xD5,0xC5,0x61,0x64,0x51,0x80,0xA8,0xFA,0xB7, + 0xC6,0x59,0x84,0x59,0xDC,0xAA,0xBF,0x2B,0x06,0x6A,0xA5,0x59,0xEB,0x2F,0xAF,0xFD, + 0x67,0x72,0xE5,0x61,0x3F,0xBF,0xAB,0xDF,0xC9,0x82,0x26,0x6A,0x0A,0xAB,0xB7,0xD7, + 0x6E,0xB4,0x47,0x72,0x2B,0xBF,0xBD,0xFD,0xD3,0xE5,0x8B,0x9B,0x02,0x0B,0xBF,0xD5, + 0x14,0xE6,0x6F,0xBC,0x00,0x02,0xAB,0xBD,0x14,0xE6,0xB3,0xE5,0xA2,0xA2,0xAA,0xAD, + 0x14,0xE6,0xF4,0xE5,0xE5,0xBF,0xFE,0x7A,0x14,0xE6,0xD3,0xDD,0xBF,0xAC,0xA0,0xA3, + 0x14,0xE6,0xD4,0xDD,0x5E,0xF8,0xE8,0xAA,0xF3,0xE5,0xB3,0xDD,0x8A,0xFF,0xFA,0x7C, + 0x14,0xE6,0xB3,0xDD,0xFB,0xDF,0x57,0x7F,0xF4,0xE5,0xB3,0xDD,0x2E,0x2F,0xAB,0xBD, + 0x35,0xE6,0xF4,0xDD,0x2F,0xAB,0x2D,0xBD,0x35,0xE6,0xF3,0xE5,0x80,0xA8,0xEA,0xFA, + 0x14,0xE6,0xD3,0xDD,0xA2,0x98,0xFE,0x7E,0x35,0xE6,0xD3,0xDD,0x2A,0xAA,0xBB,0xBD, + 0x56,0xE6,0x14,0xE6,0xB7,0x5F,0xF5,0x95,0x55,0xEE,0x15,0xE6,0xEA,0xA8,0xE0,0xF0, + 0x34,0xE6,0xF4,0xDD,0xE8,0xAE,0xFF,0x57,0x35,0xE6,0xD3,0xDD,0xFB,0xE8,0xEA,0x7E, + 0xD4,0xE5,0x14,0xDE,0xBE,0xFA,0xFE,0xFA,0x14,0xE6,0xF4,0xDD,0x23,0x28,0xEE,0xAF, + 0x55,0xE6,0xF4,0xE5,0xFF,0xF5,0xFF,0xB7,0x34,0xE6,0xF4,0xDD,0xD6,0xBA,0xEA,0xBE, + 0x55,0xEE,0x14,0xE6,0x35,0xE5,0xF5,0x55,0xB6,0xF6,0x35,0xE6,0x2B,0xAB,0xA9,0xA9, + 0xB6,0xF6,0x76,0xEE,0xEA,0xFA,0xFE,0xAA,0xB6,0xF6,0x76,0xEE,0xF7,0xEF,0xBA,0xEA, + 0x76,0xF6,0x96,0xEE,0x6F,0x5F,0xFD,0xD7,0x76,0xF6,0x96,0xEE,0xFD,0xF5,0xFF,0x67, + 0x96,0xEE,0x76,0xEE,0xFF,0xBF,0xB6,0x57,0x96,0xEE,0x35,0xE6,0xAA,0xA0,0xFA,0x5E, + 0x75,0xEE,0xF4,0xDD,0x20,0xA0,0xEA,0x7B,0x55,0xEE,0xB2,0xD5,0xF8,0xE8,0xF6,0x57, + 0xF3,0xDD,0x92,0xD5,0x2A,0xAA,0xEA,0x5F,0x15,0xE6,0xB3,0xD5,0xB2,0xBE,0xBD,0x75, + 0xF4,0xDD,0xB3,0xD5,0xAA,0xBC,0xAE,0xFF,0xF4,0xE5,0xB3,0xD5,0x28,0xAB,0xB6,0xFF, + 0xF3,0xDD,0x91,0xD5,0xA8,0xAA,0xAA,0xF6,0xD2,0xDD,0xF0,0xC4,0x68,0xE0,0xA0,0xA0, + 0x87,0x7A,0x25,0x6A,0xC9,0xAB,0xEA,0xBF,0x86,0x72,0x25,0x72,0xDA,0xBB,0xAA,0x2B, + 0x86,0x7A,0x26,0x6A,0xAA,0xBB,0x68,0xFB,0x66,0x72,0x46,0x72,0x1F,0x0B,0x3F,0xA1, + 0x87,0x7A,0x66,0x72,0x97,0xE7,0x6A,0x69,0x87,0x7A,0x46,0x72,0xF4,0xDE,0xEF,0xAE, + 0x86,0x72,0x26,0x72,0xAF,0xBF,0x1F,0xAF,0x87,0x7A,0x26,0x72,0xFB,0xC1,0xEB,0xAA, + 0x66,0x72,0x46,0x72,0x6B,0x7B,0xFD,0xFE,0x66,0x72,0x25,0x6A,0x07,0x35,0x27,0x82, + 0x86,0x7A,0x26,0x6A,0x9F,0xFB,0xEA,0xE8,0x86,0x7A,0x46,0x72,0xED,0xF7,0xDD,0xFE, + 0x66,0x72,0x25,0x72,0x8A,0x0B,0x3E,0x2E,0x66,0x72,0x25,0x6A,0xBA,0x7A,0x82,0x02, + 0x66,0x72,0x25,0x6A,0xF1,0x7B,0xAD,0x8C,0x87,0x7A,0x46,0x72,0x5E,0xED,0xAB,0xE3, + 0x87,0x7A,0x25,0x6A,0xA6,0xEF,0xAA,0xE8,0x66,0x7A,0x46,0x72,0x56,0xDF,0xE9,0x0B, + 0x87,0x7A,0x25,0x6A,0x6A,0xEA,0xAA,0x62,0x87,0x7A,0x26,0x72,0xFF,0xA2,0xB2,0x7B, + 0x66,0x72,0x26,0x72,0xBA,0xAB,0x0A,0x00,0x66,0x72,0x25,0x72,0x0B,0x0E,0xAA,0x18, + 0x66,0x72,0x26,0x72,0xA0,0xA4,0x6B,0xC2,0x86,0x7A,0x25,0x72,0xBE,0xFF,0x63,0x6A, + 0x66,0x7A,0x26,0x72,0xA8,0x62,0x01,0xB9,0x66,0x82,0x46,0x72,0xDD,0x7F,0xD7,0x59, + 0x66,0x7A,0x05,0x72,0xB6,0xB6,0xAA,0x8A,0x66,0x7A,0x25,0x72,0x0A,0x9F,0x38,0x02, + 0xA7,0x82,0x46,0x72,0xA8,0xBB,0xFF,0x97,0xC8,0x82,0x66,0x7A,0x02,0x2B,0xBF,0xD5, + 0xC8,0x82,0x66,0x7A,0x88,0xA8,0xBF,0xD5,0x09,0x8B,0xA7,0x82,0x2E,0xEA,0x02,0xC9, + 0x29,0x93,0xC8,0x8A,0xA2,0xE8,0x6A,0x62,0xA7,0x82,0xC5,0x61,0x78,0x7A,0x7C,0x5E, + 0xA5,0x59,0x03,0x41,0xE0,0xF0,0x5C,0x54,0x23,0x41,0xC2,0x38,0xA0,0xF0,0x7B,0x77, + 0xE2,0x38,0xA2,0x30,0xFC,0xDC,0xBE,0x7E,0xC2,0x30,0x81,0x28,0x58,0x7E,0xDE,0xBB, + 0xC2,0x30,0x61,0x20,0xFF,0x7E,0xAE,0xAC,0xA2,0x28,0x61,0x20,0x0B,0x0B,0x23,0xAA, + 0xC2,0x28,0xA2,0x28,0x9E,0x7D,0x63,0xB5,0xC2,0x30,0xA2,0x28,0xBA,0xF5,0x95,0xD6, + 0xC2,0x30,0xA2,0x28,0xBA,0xA6,0x06,0x0D,0xE3,0x30,0xA2,0x28,0xEB,0x8B,0x6F,0x7F, + 0xC2,0x30,0xA2,0x28,0xD8,0xEA,0xEB,0x75,0x03,0x39,0xA2,0x30,0xB5,0xBD,0xBD,0x2B, + 0x44,0x49,0xC2,0x30,0xBD,0xBD,0xBB,0x0A,0x85,0x51,0xE3,0x38,0xE2,0x7A,0x7F,0x7B, + 0x03,0x41,0xC2,0x38,0xBE,0xFF,0xDF,0x7F,0x44,0x49,0xE3,0x40,0x25,0x3F,0x2D,0xFD, + 0x85,0x59,0x23,0x41,0x82,0xBE,0xF5,0xD5,0x64,0x51,0x44,0x49,0x7B,0x7E,0xAB,0x20, + 0x64,0x51,0x23,0x49,0x0D,0x07,0x2F,0x0A,0xC6,0x61,0x44,0x49,0x0A,0xAB,0xDF,0x77, + 0xC6,0x59,0x24,0x49,0xF8,0x7E,0x6B,0x7D,0x24,0x49,0xE3,0x38,0x5E,0xF4,0x54,0x57, + 0x44,0x41,0xC2,0x38,0x8A,0xEA,0xFF,0x7D,0x24,0x41,0xE2,0x38,0x0F,0x26,0xAD,0xFD, + 0x85,0x49,0x23,0x41,0xCD,0xAD,0x35,0xF5,0x65,0x49,0x24,0x41,0x7F,0x56,0x72,0xFA, + 0x65,0x49,0xE2,0x38,0x0A,0x2B,0xAA,0x6B,0x44,0x49,0x03,0x41,0xFC,0x5C,0x54,0x55, + 0x44,0x49,0x03,0x41,0x57,0xDC,0x77,0x56,0x44,0x49,0xE2,0x38,0x0A,0x2A,0xEB,0x5E, + 0x44,0x49,0xC2,0x38,0xA8,0xB8,0xBF,0xD5,0x44,0x49,0xE3,0x38,0xAB,0x2A,0xBF,0xB7, + 0x85,0x51,0x23,0x49,0x2F,0x3D,0x3F,0x0F,0xC6,0x59,0x64,0x51,0x5F,0xEB,0xF2,0xFA, + 0xA5,0x51,0x43,0x49,0x77,0x7F,0xF8,0xBF,0x64,0x49,0x23,0x49,0x7E,0x68,0x56,0xFE, + 0x43,0x49,0x03,0x41,0x3A,0xB9,0xBB,0xDF,0xA5,0x59,0x03,0x49,0x2B,0x2F,0xAF,0xBD, + 0xA5,0x59,0x65,0x51,0xFA,0xFF,0x97,0x2E,0x26,0x72,0x84,0x59,0x25,0x95,0xB5,0xBD, + 0x06,0x72,0xA4,0x61,0x88,0xBF,0xB5,0xEE,0x27,0x72,0xE6,0x69,0xF5,0xAF,0x9A,0x5E, + 0xC8,0x8A,0x06,0x72,0x2B,0x09,0x2F,0xAF,0xE8,0x8A,0x46,0x7A,0xB8,0xF8,0x7A,0x7F, + 0xA8,0x82,0x26,0x72,0x20,0xBA,0xAF,0xB5,0xC9,0x8A,0x67,0x7A,0xE2,0xEA,0x6B,0x5F, + 0xA8,0x82,0x06,0x6A,0xA8,0xFA,0x5F,0x5D,0x47,0x72,0xC6,0x69,0xA0,0xFA,0xDF,0xBF, + 0x26,0x6A,0x84,0x59,0x5E,0x5E,0xFB,0x80,0xE5,0x61,0x64,0x51,0xD7,0xDD,0xBB,0x00, + 0xC5,0x59,0x64,0x51,0xF5,0xD7,0xB8,0x28,0xC6,0x59,0x85,0x59,0xBD,0xB5,0xE5,0x88, + 0xE6,0x61,0xA5,0x59,0xE7,0xEA,0xF9,0x7A,0xE6,0x61,0x85,0x51,0x8B,0xAE,0xEB,0xB7, + 0x06,0x62,0xA5,0x59,0xE3,0xED,0x55,0xD5,0x47,0x72,0xE5,0x61,0x3D,0xB5,0xDD,0xBD, + 0xE9,0x82,0x47,0x72,0x3F,0xA5,0xB5,0xFD,0x8B,0x9B,0x88,0x7A,0x0B,0xAB,0x5D,0xDD, + 0x2D,0xAC,0xA8,0x82,0x02,0xBF,0xF5,0x55,0x93,0xDD,0x29,0x8B,0x02,0x2F,0xAD,0xB5, + 0xF4,0xE5,0x51,0xD5,0x00,0x03,0x09,0xAD,0xF4,0xE5,0x14,0xDE,0xA8,0x88,0x00,0x00, + 0x14,0xE6,0xD4,0xDD,0x8B,0x7A,0xAE,0xEA,0xD3,0xDD,0xB3,0xDD,0x98,0xBB,0xFE,0xE5, + 0xD3,0xDD,0x92,0xD5,0x80,0x00,0xE0,0xE8,0xD3,0xDD,0xB2,0xDD,0x27,0x0F,0x0D,0xA9, + 0x14,0xE6,0xB3,0xDD,0x0A,0x0A,0xAF,0xED,0x14,0xE6,0xF4,0xDD,0xE8,0xFE,0xED,0xFF, + 0x14,0xE6,0xB3,0xDD,0xEA,0xBA,0xF8,0x6B,0x14,0xE6,0xD3,0xDD,0xB5,0xA7,0x0F,0x2F, + 0x55,0xEE,0x14,0xE6,0xB5,0x09,0x20,0x00,0x55,0xEE,0x14,0xE6,0x70,0xF2,0xEA,0xBA, + 0x35,0xE6,0xD3,0xDD,0xDF,0x57,0xDE,0xE8,0x14,0xE6,0xD3,0xDD,0xDD,0xA7,0x0B,0x02, + 0x35,0xE6,0xD3,0xDD,0xFD,0xFA,0xEA,0xBA,0x14,0xE6,0xF4,0xDD,0x8F,0x0B,0xA9,0x46, + 0x14,0xE6,0xF4,0xDD,0x0A,0x20,0x80,0x82,0x14,0xE6,0xD4,0xDD,0xFA,0x7F,0x7F,0xA8, + 0x35,0xE6,0xD3,0xDD,0x3B,0xAF,0xAD,0x3D,0x96,0xEE,0x35,0xE6,0x0F,0x29,0x29,0x0D, + 0xB7,0xF6,0x96,0xEE,0xF7,0x5D,0xEF,0x67,0xB6,0xF6,0x96,0xEE,0xDE,0xF7,0x9F,0xD5, + 0xB6,0xF6,0x76,0xEE,0xEA,0xFA,0xFA,0xFE,0x96,0xEE,0x76,0xEE,0xFE,0xDD,0xEF,0x5E, + 0x96,0xEE,0xF3,0xDD,0xA8,0xFA,0x7A,0x78,0x35,0xE6,0x93,0xD5,0x20,0xFA,0xFE,0xFF, + 0xF3,0xDD,0xB3,0xD5,0xEA,0x5F,0x57,0x57,0xD3,0xDD,0x92,0xD5,0xC8,0xEA,0xFF,0x75, + 0xD3,0xDD,0x92,0xD5,0xD7,0xA5,0xBD,0x6D,0xB3,0xDD,0x71,0xCD,0x80,0xA0,0xFF,0xB7, + 0xD3,0xDD,0x72,0xCD,0x8A,0x2A,0xEF,0xFB,0xD3,0xDD,0x92,0xD5,0xEA,0xFA,0xFB,0xFD, + 0xB2,0xD5,0x52,0xD5,0xB8,0xAE,0xEC,0xDA,0xB2,0xD5,0x72,0xD5,0xC2,0xC9,0x7D,0x75, + 0x66,0x72,0x25,0x72,0x20,0x08,0xA8,0x26,0x87,0x7A,0x46,0x72,0xF3,0x5C,0xE8,0x5F, + 0x67,0x7A,0x26,0x72,0xE6,0xAE,0x0A,0x00,0x87,0x72,0x26,0x6A,0xBA,0xFF,0xFE,0xE8, + 0x87,0x7A,0x46,0x72,0xA9,0xEF,0xEE,0x77,0x87,0x72,0x25,0x6A,0xAB,0xB7,0xFB,0xA8, + 0x87,0x7A,0x46,0x72,0xBF,0xCA,0x0A,0xFF,0x87,0x7A,0x26,0x72,0x2A,0xEA,0xA6,0x8B, + 0x86,0x7A,0x46,0x72,0x5A,0xF5,0xFD,0xFE,0x86,0x7A,0x26,0x6A,0xEB,0xF3,0xB8,0xF2, + 0xA7,0x7A,0x46,0x72,0xCF,0xE7,0xFF,0xEB,0x86,0x7A,0x46,0x72,0xA9,0xAF,0xF8,0x7C, + 0x87,0x7A,0x45,0x72,0xDC,0xE2,0xF8,0xA2,0x86,0x7A,0x46,0x72,0xE3,0xFB,0xB5,0xAD, + 0x87,0x7A,0x45,0x72,0xFD,0xE3,0xC2,0x82,0x87,0x7A,0x45,0x72,0x69,0x73,0xE3,0xF2, + 0x66,0x7A,0x45,0x72,0x50,0x6F,0xAE,0x2C,0x66,0x72,0x26,0x72,0xE2,0xE3,0x80,0xB2, + 0x87,0x7A,0x25,0x72,0x72,0xAA,0xFA,0xF8,0x87,0x7A,0x25,0x72,0xDB,0xBA,0xBA,0x9A, + 0x66,0x7A,0x46,0x72,0xB9,0xEF,0x78,0x5E,0x66,0x7A,0x46,0x72,0x98,0x80,0x40,0x62, + 0x87,0x7A,0x46,0x72,0x62,0xEA,0xEA,0x3A,0x87,0x7A,0x46,0x72,0xF1,0x05,0xA3,0x5E, + 0x87,0x7A,0x25,0x72,0xFD,0xAB,0xB8,0xA2,0xA7,0x82,0x46,0x72,0xFD,0xFB,0xDA,0xF2, + 0x87,0x7A,0x25,0x72,0xEC,0xBF,0x2B,0xA8,0x87,0x82,0x46,0x72,0xFF,0x5A,0xEA,0xB2, + 0x87,0x7A,0x25,0x72,0x8D,0xAF,0xAA,0xAF,0x87,0x82,0x25,0x72,0x5F,0xEE,0xF0,0xE2, + 0xA7,0x82,0x46,0x72,0xFF,0xD7,0xB4,0x7A,0x29,0x93,0x46,0x7A,0xFD,0xBD,0xBD,0x2D, + 0x2A,0x93,0xA8,0x82,0x6A,0x7F,0x7E,0x78,0x87,0x7A,0xC5,0x61,0x7C,0x7C,0xFE,0xFE, + 0xC4,0x61,0x02,0x41,0x5E,0xF8,0xE8,0xF0,0x23,0x41,0xC2,0x30,0x7E,0xDA,0x78,0xFA, + 0xE2,0x30,0xA1,0x30,0x7A,0x7A,0xF3,0xF7,0xC2,0x30,0x81,0x28,0xEA,0xE8,0x62,0xE2, + 0xC2,0x28,0x61,0x28,0xAA,0xAB,0x8A,0x08,0xE3,0x30,0xA2,0x28,0x57,0xF5,0xA7,0xC9, + 0xC2,0x30,0xA2,0x28,0x06,0xEA,0xEA,0xCB,0xC2,0x30,0xA2,0x28,0x57,0x55,0xA5,0x8E, + 0xC2,0x30,0xA2,0x28,0x8D,0x8F,0xAA,0x52,0xC2,0x30,0x81,0x20,0xFA,0x6A,0xEA,0xBE, + 0xC2,0x30,0x81,0x28,0x2F,0xBB,0xBF,0x2B,0x24,0x39,0xC2,0x30,0x3D,0xAD,0x2F,0xAF, + 0x64,0x49,0x24,0x41,0x0F,0x2B,0x0B,0x29,0x65,0x49,0xE3,0x38,0x5C,0x56,0x7E,0xD8, + 0x04,0x41,0xC2,0x38,0x5B,0x5E,0x7F,0x38,0x24,0x49,0xC2,0x38,0xA9,0xAB,0xAB,0x2A, + 0x64,0x51,0x03,0x41,0xBD,0x2D,0x09,0x0B,0x85,0x51,0x23,0x49,0x8A,0xAA,0xFE,0x7A, + 0xC6,0x59,0x64,0x51,0xDD,0xFD,0xEF,0xAB,0xA5,0x51,0x03,0x41,0xF8,0x7C,0x7E,0x58, + 0x44,0x49,0x03,0x41,0xEB,0xE3,0xE2,0x63,0x65,0x49,0xE3,0x38,0x7D,0xEB,0xA3,0xFF, + 0x24,0x41,0xC2,0x38,0xFD,0xFF,0xC8,0x28,0x24,0x41,0xE2,0x38,0xED,0xEB,0xAD,0x80, + 0x23,0x41,0xC2,0x38,0x2A,0xAA,0xEE,0x6A,0x44,0x41,0xC2,0x38,0xE8,0xB7,0x7D,0xD5, + 0x65,0x49,0xE3,0x38,0x5F,0xAF,0xA9,0x2F,0x65,0x49,0xE2,0x38,0xB5,0xAF,0x3E,0x0A, + 0x64,0x49,0x23,0x41,0xDF,0xBA,0x28,0xA0,0x44,0x49,0xE3,0x38,0x5E,0x5A,0x58,0x7E, + 0xE3,0x38,0xA2,0x30,0x36,0xFE,0xDE,0x9E,0x24,0x41,0xC2,0x38,0xAF,0xBD,0x2F,0xAB, + 0xA5,0x51,0x44,0x49,0xAD,0x09,0x09,0xA5,0x06,0x62,0x84,0x51,0x5F,0x7D,0xF3,0xAB, + 0xC5,0x59,0x23,0x41,0xBF,0xDF,0x5E,0x7C,0x44,0x49,0x03,0x41,0xE0,0x7C,0x7F,0x7E, + 0x23,0x49,0xE2,0x40,0xAF,0x2D,0x35,0x25,0x84,0x51,0x23,0x49,0x25,0x3D,0x35,0xB7, + 0x67,0x72,0xA5,0x59,0xF5,0xFD,0xB5,0x2D,0x67,0x7A,0xC5,0x61,0xDD,0xBF,0xAA,0x80, + 0x26,0x6A,0xE5,0x69,0xD5,0x6E,0x64,0xE8,0x06,0x6A,0xA5,0x61,0xE8,0xF2,0xF2,0x78, + 0x47,0x72,0xA4,0x61,0x03,0xFD,0xF5,0x55,0x47,0x7A,0xA4,0x61,0x20,0xAB,0xF7,0x5D, + 0x46,0x7A,0xA4,0x61,0x2A,0xAA,0xAD,0xFD,0x67,0x7A,0x26,0x72,0x00,0x00,0xAB,0x5D, + 0x67,0x72,0xC5,0x61,0xDA,0xAA,0xA8,0xE2,0x07,0x6A,0xA4,0x59,0x02,0xAA,0xFC,0x7E, + 0x47,0x72,0xA4,0x59,0x08,0xAB,0x2F,0xB5,0x26,0x6A,0xA5,0x59,0xEE,0xD8,0x5A,0x78, + 0xE6,0x61,0xA5,0x59,0xFF,0xF0,0x7E,0x75,0xC6,0x59,0x64,0x51,0xA2,0xA2,0xDA,0x5B, + 0x07,0x62,0x64,0x51,0xA2,0x02,0xBB,0x75,0xE6,0x59,0x64,0x51,0xBE,0xB2,0xF2,0xFD, + 0xA5,0x59,0x43,0x49,0x80,0x9A,0x38,0x38,0x06,0x62,0xA5,0x59,0x2F,0x25,0xF5,0xF7, + 0x47,0x72,0xA4,0x59,0x08,0xBF,0xDD,0x5F,0xC9,0x82,0xE6,0x61,0x22,0x2B,0xAD,0xF5, + 0xC9,0x82,0x67,0x7A,0xFB,0xCE,0x6B,0xF9,0x2D,0xAC,0x67,0x7A,0x2F,0xBD,0xF5,0xFD, + 0x72,0xD5,0x8B,0x9B,0x02,0x0F,0x2D,0xB5,0xF4,0xE5,0x72,0xD5,0x00,0xA2,0xAB,0xAD, + 0xF4,0xE5,0xB3,0xDD,0x20,0xA2,0xA3,0xE9,0xD3,0xDD,0xB3,0xDD,0x76,0xF0,0x20,0x80, + 0xF3,0xDD,0xB3,0xDD,0x6B,0xEF,0x7A,0x5E,0xB3,0xDD,0x72,0xD5,0x02,0x08,0xFE,0x7F, + 0xD3,0xDD,0x92,0xD5,0x0A,0x2D,0x95,0x55,0xF4,0xDD,0x92,0xD5,0x00,0x08,0x8F,0xAD, + 0xD3,0xE5,0x14,0xDE,0xAA,0xAA,0xAE,0xFE,0x55,0xEE,0xD3,0xDD,0xB5,0x29,0x2B,0x2A, + 0x55,0xEE,0xF4,0xDD,0x80,0xB0,0x7C,0x5A,0x35,0xEE,0x92,0xD5,0xA0,0x20,0xFE,0x5F, + 0x35,0xE6,0xB3,0xD5,0x20,0x00,0x00,0x09,0x55,0xEE,0x14,0xE6,0xD7,0x7E,0xFE,0xE3, + 0x35,0xEE,0x14,0xDE,0xD7,0xFF,0xB6,0xA2,0x35,0xE6,0xF4,0xDD,0xEB,0xEF,0xEA,0x60, + 0x35,0xE6,0xF4,0xE5,0xAB,0xAF,0x8A,0x2A,0x35,0xE6,0xF4,0xE5,0xFB,0xEA,0xA8,0x82, + 0x35,0xE6,0xD4,0xDD,0xBA,0x2A,0x2A,0x0A,0x96,0xEE,0x35,0xE6,0x09,0x0B,0x0B,0x0B, + 0xB6,0xF6,0x76,0xEE,0xCA,0x6A,0xEA,0xAA,0xB6,0xF6,0x75,0xEE,0x6B,0xEF,0xAB,0xEA, + 0x76,0xF6,0x96,0xEE,0xD5,0xF5,0xFF,0xDD,0x96,0xEE,0x76,0xEE,0xD8,0xCA,0x3E,0xA8, + 0x76,0xEE,0x14,0xE6,0x60,0xC0,0xC0,0x00,0x35,0xE6,0xB3,0xD5,0x7F,0xDC,0x5A,0x78, + 0xD3,0xDD,0x93,0xD5,0xBE,0xFF,0xAA,0xAA,0xD3,0xDD,0x92,0xD5,0x7E,0xBE,0xFE,0x5A, + 0xB2,0xD5,0x92,0xD5,0x65,0x75,0x75,0xFD,0xB2,0xD5,0x72,0xCD,0xF7,0xBA,0xEA,0xEE, + 0x92,0xD5,0x72,0xCD,0x80,0xAA,0xE2,0xBE,0x92,0xD5,0x51,0xCD,0x02,0x2B,0x2A,0xEA, + 0x92,0xD5,0x51,0xCD,0xF8,0xFA,0x9F,0x57,0x92,0xD5,0x51,0xCD,0x7F,0x77,0xEF,0x9D, + 0x67,0x7A,0x46,0x72,0x3D,0xAA,0xCF,0x9A,0x67,0x7A,0x46,0x72,0xB4,0x50,0xFE,0x0A, + 0x87,0x7A,0x47,0x72,0xDA,0xBF,0xEF,0xBB,0x67,0x7A,0x46,0x72,0xDB,0x82,0xC2,0x8B, + 0x67,0x72,0x46,0x72,0x3A,0x7A,0xFA,0x97,0x87,0x7A,0x46,0x72,0x7C,0x6B,0x43,0xF2, + 0x87,0x7A,0x46,0x72,0x7F,0xA1,0xBE,0xAD,0x87,0x7A,0x25,0x6A,0x2A,0xAA,0xE6,0xF8, + 0xA7,0x7A,0x26,0x6A,0xEE,0xBE,0xB6,0x2B,0x46,0x7A,0x66,0x72,0x7D,0xD5,0xBD,0x77, + 0x87,0x7A,0x46,0x72,0x0E,0xAB,0xBB,0xB5,0x86,0x7A,0x45,0x72,0xDE,0xAC,0x2A,0xA2, + 0x86,0x7A,0x46,0x72,0xA8,0xAA,0xBD,0xAA,0x86,0x7A,0x46,0x72,0xBF,0xEC,0xE2,0xA2, + 0x86,0x7A,0x46,0x72,0xD7,0x45,0x8F,0xBE,0x86,0x7A,0x46,0x72,0xEF,0xB7,0xAA,0xAA, + 0x87,0x7A,0x45,0x72,0xAF,0xBF,0xAF,0x8A,0x86,0x7A,0x46,0x72,0xFB,0xEA,0xEA,0x9C, + 0xA7,0x7A,0x67,0x72,0xFF,0x7D,0xFB,0xB3,0x86,0x7A,0x46,0x72,0xAE,0xFE,0xF6,0xD6, + 0x87,0x7A,0x46,0x72,0xA5,0xAE,0xFE,0xAA,0x67,0x7A,0x46,0x72,0xB7,0xAB,0x3E,0x22, + 0x87,0x82,0x46,0x72,0xFF,0xDA,0x98,0x3F,0x87,0x7A,0x46,0x7A,0xAA,0x83,0xEA,0x60, + 0x87,0x7A,0x46,0x72,0xBA,0xF8,0x1D,0x9B,0x86,0x7A,0x45,0x7A,0x8A,0xE8,0x2C,0xB9, + 0x87,0x7A,0x46,0x7A,0xBE,0xAF,0xAA,0xA2,0x87,0x7A,0x26,0x7A,0xAC,0xA8,0xA8,0x82, + 0x87,0x7A,0x25,0x72,0xA9,0xFA,0xBA,0x28,0xA7,0x82,0x66,0x7A,0x57,0xF5,0xAD,0xB9, + 0xC8,0x8A,0x46,0x72,0x7F,0x7E,0xFF,0x3B,0xCB,0xA3,0xA8,0x82,0xF5,0xA5,0x0D,0x0B, + 0xCB,0xA3,0xA7,0x82,0x7E,0x5E,0x78,0x7C,0x87,0x82,0xE5,0x61,0x7E,0x7C,0x7C,0x58, + 0xE5,0x61,0x43,0x49,0x7E,0x5E,0x7C,0x5C,0x03,0x41,0xC2,0x30,0xE4,0x56,0x5E,0x54, + 0xC2,0x30,0xA1,0x28,0x36,0x8F,0xC6,0x80,0xC2,0x30,0xA2,0x28,0x58,0x5F,0x5F,0x95, + 0xE3,0x30,0xA2,0x28,0xB7,0xB7,0xAE,0x8F,0x03,0x31,0xA2,0x28,0xAD,0xD7,0xAE,0xB2, + 0xE3,0x30,0xA2,0x28,0xE9,0xE8,0xC2,0x80,0xC2,0x30,0xA2,0x28,0x0B,0x2F,0x35,0x88, + 0xE3,0x30,0xA2,0x28,0x7E,0xEE,0x7D,0x57,0xC2,0x30,0x82,0x28,0xFF,0xFF,0xFB,0x23, + 0x03,0x39,0xA2,0x28,0x95,0xA5,0xB7,0x2A,0x43,0x41,0xE3,0x38,0xE5,0xAD,0xAF,0x8F, + 0x85,0x49,0x23,0x41,0x2D,0xAD,0xED,0x77,0x64,0x49,0xC2,0x38,0xF8,0x78,0x7A,0x7F, + 0x23,0x41,0xC2,0x38,0xBE,0x3D,0x0D,0x8F,0xA6,0x51,0x44,0x49,0x7D,0x8D,0x0D,0x89, + 0xA6,0x51,0x24,0x49,0xF5,0x7E,0x68,0x68,0x64,0x49,0x24,0x41,0xAE,0x0B,0x0F,0xC5, + 0xA5,0x59,0x03,0x41,0x0A,0x8A,0xEE,0x5F,0xC5,0x59,0xE3,0x38,0xF8,0xF2,0xFF,0x7D, + 0x24,0x41,0xC2,0x38,0xE8,0x58,0xDA,0xF2,0x03,0x39,0xC2,0x38,0x0E,0xAD,0x17,0xB5, + 0x24,0x41,0xE3,0x38,0x03,0x23,0x3D,0x5D,0x65,0x49,0x03,0x41,0xEA,0x3A,0x9A,0x5F, + 0x64,0x49,0xC1,0x38,0x6A,0xF0,0xE8,0xAB,0x03,0x41,0xC2,0x30,0xD5,0xA9,0xAA,0x80, + 0x23,0x41,0xE3,0x38,0x2B,0x23,0x3F,0x2B,0x85,0x51,0x03,0x41,0x8B,0x2B,0x2D,0xAD, + 0xA6,0x51,0x23,0x41,0xFC,0xFE,0x7E,0x5F,0x45,0x49,0xC2,0x38,0x7F,0x76,0xFA,0x82, + 0x03,0x39,0xC2,0x38,0xD5,0xF7,0xA6,0xBE,0x03,0x41,0xC2,0x38,0x2F,0xEF,0xBE,0x82, + 0x85,0x49,0x03,0x41,0x2D,0xFD,0xFD,0xD5,0xC6,0x59,0x23,0x41,0x22,0x2F,0xB5,0xD5, + 0xC5,0x51,0x24,0x49,0xF8,0x6E,0xFF,0x7F,0x44,0x49,0x03,0x41,0x7A,0x50,0x72,0xB1, + 0x64,0x49,0x03,0x41,0xB5,0xBD,0x9D,0x2A,0xE5,0x61,0x64,0x51,0x55,0xDD,0xAF,0x2D, + 0x26,0x6A,0x84,0x59,0x2D,0xF5,0xFE,0xAB,0x47,0x72,0xA4,0x59,0x80,0x02,0xAB,0xB7, + 0x26,0x6A,0x84,0x59,0xA8,0xF0,0x60,0x78,0xE5,0x61,0x64,0x51,0xE8,0xBB,0xFF,0x7F, + 0xC5,0x61,0x43,0x51,0x22,0xAA,0xB7,0xD5,0xC5,0x61,0x84,0x59,0xF2,0xFA,0x6B,0xFB, + 0xC5,0x61,0x84,0x59,0xB2,0x0D,0x37,0x3D,0x27,0x72,0x84,0x59,0xAB,0xFF,0x7A,0x70, + 0x27,0x6A,0x84,0x59,0xEA,0x8B,0x2D,0xFF,0x06,0x6A,0x64,0x51,0xFA,0x7A,0x7C,0x7A, + 0xA4,0x59,0x44,0x51,0x2B,0x37,0x57,0x7D,0xE6,0x61,0x44,0x49,0xA0,0xAF,0x57,0x55, + 0xA5,0x59,0x44,0x49,0x08,0x8B,0xFA,0xFF,0x85,0x51,0x44,0x49,0xFE,0x70,0x6A,0x7B, + 0x85,0x51,0x23,0x49,0x2F,0xB7,0xBD,0x5F,0xC6,0x59,0x64,0x49,0xF5,0x8B,0x0D,0x25, + 0x06,0x62,0x64,0x51,0x7F,0xEA,0xAA,0x0A,0x06,0x62,0x84,0x51,0xBF,0xF7,0x77,0xD8, + 0x06,0x62,0x84,0x51,0xAA,0x2F,0xBD,0xD7,0xE5,0x61,0x84,0x59,0x22,0xFA,0x62,0xAF, + 0x67,0x72,0xA5,0x59,0x02,0x09,0xAD,0x55,0xE9,0x8A,0x47,0x72,0x0B,0xA5,0xBD,0xD5, + 0x4D,0xB4,0xE9,0x8A,0x2B,0x2F,0xBD,0xB5,0x92,0xDD,0xEC,0xA3,0x02,0x2B,0x2B,0x25, + 0xF4,0xE5,0xB3,0xDD,0xA3,0x8B,0x2B,0x2D,0xF4,0xE5,0x92,0xD5,0xAA,0xBA,0x7A,0xFC, + 0xB3,0xDD,0x51,0xCD,0xA0,0xF8,0xDA,0xFA,0x92,0xD5,0x72,0xD5,0x6F,0xAF,0xF5,0xF5, + 0xD3,0xDD,0x72,0xCD,0xAD,0xB7,0x2F,0x0F,0xF4,0xDD,0x92,0xD5,0xA9,0x0B,0xAA,0x2B, + 0x34,0xE6,0xF4,0xDD,0xFD,0x2D,0xAF,0xF5,0x35,0xE6,0xD3,0xDD,0x02,0xFA,0xFE,0x55, + 0x14,0xE6,0xD3,0xDD,0xE0,0xB7,0x7F,0xDD,0xD3,0xDD,0x72,0xCD,0xD8,0x78,0x58,0x5E, + 0x14,0xE6,0x92,0xD5,0x0B,0x0D,0x0D,0x29,0x35,0xE6,0xF4,0xDD,0x80,0x7B,0xFE,0xBE, + 0x55,0xEE,0x14,0xE6,0x87,0x0D,0x03,0x02,0x76,0xEE,0x14,0xE6,0xDE,0xA2,0x8A,0x8A, + 0x55,0xEE,0x35,0xE6,0x75,0xF2,0xC0,0x50,0x14,0xEE,0x35,0xE6,0xD5,0xF7,0xB5,0xAD, + 0x35,0xE6,0x14,0xE6,0x3F,0xB9,0x23,0xBB,0xB7,0xF6,0x55,0xE6,0xFD,0x3D,0x29,0x0B, + 0xB6,0xF6,0x96,0xEE,0x7A,0xE8,0x7A,0x7E,0x76,0xFE,0x96,0xEE,0xD5,0xDF,0x75,0x77, + 0x96,0xEE,0x76,0xEE,0x08,0xA0,0xB2,0x66,0x96,0xEE,0x76,0xEE,0xA2,0xEA,0xDE,0x7B, + 0x76,0xEE,0x56,0xE6,0x08,0x00,0x00,0xA0,0x76,0xEE,0xD3,0xDD,0x5E,0xE0,0xE8,0x88, + 0x14,0xE6,0xB3,0xD5,0x5F,0x5F,0xFE,0x60,0xD3,0xDD,0x92,0xD5,0xFC,0xFF,0xEE,0xB8, + 0xB2,0xD5,0x52,0xCD,0xAA,0xAA,0xA8,0xE0,0x92,0xD5,0x72,0xCD,0x08,0x0A,0x98,0x88, + 0xB2,0xD5,0x72,0xCD,0xF6,0x7A,0xFB,0xFE,0x92,0xD5,0x71,0xCD,0x67,0xFE,0x6F,0x7A, + 0x71,0xCD,0x51,0xCD,0x77,0x5E,0x5F,0x9A,0x71,0xCD,0x31,0xC5,0xAB,0xFB,0xFB,0xAA, + 0x67,0x7A,0xA4,0x61,0x02,0x0A,0xAA,0xD5,0x88,0x7A,0xE5,0x69,0x8A,0xAE,0x0E,0x2D, + 0x67,0x72,0x26,0x72,0xC2,0x8A,0x27,0xAC,0x67,0x7A,0x46,0x72,0x06,0xEA,0x50,0x50, + 0x67,0x7A,0x46,0x72,0x57,0x70,0x7A,0xE3,0x87,0x72,0x25,0x6A,0x82,0xAB,0xE7,0xAA, + 0x86,0x7A,0x46,0x72,0x76,0xA5,0xAB,0xF5,0x87,0x7A,0x46,0x72,0xBF,0xAA,0xCF,0xEF, + 0x87,0x7A,0x46,0x72,0xF9,0x78,0x80,0x00,0x87,0x7A,0x46,0x72,0xB9,0xA3,0x89,0x3E, + 0xA7,0x7A,0x46,0x72,0x74,0x77,0xDF,0xDE,0x86,0x7A,0x46,0x72,0x8F,0xAB,0xFB,0xFD, + 0x86,0x7A,0x46,0x72,0x88,0x8B,0x0A,0x89,0xA7,0x7A,0x45,0x72,0xEA,0x78,0xAA,0xBF, + 0x86,0x7A,0x66,0x72,0xC3,0xBB,0xBE,0x57,0x86,0x7A,0x45,0x72,0xA2,0xB8,0x0D,0x88, + 0xA7,0x7A,0x66,0x72,0xFA,0xE2,0x56,0xDF,0x86,0x7A,0x66,0x72,0xDE,0xE6,0x8B,0xA6, + 0xA7,0x7A,0x66,0x72,0xF4,0xD7,0x7D,0x7B,0x86,0x7A,0x46,0x72,0xBE,0xFA,0x6E,0xD5, + 0xA7,0x82,0x66,0x7A,0xE5,0x75,0x75,0x75,0x87,0x7A,0x46,0x7A,0xB9,0x33,0x0B,0xAB, + 0x87,0x7A,0x25,0x7A,0xAA,0x62,0xAA,0xAA,0x87,0x7A,0x46,0x72,0xCD,0xA5,0xBF,0x3E, + 0xA7,0x7A,0x66,0x7A,0x75,0x75,0x6B,0xEB,0xC8,0x82,0x45,0x72,0xF5,0xED,0x2B,0x8B, + 0xA7,0x82,0x66,0x7A,0xFA,0xB6,0xE4,0x67,0xA7,0x82,0x46,0x72,0x8B,0x2F,0xB7,0xBA, + 0xA7,0x82,0x66,0x7A,0x9E,0xAB,0xAA,0xAA,0xA7,0x7A,0x46,0x72,0xAC,0xBF,0xE6,0xEB, + 0x2A,0x93,0x86,0x7A,0x17,0xA5,0x2D,0x2D,0x0D,0xAC,0x29,0x93,0x29,0x2B,0x0B,0x0A, + 0xEC,0xAB,0xE8,0x8A,0x78,0x78,0xF8,0x78,0xC8,0x82,0xC6,0x61,0x7A,0x7A,0xF8,0x7C, + 0xC5,0x61,0x03,0x41,0x78,0x60,0xE8,0xEC,0x23,0x41,0xC2,0x38,0xD7,0xAA,0xAA,0x00, + 0x03,0x39,0xA2,0x28,0xDF,0x6E,0x6A,0xF0,0xA2,0x30,0xC2,0x28,0x4A,0x6E,0xFF,0xBA, + 0xE3,0x30,0xA2,0x28,0x8A,0xF3,0xF9,0x75,0xE3,0x30,0xA2,0x28,0x3A,0xAB,0xBF,0xFF, + 0xE3,0x30,0xA2,0x28,0xA0,0xEA,0xF8,0x7A,0xC2,0x30,0xA2,0x28,0xE0,0x42,0xC2,0x61, + 0xC2,0x28,0x82,0x20,0xB0,0x2A,0xBF,0xBD,0xE3,0x30,0xA2,0x28,0xA5,0x2F,0x2E,0x2B, + 0x44,0x41,0xE3,0x30,0xF5,0xBD,0xEF,0x2A,0x44,0x41,0x03,0x39,0x29,0x83,0x0B,0x00, + 0x44,0x49,0xC2,0x30,0xE8,0xB2,0xFE,0x5E,0x03,0x39,0xC2,0x38,0xBE,0xBE,0x3F,0x0B, + 0x44,0x41,0xE2,0x38,0xB7,0x2F,0x3B,0xAD,0xA5,0x51,0x24,0x41,0x83,0xAB,0xBD,0xF5, + 0x85,0x51,0x24,0x41,0x62,0xE8,0x68,0x6B,0x23,0x41,0xC2,0x38,0x8A,0xFC,0x78,0x7E, + 0x03,0x41,0xA2,0x30,0x20,0xBA,0xFB,0x77,0xC2,0x40,0x03,0x39,0xFB,0xEE,0xFA,0xEF, + 0x24,0x41,0xC2,0x38,0xBE,0xBB,0xEF,0x7B,0x03,0x39,0xA2,0x30,0x0A,0x20,0xBE,0x97, + 0x24,0x41,0xC3,0x30,0x7F,0xFA,0x8A,0xAF,0x24,0x41,0xC2,0x38,0xF2,0xFD,0xB5,0xF7, + 0x24,0x41,0xE3,0x38,0x0D,0xBF,0x7B,0xED,0x23,0x41,0xE2,0x38,0xA0,0xAC,0xA7,0x0F, + 0x44,0x41,0x03,0x41,0xDF,0x83,0xE1,0x2B,0x44,0x41,0x03,0x41,0x37,0x35,0x57,0x56, + 0x64,0x49,0x23,0x41,0xDA,0x03,0xE1,0x7F,0x85,0x51,0x24,0x41,0x7B,0x8A,0xAA,0xFB, + 0x65,0x49,0x03,0x41,0x55,0x5E,0xFA,0xF8,0x65,0x49,0x03,0x39,0x57,0x7F,0x6B,0x23, + 0x85,0x49,0x03,0x41,0xDD,0xE5,0xA9,0xA2,0x85,0x51,0x24,0x41,0xB5,0x37,0xBE,0xFD, + 0x85,0x51,0x24,0x49,0x6A,0x6A,0xFA,0xAE,0x84,0x51,0x03,0x41,0xBD,0xAF,0xBA,0x82, + 0x85,0x51,0x23,0x49,0xAB,0xAF,0x2F,0xA4,0xE6,0x61,0x84,0x51,0xA5,0x25,0xAD,0x0B, + 0x26,0x62,0xC5,0x61,0xAF,0x3F,0xFF,0xB5,0x06,0x6A,0xA4,0x59,0x2E,0x78,0x7E,0x5A, + 0xE5,0x69,0x64,0x51,0xF8,0xFB,0xD5,0xF7,0xC5,0x61,0x64,0x51,0xFF,0x72,0xA8,0xA3, + 0xA5,0x59,0x23,0x51,0xD6,0x97,0xE2,0xA0,0xE6,0x69,0x84,0x59,0xFD,0xF9,0xBD,0x25, + 0x07,0x6A,0xA5,0x61,0xDD,0xDF,0x29,0x0A,0x47,0x72,0xA5,0x61,0x7A,0xCA,0xEB,0xE8, + 0xA5,0x59,0x44,0x51,0xF0,0xFE,0x9F,0xA8,0xC5,0x61,0x44,0x49,0xE8,0xAB,0xEB,0xF7, + 0x85,0x51,0x23,0x51,0x6A,0xAB,0x0B,0x02,0x84,0x51,0x44,0x49,0x75,0xFF,0x6F,0xFC, + 0x64,0x49,0x23,0x49,0x8A,0xEB,0x67,0x88,0x85,0x51,0x23,0x49,0x8B,0x2B,0xBD,0xE5, + 0x85,0x51,0x23,0x49,0x7E,0xAE,0x02,0x0B,0xC6,0x59,0x64,0x49,0x2D,0x2D,0xBF,0xFF, + 0x06,0x62,0xA5,0x51,0x8A,0xAA,0xEB,0xEF,0x06,0x62,0x84,0x51,0xA8,0xCA,0xEB,0x6D, + 0xE6,0x61,0xA5,0x59,0x76,0x7A,0xED,0x05,0xE6,0x61,0x84,0x51,0x2D,0xAF,0xA6,0xFA, + 0x27,0x72,0xA5,0x59,0xDD,0xBA,0xAA,0x2F,0x88,0x7A,0xE6,0x69,0x2D,0xAD,0x2B,0x2B, + 0x49,0x93,0xA8,0x7A,0x2D,0x35,0xBD,0xBD,0x4D,0xB4,0xE9,0x8A,0x0B,0xAF,0xFF,0xDD, + 0x93,0xDD,0xEC,0xA3,0x02,0x0F,0xAD,0xB5,0xF3,0xE5,0x72,0xD5,0xFA,0xAA,0xAB,0xB5, + 0xD3,0xDD,0x72,0xD5,0x5F,0x5E,0x7C,0xFE,0x92,0xD5,0x71,0xD5,0x0B,0x09,0xA9,0x00, + 0xD3,0xDD,0x92,0xD5,0xAD,0xAB,0xA5,0x2D,0x14,0xE6,0xB3,0xD5,0xAF,0xED,0xBF,0x8B, + 0xF4,0xDD,0xB2,0xDD,0x88,0xBE,0x20,0x20,0x14,0xE6,0xD3,0xDD,0xD5,0xD5,0xAE,0x08, + 0x14,0xE6,0xD3,0xDD,0x7F,0xEB,0x62,0x60,0x92,0xD5,0xF0,0xBC,0x30,0xB8,0xF8,0x5E, + 0x14,0xE6,0x10,0xC5,0x2B,0xAF,0xF5,0xD5,0x35,0xE6,0x92,0xD5,0x88,0x02,0x0B,0x09, + 0x76,0xEE,0x14,0xE6,0x2B,0x22,0xAA,0xAA,0x55,0xEE,0x35,0xE6,0x80,0xF4,0x57,0x5E, + 0x55,0xEE,0x15,0xE6,0xD2,0xBA,0xFB,0xEB,0x35,0xE6,0x14,0xE6,0xF8,0xBE,0xF8,0x5A, + 0x55,0xE6,0x14,0xE6,0xD7,0x95,0x35,0x0D,0xB7,0xF6,0x55,0xE6,0x2F,0x29,0x2B,0xAB, + 0xB6,0xF6,0x76,0xEE,0xA2,0xEA,0x7A,0xFE,0x96,0xEE,0x55,0xEE,0x08,0xE8,0xEA,0xFA, + 0x96,0xEE,0x55,0xE6,0xEA,0xAB,0xAD,0xFD,0x76,0xEE,0x55,0xE6,0x02,0x0E,0x8E,0x4E, + 0x75,0xEE,0x55,0xE6,0xE8,0xC2,0x2F,0xFB,0x35,0xEE,0x75,0xE6,0xAF,0xAF,0xB7,0xBE, + 0x55,0xEE,0x14,0xE6,0x6B,0xA8,0x7A,0xFA,0x14,0xE6,0xB3,0xD5,0x5C,0x58,0x78,0x5A, + 0xB2,0xD5,0x72,0xCD,0xF8,0xFC,0x2A,0x28,0xB2,0xD5,0x73,0xCD,0xBA,0xDA,0xAE,0x2B, + 0xB2,0xD5,0x71,0xCD,0x6A,0xBA,0xF7,0xED,0x92,0xD5,0x72,0xCD,0x56,0x5E,0x75,0x6F, + 0xB2,0xD5,0x51,0xCD,0x5B,0xFF,0xEF,0x3B,0x72,0xCD,0x10,0xC5,0xFB,0xFF,0xB4,0xF8, + 0x83,0x59,0x43,0x59,0x6A,0xAF,0x2F,0x02,0x06,0x6A,0x63,0x59,0x29,0xFD,0xD5,0x55, + 0x46,0x72,0x63,0x59,0x00,0xAF,0xDD,0x55,0x87,0x7A,0x84,0x61,0x08,0xA2,0xA9,0xF5, + 0x66,0x72,0x25,0x6A,0x0B,0x0F,0x89,0xED,0x87,0x7A,0x46,0x72,0xFB,0xA7,0xA7,0x25, + 0xA8,0x7A,0x46,0x72,0x55,0xEF,0x8A,0xFA,0x87,0x7A,0x46,0x72,0xA8,0xAB,0x52,0x62, + 0x87,0x7A,0x46,0x72,0xAA,0xFA,0xEE,0xBB,0x87,0x7A,0x46,0x72,0x8E,0x0B,0xBF,0xBE, + 0x87,0x7A,0x46,0x72,0x7A,0xFA,0xAA,0x83,0x87,0x7A,0x46,0x72,0xFF,0xBB,0x1E,0xDE, + 0xA7,0x7A,0x46,0x72,0x2D,0xA7,0xBD,0xBF,0xA7,0x7A,0x66,0x72,0xBF,0xB9,0xBB,0xAD, + 0xA7,0x7A,0x66,0x72,0xD5,0x57,0xBE,0xFC,0xA7,0x7A,0x66,0x72,0xEF,0xED,0xEA,0xDE, + 0xA7,0x7A,0x66,0x72,0xD7,0xB7,0xB4,0x9E,0x86,0x7A,0x46,0x72,0xA8,0x0F,0x0A,0x00, + 0x86,0x7A,0x66,0x72,0xC2,0xAC,0xCC,0x20,0x87,0x7A,0x45,0x72,0xB5,0x2A,0xF0,0xE2, + 0xA7,0x82,0x45,0x72,0x6F,0x8F,0xBE,0xAB,0x87,0x7A,0x46,0x72,0xEB,0x72,0xBE,0xA7, + 0x87,0x82,0x67,0x7A,0xD2,0xC2,0x6C,0x7F,0xA8,0x82,0x46,0x72,0x7F,0x7F,0x9D,0x3B, + 0xA7,0x7A,0x66,0x7A,0xE9,0xBD,0xDC,0xBE,0xA7,0x82,0x46,0x72,0xAA,0x27,0xAA,0xAA, + 0xA7,0x82,0x66,0x7A,0x55,0x7E,0x9E,0x58,0xA8,0x82,0x67,0x7A,0xDB,0x7F,0xCB,0xEF, + 0x87,0x82,0x66,0x7A,0xCC,0xF5,0xDD,0xC5,0xE8,0x8A,0x66,0x7A,0xD7,0xFD,0xBF,0x3F, + 0xCC,0xA3,0xA7,0x82,0x3D,0x2D,0x2B,0x0B,0x0E,0xB4,0x8B,0x9B,0x0A,0xAE,0xE2,0x70, + 0xEC,0xAB,0xA7,0x82,0xF8,0x78,0x7A,0x7A,0xC8,0x82,0xC5,0x61,0x58,0x7E,0xDE,0xFE, + 0x06,0x62,0x64,0x51,0x5F,0xFA,0xE8,0xE8,0x85,0x51,0x03,0x41,0xFE,0xFA,0x7C,0x58, + 0x23,0x41,0xE2,0x38,0x7C,0xE8,0x6E,0x4B,0xC2,0x30,0xA2,0x28,0xEC,0x20,0xF2,0xF0, + 0xC2,0x30,0xA2,0x28,0xE9,0xAA,0xEB,0x6B,0xE3,0x30,0xA2,0x28,0xB5,0xF5,0xBF,0x95, + 0xC2,0x28,0xA2,0x28,0x70,0x62,0x58,0x54,0xA2,0x28,0x81,0x28,0x38,0x22,0xB0,0xB0, + 0xA2,0x28,0x82,0x28,0x3C,0xE8,0xFE,0x38,0x03,0x39,0xA2,0x28,0x2D,0x85,0xBF,0xFF, + 0x44,0x41,0xE2,0x30,0xAA,0xAE,0xF3,0xE5,0x44,0x41,0xE3,0x38,0xE8,0xFA,0xFF,0xD7, + 0x23,0x41,0xA1,0x30,0x7C,0x7F,0xFF,0x3E,0x03,0x39,0xC2,0x38,0x02,0xEB,0xEF,0xC0, + 0x24,0x41,0xC2,0x30,0x2F,0xAF,0xB7,0xBD,0x44,0x49,0xE3,0x38,0xAA,0xBF,0xDF,0xDF, + 0x65,0x49,0xE3,0x38,0xC2,0xEA,0x7E,0x55,0x23,0x41,0xC2,0x38,0x78,0xF8,0x7B,0xFF, + 0xE2,0x38,0xA2,0x30,0xBF,0xFA,0x78,0xFC,0x23,0x39,0xC2,0x30,0xF2,0xAB,0xAB,0xAB, + 0x24,0x41,0xE3,0x38,0x77,0xFF,0x8B,0x06,0x04,0x41,0xA2,0x30,0x5F,0xFE,0xFA,0xB8, + 0xE3,0x38,0x81,0x28,0x2B,0x2F,0xFF,0xF7,0xE3,0x38,0x82,0x30,0xAA,0xA8,0xDB,0xFF, + 0x03,0x39,0xC2,0x30,0x03,0x09,0xAD,0x09,0x23,0x41,0x03,0x39,0x35,0xAF,0x3F,0x2F, + 0x44,0x41,0x03,0x41,0x2F,0x2D,0x2B,0x0E,0x44,0x41,0xE3,0x38,0xAC,0xE0,0xDA,0xDA, + 0x44,0x49,0xE3,0x38,0xAA,0x2E,0x0E,0xB7,0x64,0x49,0x24,0x41,0xF2,0xF8,0xFA,0x7F, + 0x44,0x49,0x03,0x41,0xFC,0xEA,0xFE,0xFE,0x85,0x51,0x24,0x41,0x2B,0x2D,0x3B,0x0B, + 0xA6,0x51,0x44,0x49,0xEE,0xEA,0xEA,0x50,0x64,0x49,0x03,0x41,0xA8,0x60,0xFE,0xB6, + 0x64,0x49,0x03,0x41,0x2E,0xA9,0xBB,0x82,0x85,0x51,0x24,0x49,0x20,0x2A,0xFB,0xD8, + 0x84,0x51,0x23,0x49,0xAA,0x2A,0xEE,0x7D,0x06,0x62,0x65,0x51,0x09,0x27,0xAD,0xA9, + 0xE6,0x61,0x84,0x51,0xA8,0xB8,0xFE,0xDF,0xA5,0x59,0x63,0x51,0xC0,0xCB,0x8A,0xFC, + 0xA5,0x59,0x43,0x51,0xAA,0x29,0x8A,0xB0,0xE5,0x61,0x44,0x51,0xAB,0xAF,0x2F,0xF7, + 0xE6,0x61,0x84,0x59,0x7F,0xDA,0xEA,0x8A,0x06,0x62,0x84,0x59,0x29,0xAF,0xB5,0xFD, + 0x27,0x6A,0xC6,0x61,0x82,0x00,0x2F,0xB9,0x27,0x6A,0xC6,0x61,0xFA,0x7A,0xE8,0xC0, + 0xC6,0x59,0x23,0x49,0xFA,0x7A,0x7A,0x68,0x64,0x51,0x03,0x41,0x2A,0xFA,0x5D,0x57, + 0x85,0x51,0x23,0x49,0x02,0xA2,0x0C,0x3D,0x85,0x51,0x44,0x49,0xB8,0xBA,0x70,0x28, + 0x64,0x51,0x44,0x49,0xA8,0xAC,0xB6,0x25,0xA6,0x51,0x23,0x49,0xEF,0xEB,0xF9,0xF8, + 0xE6,0x59,0x44,0x49,0xB7,0xA9,0x22,0x2D,0xC6,0x59,0x43,0x49,0xFB,0xB6,0xF8,0xE0, + 0xC6,0x59,0x65,0x51,0xB2,0x7A,0xB7,0xF7,0xA5,0x51,0x64,0x51,0x62,0xFA,0x79,0x65, + 0xE6,0x59,0x43,0x49,0x2A,0xAF,0xB7,0xD5,0xE6,0x59,0x84,0x51,0x40,0xA2,0x3A,0x7D, + 0x47,0x72,0xC6,0x59,0x25,0xAD,0x2F,0x29,0x87,0x7A,0x27,0x6A,0x0F,0x03,0xAA,0x21, + 0xE9,0x82,0x87,0x7A,0x0B,0x22,0x89,0x7F,0x6B,0x93,0xC8,0x82,0x0B,0x7F,0x7F,0x7D, + 0x8F,0xBC,0xE8,0x8A,0x2F,0xBD,0xFD,0x55,0xB3,0xDD,0x8B,0x9B,0x22,0x0B,0x2F,0xAD, + 0xF4,0xE5,0x92,0xD5,0x7B,0xFB,0xAF,0x29,0xF4,0xDD,0x72,0xD5,0x5F,0x7F,0xB8,0x80, + 0x14,0xE6,0x92,0xD5,0xBD,0xAD,0x0F,0x0A,0x35,0xEE,0xF4,0xDD,0xEF,0xAF,0xA2,0xAA, + 0x35,0xE6,0xF4,0xDD,0xDB,0xBE,0xAB,0x2A,0x35,0xE6,0xD3,0xDD,0xAB,0xB7,0x2A,0x82, + 0x14,0xE6,0x72,0xCD,0xC0,0x78,0x70,0x70,0x31,0xC5,0xCF,0xBC,0xFC,0xF7,0xDE,0x3A, + 0x72,0xCD,0xF0,0xC4,0xB5,0xBD,0xAB,0x2A,0x55,0xEE,0x92,0xD5,0x2D,0x25,0x2D,0x2D, + 0x75,0xEE,0x35,0xE6,0xE0,0xA2,0xE8,0xEA,0x55,0xEE,0x14,0xE6,0xFE,0x7E,0xE2,0x78, + 0x35,0xE6,0x14,0xE6,0xC0,0x3B,0x7F,0x75,0x35,0xE6,0x14,0xE6,0x96,0x9F,0x25,0x05, + 0x96,0xEE,0x35,0xE6,0xB5,0x2D,0x3F,0x2A,0x76,0xF6,0x96,0xEE,0xD6,0xF5,0xFF,0xF7, + 0x96,0xEE,0x35,0xE6,0x80,0xA8,0xAA,0xAA,0x95,0xEE,0x55,0xE6,0xF4,0xFF,0x57,0x55, + 0x75,0xEE,0x55,0xE6,0xBF,0x17,0x97,0xDF,0x75,0xEE,0x55,0xE6,0xFE,0xA8,0xFB,0xBF, + 0x75,0xEE,0x55,0xE6,0xAF,0xAB,0xB9,0xFF,0x76,0xEE,0x55,0xE6,0xF2,0xEA,0xB2,0xFB, + 0x55,0xEE,0x35,0xE6,0x7A,0x78,0xFA,0xBA,0x75,0xEE,0xB3,0xD5,0x5E,0x7A,0xAA,0xAA, + 0x14,0xE6,0x92,0xD5,0x77,0xFF,0x68,0x80,0xB3,0xDD,0x72,0xD5,0xEA,0xEE,0xDB,0xF8, + 0xB3,0xD5,0x71,0xD5,0x3B,0x2A,0x8B,0x60,0xB3,0xD5,0x72,0xD5,0xB2,0xA0,0xAA,0x7F, + 0xB2,0xD5,0x51,0xCD,0xFF,0xF8,0xFA,0xEB,0x71,0xCD,0x51,0xCD,0x6F,0xAB,0xE7,0xAF, + 0x83,0x61,0x43,0x59,0xF8,0xFA,0xAF,0xC9,0xA4,0x61,0x63,0x59,0x5F,0x37,0x5F,0x95, + 0x84,0x59,0x43,0x59,0xAF,0xB6,0xEB,0xBE,0xC5,0x69,0x44,0x59,0x0F,0xEB,0xFF,0x6F, + 0xE5,0x69,0x43,0x59,0x0A,0xAF,0xF7,0xF5,0x67,0x7A,0xA4,0x61,0x0A,0xBF,0x55,0x55, + 0x87,0x7A,0xA4,0x61,0xA0,0xAA,0xBF,0xD5,0x66,0x72,0x05,0x6A,0x02,0x0A,0xFE,0xB5, + 0x66,0x72,0x25,0x72,0x82,0x02,0x37,0x2B,0xA7,0x7A,0x45,0x72,0xFE,0x77,0x6E,0x3E, + 0x87,0x7A,0x25,0x72,0x0B,0x8B,0xAF,0xA5,0x87,0x7A,0x66,0x72,0xDF,0xD1,0xF3,0x8B, + 0xA7,0x7A,0x46,0x72,0xFF,0xAB,0x3B,0x2F,0x86,0x7A,0x46,0x72,0x2E,0xAA,0xF2,0xC8, + 0xA7,0x7A,0x46,0x72,0xE8,0x6A,0xEB,0xF2,0xA7,0x7A,0x66,0x72,0x5D,0xE9,0x29,0xFB, + 0xA7,0x7A,0x66,0x72,0x6D,0x8F,0xAE,0x5C,0xA7,0x7A,0x66,0x72,0xEA,0xCF,0xF7,0xBD, + 0xA7,0x7A,0x66,0x72,0xFA,0xDF,0xD6,0x5A,0x87,0x7A,0x46,0x72,0x8A,0x00,0x89,0xB9, + 0x87,0x7A,0x45,0x72,0x0D,0x2F,0x0A,0x22,0x87,0x7A,0x46,0x72,0xF0,0x7A,0xAA,0x0A, + 0x87,0x7A,0x26,0x7A,0xCA,0xA2,0x8A,0x80,0xA7,0x82,0x66,0x7A,0x25,0xF7,0xBA,0x8E, + 0xA7,0x82,0x46,0x7A,0xA8,0xAA,0xAA,0xAD,0x87,0x82,0x66,0x7A,0x3A,0xA5,0xD5,0x57, + 0xA7,0x82,0x66,0x7A,0xDE,0xB6,0xF8,0xFF,0xA7,0x82,0x66,0x7A,0xA9,0xA1,0xEA,0x13, + 0xA7,0x82,0x66,0x7A,0x77,0x7B,0x7A,0xFE,0x6A,0x9B,0x46,0x72,0xBF,0xB5,0x2D,0x0B, + 0x0D,0xB4,0x6A,0x9B,0x2D,0x0D,0x2A,0x02,0x2D,0xB4,0xCC,0xA3,0x78,0x80,0xC0,0xDE, + 0xCC,0xA3,0x66,0x7A,0x78,0x78,0x7C,0x7A,0x46,0x72,0xE5,0x69,0xE8,0xBA,0xFC,0x5C, + 0x06,0x6A,0x63,0x49,0xF8,0x70,0x7A,0x5E,0x64,0x51,0xE2,0x38,0x70,0x68,0xEA,0x7A, + 0x03,0x41,0xE2,0x38,0x62,0xDA,0x0E,0x35,0x03,0x39,0xA2,0x30,0x5E,0xDE,0x50,0x7C, + 0xC2,0x38,0xA2,0x28,0x5E,0x57,0xD7,0xD7,0xC1,0x30,0x82,0x20,0x2F,0xFB,0xEE,0xFA, + 0xA2,0x28,0x81,0x28,0xF0,0x60,0x83,0x02,0xC2,0x28,0x82,0x28,0xFB,0xBF,0xFB,0xAA, + 0xC2,0x28,0x61,0x28,0x2A,0xAA,0x2B,0xA2,0xE3,0x30,0xA2,0x30,0x6E,0xEB,0x8A,0xEB, + 0xE3,0x30,0xA2,0x30,0x2B,0xEA,0xD8,0x7A,0xE3,0x38,0xA2,0x30,0x2E,0xA7,0xF7,0xFE, + 0x44,0x41,0xC2,0x38,0x3D,0xA5,0x2D,0xBD,0x44,0x41,0xE3,0x38,0xF8,0xE0,0x78,0xF8, + 0x03,0x39,0xC2,0x38,0x6F,0xAA,0xAE,0x2E,0x24,0x41,0xE3,0x38,0x7A,0x7C,0x2A,0x22, + 0x24,0x41,0xC2,0x30,0x7E,0xFB,0xE0,0xF0,0x44,0x41,0xC2,0x30,0xDD,0xBD,0x2F,0x2B, + 0x43,0x49,0xA1,0x30,0xDF,0x5F,0xEE,0xA0,0x24,0x41,0xE3,0x38,0xFD,0xA9,0x0B,0x80, + 0x23,0x41,0xC2,0x38,0x0E,0xBA,0xFC,0x7A,0x24,0x41,0xC3,0x38,0xF0,0xE2,0xFF,0xFF, + 0xC3,0x30,0x82,0x30,0xF6,0xFA,0xF0,0xB2,0xE3,0x38,0x82,0x30,0xFF,0xB7,0xB7,0x2B, + 0x24,0x41,0xC2,0x38,0xAD,0x3D,0x23,0xAA,0x44,0x41,0xE3,0x38,0xBF,0xBB,0xFF,0x0D, + 0x64,0x49,0x24,0x41,0xA5,0xBD,0xD7,0x5E,0x64,0x49,0x24,0x41,0x57,0x72,0xE2,0x7E, + 0x23,0x41,0xE2,0x38,0xAC,0xB0,0xE3,0xEF,0x24,0x41,0xE3,0x38,0x80,0x8A,0xFB,0x9B, + 0x44,0x49,0xE3,0x38,0xAB,0xAB,0xAF,0x15,0x85,0x51,0x24,0x41,0x8B,0x22,0xBB,0x5F, + 0xA6,0x51,0x03,0x39,0xE0,0xFB,0x7B,0xDD,0x44,0x41,0xE3,0x38,0xAE,0xBA,0x3F,0x1E, + 0x85,0x51,0x24,0x41,0xBB,0x0F,0xFF,0x77,0x65,0x51,0x03,0x41,0xEC,0xE0,0x6A,0x5D, + 0x24,0x49,0xE3,0x40,0x0A,0x2B,0xBA,0x5A,0xC6,0x59,0x23,0x49,0x8B,0xA9,0xE9,0xF5, + 0xA5,0x59,0x44,0x49,0xF8,0xFA,0x7B,0x7F,0x64,0x51,0x23,0x49,0x20,0xAA,0xA2,0xFF, + 0x64,0x51,0x03,0x41,0x80,0xBA,0x9E,0xD7,0x85,0x59,0x23,0x49,0x0E,0xA7,0xA7,0x2D, + 0xE6,0x61,0x85,0x59,0x8B,0xA1,0xBB,0xFF,0xE6,0x61,0x85,0x51,0xA8,0xAE,0x77,0x7F, + 0x06,0x62,0x84,0x51,0xA2,0xAB,0xBE,0xFD,0x27,0x6A,0x84,0x51,0x80,0xAE,0xEF,0x77, + 0xE6,0x61,0x85,0x51,0x6A,0xE0,0xEE,0x9F,0xC6,0x59,0x23,0x49,0x5F,0xEE,0xEA,0x80, + 0x64,0x51,0x02,0x41,0x3F,0xBF,0xC0,0xA8,0x85,0x51,0x23,0x41,0x0A,0xAD,0xDD,0xBF, + 0x64,0x49,0x23,0x41,0x03,0x8C,0x86,0xAA,0x64,0x49,0x44,0x49,0x20,0x1C,0x2F,0x29, + 0xC6,0x59,0x64,0x49,0x2D,0xAD,0xFD,0xFF,0xE6,0x59,0x64,0x49,0xA0,0xAA,0xD5,0x57, + 0xA5,0x51,0x44,0x49,0xEC,0xA0,0xAA,0x7F,0x85,0x51,0x23,0x41,0x8F,0xAA,0xFB,0x7E, + 0xA5,0x51,0x23,0x49,0x2E,0x2B,0x2F,0xAF,0xC5,0x51,0x64,0x51,0xFE,0xFE,0xDC,0xB7, + 0x07,0x6A,0xA5,0x59,0x27,0xA5,0xA5,0x9D,0x87,0x7A,0x06,0x62,0x2A,0xAB,0xAF,0xF5, + 0xC8,0x82,0x88,0x7A,0xBB,0xC1,0xCD,0xBD,0xE8,0x82,0xA7,0x82,0xAA,0xAF,0xB3,0x7F, + 0x29,0x8B,0xC7,0x82,0x3F,0xBF,0x75,0xE5,0x31,0xCD,0x09,0x8B,0x2F,0xBD,0xD5,0xD5, + 0xD4,0xE5,0x0D,0xAC,0x02,0x02,0x0B,0x2D,0x14,0xE6,0xD3,0xE5,0xFE,0xAA,0x22,0x8B, + 0x55,0xE6,0xF4,0xE5,0xFD,0xBD,0x8F,0xAF,0x55,0xEE,0x14,0xE6,0x57,0xD5,0x3A,0x0E, + 0x55,0xEE,0x14,0xE6,0xB5,0xAE,0xAA,0x20,0x55,0xEE,0x15,0xE6,0xFA,0xFA,0xFF,0xFC, + 0xF4,0xE5,0xD0,0xBC,0xE0,0xE0,0xE8,0x78,0x72,0xCD,0x10,0xC5,0xB7,0x27,0xAD,0xF5, + 0x72,0xCD,0x30,0xCD,0xFB,0xF8,0xAE,0xDD,0x35,0xE6,0x31,0xCD,0x0F,0x2D,0x2F,0xAD, + 0x76,0xEE,0x34,0xE6,0xFB,0xEB,0xAB,0x81,0x55,0xEE,0x15,0xE6,0x7A,0xEE,0xEA,0xA2, + 0x76,0xEE,0x14,0xE6,0xDD,0xF7,0xB7,0x2F,0x96,0xEE,0x14,0xE6,0xBD,0x2F,0xAB,0x02, + 0x96,0xEE,0x76,0xEE,0x3D,0x3F,0xA8,0x82,0xB6,0xF6,0x76,0xEE,0xFA,0xFB,0x5F,0x57, + 0x76,0xEE,0x55,0xE6,0xA0,0xE0,0x38,0xDE,0x35,0xF6,0x55,0xE6,0x55,0xDD,0x5D,0xDD, + 0x55,0xEE,0x75,0xE6,0x2E,0xEB,0xEE,0xAE,0x75,0xEE,0x35,0xE6,0x2A,0x3E,0xFE,0xAA, + 0x75,0xEE,0x35,0xE6,0x8A,0xA8,0xAA,0xB7,0x55,0xEE,0x75,0xE6,0xAA,0xA8,0xA8,0xFE, + 0x75,0xEE,0x55,0xE6,0xDE,0xDF,0xAF,0xC0,0x75,0xEE,0x35,0xE6,0x7E,0xFE,0x9E,0xBA, + 0x55,0xE6,0x14,0xE6,0xFA,0x6A,0xA0,0x00,0x55,0xEE,0xB3,0xD5,0x5E,0xEA,0xA8,0x80, + 0x15,0xE6,0x92,0xD5,0xF7,0x7F,0xFA,0xA0,0xD4,0xDD,0x92,0xD5,0x5D,0x55,0xDE,0xF9, + 0xB3,0xDD,0x71,0xD5,0x7E,0x6A,0xAB,0xB0,0x92,0xD5,0x51,0xCD,0x97,0xEE,0xAC,0x20, + 0x84,0x61,0x43,0x59,0xFD,0xEB,0x02,0xCB,0x84,0x61,0x43,0x59,0x3F,0xFE,0xDE,0xBF, + 0x84,0x61,0x43,0x59,0x8E,0xB4,0xDB,0x72,0xA5,0x61,0x43,0x59,0xF8,0x7C,0x5E,0x5F, + 0x84,0x61,0x23,0x51,0x2D,0x22,0x80,0xA2,0xA4,0x61,0x63,0x59,0xFA,0x7E,0xF7,0x69, + 0x84,0x61,0x63,0x59,0x39,0x55,0xAD,0xF9,0xE4,0x69,0x63,0x59,0x2B,0xAD,0xB5,0x79, + 0x46,0x72,0x63,0x59,0x0A,0xAB,0xFD,0x5D,0x87,0x7A,0x83,0x59,0x02,0xAA,0xBD,0x55, + 0x66,0x72,0xC4,0x61,0x28,0x80,0x2A,0xB5,0x87,0x7A,0x66,0x72,0x91,0x05,0x7A,0x79, + 0xA7,0x82,0x66,0x72,0xFA,0xF8,0xFD,0x7D,0x86,0x7A,0x66,0x72,0xE0,0x74,0xD7,0xAE, + 0xA7,0x7A,0x66,0x72,0xE6,0xAF,0xFB,0x2F,0x87,0x7A,0x46,0x72,0x8E,0xB0,0xA8,0xFE, + 0xA7,0x7A,0x66,0x72,0xFF,0x56,0xDA,0x7D,0xA7,0x7A,0x66,0x72,0xCD,0x5F,0xEF,0xF7, + 0x87,0x7A,0x46,0x72,0xC8,0xC2,0x42,0x03,0xA7,0x7A,0x46,0x72,0xBD,0x2F,0xAB,0xEB, + 0xA8,0x7A,0x66,0x7A,0xF7,0x7F,0xEA,0x57,0x87,0x7A,0x46,0x7A,0x88,0xA2,0x92,0x12, + 0xA7,0x82,0x67,0x7A,0xAF,0xB7,0xDF,0xFF,0xA7,0x82,0x67,0x7A,0xCB,0x56,0x8E,0xB2, + 0xA7,0x82,0x46,0x72,0xED,0xAF,0x2B,0xA2,0x87,0x82,0x67,0x7A,0x9F,0xBD,0x34,0x02, + 0xA7,0x82,0x67,0x7A,0xF4,0xAC,0xBF,0xF9,0xA7,0x82,0x66,0x7A,0xEA,0xAA,0xBF,0x58, + 0x29,0x93,0x87,0x7A,0x5D,0x5D,0x95,0x3D,0xEC,0xAB,0xA7,0x82,0x2D,0x2F,0x0A,0x0A, + 0x0D,0xAC,0xAB,0xA3,0x88,0xA8,0xBF,0xFF,0xEC,0xAB,0xAC,0xA3,0x80,0xE8,0xAE,0xB4, + 0xCB,0xA3,0x86,0x7A,0x58,0x78,0xF8,0xE8,0x46,0x72,0xA5,0x59,0xDC,0x5C,0x5C,0x5C, + 0xA5,0x59,0x43,0x49,0x70,0xE8,0x62,0xFE,0x64,0x49,0x02,0x41,0x5E,0xFE,0x68,0x50, + 0x03,0x41,0xE2,0x38,0x7D,0xF8,0xDE,0x55,0xE2,0x30,0xA2,0x28,0xE8,0xF0,0x6A,0x7A, + 0x82,0x30,0xA2,0x28,0xDF,0x7D,0xFB,0x7F,0xC2,0x30,0xA2,0x28,0xDF,0x7B,0xEA,0x68, + 0xC2,0x28,0x81,0x28,0xBB,0x6E,0xEB,0x83,0xC2,0x30,0xA2,0x28,0x6B,0x8D,0x2E,0x00, + 0xC2,0x30,0xA2,0x28,0x82,0x8B,0x23,0xAB,0xE3,0x30,0xA2,0x30,0xA7,0x2F,0xAB,0x02, + 0xE3,0x38,0xA1,0x28,0x5B,0xFE,0xAE,0x2A,0x03,0x39,0xA2,0x30,0xF7,0xBF,0xFF,0xA2, + 0x24,0x41,0xC2,0x30,0xED,0xAA,0x82,0x02,0x45,0x41,0x03,0x41,0xDF,0xDF,0xFB,0xAD, + 0x24,0x41,0xE3,0x38,0x36,0x85,0xBB,0xA0,0x44,0x41,0x03,0x41,0xAE,0xBF,0xFB,0xBA, + 0x65,0x49,0x03,0x39,0x53,0xE9,0xC3,0xEB,0x44,0x49,0xE3,0x38,0x2F,0xBB,0xFE,0x5A, + 0x65,0x49,0x03,0x41,0x6A,0xAA,0xAB,0x0B,0x85,0x51,0x03,0x41,0x7F,0xFB,0xEA,0x78, + 0x24,0x41,0xC3,0x38,0xDA,0xD4,0x5E,0xDF,0xE3,0x38,0xC2,0x30,0xEE,0x63,0xC1,0x00, + 0xE3,0x38,0xA2,0x30,0x55,0x9B,0xAA,0x80,0x03,0x39,0xC3,0x38,0xA5,0x2D,0x2F,0x3F, + 0x44,0x41,0x03,0x39,0x75,0xAB,0x2B,0x2B,0x85,0x51,0x03,0x39,0xF5,0xEA,0xC0,0x22, + 0x44,0x49,0x03,0x41,0xDC,0x5E,0x5E,0x5B,0x24,0x41,0x03,0x39,0xEA,0xEF,0xB9,0xC1, + 0x03,0x41,0xE3,0x38,0xBE,0xF8,0xEC,0xAA,0x24,0x41,0xE3,0x38,0xFF,0xAF,0x8B,0x0B, + 0x24,0x49,0xE3,0x38,0x05,0xFF,0xDE,0x56,0x24,0x41,0xE3,0x38,0x80,0xBB,0xF9,0x6F, + 0x44,0x41,0x04,0x41,0xF5,0xF5,0x9D,0x9F,0x44,0x41,0x03,0x41,0xD5,0x5E,0xFE,0x2A, + 0x44,0x51,0x03,0x41,0xF7,0xBF,0x2F,0x3F,0x44,0x49,0x03,0x41,0xD5,0xFE,0xE2,0xA0, + 0x24,0x49,0xE3,0x40,0x56,0x97,0xAE,0xAE,0x44,0x49,0xE3,0x40,0x0B,0xAA,0xEE,0x7E, + 0x44,0x49,0x03,0x41,0xA8,0xEA,0xAF,0xED,0x23,0x49,0xE2,0x40,0x80,0xA0,0xE8,0x55, + 0x23,0x49,0xE2,0x38,0xAA,0xFA,0xFB,0xBF,0x85,0x59,0x23,0x41,0x0D,0xBD,0xFD,0xA5, + 0xA5,0x59,0x64,0x49,0x22,0x2A,0xAB,0xFD,0xC6,0x59,0x64,0x51,0xEA,0xAA,0x3E,0x6F, + 0xA5,0x59,0x44,0x49,0x0B,0x0B,0xAA,0xBD,0x85,0x51,0x44,0x49,0x98,0xD8,0xDC,0x6F, + 0xA5,0x51,0x24,0x49,0x28,0xCA,0xFF,0xDF,0xC6,0x59,0x44,0x49,0xA0,0xEB,0xFF,0x5F, + 0x85,0x51,0x23,0x41,0xFE,0xFE,0x72,0x5E,0x85,0x51,0x23,0x49,0xAF,0xAF,0xBF,0xAD, + 0x65,0x49,0x23,0x41,0xF4,0xD8,0xD6,0x5F,0x85,0x51,0x23,0x41,0x8F,0xBB,0xAF,0xF5, + 0xA5,0x51,0x44,0x49,0x3D,0xFF,0xD7,0x57,0xA5,0x51,0x44,0x49,0xB8,0xA8,0xAF,0xD5, + 0xA6,0x51,0x23,0x41,0xDF,0xFE,0xFC,0xDF,0x64,0x49,0x23,0x41,0x5E,0xFC,0xFA,0x57, + 0x44,0x49,0x03,0x41,0x2E,0xB7,0x94,0x9A,0xA4,0x51,0x44,0x49,0xA7,0x2F,0xA7,0xEF, + 0xE5,0x61,0x84,0x51,0x3D,0x29,0xAD,0x3F,0x26,0x6A,0xE5,0x61,0xB9,0xEA,0xA1,0x89, + 0xA8,0x7A,0xC5,0x61,0x2A,0xBD,0x55,0x55,0xA7,0x82,0x06,0x6A,0x02,0xAB,0xB7,0xF5, + 0xE8,0x8A,0x87,0x7A,0x8F,0x2A,0x82,0xB5,0x09,0x8B,0xA7,0x7A,0x8E,0xFF,0xFE,0x7A, + 0x10,0xCD,0x08,0x8B,0x2D,0x2D,0xBD,0xB5,0xF4,0xE5,0x31,0xCD,0x02,0x09,0x0D,0x2D, + 0x35,0xE6,0xD3,0xDD,0x0B,0xA5,0xBF,0x0A,0x55,0xEE,0x35,0xE6,0x3B,0xBF,0x09,0xAA, + 0x55,0xEE,0x14,0xE6,0x80,0xE0,0xFA,0x5E,0x35,0xE6,0xD3,0xDD,0x20,0xA8,0x6A,0x5F, + 0xD4,0xDD,0xF0,0xC4,0x78,0x78,0x5E,0x5E,0x31,0xCD,0xF0,0xC4,0xCF,0xA9,0x23,0x22, + 0x51,0xCD,0x10,0xC5,0xF7,0xB5,0xB7,0xA7,0xF4,0xDD,0x51,0xCD,0x3D,0x35,0x35,0xBD, + 0x56,0xEE,0xF4,0xDD,0x02,0x02,0x03,0x09,0x96,0xEE,0x55,0xEE,0xD5,0xFD,0xEF,0xB5, + 0x96,0xEE,0x56,0xEE,0xB7,0x2B,0x2A,0x02,0xB6,0xF6,0x76,0xEE,0xAF,0xAB,0xAA,0xAB, + 0x96,0xEE,0x76,0xEE,0x80,0x70,0xC0,0xEA,0x55,0xEE,0x96,0xE6,0xBF,0xAB,0xEA,0xAB, + 0x75,0xEE,0x55,0xE6,0x6F,0xE0,0x80,0x2E,0x75,0xEE,0x55,0xE6,0xAD,0xC7,0xFF,0x7F, + 0x75,0xEE,0x55,0xE6,0xAA,0xF0,0x7B,0x7F,0x76,0xEE,0x35,0xE6,0xB2,0xFA,0xBB,0xBB, + 0x76,0xEE,0x35,0xE6,0xA7,0xD7,0x6E,0xEB,0x76,0xEE,0x55,0xE6,0x20,0x22,0x2F,0x3D, + 0x76,0xEE,0x55,0xE6,0xE2,0x5F,0xAE,0xCE,0x35,0xEE,0x55,0xE6,0x75,0xF5,0xFF,0x77, + 0x75,0xEE,0x55,0xE6,0x5F,0x5F,0xEF,0xFD,0x75,0xEE,0x35,0xE6,0x6B,0xFA,0xEA,0xAB, + 0x55,0xE6,0xF4,0xDD,0x72,0xA2,0x80,0xA0,0x56,0xEE,0xD3,0xD5,0x77,0x2A,0x0A,0x88, + 0x56,0xEE,0x92,0xD5,0x57,0xFE,0xE2,0x00,0x35,0xE6,0x92,0xD5,0xD5,0x77,0xBB,0x20, + 0x84,0x61,0x43,0x59,0x7E,0xEA,0xCB,0xAA,0x64,0x59,0x23,0x59,0x03,0x00,0x08,0xFC, + 0x84,0x59,0x43,0x59,0xDF,0xB5,0x15,0xF5,0xA4,0x61,0x43,0x59,0x7B,0xCA,0xEF,0xFF, + 0x84,0x61,0x43,0x59,0xE2,0x3B,0xB7,0x77,0xA4,0x61,0x43,0x59,0xF3,0xBF,0xFE,0xE6, + 0x84,0x61,0x63,0x59,0x55,0x97,0xFD,0xCA,0xA4,0x61,0x63,0x59,0xB2,0xF7,0x7F,0x7A, + 0x83,0x59,0x23,0x51,0xA8,0xAE,0xFE,0xBD,0x84,0x59,0x43,0x51,0xAE,0xBF,0xFD,0x75, + 0xC4,0x61,0x22,0x51,0x0A,0xFF,0x5F,0x7F,0x26,0x72,0x43,0x51,0x02,0xA7,0xD5,0x55, + 0x87,0x7A,0x44,0x51,0x02,0xAA,0xBD,0x75,0x87,0x7A,0xA5,0x61,0x0A,0x20,0xAB,0xFD, + 0x87,0x7A,0x26,0x72,0x08,0x82,0x0B,0xBD,0xA7,0x7A,0x46,0x7A,0xFC,0xEA,0xBA,0x7E, + 0x87,0x7A,0x46,0x72,0xCA,0xCC,0x8B,0xE9,0xA7,0x7A,0x66,0x7A,0xFE,0x77,0x6F,0x71, + 0x87,0x7A,0x46,0x72,0xAB,0x3C,0x1C,0xBA,0xA7,0x82,0x46,0x72,0xEA,0xEA,0xEA,0xDB, + 0xA7,0x82,0x67,0x7A,0xDD,0x77,0xFA,0x4B,0x66,0x82,0x87,0x7A,0xD5,0x9F,0xDF,0xB6, + 0xA7,0x82,0x67,0x7A,0xFD,0xB9,0xAF,0xEB,0xA7,0x82,0x67,0x7A,0x43,0xAB,0x2B,0xAB, + 0xA7,0x82,0x67,0x7A,0xE9,0x0B,0xAF,0xFD,0xA7,0x82,0x66,0x7A,0xFE,0x5E,0x3F,0x3E, + 0xA7,0x82,0x66,0x7A,0x97,0xF7,0xBA,0xD8,0xA7,0x82,0x67,0x7A,0xB8,0xFA,0xBE,0xBE, + 0xAB,0xA3,0x87,0x7A,0xB5,0x2D,0x2B,0x0B,0x0C,0xAC,0xAB,0xA3,0x8D,0xAF,0xBA,0xAB, + 0xEC,0xAB,0xAB,0xA3,0x20,0xB0,0xAA,0xFD,0xEC,0xAB,0xCB,0xA3,0x5E,0x0B,0xED,0x4D, + 0xCB,0xA3,0x08,0x8B,0x68,0x68,0x60,0xE8,0xA7,0x82,0xA5,0x59,0x5E,0x5C,0x7C,0x68, + 0x84,0x51,0x44,0x51,0xE4,0x38,0x9E,0x5E,0x64,0x49,0x02,0x41,0x78,0xE8,0xF0,0x68, + 0x03,0x41,0xC2,0x38,0xE2,0xCA,0xE8,0xC0,0xE2,0x38,0xC2,0x30,0x57,0x56,0x76,0x52, + 0xC2,0x30,0xA2,0x28,0x27,0x0A,0x2C,0x24,0xC3,0x38,0xA2,0x28,0xBA,0xBA,0xB0,0xAA, + 0xE3,0x30,0xA2,0x30,0xFF,0xB2,0xA0,0xE2,0xE3,0x30,0xA2,0x30,0xAB,0xEE,0xEE,0xAA, + 0x65,0x49,0xC3,0x30,0x55,0xD5,0xBD,0x2B,0x65,0x49,0xE3,0x38,0xFD,0xFF,0xEA,0xA0, + 0x44,0x41,0xE3,0x38,0x77,0xFE,0xFB,0xA2,0x24,0x41,0x03,0x39,0xF7,0xFB,0x2C,0x28, + 0x44,0x41,0x03,0x41,0xF2,0xFA,0xEF,0x8D,0x44,0x41,0x03,0x39,0x8B,0xEE,0xB7,0xA7, + 0x44,0x41,0xE3,0x38,0xF6,0xAA,0xAA,0x0A,0x44,0x41,0x03,0x41,0xF3,0x62,0x6D,0x5F, + 0x24,0x41,0xC2,0x38,0x02,0xEA,0xFA,0x7E,0x03,0x41,0xC3,0x38,0xE8,0xBF,0x2F,0x0B, + 0x85,0x49,0xE3,0x38,0x29,0xAF,0xAB,0xBF,0x85,0x49,0x03,0x41,0xF8,0x7A,0xFA,0xFA, + 0x44,0x49,0xE3,0x38,0x55,0xFF,0xEA,0x2A,0x64,0x49,0xE3,0x38,0xDD,0x95,0xF5,0xF8, + 0x43,0x49,0xE3,0x38,0x75,0x7D,0xFE,0x8A,0x23,0x41,0xE3,0x38,0x7D,0xF7,0xE2,0x80, + 0x24,0x41,0xC2,0x30,0x83,0xEA,0x7F,0xB7,0x64,0x49,0x03,0x39,0x03,0x29,0xBD,0xB5, + 0x44,0x41,0x03,0x41,0x56,0x5C,0xF7,0xEF,0x24,0x41,0xC2,0x30,0x82,0xF2,0x78,0xFE, + 0x24,0x41,0xC3,0x38,0xAC,0xBF,0xBD,0xBF,0x24,0x41,0xE3,0x38,0x0B,0x8E,0x29,0x0F, + 0x24,0x41,0xE3,0x38,0xE6,0x88,0x80,0x00,0x24,0x41,0xE3,0x38,0x8F,0xAF,0xAF,0xFB, + 0x64,0x49,0x03,0x41,0xF5,0xFD,0x0D,0x29,0x85,0x51,0x24,0x41,0xF5,0xD5,0xBE,0x2A, + 0x85,0x51,0x03,0x41,0xF7,0xFF,0xEE,0xA0,0x64,0x49,0x23,0x41,0x7E,0x52,0xDB,0x75, + 0x24,0x49,0x03,0x41,0x3D,0xFD,0x69,0xC2,0x65,0x51,0x03,0x41,0xFF,0xAD,0xA9,0xAA, + 0x44,0x49,0x03,0x41,0xEB,0xFE,0x68,0xFE,0x24,0x49,0xC2,0x38,0xF7,0xF6,0xEA,0xEA, + 0x03,0x41,0xE2,0x40,0xA5,0x05,0x25,0x3A,0x85,0x51,0x03,0x41,0xAD,0x3D,0x2D,0x35, + 0xA5,0x51,0x64,0x51,0xAF,0xE2,0x43,0xEA,0x85,0x51,0x23,0x49,0x42,0xC8,0x68,0xA8, + 0x44,0x49,0x03,0x41,0xAA,0x7D,0xD5,0xFA,0x44,0x49,0x03,0x41,0xA6,0x57,0xF7,0x97, + 0x44,0x49,0x03,0x41,0xA8,0xB9,0x7F,0x5F,0x64,0x49,0x03,0x41,0xA0,0x2F,0xAD,0x55, + 0x44,0x49,0xE3,0x38,0xF8,0xE8,0xAA,0xDF,0x64,0x49,0x03,0x41,0x0F,0x29,0x27,0xF5, + 0x64,0x49,0x23,0x41,0xFE,0xBF,0xA0,0xA0,0x64,0x49,0x24,0x41,0xB7,0xFF,0xBE,0xFA, + 0x64,0x49,0x23,0x41,0xFE,0x97,0xF7,0x5A,0x85,0x49,0x23,0x41,0xED,0xCE,0xFF,0x7D, + 0x44,0x41,0x03,0x41,0xAA,0x78,0x7A,0x6E,0x23,0x41,0xE3,0x38,0x0A,0xAF,0x8A,0x00, + 0x64,0x49,0x03,0x41,0xAE,0x89,0x2D,0xAB,0xA4,0x51,0x44,0x49,0xBD,0xF5,0x9F,0x29, + 0x06,0x6A,0x84,0x51,0x2B,0xAF,0x8D,0xAF,0x47,0x72,0xE5,0x61,0xAD,0xCB,0x2B,0x0B, + 0x67,0x72,0xE6,0x61,0x57,0x7E,0xF2,0xA2,0x66,0x72,0xE6,0x69,0x3D,0xAD,0xBF,0x2E, + 0xC8,0x82,0x46,0x72,0x29,0x29,0xAD,0x2D,0xE8,0x82,0xA8,0x82,0x5C,0x7E,0x6B,0x27, + 0x2C,0xAC,0xC8,0x82,0x3D,0xB5,0xF5,0xD5,0xB3,0xDD,0xAB,0x9B,0x02,0x0B,0x09,0x2D, + 0x55,0xEE,0xF4,0xE5,0x0A,0x2F,0xEF,0xFD,0x55,0xEE,0xF4,0xE5,0x28,0xA2,0xFB,0x5F, + 0x35,0xE6,0xB3,0xD5,0xA0,0xEA,0x7E,0x7F,0xF4,0xDD,0x52,0xCD,0xE8,0xE8,0x7A,0x7A, + 0x52,0xCD,0xF0,0xC4,0xFC,0xFA,0x7E,0xFF,0x31,0xCD,0x10,0xC5,0xB5,0xAF,0x09,0x83, + 0x51,0xCD,0x31,0xC5,0xB5,0xEB,0xBF,0x69,0xB2,0xD5,0x30,0xCD,0x2F,0xAF,0xA7,0xBD, + 0x56,0xEE,0xD3,0xDD,0x0B,0x0D,0x2D,0x35,0x96,0xEE,0x56,0xEE,0xB7,0xAB,0xAB,0x2B, + 0xB6,0xF6,0x76,0xEE,0x77,0xFD,0xFF,0x2F,0xB6,0xF6,0x96,0xEE,0xDD,0xB5,0xB7,0xF9, + 0x96,0xEE,0x76,0xEE,0x48,0xF8,0x5C,0x8A,0x96,0xEE,0x35,0xE6,0xAA,0xEA,0x2A,0xA0, + 0x55,0xEE,0x75,0xE6,0xEA,0xEE,0xEA,0xAF,0x55,0xEE,0x75,0xE6,0xAA,0xBA,0xAA,0xA2, + 0x76,0xEE,0x35,0xE6,0xAD,0xAA,0xBB,0xFE,0x55,0xEE,0x55,0xE6,0xFF,0xEF,0xFF,0xFF, + 0x56,0xEE,0x55,0xE6,0xFF,0xFF,0xBF,0x9B,0x75,0xEE,0x35,0xE6,0x8E,0xFA,0xFE,0xAA, + 0x56,0xEE,0x75,0xE6,0x9E,0xAA,0xAA,0xEB,0x76,0xEE,0x55,0xE6,0xDF,0x73,0xFA,0xA0, + 0x96,0xEE,0x55,0xE6,0x55,0x55,0xFD,0xA8,0x96,0xEE,0x35,0xE6,0xDF,0xFF,0xFA,0x82, + 0x96,0xEE,0x35,0xE6,0x5F,0xDF,0xBA,0x0B,0x76,0xEE,0x35,0xE6,0xFF,0xBF,0x20,0x00, + 0x76,0xEE,0x56,0xE6,0x75,0x8F,0x0B,0xAA,0x76,0xEE,0x35,0xE6,0x55,0xFF,0xE8,0x5C, + 0x63,0x59,0x23,0x51,0x00,0xA3,0xAB,0xBF,0x64,0x59,0x23,0x51,0x9E,0xB3,0x2E,0x0F, + 0x85,0x61,0x44,0x59,0xF9,0xDA,0xEF,0x8A,0x84,0x59,0x43,0x59,0xAF,0xCD,0xB5,0xF7, + 0x84,0x61,0x43,0x59,0xDA,0x82,0x6E,0xAB,0x84,0x59,0x43,0x59,0xD4,0xBD,0x9A,0xB8, + 0x84,0x59,0x43,0x59,0x20,0x8B,0x88,0x68,0x84,0x59,0x22,0x51,0xCA,0x7A,0x7E,0x57, + 0x43,0x51,0x22,0x51,0x8B,0xDF,0xEA,0x48,0x63,0x51,0x22,0x51,0xDE,0x5F,0xEB,0x6B, + 0x43,0x51,0x02,0x49,0xBA,0xAB,0x7F,0xD9,0x44,0x59,0x03,0x49,0x97,0x3F,0xA7,0x2F, + 0x64,0x51,0x02,0x49,0x0B,0xAE,0xEA,0x9A,0x85,0x61,0x23,0x51,0x2A,0x9F,0xBF,0x8D, + 0x26,0x72,0x43,0x59,0x02,0xEB,0xF5,0xFD,0x66,0x7A,0x84,0x61,0x80,0xAF,0xF5,0x55, + 0x66,0x7A,0xA4,0x61,0x00,0x0A,0x2B,0xF5,0x87,0x7A,0x26,0x7A,0x22,0xEA,0x0A,0xB9, + 0xA7,0x82,0x67,0x7A,0xFF,0x7E,0x77,0xD7,0x87,0x7A,0x67,0x7A,0x25,0x00,0x2B,0x59, + 0xA7,0x82,0x66,0x7A,0xEB,0x9A,0xF8,0xEB,0xA8,0x82,0x67,0x7A,0xA1,0x6F,0xA9,0x0F, + 0xA8,0x82,0x46,0x7A,0xC2,0x87,0x2E,0xFE,0xA8,0x82,0x66,0x7A,0x7E,0xEC,0xA8,0xAA, + 0xC8,0x82,0x87,0x7A,0x5D,0xFB,0xAF,0xB5,0xA7,0x82,0x87,0x7A,0xB7,0xDA,0x96,0x16, + 0xC8,0x82,0x66,0x7A,0xDC,0xFE,0xFE,0xEE,0x8B,0xA3,0x87,0x82,0xD5,0xF5,0x9D,0x3F, + 0xEC,0xAB,0x4A,0x93,0x2D,0x09,0x8B,0xA2,0xEB,0xAB,0xAB,0xA3,0xAA,0xBE,0x76,0x5F, + 0xCC,0xA3,0xAB,0xA3,0x95,0x95,0x6E,0xAB,0xEB,0xAB,0xAB,0xA3,0xCA,0xAD,0xD9,0x57, + 0xCB,0xA3,0x08,0x8B,0xE0,0xC0,0x68,0x60,0xE8,0x82,0x84,0x59,0xF8,0xF8,0x78,0x7E, + 0x84,0x59,0x23,0x49,0x7C,0xD8,0x7A,0x50,0x43,0x49,0xE2,0x40,0xE0,0xE8,0xBF,0x7F, + 0x44,0x49,0xE2,0x38,0x7E,0xAA,0x8A,0x0A,0x03,0x41,0xC2,0x30,0x57,0x7F,0x7E,0x78, + 0xC2,0x30,0xA1,0x30,0x0E,0x0B,0x3F,0x15,0xE3,0x38,0xA2,0x28,0xEF,0xBA,0xF8,0xF0, + 0xC2,0x30,0xA2,0x28,0x02,0x0A,0x2A,0x03,0x03,0x39,0xC2,0x30,0xA3,0x3B,0xBF,0xBF, + 0x44,0x41,0x03,0x39,0xAB,0xDD,0xBF,0x2B,0x44,0x49,0x24,0x41,0xC2,0x6D,0xAB,0x02, + 0x44,0x49,0x24,0x41,0xC9,0xEA,0xE0,0xC0,0x44,0x41,0x03,0x39,0xAA,0xEB,0x7F,0xEE, + 0x44,0x41,0x03,0x41,0x36,0xBC,0x2D,0x00,0x44,0x49,0xE3,0x38,0xAA,0xBA,0x68,0xAA, + 0x45,0x41,0xE3,0x38,0x8A,0xBE,0x5F,0x5F,0x24,0x41,0xC2,0x38,0xF8,0xE8,0xFA,0xA7, + 0x44,0x49,0xE3,0x38,0xF5,0xD5,0xA5,0x0F,0x64,0x49,0xE3,0x38,0xF7,0xBF,0xAA,0xAA, + 0x44,0x49,0x03,0x41,0x17,0x9A,0x58,0xFA,0x64,0x51,0x03,0x41,0xFA,0xA2,0x0F,0x0D, + 0x85,0x51,0x24,0x49,0xAD,0xBF,0xBF,0x3B,0x64,0x49,0x24,0x41,0x7E,0xEC,0x78,0x70, + 0x85,0x51,0x23,0x41,0xFB,0xEA,0x2D,0xA5,0x85,0x51,0x23,0x41,0x57,0x7F,0xEA,0xCA, + 0x24,0x41,0xC2,0x38,0xF6,0xB7,0xFE,0xE8,0x44,0x41,0xC2,0x38,0x0B,0x8A,0x0B,0xA9, + 0x44,0x41,0x23,0x41,0x57,0x5F,0xEB,0x55,0x23,0x41,0xE3,0x38,0xDC,0x68,0xFA,0xFE, + 0x24,0x41,0xE3,0x38,0xBD,0xDF,0x79,0xFA,0x24,0x41,0x03,0x39,0x0A,0x09,0x0D,0x05, + 0x45,0x49,0xE3,0x38,0xEA,0x6A,0x7B,0xF7,0x03,0x41,0xE3,0x38,0x37,0x09,0x8D,0x2F, + 0x85,0x49,0x03,0x41,0x25,0x3D,0xBD,0x27,0xC6,0x59,0x64,0x49,0xFD,0xA9,0xCB,0x03, + 0xA5,0x51,0x23,0x41,0xF0,0x7E,0xDE,0xFA,0x44,0x49,0xE2,0x40,0xDA,0x5E,0x5C,0xD8, + 0x24,0x49,0xE2,0x40,0x2B,0x37,0x3F,0xBB,0x85,0x51,0x24,0x49,0xFF,0xFD,0xAA,0x81, + 0x65,0x51,0x03,0x41,0x7A,0xC2,0xE8,0xE0,0x44,0x49,0x03,0x41,0x7E,0xDE,0xAF,0xAA, + 0x64,0x49,0x03,0x41,0xD5,0x77,0xFA,0xE2,0x85,0x51,0x23,0x49,0x1D,0xAB,0xAD,0xAD, + 0x85,0x51,0x44,0x49,0xE8,0x7A,0xDC,0xE2,0x64,0x49,0x03,0x41,0xFF,0xFF,0x7B,0xFC, + 0x64,0x49,0x03,0x41,0xAB,0x23,0x2B,0x9A,0x64,0x49,0x03,0x41,0xD7,0xFE,0x88,0xAB, + 0x23,0x41,0x03,0x39,0x80,0x82,0xEE,0xC4,0x23,0x41,0xE3,0x38,0xAE,0x9F,0xFB,0x78, + 0x23,0x41,0xC2,0x38,0xB8,0xBF,0xEF,0xA5,0x65,0x49,0xE3,0x38,0xBF,0x37,0xF5,0xD7, + 0x85,0x49,0x24,0x41,0xFA,0x2B,0xAF,0xF5,0x64,0x49,0x03,0x41,0x28,0xAA,0xEA,0xFA, + 0x64,0x49,0x03,0x39,0xB2,0xFA,0x7A,0x7D,0x44,0x41,0xE2,0x38,0x2A,0x88,0xAF,0xB7, + 0x44,0x41,0x03,0x41,0xFE,0xE2,0xEE,0x65,0x44,0x49,0x03,0x41,0xA9,0x0B,0x07,0xB5, + 0xA5,0x51,0x23,0x41,0xFD,0xBB,0x2B,0xAB,0xC5,0x59,0x44,0x49,0xA9,0x25,0xB8,0xC8, + 0x27,0x6A,0x85,0x51,0xAF,0x2B,0xBD,0xFD,0x67,0x72,0xE6,0x61,0xEB,0xAA,0x21,0x25, + 0xA8,0x7A,0x26,0x6A,0xE5,0xFF,0xAE,0x0A,0xA8,0x82,0x26,0x6A,0xD5,0xFF,0x0E,0x22, + 0xA8,0x82,0x67,0x72,0xBF,0xDB,0xFB,0x6A,0xE9,0x82,0x67,0x7A,0xAF,0xAB,0xAD,0xAF, + 0x09,0x8B,0xA8,0x82,0x0B,0x2A,0x16,0x3D,0xEF,0xC4,0x29,0x93,0x2D,0xB5,0xB5,0xF5, + 0xF4,0xE5,0x6E,0xB4,0x02,0x02,0x0B,0x2D,0x15,0xE6,0xD4,0xDD,0xE8,0xFA,0x7A,0xFB, + 0x15,0xE6,0xD4,0xDD,0x7F,0xBF,0x83,0x03,0xD4,0xDD,0x31,0xC5,0x70,0x70,0xD0,0x58, + 0x31,0xCD,0xF0,0xC4,0xAA,0xAA,0xEE,0x7D,0x31,0xCD,0xF0,0xBC,0xAA,0xEA,0x3B,0xAD, + 0x51,0xCD,0x10,0xCD,0x83,0x29,0x6E,0xAA,0x72,0xCD,0x31,0xCD,0xA7,0xCF,0xBF,0xAD, + 0x15,0xE6,0x72,0xD5,0x09,0x09,0x2D,0x25,0x96,0xEE,0x35,0xE6,0x0B,0x2A,0x0B,0x09, + 0xB6,0xF6,0x76,0xEE,0x2E,0xBF,0xB9,0xFF,0xB7,0xF6,0x96,0xEE,0xBF,0xAF,0xD5,0x55, + 0xB6,0xF6,0x76,0xEE,0xF7,0xFF,0xFF,0xAB,0x96,0xEE,0x55,0xE6,0xB0,0x6A,0x2A,0x00, + 0xB6,0xF6,0x55,0xE6,0xFF,0xFF,0xAF,0x22,0xB6,0xF6,0x55,0xE6,0xF5,0xFF,0xAA,0xA2, + 0xB6,0xF6,0x55,0xE6,0x77,0xFF,0xAA,0x20,0xB6,0xF6,0x76,0xEE,0xD5,0xBF,0xA8,0xA2, + 0xB7,0xF6,0x76,0xEE,0x57,0xBA,0xAA,0xE8,0x96,0xF6,0x76,0xEE,0x39,0xAA,0x28,0xD7, + 0xB6,0xF6,0x55,0xE6,0xBE,0x8A,0xEA,0x7E,0x96,0xEE,0x35,0xE6,0x20,0x02,0x2A,0x7D, + 0xB7,0xF6,0x15,0xE6,0x2A,0xA8,0xEA,0x7F,0xB7,0xF6,0x15,0xDE,0xA0,0xA8,0xEE,0x55, + 0x76,0xEE,0xB3,0xD5,0x00,0x00,0xAA,0x7F,0x56,0xEE,0x72,0xCD,0x00,0x20,0xFA,0x57, + 0x55,0xEE,0x93,0xCD,0x80,0xFE,0x77,0x55,0xF4,0xDD,0x72,0xCD,0xC0,0x7B,0x55,0x55, + 0x84,0x59,0x22,0x51,0xFF,0xEA,0x63,0x7B,0x64,0x59,0x22,0x51,0x3F,0x0F,0x25,0x2F, + 0x84,0x61,0x64,0x59,0xFB,0x2A,0xE9,0x7F,0x84,0x61,0x23,0x51,0xFC,0xAC,0xF8,0xE0, + 0x84,0x59,0x43,0x59,0xAA,0xAB,0x2B,0x07,0xA4,0x61,0x43,0x51,0xAA,0xAA,0x88,0x7E, + 0x84,0x59,0x22,0x51,0x6A,0xE8,0xAF,0xB9,0x84,0x59,0x22,0x51,0xD7,0xF7,0x3F,0xEF, + 0x43,0x51,0x22,0x51,0x58,0x3C,0xD8,0x20,0x43,0x51,0x22,0x49,0x78,0x7A,0x0D,0x2E, + 0x63,0x59,0x22,0x51,0x5D,0x75,0xA7,0x2A,0x64,0x59,0x23,0x51,0xFD,0xD9,0xFA,0xAA, + 0x84,0x61,0x23,0x51,0x57,0xF7,0xE7,0xAF,0x84,0x61,0x64,0x59,0x19,0xA9,0xB9,0x81, + 0xA4,0x61,0x64,0x59,0xB5,0xEF,0xFD,0xFB,0x84,0x61,0x64,0x59,0x7A,0x2E,0xB4,0x1E, + 0xA4,0x61,0x64,0x59,0xFF,0x7D,0x6E,0xEB,0x06,0x72,0x63,0x59,0x0B,0xEB,0xFD,0x75, + 0x67,0x7A,0x63,0x59,0x02,0xAB,0xF5,0x57,0x67,0x7A,0x84,0x61,0x00,0x00,0x0B,0xF5, + 0x88,0x82,0x06,0x72,0x08,0x8A,0xAA,0xA9,0x67,0x82,0x87,0x7A,0x77,0xDC,0xDE,0xFB, + 0x87,0x82,0x67,0x7A,0x5C,0xFF,0xBF,0x0B,0xA7,0x82,0x67,0x7A,0xAA,0xA5,0xB6,0xA6, + 0xA7,0x82,0x67,0x7A,0x2E,0x2A,0x6B,0xFF,0xA7,0x82,0x87,0x7A,0x2D,0x05,0xFD,0x7E, + 0x08,0x8B,0x87,0x7A,0xD5,0xFF,0xBF,0x3D,0xEC,0xAB,0xE8,0x8A,0xA5,0x2D,0x2B,0x0B, + 0xEB,0xAB,0xAB,0xA3,0x6A,0xFA,0xD0,0xBF,0xCB,0xA3,0x8A,0xA3,0xAA,0xBF,0xEF,0xA8, + 0xCB,0xA3,0x6C,0xA3,0x8A,0xA8,0x8E,0xAA,0xCB,0xA3,0x8B,0xA3,0x88,0xE9,0xAB,0x8B, + 0xCB,0xA3,0x49,0x93,0x78,0xA2,0x88,0xAA,0x29,0x8B,0x06,0x6A,0x5E,0x78,0x70,0xE0, + 0xE6,0x61,0x43,0x51,0x5E,0xEC,0xF8,0xE8,0x64,0x51,0xC2,0x38,0x7E,0x7E,0x78,0xE0, + 0x23,0x41,0xC2,0x38,0x0B,0xAF,0xAF,0xF7,0x03,0x41,0xC2,0x38,0x70,0x6F,0x7E,0x57, + 0xE3,0x38,0xA1,0x30,0x95,0xBF,0xFA,0xBA,0xE2,0x38,0xA2,0x30,0x7E,0xFF,0xAB,0x2A, + 0x03,0x39,0xA2,0x30,0xD5,0xD7,0xFB,0xBC,0x23,0x41,0xE3,0x38,0xF5,0xB5,0xAD,0xBD, + 0x64,0x49,0x03,0x41,0x2D,0x2D,0x3F,0xBF,0xA6,0x51,0x44,0x49,0x57,0x5F,0x7F,0xE3, + 0x64,0x49,0x24,0x41,0xEB,0xAA,0xBE,0xBA,0x85,0x49,0x24,0x41,0xB7,0xD7,0x8B,0x0B, + 0x85,0x51,0x24,0x41,0xFA,0x7E,0xD8,0x58,0x44,0x41,0xE3,0x40,0x8E,0x3B,0x2B,0xA9, + 0x44,0x49,0xE3,0x38,0x7E,0xD8,0xEE,0xAA,0x23,0x41,0xE2,0x38,0xA5,0x3F,0x9E,0x3F, + 0xA5,0x51,0x03,0x41,0x2D,0x2F,0x2B,0x2F,0xA5,0x51,0x23,0x49,0x78,0x78,0xE0,0xA0, + 0x64,0x51,0x03,0x49,0xFF,0xAD,0xF6,0xFC,0x85,0x51,0x24,0x49,0xF5,0x65,0xAF,0x0F, + 0xA5,0x51,0x64,0x51,0x35,0xB5,0xDF,0x98,0xA5,0x59,0x24,0x49,0x7C,0xF8,0xE2,0x8A, + 0x64,0x51,0x24,0x49,0x17,0xD7,0xBE,0xE8,0xA5,0x51,0x44,0x49,0xEF,0x2F,0x3D,0x37, + 0x85,0x51,0x03,0x39,0x5F,0x7E,0x58,0x78,0x24,0x41,0xC2,0x38,0x8A,0xAA,0xEA,0x7F, + 0x24,0x41,0xE3,0x38,0xBE,0xBD,0xF5,0xD5,0x03,0x39,0xA2,0x30,0xA0,0x08,0x2A,0x28, + 0x23,0x41,0xE3,0x38,0xDF,0xBF,0xEA,0x72,0x23,0x41,0xE3,0x38,0x6A,0xFC,0xEE,0xFF, + 0x23,0x41,0xE2,0x38,0xCF,0x03,0x8A,0xDA,0x24,0x41,0xE3,0x38,0x97,0x14,0xBB,0x79, + 0x85,0x51,0xE3,0x38,0xA7,0xBF,0xEF,0xB5,0xC6,0x59,0x65,0x49,0x2B,0xAF,0xAD,0xFF, + 0x84,0x51,0x44,0x49,0x7C,0x54,0x54,0x7F,0x44,0x49,0xE2,0x40,0xF2,0x6E,0xFE,0x7E, + 0x03,0x41,0xE2,0x40,0x02,0x02,0x3B,0xA9,0x44,0x49,0x03,0x41,0x0B,0xF6,0x5F,0x7D, + 0x64,0x49,0x24,0x49,0x58,0xEF,0xBD,0xAD,0x85,0x51,0x23,0x49,0xB9,0xA9,0x2B,0x02, + 0x85,0x51,0x23,0x41,0xF2,0xEA,0x78,0x5E,0x64,0x49,0x23,0x49,0x85,0xAD,0x0B,0x2B, + 0xA5,0x51,0x44,0x41,0xEB,0x2F,0xAD,0xF5,0x85,0x49,0x44,0x49,0x56,0x7A,0x7A,0x57, + 0x44,0x41,0x03,0x41,0xD6,0x5F,0xFE,0xAC,0x64,0x49,0x03,0x39,0x8F,0xA7,0xAD,0xB5, + 0x44,0x41,0xE2,0x38,0xE8,0xAC,0xB8,0xB4,0x23,0x41,0xE2,0x38,0x42,0xC0,0xE0,0x7E, + 0x03,0x39,0xC2,0x38,0x25,0xBF,0x2B,0x82,0x23,0x41,0x03,0x39,0xAD,0x67,0x3D,0x09, + 0x44,0x41,0x03,0x39,0xBA,0xFF,0xEB,0x22,0x44,0x41,0x03,0x41,0xA2,0xCA,0x7B,0xEA, + 0xE2,0x48,0x03,0x39,0xF5,0xDD,0x75,0xD7,0x23,0x41,0xC2,0x38,0xA7,0x2F,0xEF,0xAA, + 0x43,0x41,0x03,0x41,0x65,0xEB,0xFF,0xA9,0x64,0x49,0x23,0x41,0xB7,0x95,0xB5,0x75, + 0x64,0x49,0x23,0x41,0x02,0x00,0x02,0xAF,0xA5,0x51,0x44,0x49,0x00,0x2F,0x9E,0xB3, + 0xE7,0x61,0x85,0x51,0xDB,0xEA,0x2B,0x2B,0x27,0x6A,0xA4,0x59,0x25,0x95,0xEF,0xE2, + 0xA8,0x7A,0xC5,0x59,0x0A,0x03,0xBF,0xBD,0xC9,0x82,0x66,0x72,0x02,0x22,0xAB,0xE9, + 0xA8,0x7A,0x67,0x7A,0x68,0x6A,0x68,0x78,0xA7,0x7A,0x46,0x72,0x0A,0x2F,0x2F,0x77, + 0x09,0x8B,0xA7,0x7A,0x3D,0xEF,0xAD,0xBF,0x8B,0x9B,0xE8,0x82,0x2D,0x3D,0xFD,0x55, + 0xD3,0xDD,0x6A,0x93,0x2B,0x2D,0xAD,0xB5,0x14,0xE6,0x72,0xD5,0x8A,0x0A,0x0B,0x09, + 0x15,0xE6,0xB3,0xDD,0x02,0x80,0xA0,0x70,0xB3,0xDD,0xF0,0xC4,0x58,0x7C,0x7C,0x5E, + 0x10,0xC5,0xCF,0xBC,0xEA,0x6A,0xFE,0xB6,0x30,0xCD,0xD0,0xBC,0xAB,0xA9,0xAF,0x2B, + 0x31,0xCD,0x10,0xC5,0x42,0xC8,0xB3,0x83,0x51,0xCD,0x10,0xC5,0x0B,0x8F,0x0F,0x89, + 0x14,0xE6,0x51,0xCD,0x35,0x35,0xD5,0xD5,0x96,0xF6,0xF4,0xDD,0x0A,0x0B,0x0B,0x2D, + 0xD7,0xF6,0x76,0xEE,0xBF,0xAA,0xA8,0x75,0xB7,0xF6,0x55,0xEE,0x08,0x00,0x28,0x7F, + 0xB7,0xF6,0x35,0xE6,0x00,0x00,0xA0,0x57,0xB7,0xF6,0x35,0xE6,0x02,0xA8,0xEA,0x5D, + 0xB7,0xF6,0x14,0xDE,0x82,0xA2,0xFF,0x7D,0x96,0xEE,0xF4,0xDD,0x00,0x88,0xFE,0x77, + 0x96,0xEE,0xB3,0xD5,0x00,0x20,0xAA,0x5F,0x76,0xEE,0xB3,0xD5,0x00,0x00,0xEA,0x57, + 0x96,0xEE,0x73,0xCD,0x00,0xA8,0xAA,0x57,0x55,0xE6,0x51,0xC5,0x00,0x88,0xFA,0x57, + 0x55,0xE6,0xF1,0xBC,0x80,0xAA,0xFE,0x77,0x15,0xE6,0xD0,0xBC,0x00,0xAA,0xFF,0x55, + 0xF4,0xDD,0x8F,0xB4,0x00,0xAA,0xDF,0x55,0xF4,0xDD,0xB0,0xB4,0xA8,0xFE,0x55,0x55, + 0x72,0xCD,0x4E,0xAC,0x20,0xBA,0xF7,0xF5,0x73,0xC5,0xD0,0xB4,0x2A,0xBF,0x35,0x29, + 0x93,0xCD,0x52,0xC5,0x82,0x8F,0xB3,0x7A,0xB3,0xD5,0x11,0xC5,0xEA,0xE2,0xFA,0x7E, + 0x43,0x59,0x23,0x51,0x5A,0xFA,0xE8,0x80,0x64,0x59,0x23,0x51,0x2B,0x0A,0x09,0x00, + 0x84,0x61,0x44,0x59,0x5E,0x5E,0xBE,0x2A,0x84,0x61,0x43,0x59,0xE7,0xDE,0xF8,0xFE, + 0x84,0x59,0x43,0x51,0xBA,0xA8,0xA2,0xD0,0x64,0x59,0x23,0x51,0x60,0x7A,0xDA,0x3A, + 0x84,0x59,0x23,0x51,0x8D,0xA5,0xBD,0xDD,0x84,0x59,0x22,0x51,0x7F,0x8B,0xBE,0xFF, + 0x63,0x59,0x43,0x51,0x9D,0x6C,0xA6,0xA9,0x63,0x59,0x22,0x51,0x5B,0x5C,0x5E,0xDE, + 0x63,0x59,0x02,0x49,0x2A,0xBF,0xBD,0xFB,0x64,0x59,0x23,0x51,0x5B,0x5F,0xBF,0xA3, + 0x84,0x61,0x43,0x51,0xED,0xA9,0xAA,0xEA,0x84,0x61,0x63,0x59,0x8A,0x7A,0xF0,0x64, + 0xA4,0x61,0x63,0x59,0x5A,0x8E,0x6F,0x83,0x84,0x61,0x63,0x59,0x11,0x9F,0x2A,0x20, + 0xA4,0x61,0x63,0x59,0xDA,0xFB,0xF0,0x50,0xA5,0x61,0x22,0x51,0xEA,0xE8,0x7E,0xFA, + 0x63,0x59,0x43,0x59,0x3C,0x7A,0xE0,0xC2,0x84,0x61,0x23,0x51,0x2B,0xFF,0xFF,0x7F, + 0xE5,0x69,0x03,0x51,0x02,0xAE,0xFF,0x7F,0x67,0x7A,0x43,0x59,0x00,0x2B,0xFD,0xD5, + 0x67,0x7A,0x84,0x59,0x00,0x00,0x0A,0xFD,0xC7,0x82,0x06,0x72,0xAA,0x2B,0xBB,0xFD, + 0xA7,0x82,0x66,0x7A,0xFD,0x0B,0x8B,0xBD,0xA7,0x82,0x66,0x7A,0xEA,0xF8,0xF2,0xE0, + 0x0B,0xAC,0xC8,0x82,0xD5,0xF5,0xB5,0x2D,0xEC,0xAB,0x8A,0x9B,0x0D,0x03,0xA0,0xFA, + 0xCB,0xA3,0x6A,0x9B,0x08,0xA8,0xFC,0xE7,0xCB,0xA3,0x6A,0x9B,0x8A,0xEF,0x77,0xD7, + 0xAB,0xA3,0x6A,0x9B,0xA8,0xEB,0xCF,0xE9,0xCC,0xA3,0x6A,0x9B,0x0F,0xAB,0xEB,0x5F, + 0xAB,0xA3,0x2A,0x93,0x20,0xA8,0xFA,0x7F,0x6A,0x93,0x05,0x6A,0x78,0x78,0x58,0xFE, + 0x26,0x6A,0xA4,0x59,0x57,0x56,0xFC,0xE8,0xA5,0x59,0x02,0x41,0xDC,0x58,0x78,0xF8, + 0x03,0x41,0xA2,0x38,0xFC,0x7E,0x78,0xE8,0xE3,0x38,0xA2,0x30,0x3B,0xBD,0xAA,0xE8, + 0xE3,0x38,0xA2,0x30,0xBE,0x2A,0x0F,0x2B,0x24,0x41,0xE3,0x38,0x57,0xB7,0x2F,0x3F, + 0x24,0x41,0xC2,0x30,0xB7,0xAB,0xB2,0xA0,0xE3,0x40,0x24,0x39,0xAA,0xA7,0xBA,0xBB, + 0x44,0x41,0xE3,0x38,0x2F,0xB5,0xDF,0x3F,0x85,0x51,0x23,0x41,0x03,0x29,0xBD,0xAF, + 0x85,0x51,0x03,0x39,0xAA,0xA0,0x60,0x7A,0x44,0x49,0x03,0x41,0x08,0xBE,0xFD,0x57, + 0x44,0x49,0x03,0x41,0x78,0x56,0x55,0xFB,0x24,0x41,0xE2,0x38,0x27,0x2E,0xEB,0xE2, + 0x23,0x41,0xE2,0x38,0x80,0xE2,0xFA,0x02,0x65,0x49,0xE2,0x38,0x95,0x95,0xBD,0xAF, + 0xC6,0x51,0x44,0x49,0xA5,0x7F,0xEA,0x8B,0xA5,0x51,0x44,0x49,0xC2,0xC9,0xE3,0x6A, + 0x85,0x51,0x23,0x49,0xDE,0xBA,0x2F,0xB7,0xA5,0x59,0x64,0x49,0x9D,0xFB,0xEA,0xAB, + 0xA5,0x51,0x44,0x49,0xE8,0xFA,0xBE,0x7F,0xC5,0x61,0x44,0x49,0xAF,0x2D,0x35,0x17, + 0x06,0x6A,0x64,0x51,0x7F,0x7A,0xE2,0x0A,0xC6,0x59,0x64,0x49,0xF5,0x77,0xFE,0xF0, + 0xA5,0x51,0x03,0x41,0x58,0x72,0xBF,0xA8,0x23,0x41,0xC2,0x38,0x57,0x57,0x78,0x78, + 0xE3,0x38,0x81,0x30,0xA2,0xBA,0xBE,0xA7,0x03,0x39,0xC2,0x30,0xAF,0xF5,0xAF,0x3B, + 0x23,0x41,0xE3,0x38,0x7A,0xFB,0x77,0xFD,0x03,0x41,0xE3,0x38,0xED,0xB5,0x55,0x38, + 0x23,0x41,0xC2,0x38,0xFA,0x6B,0xAF,0x2E,0x23,0x41,0xE3,0x38,0x7B,0xAF,0x2E,0x2B, + 0x64,0x49,0xE3,0x38,0x2D,0x8F,0xAE,0xAB,0x64,0x51,0x23,0x49,0x0A,0x0E,0xAB,0x73, + 0x85,0x51,0x24,0x49,0xE2,0xEB,0x7B,0xFF,0x44,0x49,0x03,0x41,0x74,0xD4,0xAA,0x2A, + 0x44,0x49,0x03,0x41,0x75,0x6F,0x2A,0x20,0x64,0x51,0x03,0x41,0xB5,0xBD,0x3B,0x2A, + 0x84,0x51,0x44,0x49,0xBD,0xAF,0xAF,0x2E,0xA5,0x51,0x64,0x49,0xCB,0x6A,0xC2,0xC0, + 0x64,0x49,0x03,0x41,0xFC,0xF8,0xE8,0x80,0x64,0x49,0x03,0x41,0x2B,0x2B,0x09,0x3F, + 0x84,0x49,0x03,0x41,0x7F,0x7E,0x7E,0xFC,0x44,0x49,0x03,0x41,0x2E,0xFE,0x7A,0x5F, + 0x44,0x41,0xE2,0x38,0x88,0x2E,0xA7,0x57,0x44,0x41,0xE3,0x38,0xBA,0xFA,0xDC,0xFF, + 0x23,0x41,0xE3,0x38,0xFC,0x5F,0xFF,0xAF,0x44,0x41,0xE2,0x38,0xDF,0x77,0x9F,0xE2, + 0x03,0x39,0xC2,0x38,0x29,0xA6,0xAA,0x02,0x84,0x49,0x03,0x39,0xAD,0x0D,0xAD,0xE7, + 0x64,0x49,0x03,0x39,0xAE,0xA8,0x80,0xA8,0x65,0x49,0x24,0x41,0x7E,0x72,0xEB,0xFD, + 0x43,0x41,0xC2,0x38,0xFE,0xB6,0xAA,0xA8,0x65,0x49,0xE2,0x38,0x97,0xB7,0x8B,0x0F, + 0x44,0x41,0x03,0x41,0x0D,0x09,0xC0,0xA0,0x44,0x49,0x23,0x41,0xEC,0xDE,0xD7,0x96, + 0x64,0x49,0x23,0x41,0x7D,0xFF,0xEE,0xC0,0x85,0x51,0x02,0x41,0x2B,0xDD,0xF7,0x5E, + 0xC6,0x59,0x44,0x49,0x2B,0xBF,0xBD,0x95,0xE6,0x61,0x84,0x59,0x02,0xAE,0xDF,0x7A, + 0x26,0x6A,0xA4,0x59,0x2F,0x8B,0x8B,0x25,0xA8,0x7A,0x05,0x62,0x82,0xA9,0xFD,0xD7, + 0x67,0x7A,0x26,0x6A,0xA2,0xAB,0xBF,0xFB,0x47,0x72,0x06,0x6A,0xE8,0x6C,0xFC,0x54, + 0xC8,0x82,0x06,0x6A,0x0A,0x0D,0xB5,0xB5,0xE8,0x82,0x87,0x7A,0x28,0x22,0x8B,0x37, + 0x6E,0xB4,0xC8,0x82,0x2D,0xBD,0xF5,0xD5,0xD3,0xDD,0x2D,0xAC,0x02,0x0B,0x2D,0xAD, + 0xF4,0xE5,0x51,0xCD,0xA0,0xE2,0x7A,0xEA,0x52,0xCD,0xD0,0xBC,0xF8,0xFE,0xDA,0x7C, + 0x10,0xC5,0xD0,0xBC,0xF6,0xAA,0x9A,0xD7,0x10,0xC5,0xF0,0xC4,0x2D,0x0F,0x29,0x05, + 0x31,0xCD,0x10,0xC5,0x02,0x8E,0x1B,0xAB,0x51,0xCD,0x10,0xC5,0xAF,0x27,0xAF,0xAB, + 0x51,0xCD,0x31,0xC5,0x28,0x0E,0x2A,0xFC,0x35,0xE6,0x52,0xCD,0x0B,0xAF,0xAD,0xAD, + 0x35,0xE6,0x10,0xC5,0x00,0xAA,0x7F,0x5E,0x14,0xE6,0xD0,0xBC,0x00,0xAA,0xFF,0x75, + 0x14,0xE6,0xD0,0xBC,0x20,0xEA,0x7F,0x55,0xF4,0xDD,0xAF,0xBC,0x00,0xAA,0xFF,0x55, + 0xB3,0xD5,0xB0,0xBC,0x00,0xA2,0xFF,0x55,0xB3,0xD5,0x8F,0xB4,0x00,0xAA,0xDF,0x55, + 0x92,0xD5,0x6F,0xAC,0x00,0xAA,0xFF,0x55,0x72,0xCD,0x6E,0xAC,0x00,0xAA,0xFF,0x5D, + 0x52,0xC5,0x4E,0xAC,0x00,0xAA,0xFE,0x57,0x31,0xC5,0x2E,0xA4,0x2A,0xBA,0xF7,0x5D, + 0xF0,0xBC,0x2D,0xA4,0xE0,0xFA,0xFF,0xD5,0x8F,0xB4,0x2D,0xA4,0xC8,0xE8,0xBA,0xB7, + 0x52,0xC5,0x2D,0xA4,0xFD,0xBD,0xAF,0x2F,0xD4,0xD5,0xD0,0xB4,0xF5,0xAF,0x0A,0x02, + 0xD4,0xD5,0xF0,0xB4,0xD5,0xEE,0xA8,0xA0,0x93,0xCD,0x31,0xBD,0xB5,0xAF,0x8A,0xAE, + 0x73,0xCD,0xF0,0xB4,0xA0,0xE2,0xFA,0x5F,0x52,0xC5,0xB0,0xB4,0xE2,0xFA,0x7E,0x5F, + 0x84,0x59,0x43,0x59,0xD7,0xE5,0xBF,0xCD,0x84,0x59,0x43,0x51,0x81,0x02,0x8C,0xAA, + 0x84,0x59,0x64,0x59,0x41,0xE0,0x2B,0x1A,0x84,0x59,0x43,0x51,0x8A,0x8A,0xF8,0xD8, + 0x64,0x59,0x23,0x51,0x1E,0x2E,0x2A,0xFA,0x84,0x59,0x22,0x51,0xCE,0xEA,0xFA,0x97, + 0x64,0x59,0x23,0x49,0xFD,0x8A,0xCA,0xAA,0x63,0x59,0x02,0x49,0x9E,0xAB,0x02,0x0A, + 0x43,0x51,0x22,0x51,0x82,0xFF,0xF8,0xD8,0x43,0x59,0x22,0x49,0xEB,0xAD,0xEB,0xEE, + 0x63,0x59,0x23,0x51,0xD5,0xF5,0xAF,0x0B,0x84,0x61,0x43,0x59,0x87,0x23,0x8B,0xAF, + 0x84,0x61,0x43,0x59,0x4A,0x80,0xC0,0x02,0xA4,0x61,0x63,0x59,0xFF,0x5B,0xF1,0x80, + 0xA4,0x61,0x63,0x59,0xAB,0x9D,0xFF,0xFA,0xA5,0x61,0x43,0x59,0x2A,0x0E,0x28,0x28, + 0xA4,0x61,0x43,0x59,0xF8,0x7E,0x6E,0xEF,0x63,0x59,0x43,0x59,0x62,0x20,0x28,0x8A, + 0x63,0x59,0x23,0x51,0xA0,0xA0,0xA8,0x76,0x64,0x59,0x23,0x51,0x5A,0xBA,0xEE,0xE9, + 0x23,0x59,0x43,0x51,0xAA,0xDE,0xFE,0xAF,0x64,0x59,0x03,0x51,0x0A,0xEA,0xBB,0x5F, + 0x84,0x59,0x02,0x51,0xAF,0xF7,0xFF,0xFD,0xC5,0x69,0x23,0x51,0x0A,0xFF,0x55,0x57, + 0x87,0x82,0x23,0x51,0x22,0x3F,0xF5,0x55,0xC8,0x8A,0x64,0x59,0x22,0x8A,0x2F,0x25, + 0xEB,0xAB,0xE7,0x82,0x2D,0x2B,0x0B,0x0A,0xEC,0xAB,0x8A,0x9B,0xF8,0x68,0x6A,0x7E, + 0x8A,0x9B,0x6A,0x9B,0xB0,0x0C,0x07,0x7F,0xAB,0x9B,0x4A,0x9B,0xFF,0x7F,0xF6,0xAF, + 0xAB,0x9B,0x4A,0x93,0xAB,0xAF,0xBE,0x2E,0xAB,0xA3,0x6A,0x9B,0x6B,0x6E,0xDA,0x08, + 0xCC,0xA3,0x29,0x93,0x57,0xFF,0xFA,0xA8,0x29,0x93,0x66,0x72,0x7E,0x7E,0xF8,0xF8, + 0x86,0x7A,0xC5,0x61,0x5B,0x7A,0xF8,0xF8,0xE6,0x61,0x44,0x49,0x5E,0xFA,0xFA,0x78, + 0x44,0x49,0xE2,0x38,0x7A,0x78,0x5A,0x6E,0x03,0x41,0xA2,0x30,0xFE,0xEB,0xCE,0xAE, + 0x04,0x39,0xC2,0x38,0xDD,0xFD,0xF3,0xAB,0x03,0x39,0xC2,0x38,0x2B,0xBD,0x35,0x95, + 0x64,0x49,0x03,0x41,0xFF,0xFD,0xBF,0x0F,0x65,0x49,0x03,0x41,0x57,0xFA,0x7A,0xE0, + 0x23,0x41,0xE3,0x38,0x02,0x6B,0x58,0x5C,0x64,0x49,0xE3,0x38,0x0A,0xBD,0xAF,0xBF, + 0x44,0x49,0x24,0x41,0x40,0x78,0x56,0x5A,0x23,0x41,0xC2,0x38,0xAA,0x88,0x28,0x1E, + 0x44,0x49,0x03,0x41,0x7B,0xC3,0x08,0x03,0x65,0x49,0xE3,0x38,0x7F,0xDB,0xEE,0x8A, + 0x43,0x41,0x04,0x41,0xAA,0xE9,0x8A,0xAB,0x44,0x41,0x03,0x41,0xAA,0xBA,0xBF,0x55, + 0xA5,0x51,0x23,0x41,0x03,0x0B,0x2D,0xBD,0xA6,0x51,0x24,0x49,0xF8,0xF8,0xEE,0xDF, + 0xA5,0x59,0x23,0x49,0xB7,0x37,0x2F,0xBF,0x06,0x62,0x43,0x49,0x7F,0x7E,0x7A,0xA2, + 0xA5,0x59,0x23,0x49,0xD7,0xDF,0x7E,0xBC,0xE5,0x61,0x24,0x49,0x3F,0xBD,0xBD,0xFF, + 0x47,0x6A,0x64,0x59,0x8A,0x2A,0x2B,0x2D,0x27,0x6A,0xA5,0x59,0x7A,0xFA,0xF0,0x78, + 0xC6,0x59,0x24,0x49,0xFE,0xFA,0xE8,0x78,0x44,0x49,0xC2,0x38,0x7C,0x70,0x50,0x7A, + 0xE3,0x38,0xA2,0x30,0xAE,0xAA,0xAE,0x2E,0x23,0x39,0xE3,0x38,0xD5,0xE5,0xAD,0x3B, + 0x44,0x41,0xE3,0x38,0xF9,0xBF,0x2F,0xAE,0x23,0x41,0x03,0x39,0x7F,0x5A,0xB0,0x80, + 0x43,0x49,0xE3,0x40,0xF7,0xFD,0xFE,0xE8,0x03,0x41,0x23,0x39,0xE0,0xA0,0xAA,0x2C, + 0x24,0x49,0xE3,0x40,0xA2,0x78,0xEA,0xAB,0x24,0x49,0xE3,0x40,0x00,0x27,0x2B,0x0A, + 0x64,0x51,0x23,0x49,0xF9,0xB2,0xB7,0x25,0x64,0x51,0x03,0x41,0xAE,0xFB,0x9E,0xB8, + 0x65,0x51,0x23,0x41,0x5C,0x7F,0xAA,0xAB,0x64,0x49,0x23,0x49,0xA5,0x05,0x87,0xAD, + 0xA5,0x59,0x23,0x41,0x2B,0xAA,0xFE,0x56,0xA5,0x51,0x03,0x41,0xA8,0xBF,0xFF,0x5F, + 0x64,0x49,0x23,0x41,0xAB,0x0A,0x08,0x83,0x85,0x49,0x23,0x41,0xDF,0xEB,0xE0,0xEA, + 0x64,0x49,0x03,0x41,0xEA,0x4B,0x7A,0x7A,0x23,0x39,0xC1,0x38,0xA8,0x7A,0x7B,0xFA, + 0x24,0x39,0xC2,0x30,0xFE,0xFE,0xFB,0xAA,0x23,0x41,0x03,0x39,0x95,0x3D,0x29,0x0D, + 0x64,0x49,0x03,0x41,0x5D,0xFB,0xEE,0x8A,0x85,0x49,0x24,0x41,0xF8,0xAB,0xB9,0xBB, + 0xA5,0x49,0x03,0x39,0x5F,0xF6,0xEE,0xA8,0x44,0x41,0x03,0x41,0x2F,0xBB,0xB8,0xBE, + 0x44,0x49,0x03,0x39,0xAA,0xDC,0xF4,0xFE,0x44,0x41,0x03,0x41,0xAF,0x2E,0xB8,0x56, + 0x44,0x41,0x02,0x41,0xAA,0x0A,0x88,0x2E,0x64,0x49,0x23,0x41,0x2D,0x0F,0x0B,0x0A, + 0x64,0x49,0x23,0x41,0xD6,0x7E,0xF0,0xB0,0x44,0x49,0x03,0x41,0xAF,0xFF,0xFF,0xAC, + 0x85,0x51,0x03,0x39,0xAA,0x8A,0xAD,0xB5,0x64,0x49,0x03,0x41,0x78,0xA0,0xA0,0xA2, + 0x64,0x51,0x23,0x41,0xF9,0x3D,0xAA,0x3B,0xE6,0x61,0x64,0x51,0x8B,0x0F,0xA5,0xD5, + 0x46,0x72,0xC5,0x61,0xF7,0xBF,0x8B,0x2D,0x67,0x72,0x05,0x62,0xFE,0x67,0x7F,0x2A, + 0x87,0x72,0x05,0x6A,0xEB,0xAD,0xAD,0x0A,0x67,0x72,0xC5,0x61,0xFE,0xFE,0xBA,0x68, + 0x87,0x7A,0xE5,0x61,0x3F,0xAF,0xBF,0xAD,0xA8,0x7A,0x46,0x72,0x2A,0x9B,0xED,0xEB, + 0x09,0x8B,0x87,0x7A,0x26,0x36,0x3D,0xF5,0x72,0xD5,0x2A,0x8B,0x2F,0x0D,0x2D,0xBD, + 0xD4,0xDD,0x31,0xCD,0xC0,0x78,0x7A,0x7B,0x31,0xCD,0xCF,0xBC,0xFA,0x78,0xF2,0x7E, + 0xF0,0xC4,0xCF,0xBC,0xDA,0x3F,0x5D,0x7F,0x10,0xC5,0xCF,0xBC,0x2F,0x25,0x17,0x07, + 0x31,0xCD,0x10,0xC5,0x8F,0x15,0x35,0x35,0x31,0xCD,0x10,0xC5,0x20,0xEE,0x3C,0xA8, + 0x51,0xCD,0x11,0xC5,0xAA,0xAB,0xAF,0x6E,0xD3,0xDD,0x31,0xC5,0x0D,0x0D,0x25,0xB5, + 0xD3,0xDD,0xAF,0xBC,0x7C,0xF8,0x58,0x70,0xD0,0xBC,0x8F,0xB4,0xC8,0xF2,0x6F,0x57, + 0xAF,0xBC,0x6E,0xB4,0x82,0x72,0x7B,0xFF,0xAF,0xB4,0x4D,0xAC,0x80,0x70,0x7A,0xEA, + 0xAF,0xBC,0x2D,0xAC,0xA8,0xFB,0x7B,0x7F,0x8F,0xB4,0x2D,0xAC,0x22,0x7B,0x77,0x7D, + 0x6E,0xAC,0x0D,0xA4,0x28,0x0A,0xFB,0x57,0x6E,0xAC,0x0C,0xA4,0x60,0xFA,0x7E,0x5D, + 0xB0,0xB4,0x0D,0x9C,0xFF,0xD5,0xD5,0x0B,0x72,0xC5,0x0D,0x9C,0x5D,0xDD,0xBD,0x2A, + 0x93,0xCD,0x2E,0xA4,0x75,0xFD,0xAA,0x88,0x72,0xC5,0x4E,0xAC,0xD5,0xAB,0x2A,0x22, + 0x93,0xCD,0x11,0xBD,0xA5,0xAF,0x0A,0x80,0xB3,0xD5,0x53,0xC5,0x0A,0xA2,0xA2,0xFF, + 0xD5,0xD5,0x52,0xC5,0xE2,0xDE,0xFF,0x5F,0x73,0xC5,0xF1,0xBC,0x8A,0xC8,0xF6,0x56, + 0x32,0xC5,0xB0,0xB4,0xE8,0xEA,0x6A,0x6A,0xF1,0xB4,0x6F,0xAC,0xFC,0xDF,0x57,0x77, + 0x84,0x61,0x43,0x59,0xFE,0xFC,0x78,0xFD,0xA5,0x61,0x43,0x51,0xB7,0xAE,0x73,0xFA, + 0x84,0x59,0x23,0x51,0xA2,0xAA,0xAF,0xDE,0x64,0x59,0x23,0x51,0xB8,0xAE,0x7E,0x5F, + 0x64,0x59,0x23,0x51,0xFA,0xDE,0xFF,0xBE,0x84,0x59,0x22,0x51,0xE7,0xEF,0xE2,0xFE, + 0x84,0x59,0x43,0x51,0x57,0x5C,0x75,0x55,0x63,0x59,0x23,0x51,0xEE,0xAA,0xCC,0xBB, + 0x63,0x59,0x23,0x51,0xBB,0xAF,0xFF,0xFD,0x63,0x59,0x23,0x51,0xD7,0xD6,0xBC,0x3A, + 0x84,0x59,0x43,0x59,0x85,0xB5,0xFD,0xF6,0xA4,0x61,0x43,0x59,0xB5,0xAF,0xB7,0xD5, + 0xA4,0x61,0x63,0x59,0xBF,0xDE,0xFF,0x77,0xA4,0x61,0x64,0x59,0x8A,0xEF,0xFB,0xED, + 0xA4,0x61,0x43,0x59,0x82,0xCE,0xE2,0x42,0xA5,0x61,0x43,0x59,0xFC,0x5F,0x5E,0x7F, + 0x63,0x59,0x22,0x51,0x80,0xC0,0x3B,0xB6,0x84,0x59,0x23,0x51,0xEF,0xCA,0xEB,0x7A, + 0x43,0x59,0x23,0x51,0xF0,0x3F,0x38,0xEA,0x64,0x59,0x23,0x51,0xEB,0xEA,0xFA,0x6D, + 0x43,0x59,0x03,0x51,0xBA,0x5A,0x6F,0xFF,0x23,0x51,0xE2,0x48,0xBB,0xFF,0x2B,0x0A, + 0x44,0x51,0x02,0x49,0x2F,0xAE,0x7A,0xEF,0x23,0x51,0xE2,0x48,0xA0,0x40,0xA0,0xB0, + 0x63,0x59,0x03,0x51,0xD5,0xD5,0xA7,0x37,0xAB,0xA3,0x63,0x59,0xB5,0x2D,0x2D,0x0B, + 0xEC,0xAB,0x8A,0x9B,0x8D,0xEB,0xA2,0xFE,0xCC,0xA3,0x4A,0x9B,0xE8,0xE2,0xFE,0x56, + 0xAB,0xA3,0x6A,0x9B,0x57,0x7B,0xEE,0xA7,0xAB,0xA3,0x6A,0x9B,0x2B,0xFD,0x7F,0xE8, + 0xAB,0xA3,0x6A,0x9B,0xA6,0x78,0x79,0x6B,0xCC,0xA3,0x8B,0x9B,0x2E,0xAA,0xD5,0x55, + 0xCC,0xAB,0x6B,0x9B,0xE2,0x62,0xFB,0xFB,0x49,0x93,0x87,0x7A,0xFE,0x78,0xFE,0x76, + 0x86,0x7A,0xC5,0x61,0x78,0x78,0xE0,0xE0,0xC5,0x61,0x44,0x51,0xFA,0xFC,0x7C,0x7C, + 0x64,0x51,0x02,0x41,0x7E,0xE0,0xBC,0xAB,0x44,0x49,0xE2,0x38,0x5F,0xFA,0x2A,0x20, + 0x44,0x49,0xE3,0x38,0x5D,0xDF,0x76,0x78,0x23,0x41,0xA1,0x30,0xFF,0xBE,0x2E,0x2B, + 0x85,0x49,0x23,0x41,0xA9,0x35,0xBD,0xAB,0xA5,0x49,0x44,0x49,0x7F,0xEC,0xFF,0x6B, + 0x64,0x49,0xE3,0x38,0x7E,0xFA,0xF8,0xEA,0x23,0x41,0xC2,0x38,0x8B,0xFB,0xDA,0xBE, + 0x64,0x49,0x03,0x41,0xA9,0x83,0xAD,0xA5,0x44,0x41,0x03,0x41,0x56,0x56,0x9E,0x9E, + 0x85,0x51,0x23,0x41,0xAD,0xA5,0xED,0x7F,0x44,0x49,0xE2,0x38,0x88,0xFE,0xBF,0xA7, + 0x44,0x41,0x03,0x41,0xEB,0xAB,0x2B,0x5F,0x23,0x41,0x03,0x39,0x7A,0xF8,0x3C,0x3E, + 0x44,0x49,0xE2,0x38,0x8B,0xAB,0x5A,0xF7,0x44,0x49,0xE2,0x40,0xFC,0xDD,0x55,0x55, + 0x64,0x51,0xE2,0x40,0x2B,0x3D,0x3D,0xBF,0xE6,0x61,0x85,0x59,0x02,0x01,0xDB,0x6D, + 0xA5,0x59,0x24,0x49,0xB8,0xE8,0xB8,0xDA,0x64,0x51,0x23,0x49,0xE0,0xA0,0xA2,0xFE, + 0xC5,0x59,0x43,0x49,0x0F,0xA5,0xF5,0x57,0x06,0x6A,0x64,0x51,0xC2,0xEA,0xED,0xD5, + 0xC5,0x59,0x44,0x49,0x5F,0x58,0x68,0xA2,0x44,0x49,0xA2,0x30,0xFA,0x5C,0xDC,0x5C, + 0xE3,0x38,0xA2,0x30,0x2E,0xBF,0xF7,0x7D,0x24,0x39,0xC2,0x30,0xAA,0xED,0xA1,0xB1, + 0x23,0x41,0xE3,0x38,0x08,0x82,0xF6,0xBE,0x44,0x41,0x03,0x41,0xDF,0x35,0x35,0xB5, + 0x65,0x49,0x24,0x41,0xFF,0xBE,0xAE,0xE7,0x44,0x49,0x03,0x41,0xFE,0xAA,0x20,0x00, + 0x64,0x49,0x23,0x49,0x5D,0x7E,0x5F,0xFB,0x64,0x51,0x03,0x41,0xF7,0xAD,0xA2,0x82, + 0xA6,0x59,0x44,0x49,0xF5,0xBD,0xAB,0x02,0xC6,0x59,0x64,0x51,0x57,0xDF,0xFA,0x6C, + 0xA5,0x51,0x23,0x49,0xFF,0x7A,0xF8,0xF2,0x44,0x49,0x03,0x41,0x20,0x6A,0xFA,0x77, + 0x64,0x49,0x03,0x41,0xF8,0xAE,0xEB,0xF7,0x23,0x41,0x03,0x41,0x62,0xA3,0xC1,0xC2, + 0x44,0x49,0xE2,0x38,0x02,0x0F,0x2F,0xB7,0x84,0x49,0x44,0x49,0x7D,0x4F,0xDD,0x57, + 0x44,0x49,0x03,0x41,0x6E,0x36,0xBA,0xFE,0x43,0x41,0x03,0x41,0x5D,0x56,0xDE,0x5F, + 0x23,0x41,0xE3,0x38,0x37,0xBA,0xA2,0xA2,0x24,0x41,0xE3,0x38,0x0A,0x2B,0xBD,0xFF, + 0x64,0x49,0x03,0x39,0xCA,0xEB,0xAF,0xBD,0x85,0x49,0x44,0x49,0xD7,0x3D,0xB7,0xBD, + 0xA5,0x51,0x64,0x49,0xB6,0xAF,0x2B,0x2A,0x85,0x49,0x23,0x41,0x57,0xF7,0x7C,0xE0, + 0x43,0x41,0x03,0x39,0x78,0x57,0x55,0xF6,0x23,0x41,0x03,0x39,0xDF,0x35,0xA5,0x7D, + 0x64,0x49,0x03,0x39,0xA7,0x2B,0x2F,0x2D,0xA5,0x49,0x44,0x49,0xAF,0xFF,0xBD,0x3F, + 0x85,0x51,0x44,0x49,0xA6,0xBF,0xFF,0x6E,0xA5,0x51,0x44,0x49,0xDF,0xEF,0xFF,0x95, + 0x85,0x51,0x23,0x41,0xD5,0xFB,0xF8,0x00,0x85,0x51,0x23,0x41,0xBF,0xD5,0x5F,0xDC, + 0x64,0x51,0x44,0x49,0xA2,0x7D,0xD5,0x55,0x64,0x51,0x44,0x49,0x30,0x32,0x3E,0x32, + 0x06,0x6A,0x44,0x51,0x0B,0xAF,0xFF,0xF5,0x88,0x72,0x85,0x59,0xAA,0x0A,0xBF,0xF5, + 0xA8,0x7A,0x06,0x6A,0x88,0x80,0xAB,0xA9,0x87,0x72,0x26,0x6A,0x78,0xB8,0x2F,0xAE, + 0x88,0x7A,0x05,0x62,0xBD,0xAF,0x08,0x02,0xC8,0x82,0x88,0x7A,0xD5,0x1D,0x35,0xFF, + 0xE9,0x82,0x87,0x7A,0x97,0xBE,0x8A,0xAB,0x4E,0xB4,0xC8,0x82,0x2D,0x3D,0xBD,0x35, + 0xB3,0xD5,0xAF,0xBC,0xA2,0xE3,0xA9,0x89,0x31,0xCD,0xD0,0xBC,0x7E,0xDE,0x7E,0xF8, + 0xF0,0xC4,0xAF,0xBC,0xFE,0xEA,0xFB,0xFF,0x10,0xC5,0xB0,0xBC,0xAB,0xAF,0xA9,0x3B, + 0x31,0xCD,0xF0,0xC4,0xA5,0xE5,0xAF,0xAF,0x51,0xCD,0x10,0xC5,0x7F,0x6D,0xCB,0x8F, + 0x51,0xCD,0xF0,0xC4,0xA8,0xAE,0xB7,0xAA,0x92,0xCD,0xF0,0xC4,0x27,0xBF,0xFD,0x7E, + 0xD3,0xDD,0x6F,0xB4,0xF0,0x6A,0x7E,0x7F,0x8F,0xB4,0x2D,0xAC,0x0A,0xC0,0x6E,0xFF, + 0x8F,0xB4,0x2D,0xAC,0x80,0xAB,0x6F,0x7F,0x6E,0xAC,0x2D,0xAC,0x30,0x7E,0x75,0x7D, + 0x6F,0xAC,0x0D,0xA4,0xA8,0xDF,0xDD,0x5D,0x6E,0xB4,0xED,0x9B,0xEA,0xEB,0xFD,0x2F, + 0x73,0xCD,0x0D,0xA4,0x55,0x55,0xF5,0x2B,0x73,0xCD,0x2D,0xA4,0xD5,0x35,0x0B,0x00, + 0xB3,0xCD,0xF0,0xBC,0xB5,0xAB,0x2A,0xA0,0x93,0xCD,0x52,0xC5,0x23,0xC2,0xF2,0x7D, + 0x93,0xCD,0x11,0xBD,0xA0,0xE0,0x7B,0xDB,0x73,0xCD,0x11,0xBD,0x2F,0xAF,0x2F,0x0D, + 0xB4,0xD5,0x52,0xC5,0x6A,0xC3,0x8B,0xA2,0x73,0xCD,0xB0,0xB4,0xA8,0xD8,0x78,0xE8, + 0x32,0xC5,0x8F,0xAC,0x00,0x8A,0xF9,0x55,0x32,0xBD,0xD0,0xB4,0x74,0xF7,0xBB,0xA9, + 0x11,0xBD,0x90,0xAC,0xEB,0xFA,0x6C,0xFE,0xB0,0xB4,0x6F,0xAC,0xBA,0xF7,0xAF,0xBB, + 0x63,0x59,0x02,0x49,0x0A,0x78,0x02,0x08,0x84,0x59,0x43,0x51,0x7B,0x5A,0x72,0x5E, + 0x43,0x51,0x03,0x51,0x98,0x3A,0x22,0x2A,0x64,0x59,0x02,0x49,0xFC,0xDE,0xBA,0xF7, + 0x43,0x51,0xE3,0x48,0x00,0x80,0xAA,0xCA,0x43,0x51,0x23,0x51,0xE0,0xC2,0x19,0x2B, + 0x63,0x51,0x23,0x51,0xFA,0xF8,0xAE,0x73,0x64,0x59,0x23,0x51,0xBF,0xF6,0xFE,0x57, + 0x63,0x59,0x03,0x51,0xBE,0xDF,0xBF,0x28,0x84,0x61,0x43,0x59,0x0D,0x7B,0xFB,0xFB, + 0x84,0x61,0x43,0x59,0xFC,0xFE,0xBF,0xFF,0x84,0x61,0x43,0x59,0xEF,0xBD,0xBB,0xEF, + 0x83,0x61,0x64,0x59,0xFD,0xFF,0x5B,0x7F,0xA4,0x61,0x43,0x59,0xAD,0xAB,0xF2,0xBB, + 0x84,0x61,0x43,0x59,0xF0,0x5D,0x7F,0x7F,0x63,0x59,0x23,0x51,0x8E,0xAF,0x22,0x22, + 0x63,0x59,0x22,0x51,0xF2,0x80,0xC0,0xAF,0x43,0x59,0x03,0x51,0x80,0xEA,0xAE,0x00, + 0x64,0x59,0x03,0x51,0xAA,0xAA,0x6A,0xE8,0x64,0x59,0x03,0x51,0xE3,0xEA,0xFF,0x7F, + 0x23,0x51,0xE2,0x48,0x88,0xE8,0x7A,0xFA,0x43,0x51,0x02,0x49,0x25,0xD9,0xD3,0xFD, + 0x23,0x51,0x02,0x49,0x88,0xB2,0x28,0xA4,0x23,0x51,0x03,0x49,0xC2,0xB2,0xE2,0x02, + 0x29,0x93,0x43,0x59,0xD5,0xD5,0xB5,0x2D,0xEC,0xAB,0xC7,0x8A,0x2D,0x29,0x0A,0x22, + 0xCC,0xA3,0x6A,0x9B,0xA0,0xB8,0x6C,0x5E,0x6A,0x9B,0x4A,0x93,0x64,0x14,0xE5,0x22, + 0x8A,0x9B,0x49,0x93,0x35,0xED,0xFF,0x7E,0x8B,0x9B,0x6A,0x9B,0x02,0xBF,0x7D,0x55, + 0x8B,0x9B,0x4A,0x9B,0x00,0xAA,0xAF,0xBF,0x8B,0x9B,0x6A,0x9B,0x22,0x2A,0xD7,0x27, + 0xAC,0xA3,0x09,0x8B,0xE0,0xAA,0xF0,0x5C,0xE8,0x8A,0xA7,0x7A,0x7C,0x54,0xE4,0xF4, + 0xC7,0x82,0x46,0x72,0x6E,0x6C,0x78,0xE8,0x46,0x72,0x44,0x51,0x76,0x5E,0x7A,0xE0, + 0x64,0x49,0x03,0x49,0xA8,0xDF,0xFF,0xD6,0x43,0x49,0x03,0x41,0x00,0x8A,0x29,0xAF, + 0x43,0x49,0xE3,0x38,0x7A,0x7E,0xFE,0xE2,0x25,0x41,0xE3,0x40,0x35,0x95,0xB5,0xFF, + 0x84,0x51,0x24,0x41,0xAB,0xB9,0x2D,0x99,0xA5,0x51,0x44,0x49,0x6A,0x62,0xE3,0xEA, + 0x64,0x49,0x03,0x41,0xFE,0xFC,0xFE,0x5E,0x44,0x49,0xE3,0x38,0xD6,0xFE,0xBE,0x3F, + 0x44,0x49,0x24,0x41,0xF5,0x76,0x78,0x68,0x23,0x41,0xE3,0x38,0xA8,0xB8,0x8E,0xB8, + 0x44,0x49,0x03,0x41,0x7F,0x7D,0xBD,0xEA,0x23,0x41,0xE2,0x38,0xB8,0xBA,0xD8,0x5E, + 0x44,0x41,0xE3,0x38,0xFA,0xFE,0xEF,0x3F,0x44,0x41,0xE2,0x40,0xEF,0xF7,0xAB,0xA8, + 0x44,0x41,0xE2,0x38,0xD7,0x7F,0xEA,0xFA,0xE3,0x40,0x03,0x39,0xAA,0x8B,0xAF,0xFB, + 0x85,0x51,0xE3,0x40,0xBD,0x2D,0x2F,0x2F,0xE6,0x61,0x84,0x51,0x8D,0xAD,0xAF,0xA3, + 0x85,0x59,0xE3,0x40,0xF8,0xD8,0x78,0xB8,0x44,0x51,0xE3,0x40,0x0A,0x0B,0xBF,0xF7, + 0x64,0x51,0x03,0x49,0xA2,0xA0,0xA9,0x35,0x64,0x51,0x23,0x49,0x0A,0x0F,0x27,0xE5, + 0xA5,0x59,0x44,0x49,0x8A,0xA3,0x8F,0xAD,0x65,0x49,0xA2,0x30,0x5C,0x5C,0x78,0xF8, + 0xC3,0x30,0xA2,0x30,0xEF,0xBA,0xB0,0xC0,0x03,0x39,0xA2,0x28,0x2D,0xAF,0xF7,0xA7, + 0x23,0x41,0xE3,0x38,0xFA,0x3D,0xDD,0x7D,0x03,0x39,0xA2,0x30,0x00,0x88,0xA8,0xA7, + 0x65,0x49,0x03,0x39,0xAD,0xAD,0xAD,0x0D,0x64,0x51,0x23,0x49,0xEA,0xA2,0x6B,0x7A, + 0x64,0x51,0x44,0x49,0x3D,0xA1,0x02,0x01,0x85,0x59,0x64,0x51,0x69,0xB9,0xAB,0x0A, + 0xA5,0x59,0x44,0x51,0xA8,0x28,0xAA,0xB6,0xC6,0x59,0x85,0x51,0x5A,0x63,0xDF,0xD7, + 0x85,0x51,0x23,0x49,0xF8,0x5A,0x7C,0x5C,0x24,0x41,0x02,0x41,0xBB,0x3F,0x0B,0x00, + 0x44,0x49,0x03,0x41,0xFD,0xE2,0xCA,0xE8,0x44,0x41,0xE2,0x38,0xE2,0xEB,0xFB,0x5E, + 0x23,0x41,0xE2,0x38,0x2B,0xB9,0xBF,0xB9,0x44,0x41,0x03,0x41,0x2A,0xB7,0xAF,0xFB, + 0x23,0x41,0x03,0x41,0x28,0x08,0xC0,0x7B,0x23,0x41,0x03,0x39,0xFD,0xCB,0xB2,0xE3, + 0x23,0x41,0xC2,0x30,0xB8,0xFC,0xF8,0xAA,0x03,0x41,0xC2,0x38,0xA0,0xAE,0xFA,0x73, + 0x24,0x41,0xE3,0x38,0xAB,0xFF,0xB9,0xB5,0x64,0x49,0x03,0x39,0x0B,0xBF,0xBD,0xB5, + 0x84,0x49,0x23,0x41,0x32,0xBD,0xEA,0xFA,0x85,0x49,0x23,0x41,0x80,0xEA,0xDF,0x55, + 0x44,0x41,0x03,0x41,0xA8,0xA0,0xE2,0x7C,0x44,0x49,0xE2,0x38,0xEA,0xA2,0xB0,0x9F, + 0x64,0x49,0x03,0x39,0x35,0xD5,0x57,0x5F,0x64,0x49,0x02,0x39,0x00,0x3B,0xBB,0xBD, + 0x85,0x49,0x03,0x41,0x68,0x7A,0xBE,0xF7,0x64,0x49,0x03,0x41,0x2F,0x3D,0xAA,0x0A, + 0xA5,0x51,0x44,0x49,0x8A,0xFF,0xF5,0x5F,0xA5,0x51,0x23,0x49,0xDC,0xA8,0xA2,0x0A, + 0xA5,0x59,0x23,0x49,0xDF,0xFB,0xFA,0x2C,0x85,0x51,0x44,0x49,0xAB,0xBF,0x9E,0xEC, + 0xA5,0x59,0x44,0x51,0xB5,0xBF,0xAB,0xFB,0xA5,0x59,0x64,0x51,0xAB,0xFF,0x96,0xF5, + 0x06,0x6A,0x64,0x59,0x23,0x3F,0xBF,0xBB,0x67,0x72,0xE6,0x61,0x00,0x03,0x8D,0xF5, + 0xA8,0x7A,0x06,0x6A,0x0A,0xFB,0xFF,0xD5,0xC9,0x82,0x46,0x6A,0xA2,0x82,0xAF,0xB5, + 0xE9,0x82,0x88,0x7A,0x3F,0xB5,0xAF,0xBA,0x0D,0xAC,0xC8,0x82,0x35,0x35,0xFD,0x95, + 0xB3,0xDD,0x0C,0xA4,0x8A,0x03,0x09,0x0D,0x72,0xD5,0xCF,0xBC,0x7E,0x5C,0x78,0x78, + 0xCF,0xBC,0xAF,0xBC,0x98,0xBC,0xBB,0xD7,0xF0,0xC4,0xAF,0xBC,0x2B,0xAB,0xAF,0xA5, + 0x10,0xC5,0xCF,0xBC,0x2A,0x0B,0x3B,0xFF,0x31,0xCD,0xF0,0xC4,0xA8,0x8A,0xCF,0x75, + 0x31,0xCD,0xD0,0xBC,0x02,0x80,0xA8,0xAD,0x31,0xCD,0xAF,0xBC,0xE0,0xFA,0x6A,0x6A, + 0xD0,0xBC,0x2E,0xAC,0x68,0x78,0x5E,0xDF,0x4E,0xAC,0x0D,0xA4,0xAB,0xBF,0x7F,0xEF, + 0x4E,0xAC,0x0D,0xA4,0xEA,0xCB,0xA9,0xBE,0xF0,0xBC,0x2D,0xA4,0x75,0xA9,0x2F,0x0B, + 0x93,0xD5,0x4E,0xAC,0x55,0xBF,0x0A,0x0A,0xB3,0xD5,0x6F,0xB4,0xD5,0xAA,0x20,0x00, + 0xB4,0xD5,0x11,0xC5,0x29,0x0A,0x00,0x00,0xB4,0xD5,0x73,0xCD,0x22,0x0A,0x04,0xD6, + 0xD4,0xD5,0x32,0xC5,0x78,0x58,0x7C,0x58,0x52,0xC5,0x12,0xBD,0x02,0x6B,0x75,0x5D, + 0x32,0xBD,0xB0,0xAC,0xA0,0xBA,0xAE,0x77,0x93,0xCD,0x11,0xBD,0x3D,0x2F,0x0D,0x09, + 0x93,0xCD,0x32,0xC5,0x80,0x80,0x80,0x60,0x93,0xCD,0xB0,0xB4,0xE8,0xEA,0xFE,0x5F, + 0xF0,0xBC,0x8F,0xAC,0x9A,0xA8,0xFA,0xAF,0x11,0xBD,0xB0,0xAC,0x02,0xC0,0xFA,0x7C, + 0xD0,0xB4,0x6E,0xAC,0xE2,0xEC,0xFE,0xDF,0xD0,0xB4,0x8F,0xAC,0xD5,0xDF,0xE9,0x3F, + 0x84,0x59,0x23,0x51,0xA8,0xEE,0x5B,0x56,0x63,0x51,0x23,0x51,0xF8,0x95,0x95,0xA5, + 0x64,0x59,0x02,0x49,0xEA,0x6A,0x7C,0xFA,0x64,0x59,0x02,0x49,0xBD,0x22,0xEE,0xEA, + 0x64,0x51,0x03,0x51,0xEF,0x7A,0xE7,0xAF,0x64,0x59,0x23,0x51,0xBF,0xCB,0xBB,0xFA, + 0x63,0x59,0x23,0x51,0x7F,0xFD,0xAF,0xB3,0x63,0x59,0x23,0x51,0x7F,0xFD,0x8B,0x8B, + 0x84,0x61,0x43,0x59,0xA9,0x2F,0x2A,0xEA,0x84,0x61,0x43,0x59,0xF8,0x7C,0x78,0xE3, + 0x84,0x61,0x43,0x59,0xAD,0xB5,0x9F,0xD5,0x84,0x61,0x63,0x59,0xA1,0xAE,0x55,0x85, + 0x84,0x61,0x43,0x59,0xCA,0xAA,0xEA,0xFF,0x63,0x59,0x23,0x51,0x83,0xAF,0xB4,0x0E, + 0x63,0x59,0x22,0x59,0x80,0x82,0x3E,0xEE,0x63,0x59,0x23,0x51,0xA2,0xEE,0xEB,0xEF, + 0x43,0x59,0x02,0x51,0xA0,0x3E,0x3F,0xF8,0x64,0x59,0x23,0x51,0xEA,0xF2,0xF2,0xFB, + 0x43,0x59,0xE2,0x48,0xB0,0x7A,0xFE,0xAA,0x23,0x51,0xE2,0x48,0x62,0xEB,0xAF,0xAA, + 0x23,0x51,0xE2,0x48,0x37,0x8A,0x82,0x02,0x23,0x51,0xE2,0x48,0xE8,0xF0,0x6B,0x2E, + 0x23,0x51,0xE2,0x48,0x3B,0xFD,0xF5,0xBF,0xA5,0x69,0xE2,0x48,0xDF,0xBF,0xBF,0x2F, + 0x8B,0x9B,0x44,0x59,0x2D,0x2B,0x0B,0x02,0xCC,0xA3,0x8B,0x9B,0x2B,0x62,0xFA,0xDE, + 0xAC,0xA3,0x6A,0x9B,0xEC,0xA9,0x2A,0xBA,0x8B,0x9B,0x29,0x93,0x2A,0x22,0xC8,0x7C, + 0x8A,0x9B,0x29,0x93,0xE0,0xE0,0xEE,0xDD,0x49,0x93,0x09,0x93,0x80,0x8A,0xA8,0xFF, + 0x6A,0x9B,0x29,0x93,0x0A,0x8F,0xF8,0xED,0x8B,0x9B,0x4A,0x93,0xB8,0xBB,0xAF,0xAF, + 0x6A,0x9B,0xE8,0x8A,0x78,0xE0,0x68,0x60,0xC8,0x82,0x87,0x7A,0xBC,0xA8,0xA0,0x83, + 0xE8,0x82,0xA7,0x7A,0xDF,0x8F,0x0F,0xA5,0xC8,0x82,0xA5,0x61,0x7A,0xF8,0xE0,0xA8, + 0xE6,0x61,0x03,0x41,0x57,0x56,0x58,0x78,0x23,0x49,0xE3,0x40,0xAA,0x3E,0xFA,0xE0, + 0x64,0x51,0x03,0x41,0xFF,0xFF,0x35,0xB5,0x64,0x51,0x03,0x41,0x55,0xFF,0xEA,0xC2, + 0x44,0x49,0x03,0x41,0x2A,0xFF,0x72,0xEA,0x64,0x49,0x03,0x41,0x03,0xAF,0xEF,0xF5, + 0x65,0x49,0xE3,0x38,0xFC,0x5E,0x7F,0x6F,0x44,0x49,0xE2,0x38,0x37,0xB5,0x75,0x55, + 0x65,0x49,0xE2,0x38,0x2A,0x0A,0xA9,0xAD,0x64,0x49,0x23,0x41,0x5C,0xDF,0x27,0xCB, + 0x64,0x49,0x02,0x41,0xFB,0xFB,0x7A,0xCE,0x23,0x41,0xC2,0x38,0x7C,0xB8,0xBA,0xEF, + 0x03,0x41,0xC2,0x38,0x0A,0x2B,0xAF,0xBE,0x43,0x49,0xE3,0x38,0xB8,0xFF,0xED,0xFF, + 0x23,0x41,0xE2,0x38,0xAA,0x38,0xBF,0xDE,0x24,0x41,0xE3,0x38,0xB7,0x37,0x07,0xA8, + 0x85,0x51,0x24,0x49,0x27,0x0B,0x2B,0xBF,0xE6,0x61,0x85,0x59,0x2A,0x22,0x88,0xBD, + 0xE6,0x61,0x44,0x51,0x5C,0x78,0xE0,0xFE,0x85,0x51,0x04,0x49,0xDD,0xAB,0xAA,0x08, + 0x64,0x51,0x24,0x49,0xE7,0xAA,0x28,0xE8,0x85,0x51,0x23,0x49,0xE5,0x2E,0x2A,0x0B, + 0xA5,0x51,0x23,0x49,0xBF,0xFE,0xDC,0x7A,0x44,0x49,0xC3,0x38,0x78,0x58,0x5E,0x5E, + 0xC3,0x30,0xA2,0x30,0x8C,0x48,0x7E,0xDD,0xC2,0x30,0xA2,0x28,0x82,0x8A,0x95,0x2E, + 0xE3,0x38,0xC2,0x30,0x41,0x41,0xDF,0xB6,0x03,0x41,0xA2,0x30,0xAD,0xBE,0x2F,0x2F, + 0x64,0x51,0x03,0x39,0x2D,0xBD,0x0F,0x2B,0x64,0x51,0x24,0x49,0xEA,0x60,0xFC,0x7A, + 0x85,0x51,0x23,0x49,0x29,0x09,0xBD,0x3F,0xA5,0x59,0x44,0x51,0xAA,0xA3,0x6E,0x6F, + 0x85,0x59,0x24,0x49,0x2A,0xAA,0xAA,0x5B,0x85,0x51,0x44,0x49,0xBA,0xF2,0xE0,0x51, + 0x85,0x51,0x03,0x41,0xF8,0xFA,0x7E,0x5F,0x23,0x41,0x03,0x41,0x2E,0x88,0x00,0x30, + 0x23,0x41,0xE3,0x38,0xA0,0xE8,0xFA,0x7F,0x44,0x41,0xE2,0x38,0x7A,0x73,0xF5,0xD5, + 0x23,0x41,0xE2,0x38,0x15,0xD5,0xB7,0xDB,0x23,0x41,0xE2,0x38,0xA2,0x88,0xE3,0xAB, + 0x44,0x49,0xE2,0x38,0xF7,0x77,0xAE,0x22,0x44,0x49,0x03,0x39,0xD5,0xF5,0xFE,0xD8, + 0x23,0x41,0x03,0x39,0x76,0x38,0x00,0x0B,0x23,0x41,0xE2,0x38,0xFD,0xE0,0xE0,0x80, + 0x23,0x41,0xE2,0x38,0x17,0xFE,0xDA,0x3F,0x44,0x41,0x03,0x41,0x27,0x09,0x27,0x9F, + 0x44,0x41,0x23,0x41,0x72,0xE0,0x08,0xE0,0x44,0x41,0x03,0x39,0xFA,0x7A,0x7E,0x5F, + 0x44,0x41,0xE2,0x38,0xFE,0xD5,0x55,0xDD,0x23,0x41,0xC2,0x30,0x3A,0xAA,0xDA,0xF8, + 0x43,0x41,0x03,0x39,0x7A,0xFB,0xF5,0x7D,0x43,0x41,0x03,0x39,0x29,0xEF,0xEB,0xF9, + 0x23,0x41,0x03,0x41,0x08,0xF7,0xFE,0xFA,0x64,0x49,0x03,0x41,0x02,0x29,0xFD,0x55, + 0x85,0x51,0x23,0x41,0xFA,0xE2,0xA3,0xA9,0x85,0x51,0x24,0x49,0xAF,0xB5,0xBE,0xBA, + 0xA5,0x51,0x24,0x49,0x8A,0xAA,0xEB,0xDF,0xA5,0x59,0x44,0x49,0xFA,0xA2,0x2B,0xAD, + 0xE6,0x61,0x64,0x51,0xD7,0xFE,0x3F,0x2A,0x27,0x6A,0x64,0x51,0xD5,0xFF,0x3F,0x0A, + 0x26,0x6A,0x84,0x59,0xBD,0xFB,0xEC,0xE8,0x26,0x6A,0xC5,0x61,0xF7,0xEE,0xA5,0x3D, + 0x27,0x6A,0xC5,0x61,0xFA,0xD6,0x9A,0xC0,0xA8,0x7A,0x06,0x62,0x2D,0x3D,0xD5,0xF5, + 0xC9,0x82,0x67,0x72,0x0A,0xAA,0x5F,0xDD,0x0A,0x8B,0x67,0x72,0x3B,0xBD,0xBD,0x77, + 0x52,0xCD,0xE9,0x82,0x0B,0x0D,0x2D,0xB5,0x72,0xD5,0xD0,0xBC,0x78,0x78,0x68,0xEA, + 0xF0,0xC4,0x8F,0xB4,0xFE,0x7E,0x6A,0x60,0xCF,0xBC,0x6E,0xB4,0x0A,0x2A,0x2F,0xB9, + 0xF0,0xC4,0x8F,0xB4,0xA8,0xAA,0x2B,0xBD,0xF0,0xC4,0xCF,0xBC,0x09,0x2F,0xF5,0x56, + 0x10,0xC5,0xAF,0xBC,0x02,0xE8,0xFE,0x5D,0xF0,0xBC,0x4E,0xAC,0xE8,0xFA,0xFE,0x7A, + 0x8F,0xB4,0x2D,0xAC,0xDF,0x77,0xF5,0x2A,0xD0,0xBC,0x0D,0xA4,0x5D,0xDD,0xFD,0x2A, + 0x31,0xC5,0x0D,0xA4,0xD5,0xF7,0xAF,0x02,0x52,0xCD,0xAF,0xB4,0xAD,0x0B,0x0A,0x00, + 0x72,0xCD,0x32,0xC5,0x07,0x08,0x0A,0xFB,0xD4,0xD5,0x52,0xC5,0x0A,0x2B,0xBD,0x75, + 0xD4,0xD5,0x93,0xCD,0xE2,0x28,0xED,0xFD,0xB4,0xD5,0x52,0xC5,0xAE,0xFA,0x7C,0xE0, + 0x93,0xCD,0xD0,0xB4,0xE0,0x6A,0xF8,0x78,0x12,0xBD,0x90,0xAC,0xE8,0x7A,0x7E,0x7F, + 0xAF,0xAC,0x6F,0xAC,0x82,0x9B,0x97,0xBD,0x93,0xCD,0xD0,0xB4,0x0D,0x8F,0x2D,0xAD, + 0x93,0xCD,0xD1,0xB4,0x80,0xE0,0x7A,0x57,0xF1,0xBC,0x6F,0xA4,0x78,0xD8,0xDE,0xF7, + 0xD0,0xB4,0x90,0xAC,0x0A,0x03,0x03,0x0A,0xF0,0xB4,0x8F,0xAC,0xEC,0x7A,0xFA,0xFA, + 0xB0,0xB4,0x4F,0xA4,0xA8,0xAA,0x26,0x80,0xF1,0xB4,0x8F,0xAC,0x37,0x2D,0x0F,0x2B, + 0x64,0x59,0x03,0x49,0xF8,0xAF,0xEF,0xFD,0x64,0x59,0x23,0x51,0xFB,0xD9,0xFF,0x5F, + 0x43,0x51,0x03,0x49,0xA0,0x6B,0xA8,0x0A,0x43,0x51,0x02,0x49,0xB8,0x3E,0x2F,0x08, + 0x64,0x59,0x23,0x51,0x9E,0xD1,0xA9,0xE3,0x84,0x59,0x23,0x51,0xF8,0x7B,0xFF,0xAB, + 0x63,0x59,0x23,0x51,0xB3,0xBE,0xBE,0xFE,0x64,0x59,0x43,0x59,0x8D,0x0A,0xFE,0xD8, + 0x84,0x61,0x43,0x59,0xEB,0xB3,0x6D,0x69,0xA4,0x61,0x43,0x59,0xE3,0x7B,0xFD,0xF5, + 0x84,0x61,0x43,0x59,0x7A,0x7B,0x7B,0x89,0x84,0x59,0x43,0x59,0xAF,0xD9,0x7F,0x7E, + 0x63,0x59,0x43,0x59,0xE8,0x5A,0x77,0x65,0x63,0x59,0x02,0x51,0x08,0xBA,0x7A,0x6A, + 0x64,0x59,0x23,0x51,0xAA,0x8B,0x3D,0x35,0x64,0x59,0x23,0x51,0xEA,0xFA,0x7E,0xFE, + 0x43,0x59,0x23,0x51,0x63,0xAA,0xF7,0x73,0x44,0x59,0x03,0x51,0x02,0xA2,0xBA,0x63, + 0x23,0x51,0x02,0x49,0xCA,0x6A,0x6F,0x59,0x43,0x51,0x02,0x49,0x7F,0xDA,0xA3,0xBB, + 0x23,0x51,0x03,0x49,0xBD,0xB5,0x34,0xAD,0x23,0x51,0x03,0x49,0xFF,0xBB,0xFB,0x43, + 0x42,0x51,0x02,0x49,0xF5,0x7F,0xBF,0xBF,0x4A,0x93,0x43,0x59,0xF5,0xB5,0x2D,0x2B, + 0xCC,0xA3,0x29,0x93,0x0D,0x03,0x02,0xA2,0xCC,0xA3,0x4A,0x9B,0xE0,0xE8,0xFC,0xDE, + 0x8B,0x9B,0x29,0x93,0xA8,0xAC,0xFA,0x7A,0x6A,0x9B,0x2A,0x93,0x72,0xAA,0xBF,0x9D, + 0x6B,0x9B,0x29,0x93,0xFF,0xCB,0xE7,0x57,0x29,0x93,0x09,0x8B,0xFA,0x38,0x38,0x20, + 0x6B,0x9B,0x29,0x93,0xED,0xF5,0x3D,0xAD,0x8B,0x9B,0x4A,0x9B,0xEF,0xAB,0x0B,0x83, + 0x6A,0x9B,0xC8,0x82,0x60,0x60,0xF0,0xF8,0xC8,0x82,0x87,0x7A,0xE8,0x74,0x5E,0xD6, + 0xC8,0x82,0x66,0x72,0x0A,0xBB,0xFF,0xFD,0xA8,0x7A,0x67,0x72,0xF7,0x7F,0xEC,0x36, + 0x68,0x7A,0x44,0x49,0x7A,0xE8,0x80,0xA0,0xC5,0x61,0x03,0x49,0x55,0x5F,0x56,0x58, + 0x23,0x49,0xE3,0x40,0x8F,0x97,0x37,0xEB,0x64,0x49,0x23,0x49,0x0D,0x85,0xB5,0xB5, + 0x64,0x51,0x03,0x41,0x7E,0x5A,0xF8,0xE0,0x23,0x41,0x03,0x41,0xF6,0x21,0x41,0x5F, + 0x03,0x41,0xE2,0x38,0xF8,0xE8,0x5C,0x56,0x03,0x41,0xC2,0x38,0xEF,0xFA,0x35,0xBE, + 0x44,0x49,0xE2,0x38,0xAD,0x3F,0xDE,0xAB,0x64,0x49,0x23,0x41,0x8B,0xF9,0xF5,0xAD, + 0x44,0x41,0x03,0x41,0xC6,0x57,0xF6,0xE8,0x03,0x41,0xC2,0x38,0xFE,0xA0,0x80,0x70, + 0x03,0x41,0xC2,0x38,0xAA,0xAE,0xEF,0xB7,0x24,0x41,0xE3,0x38,0x5E,0xDF,0x1F,0xED, + 0x24,0x41,0xE3,0x38,0x9B,0xB6,0xAC,0xAA,0x45,0x41,0x04,0x41,0xEF,0xFA,0x5F,0x77, + 0x85,0x51,0x24,0x49,0xFF,0xDD,0xDB,0x55,0x85,0x59,0x24,0x49,0x02,0xAB,0x2F,0xDD, + 0x85,0x59,0x24,0x49,0x2A,0xE8,0xDE,0xFF,0xC6,0x59,0x44,0x51,0x0B,0x2B,0x2D,0xBD, + 0xC6,0x61,0x23,0x49,0x7E,0x78,0xC8,0xA2,0xA5,0x59,0x24,0x49,0x29,0xB9,0xA9,0xAB, + 0xA6,0x59,0x23,0x41,0x6A,0x60,0xFA,0x6E,0x23,0x49,0xA3,0x30,0x7A,0x6E,0xFC,0xFE, + 0xC2,0x30,0x83,0x30,0x2B,0xAA,0xAF,0x2D,0x03,0x39,0xA2,0x30,0xF7,0xA7,0x2B,0x0D, + 0x24,0x41,0xE3,0x38,0xFD,0xEF,0xAA,0x8E,0x24,0x41,0xE3,0x38,0xBF,0xBB,0xBF,0xB7, + 0xA5,0x59,0x24,0x41,0xAD,0xEB,0x0D,0x21,0xA6,0x59,0x23,0x49,0xFF,0xF6,0xDE,0x38, + 0xA5,0x59,0x44,0x51,0xB7,0x3D,0x27,0xBB,0xA5,0x59,0x44,0x51,0xFA,0x6E,0xEA,0x88, + 0x64,0x51,0x03,0x49,0x5C,0x56,0x5E,0x58,0x24,0x49,0xE3,0x40,0x22,0xFD,0xA3,0x02, + 0x44,0x49,0x03,0x39,0xE8,0xAA,0x4A,0xEA,0x23,0x41,0xC2,0x38,0xF8,0xEB,0xFB,0x7E, + 0x03,0x39,0xC2,0x38,0xEE,0x97,0x17,0x27,0x03,0x41,0xE3,0x38,0x2B,0x2F,0xFE,0xFE, + 0x44,0x41,0x03,0x41,0x57,0xA1,0x0B,0xA9,0x64,0x49,0x23,0x41,0x5D,0x7F,0x62,0xC2, + 0x64,0x49,0x23,0x41,0x29,0x0D,0xB5,0x95,0x85,0x49,0x23,0x41,0x58,0x52,0x5A,0x5E, + 0x23,0x41,0xE2,0x38,0xEA,0xFE,0xEF,0xFF,0x24,0x41,0xE2,0x38,0x99,0xB9,0xAF,0xE7, + 0x44,0x41,0xE2,0x38,0xF7,0x7E,0xFA,0xAF,0x44,0x41,0xE2,0x38,0x3F,0xAD,0xBF,0xBE, + 0x44,0x41,0x03,0x39,0xA0,0xAB,0x77,0x7A,0x23,0x41,0xE2,0x38,0xE8,0x78,0x6A,0x72, + 0x03,0x39,0xE3,0x38,0xFB,0xEF,0x3F,0x2D,0x23,0x39,0xE2,0x38,0xAA,0xA8,0x43,0x83, + 0x23,0x39,0xE2,0x38,0x8B,0xAD,0xE5,0x5D,0x23,0x41,0xE3,0x38,0x8A,0xBE,0xAA,0xA2, + 0x44,0x49,0xE3,0x38,0xFB,0x6F,0xFA,0x02,0x44,0x49,0xE3,0x40,0xF7,0xEF,0x3F,0xAA, + 0x64,0x49,0x23,0x41,0xCB,0xA9,0xBB,0x3A,0xA5,0x51,0x44,0x49,0xFB,0xEA,0xAB,0x37, + 0xA5,0x59,0x44,0x49,0xDF,0x7F,0xD6,0x7C,0xA5,0x59,0x23,0x49,0x2F,0xBF,0xFF,0xD7, + 0xC5,0x61,0x64,0x49,0xAA,0xAF,0x27,0x25,0x67,0x72,0xC5,0x59,0x29,0x25,0xD5,0x55, + 0x88,0x72,0xE5,0x61,0x7E,0xC8,0x8B,0xB5,0x67,0x72,0xA4,0x59,0xDD,0xFB,0xF8,0x88, + 0x47,0x72,0xE6,0x61,0x8A,0xBF,0x3F,0xFF,0xC9,0x82,0x26,0x6A,0xB5,0x2D,0x2B,0x2D, + 0x0A,0x8B,0x67,0x72,0x57,0x7B,0xEE,0xA8,0xA8,0x7A,0x27,0x72,0xE7,0xA9,0xAA,0xA8, + 0xED,0xA3,0x88,0x7A,0x3D,0xB5,0xF5,0xFF,0x51,0xCD,0xED,0xAB,0xA2,0x03,0x09,0x09, + 0x10,0xC5,0xAF,0xBC,0x7E,0x7A,0x6A,0xA0,0xCF,0xBC,0x6E,0xB4,0x77,0x57,0xF7,0x5C, + 0xCF,0xBC,0x6E,0xB4,0x2D,0xBF,0xFF,0x7D,0xCF,0xBC,0x6E,0xB4,0x80,0xA8,0xF3,0xD7, + 0xAF,0xB4,0x6F,0xB4,0xA0,0xDC,0xDF,0x7E,0x31,0xCD,0x8F,0xB4,0x77,0xAD,0x2F,0x29, + 0x52,0xCD,0xAF,0xBC,0xFD,0xAB,0x8A,0x20,0x51,0xC5,0xF0,0xC4,0x55,0xB6,0x8E,0xA2, + 0x72,0xCD,0xF0,0xBC,0xA7,0x37,0xAF,0x2A,0xB3,0xD5,0x72,0xCD,0x55,0xAB,0x83,0x8B, + 0xB3,0xD5,0x10,0xBD,0x7F,0xFA,0xFA,0xE0,0x52,0xC5,0x11,0xBD,0x0D,0x2F,0xED,0x7E, + 0x93,0xCD,0x11,0xBD,0x82,0x3F,0xFF,0xF5,0xB3,0xCD,0x52,0xC5,0x00,0x02,0xAA,0xD7, + 0x93,0xCD,0xD1,0xB4,0x78,0xA0,0x00,0x00,0x73,0xCD,0xB0,0xB4,0x55,0x5F,0x7C,0x60, + 0xD1,0xB4,0x2F,0xA4,0xBE,0xBF,0x3F,0x28,0x32,0xC5,0x90,0xAC,0x03,0x82,0x42,0x62, + 0xD0,0xB4,0xCD,0x93,0xA8,0xFA,0x7F,0x57,0xF1,0xB4,0x0E,0x9C,0xBA,0x2B,0x2D,0xAF, + 0xF1,0xB4,0xB0,0xB4,0xBD,0xB6,0xF5,0xD5,0xD0,0xB4,0x90,0xAC,0xBA,0xC8,0xEA,0x7A, + 0xD0,0xB4,0x8F,0xAC,0x2E,0xB6,0x57,0xD7,0x11,0xBD,0x90,0xAC,0x2F,0xAF,0xB9,0x6F, + 0x43,0x51,0x02,0x49,0xBD,0xFF,0x5A,0x72,0x43,0x51,0xE2,0x48,0xA2,0xF8,0xFF,0xAE, + 0x64,0x59,0x23,0x51,0x75,0xF5,0xEF,0x8F,0x64,0x59,0x43,0x51,0xFD,0xDD,0x75,0x5E, + 0x64,0x59,0x02,0x49,0x6B,0x6A,0xAA,0x22,0xA4,0x61,0x02,0x49,0xEF,0xAD,0xAF,0x8A, + 0xA4,0x61,0x44,0x59,0xD7,0xBD,0xFF,0xD5,0x84,0x61,0x23,0x51,0xF8,0xBA,0x7E,0xFF, + 0x84,0x61,0x23,0x51,0x2A,0x2E,0x2F,0x0B,0x84,0x59,0x43,0x59,0xAD,0x8A,0xAE,0xEE, + 0x84,0x61,0x23,0x51,0x88,0xC2,0xAA,0x7E,0x63,0x59,0x03,0x51,0xA0,0x82,0x98,0xAE, + 0x43,0x59,0x23,0x51,0x08,0x36,0x28,0x20,0x64,0x59,0x23,0x51,0x9B,0xDF,0xBB,0xF8, + 0x64,0x59,0x02,0x51,0x3F,0x3B,0xDF,0xBA,0x64,0x59,0x23,0x51,0x7E,0xEE,0xBA,0xFB, + 0x64,0x59,0x23,0x51,0xF9,0x6B,0x6C,0x55,0x44,0x59,0x03,0x49,0xC2,0xD2,0xBC,0xD6, + 0x43,0x51,0xE2,0x48,0xFF,0xAE,0x7F,0xB2,0x23,0x51,0xE2,0x48,0x82,0xAA,0xED,0xF6, + 0x43,0x51,0x03,0x49,0xF7,0x75,0x7D,0xFB,0x43,0x51,0x03,0x49,0xFB,0xAB,0x8B,0x2E, + 0x68,0x7A,0x23,0x51,0xD5,0xD5,0x35,0x2D,0xAB,0xA3,0x27,0x72,0x2D,0x29,0x0B,0x0A, + 0xCC,0xA3,0x8B,0xA3,0xAB,0x00,0x68,0x58,0x8B,0xA3,0x4A,0x93,0x6C,0x2C,0xFF,0xDF, + 0x6A,0x9B,0x29,0x93,0xBA,0xBE,0xF8,0x72,0x4A,0x93,0x09,0x93,0xF8,0x72,0xEA,0x20, + 0x4A,0x93,0x09,0x8B,0x38,0x95,0x27,0xB4,0x6A,0x9B,0x29,0x93,0x6B,0xAB,0xBB,0x27, + 0x6A,0x93,0x09,0x93,0x8D,0xBE,0xEE,0xEA,0x8B,0x9B,0x4A,0x93,0xB2,0xAF,0xBF,0xFD, + 0x8B,0x9B,0xA7,0x82,0xFA,0x7A,0x7A,0x7A,0xA7,0x82,0x87,0x7A,0x3F,0xF0,0xC8,0xC8, + 0xA8,0x82,0x67,0x7A,0xBE,0xE2,0xFF,0x7F,0xA7,0x7A,0x67,0x7A,0xBC,0xDA,0x69,0x5F, + 0x87,0x7A,0x26,0x6A,0x5C,0x7E,0xFA,0xFA,0x26,0x6A,0x64,0x51,0x5C,0x78,0xE0,0x80, + 0x85,0x59,0xE3,0x40,0x77,0x5F,0xDE,0xC0,0x44,0x49,0xE3,0x40,0x0A,0x29,0x2B,0xA2, + 0x64,0x49,0x23,0x49,0x80,0xCA,0xBE,0xDD,0x44,0x49,0xC2,0x38,0xFA,0x7E,0x76,0xE8, + 0x03,0x39,0xC2,0x38,0xBF,0xBF,0x89,0xAA,0x03,0x39,0xC2,0x38,0x80,0xA8,0xAE,0xD6, + 0x44,0x49,0xE3,0x38,0x8B,0xAB,0xBF,0xF5,0xA5,0x51,0x23,0x41,0xF5,0xE5,0xA5,0x3D, + 0x85,0x51,0x23,0x41,0x7A,0x7A,0x72,0xE0,0x23,0x41,0xC3,0x38,0x73,0xEA,0xB8,0xFA, + 0x03,0x41,0xC2,0x38,0xEF,0xAA,0xF0,0x70,0x23,0x41,0xE3,0x38,0xBB,0xAB,0xAB,0xDD, + 0x24,0x41,0xE3,0x38,0xCA,0xFA,0xF8,0xEA,0x03,0x41,0x23,0x39,0x2A,0xA0,0x80,0x88, + 0x44,0x49,0xE3,0x38,0xAA,0xAA,0x2B,0xA7,0x64,0x51,0x24,0x49,0xF5,0xB9,0xCE,0xFF, + 0x85,0x51,0x44,0x51,0x7B,0xF9,0x89,0x87,0x85,0x59,0x65,0x51,0x25,0x0D,0xAB,0xC9, + 0xE6,0x61,0x85,0x59,0xE1,0xE3,0x7D,0x55,0xC6,0x59,0x65,0x51,0xB7,0xBA,0xE3,0xCD, + 0x85,0x51,0x44,0x49,0x6A,0x68,0xE2,0x5C,0x44,0x49,0xC2,0x30,0x7E,0xF4,0x7E,0x5F, + 0xC2,0x30,0xA2,0x30,0xBF,0x98,0x20,0x22,0x24,0x39,0xC2,0x30,0xA5,0x3D,0xA5,0xFD, + 0x24,0x41,0xE3,0x38,0xAA,0x9E,0xEE,0xE7,0x03,0x41,0xE3,0x38,0x27,0x2B,0xE0,0xEA, + 0xA5,0x59,0x03,0x41,0x09,0x2D,0x0F,0x3D,0x07,0x62,0x85,0x59,0xDF,0x7B,0xB3,0xBB, + 0x07,0x6A,0x85,0x59,0x57,0x7F,0xF2,0xE8,0xC6,0x59,0x44,0x51,0x29,0xAA,0xE2,0xEA, + 0xA5,0x59,0x03,0x41,0x58,0x78,0x7A,0x7A,0x24,0x49,0x03,0x41,0x8A,0xAA,0xF5,0x55, + 0x24,0x41,0x03,0x41,0x60,0xE0,0x60,0x63,0x03,0x41,0xC2,0x38,0x7A,0x6A,0xEE,0xBA, + 0x24,0x41,0xE3,0x38,0xA5,0xA5,0xAF,0xAD,0x23,0x41,0x03,0x39,0xB7,0xAF,0x3F,0x35, + 0x64,0x49,0x24,0x41,0x6D,0xA9,0xAD,0xBD,0x64,0x49,0x23,0x41,0x09,0xAF,0xA2,0x8A, + 0x65,0x49,0x03,0x41,0xBF,0xDF,0xBA,0x8A,0x64,0x49,0x03,0x39,0x78,0xEC,0x7F,0x7E, + 0x23,0x41,0xE3,0x38,0xFF,0x5F,0x7F,0x2A,0x03,0x41,0xC2,0x30,0xAE,0xAF,0x5D,0xFC, + 0x44,0x41,0xE2,0x38,0x2B,0x8E,0x75,0xD5,0x23,0x41,0xE2,0x30,0x3A,0x3B,0xFF,0xAF, + 0x24,0x39,0x03,0x39,0x68,0x56,0xFF,0xF5,0x44,0x41,0xE3,0x38,0x7B,0xFF,0xE8,0xAA, + 0x23,0x39,0xE3,0x30,0xE7,0xD7,0xF7,0xEA,0x23,0x39,0xE3,0x30,0xAC,0x3E,0xFB,0xF2, + 0x03,0x39,0xE2,0x30,0xDF,0x3E,0xBA,0xF8,0x44,0x41,0xE2,0x38,0xF5,0xF6,0xF7,0x35, + 0x85,0x49,0x03,0x39,0xAD,0x2D,0xA5,0xF5,0x64,0x49,0x03,0x41,0xF8,0xDE,0xFA,0xAA, + 0x44,0x49,0x23,0x39,0x02,0x82,0x02,0x20,0x85,0x51,0x23,0x49,0xB7,0xBF,0xE2,0xE2, + 0x85,0x51,0x23,0x49,0x58,0x7F,0xD7,0x7F,0x64,0x49,0x23,0x49,0xAB,0xB5,0xB5,0x5F, + 0xA5,0x59,0x23,0x49,0x2F,0xAF,0xFF,0x7D,0xC5,0x59,0x64,0x51,0x03,0x0B,0x2B,0xB5, + 0x05,0x62,0x84,0x51,0x3A,0xBB,0xAD,0xF5,0x47,0x72,0xC5,0x61,0x02,0x8A,0xEB,0xBD, + 0x47,0x72,0xE5,0x61,0xFE,0xFE,0x2E,0x2B,0xC9,0x82,0x26,0x6A,0x25,0xB5,0xF5,0xFF, + 0x2A,0x8B,0x88,0x7A,0xAA,0x0B,0xA9,0xBB,0x29,0x93,0x87,0x7A,0xD7,0x7E,0xEA,0xA0, + 0x0A,0x8B,0x88,0x7A,0x2B,0xB5,0xFF,0xB6,0x52,0xD5,0x4A,0x93,0x09,0x2D,0x2D,0x2D, + 0x72,0xD5,0xF0,0xC4,0x7C,0x78,0xF8,0xE0,0x51,0xCD,0x4E,0xAC,0x5E,0x7A,0xA8,0x00, + 0x72,0xCD,0x4E,0xAC,0x55,0xD5,0xFF,0x02,0xD3,0xDD,0x6E,0xB4,0x55,0x55,0x7F,0xA8, + 0xF0,0xC4,0x4D,0xAC,0x96,0xD7,0x97,0x00,0x92,0xD5,0xD0,0xBC,0xBD,0xAD,0x2D,0x0B, + 0xB3,0xD5,0x51,0xCD,0x5D,0xFF,0x0B,0x0A,0xD4,0xDD,0x72,0xCD,0x5D,0xEA,0x60,0x6A, + 0x93,0xCD,0x52,0xCD,0x57,0xDC,0x37,0x87,0xD4,0xD5,0x72,0xCD,0x8D,0xF9,0xFE,0xDE, + 0xB4,0xD5,0x73,0xCD,0x70,0x5A,0xF7,0xD7,0x72,0xCD,0x11,0xBD,0x7E,0xE8,0xF8,0xBC, + 0x32,0xC5,0x11,0xBD,0xBF,0xFE,0x90,0x60,0x52,0xC5,0xF1,0xBC,0x80,0xAE,0xAF,0xF7, + 0x93,0xCD,0x32,0xC5,0x03,0xAB,0xBF,0xFD,0xB4,0xCD,0x52,0xC5,0x5A,0x0B,0xAF,0xBD, + 0x93,0xCD,0xF1,0xBC,0x57,0xE0,0xA0,0xE0,0x12,0xBD,0xED,0x9B,0xE0,0xE0,0x68,0x78, + 0x6E,0xA4,0xCC,0x93,0x57,0xD5,0x95,0x35,0xD0,0xB4,0x4E,0xA4,0x29,0x39,0xAB,0x02, + 0xD0,0xB4,0x8F,0xB4,0xB0,0x78,0xF8,0xEA,0xD1,0xB4,0x6F,0xAC,0xEA,0xA2,0xDE,0xEF, + 0xD1,0xB4,0x6F,0xAC,0x3F,0xAF,0xB7,0xAE,0xF1,0xB4,0x90,0xAC,0x4F,0xBE,0xA9,0xEB, + 0x63,0x59,0x23,0x51,0x7E,0x59,0xE6,0xAE,0x43,0x51,0x02,0x49,0x20,0xAA,0xFB,0x6A, + 0x43,0x51,0x23,0x51,0x02,0x02,0x29,0x99,0x64,0x59,0x23,0x51,0x28,0xAE,0xDB,0x4F, + 0x64,0x59,0x23,0x51,0xA2,0xE8,0xA8,0xB7,0x84,0x59,0x43,0x59,0x82,0x6B,0x5F,0x5F, + 0x84,0x61,0x23,0x51,0xFD,0xBB,0xEA,0xC2,0x84,0x61,0x23,0x51,0xF6,0xFF,0xEF,0x8B, + 0x84,0x61,0x43,0x59,0x0A,0x03,0x27,0xAA,0xA4,0x61,0x43,0x59,0xFA,0x6A,0xE0,0xF2, + 0x64,0x59,0x23,0x59,0xFE,0xFB,0xBA,0xE8,0x64,0x59,0x23,0x51,0xC8,0x8A,0xEF,0x6B, + 0x64,0x59,0x23,0x51,0xBA,0xBF,0x1F,0xEF,0x64,0x59,0x23,0x59,0xA8,0xA8,0x02,0xA9, + 0x85,0x61,0x24,0x51,0xFE,0xFA,0x63,0xFF,0x64,0x59,0x23,0x51,0xAE,0xDD,0x7D,0x6F, + 0x44,0x59,0x03,0x51,0x5F,0xBC,0xBD,0x6F,0x23,0x51,0xE2,0x48,0xB8,0xF0,0x28,0xB3, + 0x43,0x51,0x03,0x49,0xFB,0xFA,0xEA,0xDB,0x23,0x51,0xE2,0x48,0x72,0xC8,0x82,0xA2, + 0x23,0x51,0x03,0x49,0xC1,0xB5,0xCF,0x0A,0x64,0x59,0x03,0x51,0xBF,0xBF,0x37,0x37, + 0x4A,0x93,0x64,0x59,0x2D,0x2D,0x0B,0x0B,0xCC,0xA3,0x4A,0x9B,0xAD,0x8B,0x2A,0xEE, + 0xEC,0xAB,0x8B,0x9B,0x5E,0xAF,0xAD,0x8F,0xCC,0xAB,0x4A,0x93,0x77,0x5A,0xE8,0xA0, + 0xAB,0xA3,0x4A,0x93,0x77,0xDD,0xEE,0xA8,0x6A,0x9B,0x29,0x93,0xFE,0xE6,0xF7,0x5E, + 0x6A,0x9B,0x09,0x8B,0x5E,0xFE,0xA3,0xAB,0x4A,0x93,0x09,0x93,0xAF,0xED,0xEF,0x30, + 0x4A,0x93,0x08,0x93,0x20,0xAA,0xA1,0xE8,0x6A,0x93,0x09,0x93,0x3B,0xAD,0xAF,0xEF, + 0x6A,0x9B,0xC8,0x82,0x72,0x62,0xFA,0x7A,0xA7,0x7A,0x67,0x72,0xA2,0xB8,0x68,0xAA, + 0xA8,0x7A,0x47,0x72,0xE2,0xE2,0x7F,0xF7,0x67,0x7A,0x26,0x72,0x80,0xE0,0x52,0x50, + 0x88,0x7A,0x47,0x72,0x7B,0x7D,0x77,0x49,0x46,0x72,0x06,0x6A,0x5F,0x7A,0x7A,0xFA, + 0x26,0x6A,0x64,0x51,0x7A,0xE8,0xEA,0x08,0xE5,0x61,0x23,0x49,0x55,0x5F,0x5E,0x68, + 0x43,0x49,0xE3,0x40,0xAA,0xFB,0x5F,0x54,0x43,0x49,0xE3,0x40,0xE8,0xEB,0xEF,0xF5, + 0xE3,0x40,0xC2,0x30,0xBE,0xEE,0xEA,0x60,0xE2,0x38,0xA1,0x30,0x0C,0xA8,0xFA,0xFB, + 0x03,0x41,0xC2,0x38,0x0B,0x0D,0x7D,0xF5,0xA5,0x51,0xE3,0x38,0x0F,0x2F,0xAD,0xFD, + 0x85,0x51,0x23,0x41,0xC0,0xCA,0xEA,0x7A,0x23,0x41,0xE3,0x38,0xBA,0xDC,0xDF,0x5F, + 0x24,0x41,0xC2,0x38,0xDA,0x2A,0x02,0x00,0x03,0x41,0xE3,0x38,0x7F,0xEC,0xBA,0x38, + 0x03,0x41,0xE3,0x38,0x36,0xD5,0xD7,0x5E,0x23,0x41,0xE4,0x38,0xEA,0xBF,0x0B,0x0A, + 0x44,0x49,0xE3,0x38,0x2B,0xB7,0xAE,0xE8,0x65,0x51,0x23,0x49,0xDC,0xF0,0x70,0xF2, + 0x85,0x59,0x03,0x41,0x0B,0x2B,0xBF,0x77,0xC6,0x59,0x44,0x51,0x8B,0x3A,0xAA,0xFD, + 0xA5,0x59,0x65,0x51,0xBC,0xBC,0xFE,0xFE,0xC6,0x59,0x64,0x51,0x5A,0x7A,0x4B,0x4F, + 0x85,0x51,0xC2,0x30,0xE8,0x6A,0x7E,0x5E,0xE3,0x38,0x82,0x30,0xA0,0xEA,0xDE,0xBF, + 0xC3,0x30,0xA2,0x30,0xE2,0xFF,0x5F,0x94,0xE3,0x30,0x82,0x28,0xAB,0xFD,0xBA,0xA8, + 0xE3,0x38,0xA2,0x30,0x21,0x7D,0x5F,0x5E,0x03,0x41,0xA3,0x30,0x2B,0xFB,0xBF,0xBD, + 0x64,0x51,0x03,0x41,0x2D,0x25,0x15,0xD5,0xE6,0x61,0x85,0x51,0x09,0xAB,0xFD,0x55, + 0xE6,0x61,0x64,0x51,0x00,0x82,0x8B,0xBF,0xC6,0x61,0x64,0x51,0x6A,0xF8,0xF0,0x80, + 0x64,0x51,0x03,0x41,0xA8,0xE0,0x60,0xF0,0x24,0x49,0x03,0x41,0x56,0xFE,0x2F,0xAC, + 0x24,0x41,0xE3,0x38,0xAB,0xA6,0x7E,0x78,0x04,0x41,0xC3,0x38,0x5E,0x72,0xAA,0x22, + 0x03,0x39,0xA3,0x38,0x0B,0xAA,0x88,0x28,0x03,0x39,0xC2,0x38,0x2A,0x2F,0xBD,0xBF, + 0x85,0x49,0x03,0x39,0x2B,0x2F,0xAD,0x8D,0x85,0x49,0x24,0x41,0xFF,0xD8,0xE0,0xFC, + 0x85,0x49,0xE2,0x38,0x8A,0x8A,0xFE,0x5D,0x44,0x41,0x03,0x39,0xA8,0xAE,0xFF,0x2D, + 0x23,0x41,0xE3,0x38,0x00,0xA0,0xF8,0xE0,0x23,0x41,0xC2,0x30,0xFE,0x66,0xFB,0xA8, + 0x03,0x39,0xC2,0x30,0x2F,0x2F,0x1F,0xF8,0x24,0x41,0xE2,0x30,0xAD,0x2F,0xAF,0xB5, + 0x23,0x39,0xE3,0x38,0xAA,0x88,0xA8,0x0F,0x24,0x41,0x03,0x39,0x1E,0xB9,0xAD,0xE2, + 0x23,0x39,0xE2,0x38,0xE8,0x78,0xB2,0xA0,0x23,0x39,0xE2,0x30,0xFF,0x55,0x5F,0xF0, + 0x23,0x41,0x03,0x39,0x75,0x25,0xA5,0x55,0x23,0x41,0xC2,0x30,0x27,0xAA,0xAF,0x0A, + 0x23,0x41,0xE2,0x38,0x17,0x0E,0x82,0x02,0x64,0x49,0x23,0x41,0x0B,0x0B,0x7F,0xFF, + 0x64,0x49,0x23,0x41,0x37,0xDF,0xBA,0xE7,0x84,0x51,0x44,0x49,0x5E,0x2F,0x65,0x7D, + 0x85,0x51,0x23,0x41,0xFD,0xD7,0xFB,0xC2,0x65,0x49,0x23,0x49,0xF7,0xB5,0x36,0xF7, + 0x85,0x51,0x23,0x49,0xFF,0xBF,0x35,0x8F,0xC5,0x61,0x22,0x49,0xDF,0xFE,0xA8,0x2B, + 0xA4,0x59,0x64,0x51,0x9B,0x7D,0xD8,0xA8,0x06,0x62,0x64,0x51,0x2F,0xAD,0x75,0xFF, + 0x26,0x6A,0x84,0x59,0x00,0xAE,0xF7,0xDD,0x67,0x7A,0xA5,0x61,0x2A,0x2B,0xAD,0xF5, + 0x0A,0x8B,0x26,0x72,0x0A,0x2B,0xAB,0xFD,0x2A,0x8B,0xC9,0x82,0xC0,0xA2,0x29,0xF9, + 0x09,0x8B,0xA8,0x7A,0xFA,0xF0,0xA0,0x28,0x52,0xD5,0x09,0x8B,0x2D,0x2D,0xB5,0xB5, + 0x35,0xE6,0x52,0xD5,0x5F,0xEB,0x0B,0x09,0x55,0xEE,0x72,0xD5,0x55,0xBF,0xAA,0x00, + 0x35,0xEE,0x72,0xD5,0xAD,0x8A,0x00,0x00,0x55,0xEE,0xF4,0xDD,0x5F,0xFF,0xEF,0xF2, + 0x35,0xE6,0xD3,0xDD,0x7D,0xAB,0x8A,0x80,0x14,0xE6,0x92,0xD5,0xF7,0xAA,0x00,0x08, + 0x34,0xE6,0x92,0xD5,0x7F,0xFE,0x8A,0x20,0x14,0xDE,0x52,0xC5,0x57,0x5F,0x5A,0x58, + 0xB3,0xD5,0x52,0xC5,0xA5,0x3D,0xAF,0xAD,0xB3,0xD5,0x73,0xCD,0xFE,0xEA,0xAA,0x3B, + 0x93,0xCD,0x52,0xC5,0xEE,0xAE,0xFE,0xF8,0x72,0xCD,0x32,0xC5,0xF4,0xF8,0x78,0xE0, + 0x52,0xC5,0x12,0xBD,0x6E,0xF8,0x7A,0xAA,0x32,0xC5,0xF1,0xBC,0x5F,0x76,0x7A,0xD8, + 0x52,0xC5,0xF1,0xBC,0x2B,0xE5,0x5D,0x5D,0x73,0xCD,0xF1,0xBC,0x22,0x0B,0xAF,0xF7, + 0x73,0xCD,0xD0,0xB4,0xE0,0xF8,0x7E,0x7F,0xD1,0xB4,0xCD,0x9B,0x78,0xF8,0x7E,0x7E, + 0xB0,0xB4,0xCC,0x93,0x25,0x2F,0x0B,0x0B,0xD1,0xB4,0x8F,0xAC,0xA2,0xE2,0x40,0xA2, + 0xD0,0xB4,0x8F,0xAC,0xEA,0xDB,0x7A,0xCC,0xB0,0xB4,0x70,0xAC,0xDA,0x90,0x3C,0x2E, + 0xB0,0xB4,0x70,0xAC,0xA8,0xEA,0xFE,0x18,0xD1,0xB4,0x90,0xAC,0xEB,0xE9,0xD5,0xBD, + 0x63,0x59,0x23,0x51,0xAE,0xFA,0xF1,0xA3,0x84,0x59,0x43,0x51,0x75,0xDF,0xEB,0xFE, + 0x84,0x59,0x23,0x51,0x57,0xFA,0xFA,0xDC,0x83,0x59,0x23,0x51,0x7D,0xF5,0xFD,0xEF, + 0x63,0x59,0x23,0x51,0xDF,0xB2,0x83,0xCB,0x63,0x59,0x23,0x51,0xF1,0xAA,0xAF,0xAA, + 0x84,0x61,0x43,0x59,0xDB,0xED,0x0F,0x39,0xA4,0x61,0x44,0x59,0xEB,0x2D,0xE8,0xAA, + 0xA4,0x61,0x64,0x59,0xFF,0xBD,0xA9,0xFF,0x84,0x59,0x43,0x59,0xF8,0x6C,0xEF,0xBF, + 0x64,0x59,0x23,0x51,0xAA,0x21,0x2A,0xEE,0x63,0x59,0x23,0x51,0xDA,0x7A,0x6F,0xEE, + 0x64,0x59,0x23,0x51,0xEA,0x8A,0xE9,0xFF,0x44,0x59,0x23,0x51,0xAB,0x5E,0x77,0xDA, + 0x44,0x59,0x23,0x51,0x92,0x73,0xB6,0xA7,0x44,0x59,0xE2,0x48,0xA0,0xE8,0x78,0xF8, + 0x23,0x51,0x03,0x49,0x6B,0xDF,0x69,0x6D,0x23,0x51,0xC2,0x40,0xAA,0x98,0xAA,0xAA, + 0x23,0x51,0xE2,0x48,0xBA,0x6A,0xDA,0xB2,0x23,0x51,0xE2,0x48,0x92,0x23,0x02,0xAA, + 0x43,0x51,0x03,0x49,0xCA,0xAF,0x5F,0xF7,0xE9,0x8A,0x23,0x51,0xD5,0x95,0xB5,0x25, + 0xAB,0xA3,0x88,0x82,0x8D,0x2B,0x8B,0x88,0xAB,0xA3,0x6B,0x9B,0xFE,0x2E,0xA6,0x2F, + 0xEC,0xAB,0xAB,0xA3,0x85,0xAD,0x21,0x2D,0x0D,0xAC,0xCC,0xA3,0x7F,0x7D,0x7F,0x7A, + 0xCB,0xA3,0x8B,0x9B,0xFE,0x5C,0x56,0x5E,0x8A,0x9B,0x29,0x93,0x6E,0xF8,0x78,0xD8, + 0x6A,0x9B,0x29,0x93,0xED,0xA7,0xCA,0x7B,0x6A,0x9B,0x09,0x8B,0x3F,0xDF,0xFE,0xFE, + 0x6A,0x9B,0x2A,0x93,0x7E,0xF9,0xAF,0xAB,0x6A,0x9B,0x08,0x93,0xAD,0x8B,0x82,0x02, + 0x4A,0x93,0xC8,0x82,0x7A,0x68,0x60,0x70,0xA8,0x7A,0x46,0x72,0xA8,0x5A,0x78,0xFE, + 0x88,0x7A,0x46,0x72,0xBA,0x69,0xE9,0xEF,0x67,0x7A,0x06,0x6A,0x90,0xFE,0xEE,0xAA, + 0x67,0x7A,0x06,0x6A,0x60,0x7E,0xFF,0xDF,0x47,0x72,0x06,0x6A,0x7B,0x8D,0x7F,0xE6, + 0x26,0x6A,0xE6,0x69,0x80,0xE0,0xA8,0xC0,0x06,0x6A,0x64,0x51,0x78,0xEA,0xC0,0x00, + 0xE5,0x61,0xC2,0x38,0x7F,0x7E,0x7A,0xF8,0x23,0x49,0xC2,0x38,0xBD,0xAD,0x2B,0x80, + 0x23,0x41,0xE2,0x38,0x5F,0x57,0x5E,0x58,0xE2,0x38,0x81,0x30,0xA2,0x00,0xAC,0xBE, + 0x03,0x39,0xC2,0x38,0xAB,0xBB,0xFE,0xE7,0x23,0x41,0xE3,0x38,0x2D,0xFB,0xAD,0xAD, + 0x44,0x49,0xE3,0x38,0xE2,0xEA,0xFE,0x7B,0x03,0x41,0xE3,0x38,0xAA,0x76,0x4A,0xEB, + 0x23,0x41,0xE3,0x38,0x0A,0xED,0xF5,0x5F,0x24,0x41,0xE2,0x38,0xE0,0xF2,0xFA,0xE3, + 0x24,0x41,0xC2,0x38,0xEA,0xBD,0xEA,0xAE,0x24,0x41,0xE2,0x38,0xAC,0x77,0xDE,0x8A, + 0x44,0x49,0xE2,0x38,0xCA,0xFB,0x57,0xF5,0x44,0x49,0x03,0x41,0x2A,0x5B,0xFD,0x9D, + 0x44,0x49,0x03,0x41,0xF8,0x7F,0x5E,0xFE,0x85,0x51,0x24,0x49,0xA3,0xBD,0xBF,0x27, + 0xA5,0x59,0x65,0x51,0xFE,0x8B,0x2F,0x8F,0x85,0x51,0x44,0x49,0xC3,0x6E,0x7C,0x5C, + 0x44,0x49,0xC3,0x30,0x58,0xF0,0xE0,0xF8,0x04,0x39,0xA2,0x30,0xD5,0x7F,0x7A,0xF8, + 0xE3,0x30,0xA2,0x30,0x9C,0x9F,0x95,0x95,0x24,0x39,0xC3,0x30,0xFD,0xFF,0xEB,0x82, + 0x03,0x39,0xA2,0x30,0x7F,0xBF,0xEA,0xEC,0x04,0x39,0xC3,0x38,0x55,0xF5,0xAF,0xBD, + 0x23,0x41,0xE3,0x38,0x3D,0xFD,0xD5,0xBD,0x85,0x59,0x03,0x41,0x0B,0x0F,0xAD,0xBF, + 0xA5,0x59,0x65,0x51,0x0F,0x8A,0xDB,0xFF,0x26,0x6A,0x85,0x51,0xEB,0x8B,0xAF,0xF5, + 0xC6,0x59,0x44,0x49,0x7E,0x5E,0xEC,0xBC,0x44,0x49,0x04,0x41,0x7F,0x28,0xBA,0xF8, + 0x24,0x41,0xE3,0x38,0xFC,0xEE,0xFE,0xBC,0x04,0x41,0xC3,0x38,0xA2,0xE8,0xB0,0xF8, + 0xE3,0x38,0xC3,0x38,0x00,0x23,0x00,0x08,0x03,0x39,0xC3,0x30,0xAF,0xBF,0x0F,0x28, + 0x64,0x49,0x03,0x39,0x2B,0x2F,0xBF,0xB5,0x64,0x41,0x03,0x41,0x68,0x7E,0xFE,0xFB, + 0x44,0x41,0x03,0x41,0x57,0xD5,0xFF,0xF3,0x85,0x49,0x03,0x41,0xBD,0xAF,0xBD,0xFF, + 0x85,0x49,0x23,0x41,0x5E,0xFE,0x68,0xDA,0x44,0x41,0xE2,0x38,0xAA,0xA2,0xAB,0x7F, + 0x03,0x39,0xC2,0x30,0x78,0xA8,0x2A,0x00,0x03,0x39,0xC2,0x30,0x2F,0xCB,0xE8,0x23, + 0x44,0x39,0xE3,0x38,0xBD,0xFD,0xDD,0x55,0x24,0x39,0x03,0x39,0xD0,0x5C,0x5E,0x5D, + 0x23,0x39,0xC2,0x30,0xA2,0xA8,0xFE,0x77,0x03,0x39,0xE2,0x30,0xE0,0xDE,0xBB,0xAD, + 0x23,0x41,0xC2,0x30,0xAF,0x2B,0x0F,0x2F,0x43,0x41,0xE2,0x38,0x6B,0xFE,0x2A,0xAA, + 0x85,0x49,0x23,0x41,0xF5,0x7D,0x97,0x3D,0xA5,0x51,0x23,0x41,0x7D,0xEF,0x6A,0x80, + 0x85,0x51,0x23,0x41,0xF7,0xFF,0xEB,0x20,0x84,0x51,0x44,0x49,0x5B,0x6A,0xBA,0xC8, + 0xA6,0x51,0x44,0x49,0xF5,0xFF,0xFF,0xF8,0xA5,0x59,0x23,0x41,0xD7,0xFF,0xA2,0x02, + 0xA5,0x59,0x64,0x51,0x75,0xA5,0xE5,0x88,0xC5,0x59,0x84,0x51,0x8D,0x2B,0xAB,0xFB, + 0xE6,0x61,0x84,0x59,0x6A,0xC7,0x27,0x3F,0xC5,0x61,0x84,0x59,0xE3,0x00,0x8E,0x9C, + 0x06,0x6A,0x64,0x59,0xFD,0xFB,0xAA,0x03,0x06,0x6A,0x84,0x59,0xB5,0xB7,0x37,0x3E, + 0x88,0x7A,0x06,0x6A,0x2F,0xAF,0xED,0xAF,0x09,0x8B,0x46,0x72,0x2A,0x8F,0xBD,0xB5, + 0x09,0x8B,0xA8,0x82,0x2F,0xA7,0xA9,0x2F,0x2E,0xAC,0xE9,0x82,0x2D,0x35,0x3D,0xB5, + 0x35,0xEE,0xB0,0xBC,0x0B,0x0B,0x0B,0x09,0x76,0xEE,0x35,0xEE,0xFE,0xEA,0x2A,0x28, + 0x76,0xEE,0x35,0xE6,0xFF,0xFA,0xAA,0xAA,0x76,0xEE,0x35,0xE6,0x7E,0xEA,0xE8,0x6A, + 0x55,0xEE,0x35,0xE6,0x7F,0xA8,0xE8,0x7A,0x14,0xEE,0x35,0xE6,0xFE,0x75,0xD5,0xF5, + 0x35,0xE6,0xF4,0xDD,0x88,0x88,0xA8,0x78,0xF4,0xDD,0x11,0xC5,0xF0,0x78,0x7C,0x5A, + 0xB3,0xCD,0x31,0xC5,0xAF,0x8F,0x2D,0x89,0xB3,0xD5,0x52,0xC5,0x2A,0xAA,0xBA,0xF6, + 0xD3,0xCD,0x73,0xCD,0x5F,0xDF,0x6F,0x7D,0x93,0xCD,0x52,0xC5,0x7F,0x6A,0xBB,0xBE, + 0x73,0xCD,0x12,0xBD,0xFF,0x7A,0x7A,0x68,0x32,0xC5,0x11,0xBD,0x60,0xEA,0x09,0x0A, + 0x32,0xC5,0xD0,0xB4,0xFF,0x6A,0xEA,0xA8,0x11,0xBD,0xB0,0xB4,0x0A,0x8B,0xE8,0x6A, + 0xF1,0xB4,0x89,0x72,0x80,0xA8,0xFE,0x5E,0x90,0xAC,0xAD,0x93,0xFE,0xBF,0xAD,0x2D, + 0xB0,0xB4,0x4F,0xA4,0x05,0x0B,0x2A,0x0B,0xD0,0xB4,0x90,0xAC,0x8B,0xDE,0x7E,0xFB, + 0xD1,0xB4,0x6F,0xAC,0x0A,0x1D,0xAB,0x8A,0xD1,0xB4,0x8F,0xAC,0x9F,0x3E,0xFC,0x08, + 0xD1,0xB4,0x90,0xAC,0xFA,0xBC,0xFA,0x2A,0xD1,0xB4,0x8F,0xAC,0x88,0xF8,0x7B,0x5F, + 0x84,0x59,0x43,0x51,0x3F,0x2E,0x6A,0x2B,0x84,0x59,0x22,0x51,0xA8,0xA2,0xE9,0xBF, + 0x84,0x59,0x23,0x51,0xFF,0xFA,0xFB,0xE2,0x64,0x51,0x23,0x51,0xAF,0xF6,0xAB,0xA9, + 0x63,0x59,0x22,0x51,0x8A,0x82,0x8D,0x02,0x84,0x59,0x43,0x59,0xEB,0xFF,0xBD,0xB5, + 0xA4,0x61,0x64,0x59,0xDF,0xFE,0x3B,0x1A,0x84,0x61,0x43,0x59,0xEA,0xFF,0x4E,0x7E, + 0xA4,0x61,0x23,0x51,0xE8,0xFA,0x7F,0xF5,0x63,0x61,0x43,0x51,0xA9,0xCF,0xED,0xAB, + 0x63,0x59,0x23,0x51,0xFF,0xAA,0xA3,0xEA,0x64,0x59,0x43,0x59,0xF5,0xE2,0x4B,0x65, + 0x44,0x59,0x23,0x51,0x2E,0x2C,0x0E,0x4D,0x43,0x59,0x23,0x51,0xD8,0x9E,0x7C,0xB8, + 0x43,0x59,0x03,0x51,0xFF,0x56,0xFC,0xBE,0x43,0x51,0x03,0x49,0x78,0x69,0xAA,0xB0, + 0x23,0x51,0x03,0x49,0x77,0x75,0x62,0x5C,0x03,0x49,0xE2,0x48,0xB2,0xDD,0x57,0x0C, + 0x23,0x51,0xE2,0x48,0xA2,0x22,0xE8,0x6A,0x24,0x51,0xE2,0x48,0xB6,0xEE,0xF5,0xAD, + 0x63,0x59,0xE2,0x40,0xFF,0xBF,0xAD,0x2D,0x4A,0x93,0x83,0x59,0x25,0x2D,0x29,0x0B, + 0xAB,0xA3,0x4A,0x9B,0xCF,0xFF,0x2A,0x02,0xEC,0xAB,0x6B,0x9B,0xA5,0x8F,0x2A,0x0B, + 0xEC,0xAB,0xAB,0xA3,0x3D,0xE6,0x6C,0xF8,0xEC,0xAB,0x8A,0x9B,0x08,0xC8,0xFB,0x57, + 0xCB,0xA3,0x8A,0x9B,0xFB,0xCE,0xEB,0x55,0xAB,0xA3,0x6A,0x9B,0x57,0xE8,0xEE,0xA9, + 0x8B,0x9B,0x29,0x93,0x7B,0xFE,0xBA,0xA8,0x8B,0x9B,0x49,0x93,0x55,0xD5,0xEE,0x02, + 0x8A,0x9B,0x4A,0x93,0x7D,0xDF,0x6B,0xF2,0x6A,0x9B,0x2A,0x93,0xAE,0xAC,0xBF,0xFE, + 0x6A,0x9B,0x87,0x82,0x68,0x62,0xEA,0xFA,0xA8,0x7A,0x46,0x72,0xFC,0xDE,0x7F,0x7E, + 0x67,0x72,0x06,0x72,0x8A,0x22,0xEA,0x8A,0x67,0x72,0x26,0x72,0xEA,0xE8,0xFE,0xF9, + 0x47,0x72,0x05,0x6A,0xBB,0xEE,0x7A,0x20,0x47,0x72,0x06,0x6A,0xCA,0xA2,0x7A,0x78, + 0x47,0x72,0x06,0x6A,0x69,0xFA,0x7F,0x57,0x26,0x6A,0x06,0x6A,0x6F,0xD7,0x37,0x25, + 0x06,0x62,0x43,0x51,0x78,0xE0,0x80,0x80,0xA5,0x59,0x03,0x41,0x5F,0x7F,0xFA,0xE8, + 0x23,0x41,0xE2,0x38,0x70,0x62,0xB8,0xEC,0x03,0x41,0xA1,0x30,0xFF,0x7E,0xFA,0xC8, + 0x03,0x41,0xC2,0x38,0xAD,0x83,0xA1,0x3F,0x44,0x49,0xE2,0x38,0xAD,0xAD,0x8B,0xAB, + 0x44,0x49,0xE2,0x38,0x5E,0x7A,0xE8,0xA8,0xE3,0x40,0x03,0x39,0x7E,0xD7,0xFD,0x3F, + 0x03,0x41,0xC2,0x38,0xA8,0xF8,0xFA,0xFA,0x03,0x41,0xC2,0x38,0x82,0xAE,0xF7,0xF7, + 0x24,0x41,0xE3,0x38,0xBF,0x3D,0xBD,0xBD,0x44,0x41,0x03,0x41,0xF7,0xFF,0xAF,0xAA, + 0x44,0x49,0x03,0x41,0xE5,0xBB,0xEA,0x82,0x24,0x49,0x03,0x41,0xBF,0x7A,0x23,0x0B, + 0x44,0x49,0x03,0x41,0xBB,0xCF,0xBB,0xBF,0xC6,0x61,0x44,0x49,0xFD,0xA5,0x2D,0xAD, + 0xC6,0x61,0x65,0x51,0xFD,0xFF,0xFA,0xCA,0x86,0x51,0x04,0x41,0xEE,0x7C,0xFE,0xEA, + 0x24,0x41,0xC3,0x38,0xE0,0xCA,0xEA,0xE6,0x03,0x39,0xC3,0x38,0x5D,0xFB,0x72,0xFE, + 0xE3,0x38,0xA2,0x30,0x5D,0x5E,0xDE,0x5E,0x45,0x41,0xC3,0x30,0x81,0xFB,0xFD,0xF5, + 0x03,0x39,0xC3,0x30,0xFE,0xEF,0xFE,0xE0,0x24,0x41,0xC3,0x30,0xBF,0xAB,0xF9,0xCD, + 0x44,0x41,0xE3,0x40,0xFF,0xAA,0x89,0xBF,0x65,0x49,0x03,0x41,0x3D,0xBF,0x3E,0xAB, + 0x85,0x51,0x44,0x49,0xAA,0x5A,0xFB,0xEF,0x85,0x51,0x24,0x49,0x2B,0xAB,0xFE,0x7A, + 0x85,0x59,0x04,0x49,0x88,0xFA,0xFA,0x7D,0x44,0x49,0xE3,0x38,0xC0,0xF8,0xEF,0xFE, + 0x04,0x41,0xC3,0x38,0xA2,0x0B,0x2F,0x3F,0x04,0x41,0xC3,0x38,0x68,0xEA,0x70,0xB0, + 0x24,0x41,0xC3,0x38,0xD7,0xFD,0xAB,0x29,0x04,0x41,0xC3,0x38,0xA8,0xEF,0xAF,0xEF, + 0x44,0x41,0xC2,0x30,0x2F,0x8B,0x2F,0xB7,0x65,0x49,0x04,0x41,0xEB,0xFB,0xEE,0xFE, + 0x44,0x41,0x23,0x41,0x55,0xD5,0x9D,0x57,0x64,0x49,0xE3,0x38,0xAA,0x2B,0xFA,0xD7, + 0x44,0x41,0x03,0x39,0xEA,0x7E,0xFA,0xE8,0x23,0x41,0xC2,0x30,0xA8,0xFE,0xFA,0x5A, + 0x03,0x39,0xC2,0x30,0x80,0xA0,0xAB,0x8D,0xC2,0x38,0xE2,0x30,0x77,0xF7,0xF5,0xDD, + 0xE3,0x38,0xC2,0x30,0xA2,0xA3,0x3E,0x2A,0x03,0x39,0xC2,0x30,0xE2,0xE8,0x8A,0xAF, + 0x03,0x39,0xC2,0x30,0xFF,0xFB,0xAA,0xA8,0x24,0x39,0xC3,0x30,0xFD,0xFB,0xBF,0xAB, + 0x03,0x39,0xC2,0x30,0x2F,0x8A,0x00,0x80,0x23,0x41,0xE3,0x38,0x0A,0x3B,0x3B,0xAD, + 0x85,0x51,0x23,0x41,0xBD,0xAB,0x37,0xBD,0xC5,0x51,0x64,0x49,0x0B,0xAF,0xFA,0xFB, + 0xC6,0x59,0x85,0x51,0x7A,0x6E,0xFA,0x55,0x84,0x51,0x64,0x51,0xDF,0xF2,0xEB,0x79, + 0x85,0x51,0x23,0x49,0x00,0x02,0xBE,0x7E,0xE6,0x61,0x43,0x49,0xAB,0x0A,0x0B,0xAD, + 0x06,0x62,0xC6,0x61,0x75,0x5A,0xF2,0xA1,0x06,0x6A,0xA5,0x59,0x7D,0xFB,0xBE,0x3F, + 0x27,0x6A,0xA4,0x59,0xD5,0xDF,0x78,0xF2,0x06,0x6A,0xC5,0x61,0x5A,0x6E,0x21,0x9F, + 0x47,0x72,0x84,0x59,0x0F,0x27,0xB7,0xBF,0xA8,0x82,0x06,0x6A,0x5D,0xFF,0xA9,0x81, + 0x67,0x7A,0x06,0x6A,0x0D,0xF5,0xDF,0x7E,0xC9,0x82,0x46,0x72,0x0F,0x2B,0x29,0xA5, + 0x09,0x8B,0xC8,0x82,0xF5,0xD5,0xBA,0xA9,0x6B,0x93,0xE9,0x82,0x35,0x3D,0x27,0x2D, + 0x15,0xE6,0xED,0xA3,0x09,0x0D,0x2D,0x2D,0x75,0xEE,0x35,0xEE,0x8A,0x8B,0xED,0xF5, + 0x75,0xEE,0x35,0xE6,0x8A,0xA8,0xEE,0xFD,0x55,0xEE,0x15,0xE6,0x88,0x88,0xA8,0x42, + 0x55,0xEE,0x14,0xE6,0x8A,0xEE,0xFF,0x55,0x35,0xE6,0xF4,0xDD,0xA0,0xE8,0xFA,0x7B, + 0x14,0xDE,0xB4,0xD5,0xC0,0x80,0x68,0x7E,0x93,0xD5,0xF1,0xBC,0xDC,0xA8,0xAC,0xAE, + 0xB4,0xD5,0x52,0xC5,0xA9,0x8B,0xAA,0xA0,0x93,0xCD,0x32,0xC5,0xBA,0xE8,0x68,0xEA, + 0x72,0xCD,0x32,0xC5,0x00,0x83,0x2D,0xEF,0x73,0xCD,0x93,0xC5,0x82,0xAA,0x7C,0xAA, + 0x73,0xC5,0x32,0xC5,0xF8,0xEA,0xEA,0xAA,0x52,0xC5,0x11,0xBD,0xBA,0xFE,0xF7,0x67, + 0x32,0xC5,0xF1,0xBC,0xAC,0xAB,0x7F,0x5E,0x32,0xC5,0xED,0x9B,0xE8,0xE8,0x6A,0x7A, + 0xEE,0x9B,0x89,0x72,0x54,0x9E,0xBE,0x2A,0x4F,0xA4,0x6C,0x8B,0x2D,0x2B,0x0B,0x02, + 0xD1,0xB4,0x6F,0xAC,0x25,0xFD,0xB5,0xF5,0xD0,0xB4,0x90,0xAC,0xF6,0x3B,0xB5,0xB5, + 0xD1,0xB4,0x8F,0xAC,0xAA,0xEF,0x2B,0xB0,0xD0,0xB4,0x6F,0xAC,0xA0,0xFE,0x7E,0x57, + 0xB0,0xB4,0x4F,0xA4,0x00,0xAA,0xA6,0xB7,0xB0,0xB4,0x4F,0xA4,0xB0,0xBB,0xAF,0xB5, + 0x63,0x59,0x22,0x49,0x83,0xFA,0x7A,0x5B,0x84,0x59,0x22,0x51,0xBB,0xED,0x3B,0x3F, + 0x63,0x59,0x23,0x51,0x00,0x83,0x3C,0x2F,0x84,0x59,0x22,0x49,0xF6,0xA2,0xAC,0xBA, + 0x84,0x61,0x63,0x59,0x55,0x79,0x4B,0x45,0x84,0x61,0x43,0x59,0x2D,0x2B,0x2B,0x0E, + 0x84,0x61,0x63,0x59,0x15,0xB6,0xFE,0x7A,0x84,0x59,0x43,0x59,0xEE,0xBE,0xFE,0xFE, + 0x84,0x61,0x23,0x51,0xFF,0xAA,0xBA,0x68,0x63,0x59,0x02,0x51,0xA2,0x0A,0xB8,0x7F, + 0x63,0x59,0x23,0x51,0x2A,0x02,0x2B,0x7F,0x84,0x61,0x23,0x51,0xFA,0xE8,0xDB,0xF7, + 0x64,0x59,0x23,0x51,0xFA,0xFE,0x62,0x6F,0x44,0x51,0x03,0x51,0x8A,0x02,0x0B,0x6B, + 0x44,0x51,0x03,0x49,0x7E,0x6A,0x73,0x68,0x43,0x51,0xE1,0x48,0xA0,0xEA,0xFB,0xEA, + 0x23,0x51,0xE2,0x48,0xAA,0xA5,0xD5,0xFB,0x23,0x51,0xE3,0x48,0xEF,0xE8,0xAA,0xAA, + 0x23,0x51,0xC2,0x48,0xA2,0xAA,0xBA,0x78,0x23,0x51,0xC2,0x48,0xAA,0xEF,0xB7,0x25, + 0xE6,0x69,0x03,0x51,0xF5,0x35,0x3D,0x2F,0x6A,0x9B,0x25,0x72,0x29,0x01,0x03,0x02, + 0xCC,0xA3,0x8B,0x9B,0xEF,0xEF,0xED,0x8B,0xAC,0xA3,0x8B,0x9B,0x0A,0xF9,0x79,0x62, + 0xAB,0xA3,0x29,0x93,0x80,0x7A,0xFE,0xFE,0x69,0x9B,0x28,0x93,0x8A,0xAD,0xAA,0x80, + 0x8A,0x9B,0x49,0x93,0x8B,0xAB,0x2F,0xBF,0x8A,0x9B,0x49,0x93,0x00,0x82,0xFC,0x7A, + 0x8B,0x9B,0x29,0x93,0x80,0x32,0xEB,0x7F,0x8B,0x9B,0x09,0x8B,0x88,0x28,0xFB,0x55, + 0x8B,0xA3,0x09,0x93,0xA2,0xE0,0xEF,0xED,0x4A,0x93,0xE9,0x8A,0x80,0xA8,0xF8,0xFF, + 0x09,0x8B,0x67,0x7A,0xE0,0xF8,0xE8,0x78,0x87,0x7A,0x26,0x72,0xDC,0xFA,0xFE,0xDE, + 0x67,0x7A,0x26,0x6A,0x6F,0x5B,0x8A,0xFF,0x46,0x72,0x05,0x6A,0xBB,0xDE,0x80,0x02, + 0x46,0x72,0x06,0x6A,0x3A,0xFA,0x8B,0xEB,0x47,0x72,0x06,0x6A,0x5C,0xDE,0x7B,0xB5, + 0x26,0x6A,0xE5,0x69,0xAD,0x36,0xBA,0xA8,0x47,0x72,0x06,0x6A,0xC1,0xAB,0x29,0x0F, + 0x68,0x72,0x06,0x6A,0x7A,0x7A,0xB0,0x22,0x67,0x72,0x43,0x49,0x7E,0xFA,0xF8,0xE0, + 0x64,0x49,0xE3,0x40,0x77,0x5E,0xFE,0xF8,0x03,0x41,0xC2,0x38,0xA8,0x0A,0x80,0x78, + 0x03,0x41,0xC2,0x38,0x02,0xA2,0xEB,0xF9,0x24,0x41,0xC2,0x38,0x0A,0x2E,0xBB,0xA9, + 0x44,0x49,0x03,0x39,0x02,0xC0,0xEF,0xA5,0x23,0x41,0xE2,0x38,0x5F,0xDA,0xDE,0xC2, + 0x03,0x41,0xC2,0x38,0xF2,0xCA,0xE8,0xFA,0x03,0x39,0xC2,0x38,0xB7,0xEF,0x3F,0xDF, + 0x24,0x41,0xC2,0x38,0xAF,0x2F,0x2F,0x9F,0x64,0x49,0x03,0x41,0xBD,0xAF,0x2D,0x0D, + 0x64,0x49,0x03,0x41,0xFA,0xF8,0xE8,0x58,0x24,0x49,0x03,0x41,0x8A,0x22,0x0A,0x2F, + 0x44,0x49,0x24,0x49,0x37,0x1A,0xDC,0x94,0xA6,0x59,0x44,0x49,0x2F,0x0F,0x3F,0xBD, + 0xC6,0x59,0x65,0x51,0xC2,0xE2,0x60,0xFB,0x85,0x51,0x23,0x41,0x6B,0x6A,0xEE,0xE0, + 0x24,0x41,0xC2,0x38,0xFF,0xD7,0x76,0x78,0x24,0x41,0xC3,0x38,0x7F,0xFF,0x73,0xF3, + 0xE3,0x30,0xA2,0x30,0x77,0xFD,0xBE,0x2E,0x03,0x39,0xC3,0x30,0xB5,0xD5,0xB7,0x2F, + 0x45,0x41,0x04,0x39,0x55,0x7A,0xE3,0x7B,0x03,0x39,0xE3,0x38,0xC9,0xBF,0xDF,0x1F, + 0x24,0x41,0xC2,0x38,0xBA,0x9F,0x2E,0x22,0x44,0x49,0x04,0x41,0x0A,0x2B,0x29,0x0D, + 0x65,0x51,0x44,0x49,0xF5,0xFD,0xBB,0x75,0x44,0x49,0x03,0x41,0x88,0xEA,0xE8,0xE0, + 0x24,0x41,0xE3,0x40,0x0A,0x0F,0x27,0x8A,0x24,0x41,0xE3,0x38,0xE8,0x70,0x58,0x6A, + 0x03,0x41,0xE3,0x38,0xD7,0xD7,0x7F,0xFB,0x24,0x41,0xE3,0x38,0xBF,0xBF,0x57,0x5B, + 0x24,0x41,0x03,0x39,0x27,0x1E,0xF6,0x7F,0x24,0x41,0xE3,0x38,0x78,0x78,0x6B,0xAF, + 0x24,0x41,0xE3,0x38,0xBD,0xFD,0x3D,0x37,0x65,0x49,0x03,0x41,0xFA,0xEA,0x62,0xE9, + 0x44,0x49,0xE3,0x38,0xAF,0x6A,0x0B,0x0A,0x44,0x49,0xC2,0x30,0x7E,0xFA,0xE8,0xE0, + 0x23,0x41,0xC2,0x30,0x8A,0xDA,0x5E,0x52,0xE2,0x38,0xC2,0x30,0x7C,0xF6,0xC5,0x2B, + 0x03,0x39,0xC2,0x30,0x2D,0xED,0xAB,0x2A,0x23,0x39,0xC2,0x30,0xF7,0x97,0x8F,0xAE, + 0x24,0x39,0xC2,0x30,0xFD,0xBF,0xEB,0x2A,0x23,0x39,0xE3,0x30,0xFD,0xFE,0xD4,0x7E, + 0x24,0x39,0xC3,0x30,0xFE,0xFF,0xFE,0xA3,0x23,0x39,0xE3,0x38,0x2B,0x89,0xB7,0xF5, + 0x44,0x41,0xE3,0x30,0x7F,0xEF,0xBA,0x8B,0x23,0x41,0xE2,0x38,0xED,0x7D,0xFF,0x8B, + 0x44,0x41,0xE3,0x38,0x09,0xF5,0xDB,0xD5,0x85,0x51,0x03,0x41,0x82,0xE3,0xFF,0xFD, + 0x85,0x51,0x02,0x39,0x28,0x8A,0xB5,0x57,0x84,0x51,0x23,0x41,0x20,0xBA,0xEA,0x7F, + 0x84,0x51,0x03,0x41,0x68,0x6A,0xFE,0xAF,0xA5,0x59,0x03,0x41,0x29,0x2D,0xAF,0x2F, + 0x06,0x62,0xA5,0x59,0x8B,0xBF,0xAD,0x2B,0x26,0x6A,0xC5,0x61,0xDC,0xAB,0x8B,0xB7, + 0x27,0x6A,0xC6,0x61,0xEB,0xBF,0x37,0x56,0x67,0x7A,0xE5,0x69,0x5F,0xEA,0xC8,0x03, + 0x26,0x72,0xC6,0x61,0xB7,0xBF,0xFF,0xFC,0x88,0x7A,0x06,0x6A,0x0D,0xAD,0xF7,0xD5, + 0x68,0x7A,0x06,0x6A,0x78,0x7A,0x77,0x6B,0xA8,0x7A,0xC4,0x61,0x2B,0xAB,0xBF,0xF5, + 0x09,0x8B,0x67,0x72,0x0A,0x09,0xAD,0xBD,0x29,0x8B,0xE8,0x82,0x0D,0xFD,0xFF,0x5D, + 0xD4,0xDD,0x6A,0x93,0x2D,0x2D,0x35,0xB5,0x55,0xEE,0xD3,0xDD,0x0A,0x2B,0xA9,0x2D, + 0x55,0xEE,0x35,0xE6,0xBF,0x33,0xAF,0xFF,0x55,0xEE,0x15,0xE6,0xEA,0xBA,0xFE,0xFF, + 0x35,0xE6,0x14,0xE6,0xF7,0x7E,0xFA,0x56,0x14,0xE6,0xB3,0xD5,0xA8,0xE8,0xFE,0x5A, + 0xD4,0xDD,0x32,0xC5,0xA0,0xE8,0xFA,0x7A,0x93,0xCD,0x11,0xBD,0x2F,0x2E,0x09,0x2D, + 0xB4,0xD5,0x93,0xCD,0x6A,0x4B,0x7F,0x7B,0x93,0xCD,0x73,0xCD,0x72,0x6A,0xEE,0x68, + 0x52,0xC5,0x32,0xBD,0x38,0xBA,0x78,0x38,0x72,0xCD,0x32,0xC5,0x08,0x8A,0xEA,0xDA, + 0x73,0xCD,0x32,0xC5,0x8A,0xEF,0x5D,0x77,0x32,0xC5,0xF1,0xBC,0xFE,0xBC,0xEC,0x68, + 0x12,0xBD,0xB0,0xB4,0xE0,0xFC,0x5F,0x76,0xB0,0xB4,0x0E,0x9C,0x60,0xF8,0xE8,0x78, + 0x2E,0xA4,0xAC,0x93,0x17,0x3F,0x3E,0xFA,0x6F,0xAC,0x0F,0x9C,0xAD,0x2A,0x03,0xA9, + 0xB0,0xB4,0x6F,0xAC,0xD5,0x95,0xB9,0xBD,0xD1,0xB4,0x6F,0xAC,0x27,0x3B,0xEE,0xFE, + 0xB1,0xB4,0x4F,0xA4,0xF8,0xF8,0xFF,0x5F,0x6F,0xA4,0x2F,0xA4,0xB2,0x2A,0xEB,0xAB, + 0x8F,0xAC,0x4F,0xA4,0x2F,0xAF,0xEA,0xFB,0xB0,0xAC,0x4F,0xA4,0xF5,0xB7,0x09,0x0F, + 0x63,0x59,0x02,0x51,0x7E,0xEE,0x2D,0xAF,0x63,0x59,0x22,0x51,0x3D,0x2F,0x02,0xE0, + 0x84,0x59,0x23,0x51,0x87,0xCA,0xA8,0xE3,0x84,0x59,0x22,0x51,0x7E,0xA3,0x80,0x2B, + 0xA5,0x61,0x63,0x59,0x25,0xD5,0xF5,0xEB,0xC5,0x61,0x43,0x59,0xAF,0x2F,0xE7,0xFD, + 0x84,0x61,0x43,0x59,0xE0,0xF8,0xEE,0x7E,0x84,0x61,0x23,0x59,0xFC,0xDB,0xEB,0xDA, + 0x64,0x59,0x23,0x51,0xA2,0xFB,0x7B,0x5A,0x63,0x59,0x23,0x51,0xFF,0xD8,0xBD,0xA9, + 0x63,0x59,0x23,0x51,0x7F,0xAA,0x8A,0x6E,0x64,0x51,0x02,0x51,0xAE,0xB4,0xBA,0xAA, + 0x43,0x59,0x03,0x51,0xE8,0xA8,0xFF,0xFA,0x43,0x51,0x03,0x49,0xAF,0xBE,0xAF,0xBE, + 0x64,0x59,0x02,0x49,0xF8,0xD2,0x5B,0x7F,0x23,0x51,0x03,0x49,0x88,0x38,0x0B,0x03, + 0x23,0x51,0x03,0x49,0x7F,0xAC,0xEE,0x63,0x23,0x51,0xE2,0x40,0xAA,0xEA,0xB6,0x0A, + 0x23,0x51,0xC2,0x48,0x72,0xBA,0xEA,0x00,0x64,0x59,0x03,0x51,0xFD,0x8B,0xAA,0xAA, + 0xC9,0x8A,0x64,0x59,0x95,0xB5,0x35,0x35,0xAC,0xA3,0x09,0x8B,0x2D,0x2B,0x2B,0xAA, + 0xCC,0xA3,0x8B,0x9B,0xEB,0xEB,0xAA,0x0F,0xEC,0xAB,0xAB,0xA3,0x75,0x75,0xFB,0x07, + 0xEC,0xAB,0x4A,0x93,0x5F,0xFE,0xAC,0x88,0xAB,0xA3,0x49,0x93,0xFF,0xDF,0xAA,0xE0, + 0x6A,0x9B,0x49,0x93,0x8B,0x28,0x2A,0xCC,0x6A,0x9B,0x08,0x93,0xA0,0x72,0xF8,0xB2, + 0x49,0x93,0xE8,0x8A,0x7E,0x7F,0xD6,0x88,0x29,0x93,0xE8,0x8A,0xFA,0xDE,0xFE,0xEB, + 0xE9,0x92,0x09,0x8B,0x55,0xFF,0x5F,0x95,0x29,0x93,0xC8,0x82,0x68,0x7A,0x7A,0xFF, + 0xE9,0x8A,0x87,0x7A,0x7A,0xE8,0x82,0xA0,0xA8,0x82,0x46,0x72,0x77,0x7F,0x7A,0x7C, + 0x67,0x72,0x26,0x72,0x7D,0x6F,0x3B,0x2A,0x66,0x72,0x05,0x6A,0xEB,0x6A,0xE8,0xB8, + 0x67,0x72,0xE5,0x69,0x6E,0xEE,0xFE,0x2E,0x47,0x72,0xE5,0x69,0xAF,0x27,0x37,0x9E, + 0x47,0x72,0x06,0x6A,0x77,0x56,0xFC,0xAF,0x67,0x7A,0x06,0x6A,0xA5,0xBF,0x8E,0xAA, + 0x87,0x7A,0x47,0x72,0xF5,0xB7,0xFE,0x2F,0x87,0x7A,0xE6,0x61,0x70,0x82,0x00,0x00, + 0x26,0x6A,0x03,0x41,0x5E,0x7C,0x78,0xF8,0x03,0x41,0xA2,0x38,0x5C,0xE0,0x80,0xA0, + 0xE2,0x38,0xA2,0x30,0x82,0x2A,0x1E,0xAE,0x03,0x41,0xE3,0x38,0xE9,0xFD,0xC2,0xEB, + 0x24,0x41,0xE2,0x38,0xF5,0xFA,0xE2,0xAB,0x24,0x41,0xE3,0x38,0xEF,0x5F,0x7B,0x5D, + 0xE3,0x38,0xC2,0x38,0x80,0xA0,0xC8,0x03,0x23,0x41,0xC2,0x38,0x57,0xDF,0xFF,0xBF, + 0x03,0x41,0xE3,0x38,0x05,0x01,0x69,0x2B,0x44,0x49,0x03,0x39,0xAA,0x6A,0xAD,0xB5, + 0x64,0x49,0x03,0x41,0xF8,0x7E,0xDA,0x7A,0x24,0x49,0xE3,0x40,0xB6,0xAE,0xB6,0xFF, + 0x65,0x51,0x03,0x41,0x3D,0xB5,0xD5,0x55,0x85,0x51,0xC3,0x40,0x0A,0xAA,0xAA,0xFD, + 0xA6,0x59,0x24,0x49,0xA2,0x22,0xBB,0xFD,0x85,0x51,0x44,0x49,0x42,0xE8,0xFA,0x2F, + 0x65,0x49,0xC2,0x30,0x7E,0x7A,0x78,0xE0,0x03,0x41,0xC3,0x30,0xA1,0xE3,0xFA,0xFA, + 0xE3,0x38,0xC3,0x30,0xDC,0x5A,0xFC,0xFF,0x04,0x39,0xC3,0x30,0x8D,0xBD,0xD5,0x7D, + 0x24,0x39,0xA2,0x30,0x22,0x3E,0xFF,0xD5,0x03,0x39,0xC3,0x30,0x00,0x00,0x0A,0x3D, + 0x24,0x41,0x03,0x39,0x5B,0xBB,0x83,0xAD,0x44,0x49,0x03,0x41,0x0D,0x0B,0x3D,0x09, + 0x64,0x49,0x24,0x49,0xAE,0xAF,0xAF,0xBB,0x44,0x49,0x03,0x41,0x80,0xA0,0x72,0xFE, + 0x24,0x41,0xC2,0x38,0x00,0xAA,0xBA,0x78,0x03,0x41,0xC3,0x38,0x82,0x2A,0xA0,0x3F, + 0x03,0x41,0xE3,0x38,0xBA,0x9E,0x5A,0xF8,0x24,0x41,0x03,0x39,0x57,0x3A,0x0B,0xEF, + 0x65,0x41,0xE3,0x30,0xFF,0xDF,0x7C,0x7F,0x44,0x39,0xE3,0x38,0xBF,0xBF,0xF7,0x75, + 0x23,0x39,0xE3,0x38,0x38,0xFA,0xBD,0x2F,0x44,0x41,0x03,0x39,0x8B,0xA9,0xEA,0xE2, + 0x64,0x49,0x02,0x39,0xA0,0xEB,0xFF,0x57,0x44,0x41,0xC2,0x30,0xF8,0x6A,0xF2,0xFF, + 0x02,0x39,0xC2,0x30,0x57,0xDF,0xDE,0x78,0x03,0x39,0xC2,0x30,0xBF,0xA6,0x8B,0xE5, + 0x23,0x39,0xE2,0x38,0xFD,0xAF,0x0B,0xA9,0x23,0x39,0xE2,0x30,0xFF,0xFA,0xE2,0xE3, + 0x24,0x39,0x03,0x39,0x2F,0xE5,0x75,0xB5,0x24,0x39,0xE3,0x38,0x7C,0xFC,0xA8,0x08, + 0x03,0x39,0xC2,0x30,0xA2,0xE0,0xB8,0xB0,0x03,0x39,0xC2,0x30,0x2B,0xAF,0xDD,0x7A, + 0x23,0x41,0xC2,0x30,0x0B,0xBF,0xDD,0x5D,0x64,0x41,0xC2,0x38,0xEA,0xAA,0xAB,0xAD, + 0x23,0x41,0xE3,0x38,0xD7,0x5B,0xFC,0xA8,0x43,0x41,0xE3,0x38,0x8D,0xB5,0xF7,0xFF, + 0x44,0x41,0xE3,0x38,0xFE,0xBA,0x3B,0xB9,0x23,0x41,0xE2,0x38,0x00,0xC7,0xF6,0xBC, + 0x44,0x49,0xE2,0x38,0x02,0xFA,0x9E,0xEB,0xA5,0x51,0x23,0x49,0x27,0xBF,0xB7,0xBD, + 0x47,0x6A,0x84,0x51,0x27,0x3F,0xBD,0xFD,0x88,0x7A,0xE6,0x61,0xF5,0xFA,0xAA,0x0B, + 0x47,0x72,0xA5,0x61,0x55,0x57,0x5C,0xE2,0x47,0x72,0x85,0x59,0x0B,0x2D,0xB7,0xFE, + 0x47,0x72,0xE5,0x69,0x78,0x60,0xDB,0x79,0x05,0x6A,0xC5,0x61,0x83,0xBF,0x8E,0x0B, + 0x67,0x72,0xE5,0x61,0x8B,0x09,0x09,0xB5,0x47,0x72,0xE5,0x61,0xF6,0xBE,0xE0,0x00, + 0xA7,0x7A,0x26,0x72,0x09,0x2B,0x09,0x2B,0x09,0x83,0xA8,0x7A,0xEB,0xA5,0x35,0x7D, + 0x8F,0xB4,0xE8,0x82,0x2D,0x2D,0x2D,0x2D,0x35,0xE6,0x31,0xCD,0x0B,0x29,0xAD,0x2D, + 0x35,0xE6,0x14,0xE6,0xA8,0xBF,0xF7,0x55,0x35,0xE6,0xF4,0xDD,0xA8,0xA8,0xFA,0xDF, + 0x34,0xE6,0xF4,0xDD,0xEA,0x6A,0xFB,0x7B,0x14,0xDE,0x93,0xD5,0xF8,0xFE,0xFE,0x7A, + 0x93,0xD5,0xF1,0xBC,0x68,0x58,0x58,0x5E,0x93,0xCD,0x11,0xBD,0x2D,0x29,0x29,0x2F, + 0xB4,0xCD,0x73,0xCD,0xAA,0xEA,0xFE,0x7B,0x93,0xCD,0x32,0xC5,0x82,0xCA,0xFE,0x7F, + 0x92,0xC5,0x32,0xC5,0x9E,0xFF,0xF7,0xF7,0x52,0xC5,0x32,0xC5,0x80,0xA0,0xC6,0xC8, + 0x52,0xC5,0x11,0xBD,0xF0,0xEA,0xFA,0x72,0x12,0xC5,0xB0,0xAC,0xA0,0xFA,0xFE,0x60, + 0xF1,0xBC,0x90,0xAC,0xF8,0xF8,0xF6,0xDF,0xB0,0xAC,0xED,0x9B,0xF8,0x78,0x5E,0x57, + 0x2E,0xA4,0xCD,0x93,0x8E,0x3D,0xF7,0xF5,0x90,0xAC,0xEE,0x9B,0x2F,0x2F,0x2B,0x29, + 0xB0,0xB4,0x4F,0xAC,0xAE,0xEF,0xE2,0xFA,0x90,0xAC,0x4F,0xA4,0x88,0xA0,0xFE,0x57, + 0x6F,0xAC,0x0E,0x9C,0x72,0xE8,0xAA,0x02,0x90,0xAC,0x2E,0xA4,0x29,0x29,0x2F,0x0A, + 0x90,0xAC,0x6F,0xA4,0x6A,0x00,0x28,0x08,0xB0,0xAC,0x4E,0xA4,0x2A,0xB0,0xF8,0x58, + 0x84,0x59,0x22,0x51,0xFD,0x9F,0xF7,0xCA,0x84,0x59,0x43,0x51,0xFF,0x8E,0xF7,0x5A, + 0x83,0x59,0x22,0x51,0xCA,0xAA,0x6A,0xEB,0x84,0x61,0x22,0x51,0x2F,0xAF,0x0D,0xA9, + 0x84,0x61,0x43,0x51,0x4C,0xCB,0xAE,0xFE,0x63,0x59,0x23,0x51,0x00,0xD8,0x5E,0x69, + 0x64,0x59,0x22,0x51,0xEA,0x8A,0xFE,0xFF,0x84,0x59,0x22,0x51,0xDA,0x28,0xAA,0xAF, + 0x63,0x59,0x23,0x51,0xF8,0x68,0xF8,0x30,0x64,0x59,0x22,0x51,0x8B,0x09,0xD7,0x5E, + 0x64,0x59,0x02,0x49,0xFF,0xFA,0xFC,0xFF,0x43,0x51,0x02,0x49,0xAA,0xAB,0x6F,0xCB, + 0x43,0x51,0x03,0x49,0xFA,0xFA,0xAB,0x0F,0x64,0x59,0x03,0x49,0xBF,0xFB,0xA1,0xFB, + 0x44,0x51,0x02,0x49,0xAE,0xAA,0x6A,0x40,0x44,0x51,0xE3,0x48,0xEF,0xAB,0x8F,0xAD, + 0x23,0x51,0xE2,0x48,0xE2,0xE0,0xE0,0x68,0x24,0x59,0x02,0x49,0xA3,0x89,0x3B,0x39, + 0x43,0x59,0x03,0x51,0x29,0x03,0xA2,0x20,0x64,0x59,0x44,0x59,0xDB,0x21,0xA5,0x95, + 0x4A,0x93,0xA5,0x61,0xB5,0x25,0x25,0x2D,0xCB,0xA3,0x4B,0x9B,0x39,0xBD,0xBF,0xBF, + 0xCC,0xA3,0x8B,0x9B,0x0B,0xBC,0xBB,0xAF,0xEC,0xAB,0xCC,0xA3,0x0C,0x02,0xAE,0xCB, + 0xEC,0xAB,0xAB,0xA3,0xB8,0xAC,0xF8,0x7E,0xCC,0xA3,0x6A,0x9B,0xE8,0xAA,0x68,0xBA, + 0xAB,0xA3,0x49,0x93,0xFE,0xFB,0xAE,0xB2,0x8A,0x9B,0x29,0x93,0xAF,0x88,0xBA,0x5E, + 0x6A,0x9B,0x09,0x8B,0xC8,0x82,0xFC,0x74,0x49,0x93,0xE8,0x8A,0xAA,0xE8,0xEE,0xF7, + 0x29,0x93,0xC8,0x82,0xC2,0xE2,0x7A,0x5E,0x09,0x8B,0xC8,0x82,0x7F,0x70,0x7F,0x5D, + 0xE9,0x8A,0x87,0x7A,0xF0,0x78,0xF8,0xF2,0x87,0x7A,0x26,0x6A,0xDA,0xFA,0x78,0xB8, + 0x67,0x72,0x46,0x72,0x7E,0xB6,0xB5,0xAB,0x67,0x72,0x26,0x72,0xFC,0xBA,0x25,0xAD, + 0x46,0x72,0x05,0x6A,0x60,0xC2,0xE0,0x80,0x46,0x72,0xE5,0x69,0xDB,0x29,0x29,0x0A, + 0x46,0x72,0x05,0x6A,0xDA,0xCA,0xAE,0xAA,0x47,0x72,0x06,0x6A,0x00,0x89,0x00,0x08, + 0xA7,0x7A,0x46,0x72,0xED,0x25,0x2B,0x27,0xE8,0x82,0x87,0x7A,0x77,0xCF,0xFB,0xEB, + 0xA8,0x7A,0x64,0x51,0x5E,0x6A,0xE0,0xA0,0x84,0x51,0xE3,0x40,0x5F,0x7E,0x5C,0x58, + 0xE3,0x38,0xA2,0x38,0xC0,0xAA,0xE2,0xEA,0xE3,0x38,0xA1,0x30,0x0F,0x0F,0x2F,0x27, + 0x24,0x39,0xC2,0x38,0x2B,0xA7,0x9F,0xFE,0x03,0x41,0xA2,0x30,0xE0,0xE0,0x68,0x7B, + 0xE3,0x38,0xA2,0x30,0x25,0xAB,0xAB,0xB9,0x23,0x41,0xE3,0x38,0xBD,0xAF,0x0B,0xAB, + 0x23,0x41,0xC2,0x38,0xAE,0xFA,0xF2,0x6A,0x45,0x41,0xE3,0x38,0x3F,0xF5,0xFF,0x57, + 0x44,0x49,0xE3,0x38,0xE8,0xF8,0xEE,0xED,0x03,0x41,0xE3,0x38,0x88,0x7A,0x82,0xE0, + 0x03,0x41,0xE3,0x40,0x80,0x03,0xF2,0x61,0x03,0x41,0xC3,0x38,0x8A,0xAA,0x6B,0xDB, + 0x44,0x49,0xC3,0x38,0xAA,0xAB,0xAD,0xEF,0x86,0x51,0x03,0x41,0x2B,0xB9,0xB5,0xFD, + 0x65,0x49,0x03,0x41,0xA0,0xF8,0xEA,0x7A,0x24,0x41,0xC3,0x30,0xFE,0x58,0x7A,0xFA, + 0xE3,0x38,0x82,0x28,0x2E,0xBF,0xDA,0xE8,0xC2,0x30,0x81,0x28,0x80,0xEA,0xFE,0xFF, + 0xC3,0x30,0x81,0x28,0x2F,0x2F,0x2F,0x2B,0x03,0x39,0xC3,0x30,0x35,0xBB,0xBF,0x9F, + 0x24,0x41,0xE3,0x38,0x2F,0x27,0xAF,0xAB,0x65,0x49,0x03,0x41,0x2F,0xAF,0xAD,0x0F, + 0x65,0x49,0x23,0x41,0x6A,0x6A,0xF7,0xAB,0x44,0x49,0x03,0x41,0x2F,0xAF,0xFF,0xDC, + 0x45,0x49,0xE3,0x38,0x7E,0x6E,0xA0,0xAA,0x24,0x41,0xC3,0x38,0xBD,0xFF,0xFC,0xFC, + 0x03,0x39,0xE3,0x38,0xBC,0xFC,0xFA,0xBF,0x24,0x39,0xC3,0x30,0xA2,0xC2,0x8A,0xE6, + 0x03,0x39,0xC2,0x30,0xCA,0x4A,0x52,0x5A,0x03,0x39,0xA2,0x30,0xAA,0xA3,0x9F,0xFD, + 0x23,0x39,0xE3,0x38,0x02,0x2C,0xBD,0x7D,0x44,0x41,0xE3,0x38,0x80,0xFA,0x5E,0x55, + 0x24,0x41,0xC2,0x30,0x78,0xDA,0xFF,0xFF,0x03,0x39,0xC2,0x30,0x2B,0xAD,0xAB,0xFA, + 0x03,0x39,0xC2,0x30,0x80,0x20,0xEF,0xF7,0x03,0x39,0xC2,0x30,0xF6,0xA2,0xEE,0xE8, + 0x23,0x39,0xE3,0x30,0xAD,0xBD,0xF5,0xE9,0x23,0x39,0xE3,0x30,0x22,0xAA,0xBF,0x77, + 0x23,0x39,0xE2,0x30,0x8A,0x63,0xAB,0xBE,0x44,0x41,0xE3,0x38,0x3B,0xBD,0x79,0xDF, + 0x24,0x41,0xE3,0x38,0xDE,0xFA,0xFE,0x7C,0x24,0x39,0xE2,0x30,0x7B,0xFF,0xB0,0xAA, + 0x03,0x39,0xC2,0x30,0x5D,0xD7,0xF7,0xFC,0x44,0x41,0xE2,0x30,0x3D,0xF5,0xDF,0xB5, + 0x44,0x41,0x03,0x39,0xFA,0xBA,0xEB,0xFE,0x23,0x41,0xE3,0x38,0xFE,0xBE,0xAA,0xAE, + 0x03,0x41,0xE2,0x38,0xA0,0x50,0x5F,0x55,0x24,0x41,0xC2,0x38,0xAF,0x7E,0x63,0x8A, + 0x64,0x49,0x03,0x39,0xAD,0xAD,0xAB,0xAF,0x84,0x51,0x44,0x49,0x95,0x35,0x15,0xED, + 0xC5,0x59,0x64,0x51,0x3F,0xFE,0xFE,0x5F,0x67,0x72,0xA5,0x59,0x0B,0x25,0xD5,0x55, + 0x88,0x7A,0xE6,0x61,0xE8,0x08,0x03,0x25,0x87,0x7A,0xE5,0x61,0x57,0x5F,0xE0,0xC0, + 0x06,0x62,0xA5,0x59,0xAA,0x26,0x1C,0x78,0x67,0x72,0xA5,0x59,0xBF,0xAF,0x2A,0x2D, + 0x88,0x72,0xE5,0x61,0xDB,0xAA,0x2A,0x28,0xA8,0x7A,0x46,0x72,0xFD,0x75,0xAB,0x2B, + 0xA8,0x82,0x67,0x72,0xF9,0x4D,0xBF,0x1A,0xA8,0x7A,0x47,0x72,0x02,0x2B,0x2A,0xA6, + 0xB0,0xBC,0x88,0x7A,0x2D,0x3D,0x3D,0xBD,0xF4,0xDD,0xD1,0xC4,0x0B,0x0B,0x2B,0x2D, + 0x14,0xE6,0xD4,0xDD,0xA0,0x78,0xD7,0x55,0x14,0xE6,0xB3,0xD5,0x8A,0xAA,0xEF,0x5F, + 0x14,0xDE,0xB3,0xD5,0x82,0xEC,0x7E,0xDF,0xD4,0xD5,0x52,0xCD,0xE0,0xEA,0x6A,0x6A, + 0x73,0xC5,0xD1,0xBC,0xDE,0x9C,0xBE,0x3E,0xD3,0xCD,0x73,0xCD,0xF5,0xF5,0xFF,0xED, + 0x93,0xCD,0x52,0xC5,0x80,0xEA,0xE8,0x78,0x73,0xCD,0x11,0xBD,0xEA,0xE8,0x7E,0x7A, + 0x52,0xC5,0xF1,0xBC,0x2B,0x3F,0xD5,0xDF,0x73,0xCD,0x11,0xBD,0xA2,0x0A,0x22,0x2D, + 0x73,0xCD,0xD1,0xB4,0xE2,0xE2,0xE8,0x78,0x11,0xBD,0xB1,0xB4,0xE8,0xFA,0x7C,0xEB, + 0xD1,0xB4,0x4E,0xA4,0xAA,0x6A,0x78,0x58,0x2E,0xA4,0x4C,0x83,0xA8,0xF8,0xFC,0x5E, + 0xEE,0x9B,0x6C,0x8B,0x82,0x0A,0xA7,0x25,0x90,0xAC,0xEE,0x9B,0xAD,0x29,0x2F,0xAB, + 0x90,0xAC,0x2F,0xA4,0xC0,0xF8,0xDE,0x5F,0x4F,0xA4,0xEE,0x9B,0x80,0xAA,0xE6,0xBE, + 0x6F,0xAC,0x2E,0x9C,0x29,0x29,0x39,0x0E,0x90,0xAC,0x2E,0xA4,0x08,0x80,0x78,0xE8, + 0x90,0xAC,0x0E,0x9C,0x8A,0xE6,0xFD,0xF7,0x6F,0xAC,0x4E,0xA4,0x78,0x77,0xEA,0x35, + 0x63,0x59,0x02,0x49,0x00,0x28,0x0F,0x27,0x84,0x59,0x23,0x51,0xE8,0xFB,0x5A,0xFC, + 0x63,0x59,0x23,0x51,0xAB,0x0B,0x03,0x2F,0x84,0x61,0x23,0x51,0xAC,0xDA,0xBA,0xBC, + 0x63,0x59,0x01,0x51,0x2C,0xAE,0xAA,0xBF,0x43,0x59,0x23,0x51,0x8A,0x60,0x72,0xB8, + 0x84,0x59,0x22,0x51,0xFF,0x7F,0x7B,0x5F,0x63,0x59,0x23,0x51,0xCA,0xFF,0xDD,0xB7, + 0x63,0x59,0x02,0x49,0xA8,0x48,0xFA,0xFE,0x63,0x51,0x22,0x51,0x73,0x63,0xFB,0x5F, + 0x43,0x51,0x02,0x49,0xAB,0x43,0xE8,0xFE,0x44,0x51,0x02,0x49,0xE5,0x2D,0x2D,0x22, + 0x64,0x59,0x03,0x49,0x8A,0xEB,0x6F,0x7F,0x43,0x51,0xE2,0x48,0x8A,0xE8,0xEB,0xF7, + 0x44,0x51,0xE3,0x48,0x7A,0xFF,0xAA,0x8B,0x44,0x51,0xE2,0x48,0xED,0x3F,0xBB,0xFB, + 0x43,0x51,0x03,0x51,0xF7,0xDA,0xF2,0xB6,0xA5,0x61,0x23,0x51,0xF5,0x75,0xBD,0xDF, + 0x64,0x59,0x23,0x51,0xBA,0xDA,0xF8,0xF0,0x64,0x59,0x23,0x51,0xA6,0x35,0x1D,0xBD, + 0x2A,0x93,0x84,0x61,0x2D,0x09,0x0F,0x0B,0xAB,0xA3,0x4A,0x9B,0xAD,0x2D,0x2D,0x27, + 0xCC,0xA3,0x8B,0xA3,0x2F,0x3D,0xDE,0x08,0x0D,0xAC,0xAB,0xA3,0xAA,0xEE,0xF7,0x3F, + 0x2D,0xB4,0xCC,0xA3,0x55,0xBF,0xAD,0x0E,0x0D,0xAC,0xAB,0xA3,0x67,0xFA,0xE8,0xEE, + 0xEC,0xAB,0x8B,0x9B,0xFF,0xDE,0x5A,0xF8,0x8B,0x9B,0x28,0x93,0x7E,0xFE,0xF8,0x6C, + 0x29,0x93,0xE9,0x8A,0xF8,0xE0,0xEA,0xFA,0x09,0x8B,0xC8,0x8A,0x68,0xFB,0x7A,0x7A, + 0x09,0x8B,0xA7,0x82,0xDA,0x3E,0xAE,0x9A,0x08,0x8B,0xA8,0x82,0xBD,0xAA,0x2A,0x2A, + 0x09,0x8B,0x87,0x7A,0x62,0x70,0xF8,0xFA,0x87,0x7A,0x26,0x6A,0xBA,0xF6,0xF6,0xB8, + 0x67,0x72,0x05,0x72,0xC8,0xA2,0xA8,0xA8,0x67,0x72,0x26,0x72,0xA9,0xFE,0xFE,0xFB, + 0x46,0x72,0x26,0x6A,0x82,0xA8,0xFA,0x24,0x46,0x72,0x06,0x6A,0x0A,0x2A,0x1E,0xD8, + 0x46,0x72,0x05,0x6A,0x20,0xA6,0x8B,0x8B,0x87,0x82,0x26,0x72,0xD7,0xBF,0xFF,0x0B, + 0xA8,0x82,0x46,0x72,0x2D,0xA2,0x20,0x08,0xE8,0x82,0xA8,0x82,0x8D,0xF5,0xD5,0x57, + 0xC8,0x82,0x26,0x6A,0x6A,0xE8,0x8A,0x88,0x67,0x7A,0xE3,0x40,0x7E,0x7E,0xE8,0xE8, + 0x03,0x49,0xA2,0x30,0x7F,0xFF,0xEE,0xE0,0xE3,0x38,0xA2,0x30,0xBD,0xFF,0x6E,0x5A, + 0xE3,0x38,0x81,0x30,0x80,0x2A,0xAB,0xED,0xE3,0x38,0x81,0x28,0xE8,0xAA,0xB2,0xBF, + 0xE3,0x38,0xA2,0x30,0xAD,0x3E,0x3E,0xAF,0x24,0x41,0xC3,0x30,0x2B,0xBF,0xF6,0xFF, + 0x24,0x39,0xC2,0x30,0xF8,0xBA,0xEA,0xEF,0x04,0x39,0xC2,0x38,0x7A,0xBE,0xFF,0xFF, + 0x23,0x41,0xE3,0x38,0x2D,0x6D,0xD5,0x55,0x44,0x49,0xE3,0x38,0xB8,0xAB,0xEB,0xFD, + 0x24,0x41,0x03,0x41,0x5D,0xF0,0xCA,0x82,0x65,0x49,0xC2,0x38,0xDF,0xF3,0xAA,0x22, + 0x65,0x49,0xE3,0x40,0x77,0xFD,0x2A,0x8A,0x24,0x41,0xE3,0x38,0x2B,0x2B,0x2A,0x28, + 0x65,0x49,0x03,0x41,0x6F,0xCE,0xEA,0xEB,0x24,0x41,0xC3,0x30,0xAA,0xFC,0x78,0xFA, + 0x03,0x39,0xA2,0x30,0x7C,0xE0,0x82,0xAA,0xE3,0x30,0x82,0x28,0xDF,0x7F,0x9F,0x2E, + 0xE3,0x30,0xA2,0x28,0x95,0xB5,0xA7,0xAC,0x03,0x39,0xC3,0x30,0xDF,0xFA,0x8B,0xAB, + 0x23,0x41,0xE3,0x38,0x0F,0xBB,0xBD,0x0B,0xC6,0x51,0x23,0x41,0xB5,0xF5,0xBD,0x2B, + 0xA6,0x51,0x44,0x49,0x7E,0xDF,0xFC,0xE8,0x64,0x49,0x03,0x41,0xF8,0xD7,0xFE,0x80, + 0x44,0x49,0x03,0x41,0xEA,0xEB,0xEA,0xE6,0x03,0x41,0xC3,0x38,0xA8,0xBC,0x9E,0xFA, + 0xE3,0x38,0x03,0x31,0x22,0x83,0x82,0x00,0x03,0x39,0xC2,0x30,0x8A,0xFE,0x7F,0x55, + 0xE3,0x30,0xA2,0x30,0xB8,0xF6,0xFE,0x2A,0xE2,0x30,0xA1,0x30,0x8F,0x8A,0xA8,0x00, + 0x03,0x39,0xC2,0x30,0x62,0x7F,0xD7,0xFF,0xE2,0x30,0xC2,0x30,0xF6,0xFF,0xBE,0xFE, + 0x03,0x39,0xC2,0x30,0xFE,0xE2,0xE3,0xAD,0x03,0x39,0xC2,0x30,0xDF,0xFF,0xFA,0xA8, + 0x03,0x39,0xC2,0x30,0xBF,0x2E,0xAA,0xF2,0x03,0x39,0xC2,0x30,0xDE,0xFC,0xF6,0x3F, + 0x03,0x39,0xE3,0x30,0x2E,0x0F,0x6B,0xEA,0x24,0x39,0xC2,0x30,0xA2,0xBB,0x7F,0x5D, + 0x24,0x39,0xC2,0x30,0x23,0x0B,0x2D,0xB7,0x23,0x39,0xE3,0x38,0xDE,0x55,0xFF,0xF2, + 0x03,0x39,0xE3,0x30,0x60,0xC2,0xCA,0x7D,0x23,0x39,0xE3,0x38,0xBF,0xDD,0xDB,0x57, + 0x24,0x39,0xC2,0x30,0x7C,0xD8,0xFA,0xBF,0x44,0x49,0xC2,0x30,0xAD,0xAF,0xB5,0xBF, + 0x44,0x41,0x03,0x39,0x97,0xB5,0xD7,0xD5,0x44,0x41,0x03,0x39,0xD6,0xDF,0xB7,0x2D, + 0x44,0x41,0xC2,0x30,0xD7,0xBE,0xE8,0xA8,0x43,0x41,0xE3,0x38,0xFF,0xFF,0xCF,0x9B, + 0x65,0x49,0xE3,0x38,0x35,0xBF,0xF7,0xFF,0x85,0x51,0x03,0x39,0x8A,0x8B,0xBF,0xF5, + 0x84,0x51,0x44,0x49,0xAA,0xB2,0xDE,0xB7,0xA5,0x59,0x64,0x51,0x22,0x29,0x35,0x95, + 0x47,0x72,0xA5,0x59,0x09,0xAD,0xD5,0x55,0xA7,0x7A,0xA5,0x59,0x88,0x82,0xAB,0xA5, + 0x67,0x72,0x85,0x59,0x78,0x78,0xC8,0xA8,0x06,0x6A,0x64,0x51,0x27,0x35,0xFF,0xDE, + 0x67,0x72,0xA5,0x59,0x02,0x02,0x03,0x0D,0xA8,0x7A,0x46,0x6A,0x2F,0x2F,0xF7,0x5F, + 0xC9,0x82,0x67,0x7A,0xBA,0xE8,0xA2,0x01,0xC9,0x82,0x67,0x72,0xFF,0xDE,0xFA,0xB8, + 0x2E,0xAC,0xA8,0x7A,0x35,0x35,0xB5,0xBD,0xB4,0xDD,0x6F,0xB4,0x0B,0x2B,0xAD,0xAD, + 0xD3,0xDD,0x72,0xCD,0xA8,0x6F,0xF5,0xF5,0xB3,0xD5,0x72,0xCD,0x2A,0x0E,0xB7,0x57, + 0xD4,0xDD,0x93,0xD5,0xA3,0xEA,0xBD,0xF5,0xB3,0xD5,0x11,0xBD,0xE0,0xE0,0xF8,0x78, + 0x73,0xCD,0xF1,0xBC,0x27,0x05,0x35,0x3D,0xB3,0xD5,0x53,0xC5,0x8B,0x8A,0xFF,0x5F, + 0x93,0xCD,0x52,0xC5,0xE0,0xAA,0xEE,0xB5,0x73,0xCD,0xF1,0xB4,0xF2,0xEA,0xE8,0x88, + 0x52,0xC5,0xB0,0xB4,0xFF,0xD7,0xF6,0xB8,0x52,0xC5,0xF1,0xBC,0x2F,0xA9,0xFF,0x57, + 0x31,0xC5,0xB0,0xB4,0xE8,0xFC,0xD6,0x57,0xF1,0xBC,0x90,0xAC,0xC8,0xEF,0xFC,0xFB, + 0xD0,0xB4,0xAD,0x93,0xE0,0x62,0x7C,0x7A,0xAD,0x93,0xEA,0x7A,0xF8,0xFE,0xF7,0xD7, + 0x4F,0xA4,0x6C,0x8B,0xA5,0x2D,0x2F,0x0B,0x70,0xAC,0x2E,0xA4,0xAE,0x28,0x78,0x5B, + 0x4F,0xA4,0x0E,0x9C,0xC8,0x92,0xD3,0x5D,0xB0,0xAC,0x0E,0x9C,0xF5,0xFE,0xEF,0x2B, + 0x90,0xAC,0x2E,0xA4,0xAF,0x99,0xE2,0x20,0x6F,0xAC,0x2E,0x9C,0xC2,0xA2,0xDF,0x00, + 0x90,0xAC,0x0D,0x9C,0xD7,0xD7,0xBF,0x00,0xD0,0xB4,0x4E,0xA4,0xDD,0xBD,0x0B,0x8A, + 0x64,0x59,0x22,0x51,0xA5,0xEE,0xBA,0x2F,0x84,0x61,0x22,0x51,0xFF,0xE5,0xEB,0xA0, + 0x83,0x61,0x23,0x51,0xB7,0xAF,0x3F,0xBF,0x84,0x61,0x22,0x51,0xBE,0xFC,0x5A,0x5A, + 0x43,0x51,0x02,0x51,0xAA,0xE0,0xEA,0x21,0x63,0x51,0x22,0x51,0xF7,0x95,0xED,0xAF, + 0x43,0x59,0x22,0x49,0xDA,0xDE,0x0A,0x8A,0x63,0x51,0x23,0x51,0xAF,0xFE,0xEF,0xAF, + 0x43,0x51,0x02,0x49,0xF2,0xFE,0xE8,0xAE,0x22,0x51,0x02,0x49,0x2A,0x6E,0xDE,0xD7, + 0x43,0x51,0xE2,0x48,0x2E,0xA9,0xAE,0xAB,0x43,0x51,0x02,0x49,0x00,0xB8,0xBE,0x6E, + 0x43,0x51,0x03,0x49,0x78,0xEC,0x7E,0x97,0x64,0x59,0x03,0x49,0x55,0xD5,0x3F,0xFF, + 0x43,0x51,0x02,0x49,0xAB,0xFC,0xEB,0x5A,0x23,0x51,0xE2,0x48,0x6E,0x8B,0x3A,0x2A, + 0x44,0x59,0x03,0x51,0xB7,0x15,0xA7,0x2B,0x64,0x59,0x23,0x51,0xB3,0x8B,0xBB,0x2D, + 0x64,0x59,0x23,0x51,0xFA,0x7E,0xEA,0xEE,0xC5,0x69,0x23,0x51,0xF5,0xB5,0xF5,0x37, + 0x4A,0x9B,0x26,0x72,0x2D,0x0D,0x09,0x0B,0xAB,0xA3,0x6A,0x9B,0x0D,0xA9,0xEE,0xAB, + 0xEC,0xAB,0x8B,0xA3,0xAB,0x2B,0xA5,0xBD,0x0D,0xAC,0xCC,0xA3,0xBF,0xAF,0x2D,0x2D, + 0x2D,0xB4,0xEC,0xAB,0x89,0xA2,0x80,0x3F,0x2D,0xB4,0xCC,0xA3,0xFE,0xBA,0xAF,0xE2, + 0xED,0xAB,0x6B,0x9B,0x68,0xEC,0xF8,0xE8,0x8B,0x9B,0x29,0x93,0x7A,0xEB,0xFB,0x88, + 0x6B,0x9B,0x09,0x8B,0x5F,0x7F,0xFA,0xE0,0x29,0x93,0xC8,0x82,0x5E,0xDE,0x5E,0xB8, + 0xE8,0x8A,0xC8,0x82,0x30,0x0A,0x0B,0xFA,0x08,0x8B,0xC8,0x82,0x8A,0x28,0x77,0xF7, + 0xE8,0x82,0x87,0x7A,0x78,0x7A,0xFE,0x7C,0x87,0x7A,0x26,0x6A,0xBC,0xEC,0xD8,0x58, + 0x67,0x72,0x26,0x72,0x9A,0xFA,0x6F,0xAF,0x66,0x72,0x05,0x6A,0xD8,0xF6,0xFF,0xBE, + 0x46,0x72,0x26,0x6A,0x3E,0xA5,0xEE,0xA7,0x46,0x72,0x26,0x6A,0xFA,0xEB,0x8A,0x8A, + 0x67,0x7A,0x26,0x72,0xF5,0x0D,0x02,0x3B,0xA8,0x82,0x46,0x7A,0xAF,0x36,0xAE,0x02, + 0xC8,0x82,0x87,0x82,0x1F,0xAD,0xAB,0xAA,0xC8,0x82,0x68,0x7A,0xAA,0xBA,0xF6,0xB8, + 0xC9,0x82,0x67,0x72,0x6A,0xF2,0xF8,0xFA,0x88,0x7A,0xE5,0x61,0x58,0x72,0xE0,0xE0, + 0xC5,0x59,0xE2,0x38,0x5E,0x5A,0xFE,0xF8,0x03,0x41,0x81,0x30,0x7A,0xE8,0xA8,0xA0, + 0xC2,0x30,0x81,0x28,0xAF,0x5E,0x77,0xD4,0xC2,0x30,0x81,0x28,0x3F,0xAB,0x2B,0xAD, + 0xC2,0x30,0xA2,0x28,0x80,0xA0,0xF8,0xFF,0xE3,0x38,0xA2,0x30,0x08,0x0A,0xFB,0xFE, + 0x23,0x41,0xA1,0x30,0x83,0xAB,0xAF,0xFD,0xE3,0x38,0xA1,0x30,0xA0,0xE0,0xE8,0xFA, + 0xE3,0x38,0xC2,0x30,0xA8,0x2B,0x23,0x03,0x24,0x41,0xC2,0x38,0x2B,0xAF,0xFF,0x7F, + 0x24,0x41,0xC3,0x38,0x00,0x82,0xFD,0xFD,0x65,0x49,0x03,0x41,0x21,0x29,0xAB,0xA5, + 0x85,0x51,0x24,0x41,0xAA,0xE2,0xCF,0xB7,0x44,0x41,0x03,0x41,0xD6,0x6A,0x60,0xC2, + 0x44,0x49,0xE3,0x38,0xA2,0xEF,0x7F,0x7F,0x23,0x41,0xE3,0x38,0x70,0xBA,0xEE,0xB7, + 0xE3,0x30,0xA3,0x30,0x0A,0x00,0x80,0xF0,0xC2,0x30,0xA2,0x28,0x00,0xA0,0x90,0x97, + 0x04,0x39,0xC3,0x30,0x77,0xA5,0xB5,0xFD,0xC3,0x38,0xE3,0x30,0x7F,0xDF,0xDF,0xD5, + 0x44,0x49,0xC2,0x30,0xAB,0x2D,0xBD,0x3F,0x85,0x49,0x44,0x49,0x25,0x2D,0x2F,0xB5, + 0xA5,0x51,0x65,0x49,0x48,0x70,0x5A,0x5D,0x65,0x49,0x23,0x41,0xE0,0xE0,0xF8,0x78, + 0x44,0x41,0x03,0x41,0xBF,0xBF,0x7F,0x5F,0x03,0x41,0xE3,0x38,0x6A,0xEA,0x58,0xF0, + 0x03,0x39,0xC3,0x30,0xAF,0x3B,0xFB,0x7F,0xE3,0x38,0xC2,0x30,0x57,0x56,0xD7,0xDE, + 0xE3,0x38,0xC3,0x30,0xE1,0xB7,0x14,0x0D,0x03,0x39,0xC3,0x30,0xBF,0xBF,0xBE,0xAA, + 0x03,0x39,0xC2,0x30,0x9A,0xA8,0xBA,0xEE,0xE3,0x30,0xC2,0x30,0x7C,0x5C,0x5B,0x92, + 0x03,0x39,0xC2,0x30,0xE5,0x7B,0xBF,0xEB,0x03,0x39,0xC2,0x30,0xEB,0xB7,0x7C,0x7A, + 0x03,0x39,0xC2,0x30,0xE2,0xA3,0x5F,0x75,0xE3,0x38,0xC2,0x30,0x2A,0xFA,0xFA,0x03, + 0x03,0x39,0xC2,0x30,0xEA,0xBD,0xFB,0xF2,0xC4,0x38,0xE2,0x30,0xB7,0xF5,0x5F,0x7F, + 0x03,0x39,0xC2,0x30,0x3F,0xDF,0xFB,0xDA,0x24,0x39,0xC2,0x30,0x62,0xFE,0xFB,0xDD, + 0xE3,0x30,0xA2,0x30,0xCB,0xCA,0xF8,0xE8,0xE3,0x30,0xA1,0x30,0xA0,0xAB,0xAF,0xBF, + 0x03,0x39,0xC2,0x30,0x2F,0xBD,0xFD,0xDD,0x03,0x39,0xC2,0x38,0x0F,0xBB,0x9B,0x0D, + 0x23,0x41,0xE2,0x38,0x2A,0x2C,0x0F,0x0D,0x44,0x41,0x03,0x39,0x8F,0xBF,0xD7,0xFC, + 0x44,0x41,0x23,0x41,0x57,0x65,0xB7,0xF5,0x44,0x41,0xE3,0x38,0xBE,0xFA,0xF8,0x1A, + 0x44,0x41,0x03,0x39,0xEE,0xAF,0xFB,0x2F,0x23,0x41,0xC2,0x38,0xFA,0xDE,0xF8,0xF8, + 0x64,0x49,0x03,0x41,0x0D,0x0D,0xAD,0xFD,0x85,0x51,0x23,0x41,0x1F,0xBE,0xAE,0xED, + 0xA5,0x51,0x44,0x49,0xA2,0x23,0x25,0x3D,0xC5,0x61,0x43,0x49,0x2B,0xFF,0xDF,0xFF, + 0x26,0x6A,0x64,0x51,0x80,0xAB,0xAF,0xF5,0xE6,0x61,0x63,0x51,0x7E,0xEA,0xC2,0x8B, + 0x26,0x6A,0x84,0x59,0x2D,0x25,0x9F,0xBF,0xA8,0x7A,0x26,0x6A,0x3F,0xAF,0x2B,0x2D, + 0xC9,0x82,0x67,0x72,0x8A,0xEA,0xF6,0x7F,0xC9,0x82,0x88,0x7A,0x6B,0xA2,0xBE,0xF7, + 0xAB,0x93,0xA8,0x7A,0x35,0xB5,0xF5,0xF5,0x52,0xCD,0xEC,0xA3,0x0B,0x2B,0xAD,0xAD, + 0x93,0xD5,0x11,0xC5,0x0A,0x2B,0xAD,0xB5,0x93,0xD5,0x52,0xCD,0xF4,0x54,0x7B,0xFB, + 0x93,0xCD,0x31,0xC5,0x8A,0xAE,0xAF,0xFF,0x93,0xD5,0xF0,0xBC,0x78,0x58,0x5F,0x57, + 0x93,0xCD,0xF1,0xBC,0xAD,0x29,0x8F,0x2A,0x73,0xCD,0x11,0xBD,0xF8,0x78,0xE0,0x60, + 0x52,0xC5,0xF1,0xBC,0x0E,0xBF,0xF7,0x57,0x73,0xCD,0xD1,0xB4,0xA8,0x28,0xAF,0xFD, + 0x52,0xC5,0x11,0xBD,0x78,0xAA,0xCF,0x6F,0x11,0xBD,0x6F,0xAC,0xA8,0xF8,0x78,0x5E, + 0xB0,0xB4,0x4F,0xA4,0xA0,0x92,0xBE,0x17,0xB0,0xB4,0x90,0xAC,0x4A,0x32,0x52,0x76, + 0x4F,0xA4,0xC9,0x7A,0xE0,0xF8,0x58,0x58,0x2E,0x9C,0xEA,0x7A,0xB5,0xBD,0x25,0x0D, + 0xD0,0xB4,0xEE,0x9B,0xFD,0xED,0xAB,0x0A,0xF1,0xBC,0x4E,0xA4,0x55,0x55,0xBD,0x0A, + 0x32,0xBD,0x0E,0x9C,0xFD,0xAE,0xA2,0x80,0xD0,0xB4,0x6F,0xAC,0xBD,0xAA,0xA8,0x20, + 0xD0,0xB4,0x6F,0xAC,0xA2,0xAF,0xDF,0xFE,0xB0,0xAC,0x6F,0xAC,0x00,0xAE,0xDC,0xDE, + 0xB0,0xB4,0x4F,0xA4,0xA2,0xE2,0xFB,0xE2,0xB0,0xAC,0x6F,0xAC,0xCB,0xD5,0xD7,0xF7, + 0x84,0x59,0x43,0x51,0xBF,0xBA,0xE2,0xFE,0x84,0x59,0x43,0x59,0x0A,0x8B,0x0F,0xB7, + 0x63,0x59,0x23,0x51,0x0F,0x8A,0xEE,0xFC,0x63,0x59,0x02,0x51,0xFA,0xEA,0xEA,0xFB, + 0x43,0x51,0x02,0x49,0x00,0x7F,0x6F,0x7F,0x64,0x51,0xE2,0x48,0x0A,0xA5,0xBF,0xAE, + 0x63,0x51,0x22,0x51,0xBF,0xFD,0x7F,0x53,0x43,0x51,0x22,0x51,0xC8,0x70,0x70,0x7A, + 0x43,0x51,0x02,0x49,0x8E,0xE2,0x62,0xD8,0x43,0x51,0x02,0x49,0x97,0x8F,0xBF,0xEB, + 0x44,0x51,0x03,0x49,0xEB,0x2A,0x2E,0x01,0x43,0x51,0x02,0x49,0xAE,0x27,0xAD,0xAD, + 0x64,0x51,0x02,0x49,0xF5,0x37,0xD7,0x5D,0x43,0x51,0x03,0x51,0xEA,0xC2,0xC3,0xFB, + 0x43,0x51,0xE2,0x48,0x78,0xEB,0xBE,0xFA,0x64,0x59,0x03,0x51,0xF7,0xAF,0xAF,0x8B, + 0x64,0x59,0x23,0x51,0xAA,0x2A,0xEA,0xEA,0x64,0x59,0x23,0x51,0x2D,0xAE,0xDE,0xFD, + 0x44,0x59,0x23,0x59,0x08,0x20,0x00,0xC0,0xE5,0x69,0x03,0x51,0xBF,0xBF,0x3D,0x35, + 0x4A,0x9B,0x67,0x7A,0x09,0x09,0x0B,0x0B,0xAB,0xA3,0x6B,0x9B,0x23,0xAB,0xAF,0x2E, + 0xEC,0xAB,0x8B,0x9B,0xFF,0xFD,0x2F,0xBB,0xEC,0xAB,0xAC,0xA3,0x2F,0xBF,0xAF,0xAF, + 0x0D,0xAC,0xCC,0xA3,0x3A,0xAF,0xBB,0xBF,0x0D,0xAC,0xCC,0xAB,0x60,0x82,0xA2,0xEB, + 0x0D,0xAC,0xAB,0xA3,0x7F,0xAE,0xBF,0x8A,0xEC,0xAB,0x8B,0x9B,0x5F,0xF2,0xE2,0xA0, + 0xAB,0xA3,0x4A,0x93,0x75,0x7E,0xFE,0xA0,0x6A,0x9B,0xE9,0x8A,0xDE,0x6E,0xA8,0x88, + 0x29,0x93,0xC8,0x82,0x77,0xFE,0xAA,0xA0,0xE8,0x8A,0xC8,0x82,0xCB,0xBF,0xD4,0xF8, + 0xE9,0x82,0x67,0x72,0xF0,0x62,0x72,0x7C,0x67,0x72,0x26,0x72,0xD8,0xF8,0xFC,0x7F, + 0x46,0x72,0x06,0x6A,0x2A,0x0A,0x28,0x6A,0x46,0x72,0x26,0x6A,0xD8,0x28,0x88,0x2B, + 0x46,0x72,0x05,0x6A,0xAC,0x8A,0x88,0x60,0x66,0x72,0x05,0x6A,0xFB,0xBE,0xEF,0x81, + 0x87,0x7A,0x26,0x72,0x9B,0x3B,0x2B,0x02,0xE8,0x8A,0x88,0x7A,0x9F,0x95,0xBF,0xAB, + 0xC8,0x8A,0xA8,0x7A,0x9F,0xFE,0xFC,0x7B,0xE9,0x8A,0x88,0x7A,0xFA,0xA8,0xA2,0xEA, + 0xA8,0x82,0x68,0x7A,0x78,0xA0,0x80,0xE8,0x87,0x7A,0x26,0x6A,0x62,0x20,0xA0,0x62, + 0x46,0x6A,0x43,0x49,0x5E,0x58,0x68,0x78,0x23,0x49,0xA2,0x30,0xFA,0x7A,0xFC,0x78, + 0xA2,0x30,0x61,0x28,0xF0,0xFA,0xDE,0xD8,0xA2,0x28,0x61,0x28,0x2B,0x2F,0x2B,0xA2, + 0xC2,0x30,0xA2,0x28,0xD7,0xED,0xAF,0x6D,0xC2,0x30,0x82,0x28,0x08,0xAE,0xBB,0xDB, + 0xC2,0x30,0xA2,0x30,0x0F,0x2A,0x1F,0xD7,0xC2,0x30,0xA2,0x30,0xDC,0x54,0x5A,0xF2, + 0xE2,0x38,0xA2,0x30,0x0F,0xED,0xBD,0xF7,0xE3,0x38,0xC3,0x38,0xE0,0xE0,0xFF,0x3B, + 0x03,0x41,0xE3,0x38,0xBD,0xBD,0x05,0xA2,0x44,0x49,0xE3,0x38,0x2B,0x3F,0xDF,0x5F, + 0x44,0x49,0x03,0x41,0x82,0xEE,0xF5,0x75,0x44,0x49,0x03,0x39,0x2A,0xEB,0xAD,0x35, + 0x45,0x49,0xE3,0x38,0x5E,0xDF,0xFC,0x7C,0x03,0x39,0xA2,0x38,0x2A,0x28,0x28,0xAB, + 0x03,0x39,0xA2,0x30,0x7A,0x7C,0xE8,0xA0,0xC3,0x30,0x81,0x28,0x2B,0xA9,0x7F,0xD6, + 0xE3,0x30,0x82,0x28,0x3A,0x2B,0xAF,0xBD,0x04,0x39,0xC2,0x30,0xE3,0xA3,0x77,0x7F, + 0x44,0x49,0xC2,0x30,0x35,0xA7,0x35,0xB5,0x85,0x49,0x03,0x41,0x2B,0xAE,0xDF,0x55, + 0x64,0x49,0x03,0x41,0x88,0xFE,0xF5,0xD7,0x64,0x49,0xE3,0x38,0xE0,0xF0,0xAF,0xDF, + 0x24,0x41,0xE3,0x38,0xEB,0xEB,0x5E,0x57,0x03,0x39,0xA2,0x30,0xA2,0xF2,0xFA,0xDA, + 0xE3,0x38,0xA2,0x30,0xEA,0xBA,0x2A,0xB7,0x04,0x39,0xC3,0x30,0xB5,0xBF,0x3E,0x97, + 0x03,0x39,0xC3,0x30,0xFF,0x7E,0xEA,0xAB,0x03,0x39,0xC3,0x30,0xAB,0xFB,0xBF,0xBD, + 0x03,0x39,0xC3,0x30,0xA2,0xAA,0xB8,0xDA,0x03,0x39,0xC2,0x30,0x2A,0x0A,0xBA,0xFE, + 0xE3,0x38,0xC2,0x30,0x2F,0xD7,0x57,0x55,0xE3,0x30,0xA2,0x30,0xA8,0x3F,0x2F,0x2F, + 0x03,0x39,0xA2,0x28,0xFA,0xFA,0xF0,0x72,0xE3,0x38,0xC2,0x30,0x0D,0xAD,0x95,0x25, + 0x03,0x41,0xE3,0x30,0x53,0x5D,0xF5,0xF5,0x24,0x41,0xC3,0x30,0xF7,0xBF,0xBA,0xAE, + 0x03,0x39,0xC2,0x30,0x7E,0x7E,0xBC,0xB8,0x03,0x39,0xC2,0x30,0xBF,0xBB,0xA8,0xC0, + 0x03,0x39,0xC2,0x30,0x78,0xEA,0xE8,0x82,0x03,0x39,0xA1,0x30,0xF7,0xBB,0xAA,0xA0, + 0x03,0x39,0xC2,0x30,0xFD,0x5F,0xCB,0x8A,0x03,0x39,0xC2,0x38,0x0B,0x03,0x0B,0xAB, + 0x44,0x41,0xE3,0x38,0xAD,0x3F,0xAB,0xAB,0x64,0x49,0x23,0x41,0xB8,0xFE,0xBE,0x6F, + 0x64,0x49,0x23,0x41,0x56,0x78,0x5F,0x5F,0x23,0x41,0x03,0x39,0xFB,0xDF,0xDD,0x36, + 0x23,0x41,0x03,0x39,0xEE,0x7B,0xBF,0xAE,0x03,0x41,0xE3,0x30,0xA2,0x8A,0x00,0x28, + 0x24,0x41,0xE2,0x38,0x16,0xF7,0xBE,0xAF,0x44,0x49,0xE2,0x38,0x3E,0x37,0x37,0xFF, + 0xA5,0x51,0x23,0x49,0xBD,0xBB,0x2B,0x8F,0x84,0x51,0x44,0x49,0xEB,0xEE,0xF8,0xE8, + 0xA5,0x59,0x44,0x49,0x2F,0xB5,0x5F,0x5F,0xA4,0x59,0x64,0x51,0x2B,0xAE,0x29,0x0B, + 0x06,0x62,0xA4,0x59,0x2F,0xAD,0xBB,0xEB,0xC8,0x7A,0x06,0x62,0xAD,0x29,0x2D,0x25, + 0x09,0x83,0x67,0x72,0x7E,0x5A,0x6A,0xA2,0xC8,0x82,0x67,0x72,0xAE,0x8B,0xBD,0xD5, + 0x2A,0x83,0x87,0x7A,0x3D,0xFF,0xF5,0xF5,0xAF,0xBC,0x4A,0x93,0x0B,0x0B,0x29,0x0D, + 0x52,0xCD,0xAF,0xB4,0x0B,0x8E,0x2F,0xAD,0x72,0xCD,0x32,0xC5,0x82,0x2B,0x89,0xA5, + 0x93,0xCD,0x31,0xC5,0xF7,0xFF,0xE7,0x89,0x32,0xC5,0xF1,0xBC,0xF8,0x1F,0x3C,0xBC, + 0x94,0xCD,0x52,0xC5,0x89,0x2B,0x0B,0x23,0x94,0xCD,0x32,0xC5,0x78,0xE8,0xE0,0x58, + 0x32,0xC5,0xF1,0xBC,0x7B,0x50,0xFC,0x96,0x11,0xBD,0xD0,0xB4,0xEC,0xEA,0xD0,0xDB, + 0x32,0xC5,0x90,0xB4,0x22,0xAA,0xBB,0x77,0xF1,0xBC,0x4F,0xA4,0x7C,0x78,0x7A,0xFF, + 0x8F,0xAC,0x4F,0xA4,0xB7,0xBD,0x2A,0x0A,0xD0,0xB4,0x4F,0xA4,0x7E,0x7B,0x6B,0x8A, + 0xD0,0xB4,0xEA,0x7A,0x5E,0xFE,0xAA,0x00,0xF0,0xBC,0x8C,0x8B,0x25,0x2B,0x02,0x08, + 0x11,0xBD,0xB0,0xB4,0xB9,0x8E,0x80,0x7F,0x11,0xBD,0xD0,0xB4,0x22,0x0A,0xBA,0xB5, + 0x52,0xC5,0x11,0xBD,0x6D,0xBB,0x2D,0x3D,0x51,0xC5,0xD0,0xB4,0x5F,0x5A,0xFA,0xF8, + 0x11,0xBD,0x8F,0xAC,0x57,0x7E,0xFA,0xB0,0xF1,0xBC,0x8F,0xAC,0x7F,0x7F,0xEF,0xE2, + 0xB0,0xB4,0x6F,0xAC,0x5D,0x9F,0x23,0xC2,0x90,0xAC,0x6F,0xAC,0x55,0x2B,0x7A,0x7B, + 0x64,0x59,0x43,0x51,0x8E,0x98,0xF6,0x57,0x64,0x59,0x23,0x51,0xF0,0x7A,0x5F,0xDB, + 0x64,0x59,0x23,0x51,0xDB,0xE5,0xA3,0xCB,0x43,0x51,0x22,0x51,0xF5,0x74,0x74,0x08, + 0x43,0x51,0x02,0x49,0xAB,0xDA,0x38,0x2F,0x43,0x51,0x23,0x51,0x8E,0xAF,0x9C,0x58, + 0x63,0x51,0x02,0x49,0xEF,0x8F,0xAF,0xFE,0x43,0x51,0xE2,0x40,0xA8,0xC2,0xEA,0x7B, + 0x23,0x49,0xE2,0x48,0xD4,0xBA,0xA7,0x89,0x43,0x51,0x03,0x49,0x0B,0x8F,0x85,0xD5, + 0x44,0x51,0x03,0x49,0xEA,0xEA,0x5F,0x57,0x23,0x51,0x03,0x49,0x0D,0x8F,0xDC,0x2E, + 0x43,0x59,0x03,0x51,0xDD,0x3B,0x68,0xFA,0x23,0x51,0xE3,0x48,0x82,0xB2,0xF8,0xFB, + 0x44,0x59,0x03,0x51,0x55,0x35,0xA9,0x3F,0x64,0x59,0x23,0x59,0xAB,0xE0,0x68,0xCA, + 0x64,0x59,0x23,0x51,0x78,0xE2,0xFA,0x5E,0x44,0x59,0x23,0x51,0xFD,0xDD,0x74,0x05, + 0x44,0x59,0x03,0x51,0xEB,0xAF,0x83,0x80,0x87,0x82,0x23,0x51,0xB5,0xB5,0xB5,0x2D, + 0x8B,0xA3,0xC8,0x8A,0x29,0x09,0x09,0x0B,0xCC,0xAB,0x6A,0x9B,0xBF,0xA7,0xAD,0xAA, + 0xCC,0xA3,0xAB,0xA3,0x0B,0xB9,0x7B,0xEB,0xEC,0xAB,0x8B,0x9B,0x2A,0x8A,0xAD,0xEE, + 0x0D,0xAC,0xAB,0xA3,0x28,0x0E,0x37,0xD7,0x2D,0xB4,0xCC,0xA3,0xA8,0xA2,0xCB,0xED, + 0x0D,0xAC,0xCC,0xAB,0xAA,0xF0,0xE2,0x6D,0x0D,0xAC,0xCC,0xAB,0xE2,0xFB,0xE8,0xDA, + 0xEC,0xAB,0xAB,0xA3,0x56,0x68,0x00,0x6E,0xCC,0xAB,0x6A,0x9B,0x5F,0xAA,0x80,0xFE, + 0xAB,0xA3,0x09,0x8B,0x5A,0x7A,0xF0,0x78,0x09,0x93,0x87,0x7A,0xAA,0xF8,0x7C,0x7E, + 0xA8,0x82,0x46,0x72,0xF0,0xE8,0xFF,0x57,0x67,0x7A,0x26,0x72,0x76,0x87,0x37,0xF7, + 0x46,0x72,0x26,0x6A,0xA8,0xC0,0x80,0x20,0x46,0x72,0x26,0x6A,0xAD,0x9F,0xBA,0xA3, + 0x46,0x72,0x05,0x6A,0x32,0x2B,0x0A,0x2F,0x87,0x7A,0x46,0x72,0x79,0xDD,0xFD,0x8B, + 0xC8,0x82,0x67,0x72,0x3D,0x0F,0x09,0x02,0xC8,0x82,0x87,0x7A,0xA8,0xB0,0xFA,0xF2, + 0xC8,0x82,0x67,0x7A,0xA8,0xAA,0xAA,0x5A,0xC9,0x82,0x25,0x6A,0x80,0xAB,0xFE,0x56, + 0x88,0x7A,0x26,0x6A,0x80,0xFA,0x5F,0x5D,0x67,0x7A,0x05,0x6A,0x80,0xFA,0x5B,0xD7, + 0x26,0x6A,0xA4,0x59,0x70,0x60,0xE0,0xAA,0xA4,0x59,0xC2,0x38,0x5F,0x7E,0xDE,0x78, + 0xC2,0x38,0x82,0x30,0x56,0x5E,0x7C,0x5C,0xA2,0x30,0x81,0x28,0xAA,0xAF,0x22,0x29, + 0xC2,0x30,0xA2,0x28,0x6D,0xE8,0xC0,0xE0,0xC2,0x30,0x81,0x28,0x7B,0xEA,0xA2,0xAA, + 0xC3,0x30,0x81,0x28,0xFA,0xFB,0xBC,0x2A,0xC2,0x30,0xA2,0x30,0xEF,0xAF,0x0B,0x0B, + 0xE3,0x38,0xA2,0x30,0xF5,0xAF,0x2B,0x02,0x03,0x39,0xC2,0x30,0x3D,0xAF,0xAB,0x0E, + 0x03,0x39,0xC2,0x38,0x9C,0x5C,0x7E,0x7E,0x03,0x41,0xC3,0x38,0x8A,0xC9,0xED,0xAD, + 0x44,0x49,0xE3,0x38,0xAD,0xAD,0x0D,0x2B,0x65,0x49,0x03,0x41,0xF5,0xAE,0xAA,0xCA, + 0x24,0x41,0xE3,0x38,0x54,0x5C,0x8C,0x80,0x24,0x41,0xE3,0x38,0x55,0x7D,0x6A,0x80, + 0x03,0x39,0xC2,0x30,0xAB,0x9D,0x97,0xBA,0xE3,0x38,0x82,0x28,0x7C,0xF0,0xF8,0xA0, + 0xC2,0x30,0x82,0x28,0x9F,0xDF,0xD7,0xB6,0xC2,0x30,0xA2,0x28,0x00,0xB3,0x7F,0xD6, + 0xE3,0x38,0x82,0x28,0x2A,0xAA,0xAD,0xBF,0x23,0x41,0xC3,0x38,0xAF,0x3D,0x9D,0xBD, + 0x44,0x49,0xE3,0x38,0xDF,0xFF,0xC0,0x8A,0x24,0x41,0xC2,0x38,0xEE,0xF2,0xFA,0xF8, + 0xE3,0x38,0x82,0x30,0x30,0xFE,0xF6,0xFF,0xC3,0x30,0x82,0x28,0x20,0xAB,0xA7,0xDF, + 0xC2,0x30,0xA2,0x28,0x0E,0x2E,0x0A,0x83,0xE3,0x30,0xA2,0x28,0x2F,0xB7,0x7F,0xFF, + 0xE3,0x30,0xA2,0x28,0x0B,0x0A,0x2F,0xA3,0x03,0x31,0xA2,0x28,0x8A,0xAA,0xBE,0xDD, + 0xE3,0x30,0xA2,0x30,0x20,0x22,0xB6,0xBF,0x03,0x39,0xC2,0x30,0xFF,0x9B,0xFA,0xE8, + 0x03,0x31,0xA2,0x30,0xDF,0xFC,0xEB,0xEB,0xE3,0x38,0xC2,0x30,0xA5,0xA5,0x2A,0x08, + 0x03,0x39,0xC2,0x30,0x53,0xEB,0xBF,0xFC,0x03,0x39,0xC2,0x30,0xA5,0x95,0x97,0x55, + 0x03,0x39,0xA2,0x30,0x2A,0x9A,0x2A,0xA2,0x03,0x39,0xE3,0x38,0xBC,0xD7,0x57,0xDE, + 0x24,0x41,0xE3,0x38,0xDA,0x7D,0xF2,0x4A,0x03,0x41,0xE2,0x38,0x79,0xAB,0x3A,0xA2, + 0x24,0x41,0xE2,0x38,0xFF,0x6B,0xE8,0x0F,0x03,0x41,0xE3,0x38,0xBD,0xA7,0xFD,0x7B, + 0x23,0x41,0xC2,0x30,0xB7,0xBE,0x2A,0xAA,0x24,0x41,0xE2,0x38,0x97,0xF7,0xB9,0x8B, + 0x64,0x49,0x03,0x41,0xEF,0xB7,0x25,0x0D,0x64,0x49,0x03,0x39,0xEE,0x5A,0xFA,0xF2, + 0x03,0x41,0x44,0x39,0xAA,0xFA,0x2B,0xFF,0x24,0x41,0xE2,0x38,0x2A,0x8E,0xFB,0xDE, + 0x23,0x41,0x03,0x39,0x03,0x3F,0x6F,0xD7,0x23,0x41,0xE3,0x38,0x2E,0x08,0xAF,0xBF, + 0x24,0x41,0xE2,0x38,0x2E,0x2A,0x2F,0xB7,0x44,0x49,0xE2,0x38,0xAA,0x0A,0xF2,0x7E, + 0x85,0x51,0x03,0x41,0x2B,0x0F,0x3D,0xBD,0xA5,0x51,0x44,0x49,0x7E,0xAE,0x8B,0xAD, + 0xE6,0x59,0x64,0x51,0x5D,0xF9,0xAA,0x2C,0xC5,0x59,0x64,0x51,0x8D,0xBD,0x9F,0x3F, + 0x26,0x6A,0xE5,0x61,0x75,0x35,0x9F,0xA2,0xA8,0x72,0x06,0x6A,0x2D,0xBF,0xEF,0xBF, + 0xE9,0x82,0x87,0x72,0xEB,0xFB,0x3D,0xED,0xC8,0x82,0x67,0x72,0xD6,0x5A,0xF8,0x60, + 0xA8,0x7A,0x46,0x72,0x0A,0x2D,0x37,0x9E,0x6E,0xAC,0xA8,0x7A,0x0F,0x2B,0x2D,0x2D, + 0x11,0xC5,0x8E,0xB4,0x29,0xAF,0x2D,0x29,0xB3,0xD5,0x11,0xBD,0xFD,0xB5,0xAF,0x0B, + 0xB3,0xD5,0x32,0xC5,0xAB,0xEB,0xFA,0x78,0x32,0xC5,0xAF,0xAC,0xA8,0xAA,0xAF,0xB5, + 0xB4,0xD5,0x32,0xC5,0xA9,0xA9,0xA9,0x8F,0x73,0xCD,0x33,0xC5,0x70,0xE8,0xA8,0xE8, + 0x53,0xC5,0x11,0xBD,0xF7,0x5A,0x58,0x78,0x11,0xBD,0xB0,0xB4,0x7F,0x7E,0x7E,0x5C, + 0xB0,0xB4,0x0E,0xA4,0xE0,0xFA,0xFC,0xBE,0xB0,0xB4,0x2E,0xA4,0xAF,0xAD,0xAB,0x8A, + 0x11,0xBD,0x6F,0xAC,0x9D,0x2F,0x0B,0xAA,0xF1,0xBC,0x6F,0xAC,0xA2,0x88,0x68,0x5E, + 0xD1,0xB4,0x4E,0xA4,0x80,0xFE,0x55,0x55,0xB0,0xB4,0x2E,0xA4,0x80,0xAF,0xBF,0x55, + 0xB0,0xB4,0x0E,0x9C,0xA0,0xAA,0x7E,0x57,0xF1,0xB4,0xCD,0x9B,0x2A,0xBA,0xFF,0xD5, + 0xF1,0xBC,0x4E,0xA4,0x00,0xAB,0xF5,0x55,0x11,0xBD,0x6F,0xAC,0x00,0x8B,0xBF,0xF5, + 0x32,0xC5,0x8F,0xAC,0xAA,0x02,0xBA,0xDD,0x32,0xC5,0xD0,0xB4,0x7A,0xBC,0xF6,0x9B, + 0x11,0xBD,0xB0,0xB4,0x5F,0x08,0x20,0x00,0x32,0xC5,0x8F,0xAC,0x55,0xEC,0x88,0x0A, + 0x64,0x59,0x23,0x51,0xFE,0xDC,0x55,0xD5,0x43,0x51,0x23,0x51,0xCB,0x62,0xBC,0x75, + 0x63,0x51,0x03,0x49,0x8D,0xFE,0x5A,0xF7,0x43,0x51,0x02,0x49,0x0C,0xBA,0xFE,0x8A, + 0x43,0x51,0x03,0x51,0x2A,0x8A,0x4A,0xC8,0x64,0x59,0x03,0x49,0xEB,0xB2,0xFB,0x6B, + 0x43,0x51,0xE2,0x48,0xE2,0x82,0xF8,0x6E,0x43,0x51,0xE2,0x40,0xDB,0xEE,0xFB,0xA3, + 0x43,0x51,0x03,0x49,0x7F,0x7F,0xFB,0x8B,0x44,0x51,0x02,0x49,0xFD,0xAB,0x8A,0xB8, + 0x23,0x51,0x02,0x49,0x5E,0x7F,0xA2,0x02,0x43,0x51,0xE3,0x48,0x8A,0xE2,0xA0,0xA8, + 0x44,0x59,0xE2,0x50,0xEA,0x62,0xFA,0xEA,0x44,0x59,0xE2,0x48,0xBD,0x2D,0xAA,0x02, + 0x85,0x61,0x23,0x51,0xFD,0x7F,0x5E,0x78,0x64,0x59,0x23,0x51,0xB9,0xB1,0x22,0x83, + 0x64,0x59,0x23,0x51,0xF4,0xFE,0xFF,0xAD,0x64,0x61,0x23,0x51,0xBD,0xA9,0xCB,0xFB, + 0x64,0x59,0x23,0x51,0xAC,0xBF,0xF5,0x2F,0xA8,0x82,0x44,0x59,0x3D,0x3D,0x2D,0x2D, + 0xAB,0xA3,0x09,0x93,0xAF,0xAD,0x0D,0x2B,0xCB,0xA3,0x8B,0x9B,0x1F,0xAD,0xAB,0xAA, + 0xCC,0xA3,0x8B,0xA3,0x83,0xA2,0xD2,0xEA,0xCB,0xA3,0x6A,0x9B,0xA2,0xAA,0xEB,0x7F, + 0xAB,0xA3,0x4B,0x9B,0x00,0xE0,0xEB,0x5F,0xAC,0xA3,0x4B,0x9B,0x82,0xAB,0xEB,0xFD, + 0xCC,0xAB,0x2A,0x93,0x02,0xAA,0xBB,0x5F,0xCC,0xA3,0x29,0x93,0x00,0xAA,0xDF,0x55, + 0xAB,0xA3,0x09,0x8B,0x80,0xEA,0xFE,0xD5,0x6A,0x9B,0xC8,0x82,0x00,0xEA,0xFE,0x5F, + 0x29,0x93,0x67,0x7A,0xA0,0xF8,0xFA,0x5F,0xC8,0x82,0x67,0x72,0xDE,0x5F,0xFF,0xFF, + 0x67,0x7A,0x46,0x72,0x53,0xCC,0x7A,0x74,0x67,0x72,0x26,0x72,0xCE,0x4A,0x6A,0x7F, + 0x46,0x72,0x25,0x6A,0xA8,0x90,0x7B,0x57,0x46,0x72,0x05,0x6A,0xAE,0xA2,0xAF,0x3F, + 0x67,0x72,0x06,0x6A,0xBF,0xA6,0xAF,0xAA,0xE9,0x82,0x46,0x72,0x97,0xBD,0xAE,0x23, + 0xE8,0x82,0x87,0x7A,0xAF,0xFA,0xDA,0x74,0xC8,0x82,0x46,0x72,0x88,0xA8,0xAA,0x7A, + 0xA8,0x82,0x05,0x6A,0xE8,0xF8,0x7E,0x5F,0x67,0x72,0xC5,0x61,0xE8,0x6A,0x7F,0x5F, + 0x05,0x6A,0xA4,0x59,0xE0,0x6D,0xFE,0x5F,0x05,0x6A,0x84,0x59,0x02,0xAB,0x9E,0xFF, + 0x25,0x62,0xC5,0x61,0x6F,0xDF,0xFD,0xED,0xC5,0x61,0xE3,0x40,0x78,0x78,0xE8,0x80, + 0x04,0x41,0x61,0x28,0x5E,0x5E,0x78,0x78,0xC2,0x30,0x61,0x28,0x3F,0x2D,0x2F,0xAD, + 0xE3,0x38,0xA2,0x30,0x7F,0xF2,0xAE,0x3F,0xE3,0x38,0xA2,0x30,0x7F,0xFB,0x8A,0xA0, + 0x04,0x39,0xC3,0x30,0xD5,0xDD,0xF5,0x0A,0xE3,0x38,0xA2,0x30,0xAF,0xAE,0x5E,0xF8, + 0x03,0x39,0xC2,0x38,0xA9,0x2D,0x09,0x2B,0xE2,0x40,0x23,0x39,0xFC,0xFE,0xFF,0xAF, + 0x03,0x41,0xA2,0x38,0xE8,0xA8,0x2C,0x2E,0x24,0x41,0xC3,0x38,0xA5,0x2F,0x8A,0xA0, + 0x65,0x49,0x03,0x41,0xAD,0xB5,0x0D,0xEB,0x65,0x49,0x24,0x41,0xAB,0x9F,0xDE,0x9B, + 0x44,0x49,0x23,0x41,0x54,0x77,0x5F,0x55,0x44,0x41,0x03,0x41,0xE2,0xF2,0xFF,0xB7, + 0x44,0x41,0xE3,0x38,0xFB,0xDA,0xE2,0xFA,0x03,0x39,0xC2,0x30,0x7E,0xFA,0xC2,0xE2, + 0xE3,0x30,0x81,0x28,0xDF,0x5F,0xFC,0xF8,0xE3,0x30,0xA2,0x30,0x5F,0x89,0x29,0xBD, + 0x03,0x39,0xA2,0x30,0x1D,0xFB,0xEE,0xAE,0x24,0x41,0xC3,0x30,0x2F,0x25,0x2F,0x0B, + 0x64,0x49,0x04,0x41,0xEF,0xFF,0xEF,0xEF,0x24,0x41,0xA2,0x30,0xE0,0xB0,0xFA,0x5E, + 0xE3,0x38,0xA2,0x30,0x7F,0x7B,0xEB,0x8B,0xE2,0x30,0x81,0x28,0xFF,0x7B,0xAA,0xA0, + 0x03,0x39,0x82,0x28,0xEB,0x7B,0xFB,0x0B,0xE3,0x30,0xA2,0x28,0xEF,0xBB,0x8B,0x28, + 0xE3,0x30,0xA2,0x30,0xE3,0xFB,0xFF,0xD6,0xE3,0x30,0xA2,0x30,0x97,0x1F,0xAB,0x2E, + 0x03,0x39,0xC2,0x30,0x57,0x7B,0xEB,0xAA,0x44,0x41,0xE3,0x38,0x55,0xDD,0xBD,0x8F, + 0x03,0x39,0xC2,0x30,0xFE,0xBC,0xA8,0x2A,0x03,0x39,0xC2,0x30,0xAF,0xAF,0xB6,0xFA, + 0xE2,0x38,0xC2,0x30,0xA2,0x2A,0xBF,0xD5,0xE2,0x38,0xA2,0x30,0xFE,0x2C,0x2E,0xAA, + 0x04,0x41,0xE3,0x30,0xF9,0x8D,0xAF,0xA9,0x23,0x41,0xE3,0x38,0x1D,0xAF,0xBA,0xA3, + 0x44,0x41,0x03,0x39,0x7D,0x5D,0x8B,0x2A,0x03,0x41,0xE3,0x38,0xE7,0xBE,0xA4,0x24, + 0x44,0x49,0x03,0x39,0xBD,0xBB,0x7B,0x02,0x44,0x49,0x03,0x39,0xF7,0xFF,0xFF,0x0F, + 0x43,0x41,0xE3,0x38,0xF7,0xEF,0xFE,0xA8,0x23,0x41,0x03,0x39,0x9D,0x1B,0x03,0x02, + 0x85,0x51,0x03,0x39,0x2B,0x2F,0xFD,0xF7,0x85,0x49,0x03,0x41,0xDC,0xFA,0xFB,0xFF, + 0x44,0x41,0xE2,0x38,0xE2,0xEA,0x7A,0xFA,0x23,0x41,0xE3,0x38,0x56,0x9F,0x3D,0xAE, + 0x64,0x49,0x03,0x39,0xFD,0xFF,0xBA,0x8A,0x44,0x41,0x03,0x39,0xFE,0xAA,0x9E,0x2A, + 0x44,0x41,0xE2,0x38,0xFF,0xD7,0xFE,0xEC,0x23,0x41,0x03,0x39,0x77,0x2B,0x01,0xAD, + 0x44,0x49,0x03,0x41,0xAB,0xAA,0xFE,0xE8,0x85,0x51,0x44,0x49,0x2B,0xBD,0x65,0xD5, + 0xA5,0x51,0x64,0x51,0xF8,0xFE,0xBD,0x35,0xC6,0x59,0x84,0x51,0xB5,0x1D,0x1A,0x2B, + 0x67,0x72,0xA5,0x59,0xAB,0x2B,0x2B,0xAD,0x67,0x72,0x06,0x62,0x0A,0x22,0xA8,0xDE, + 0xA8,0x7A,0x06,0x6A,0x02,0x0A,0xAF,0x75,0xA8,0x7A,0x26,0x6A,0x00,0x02,0xAB,0xB5, + 0x88,0x7A,0x47,0x72,0x5E,0x5B,0xB0,0xAE,0x4D,0xAC,0xA8,0x7A,0x2D,0x2D,0x25,0x25, + 0x72,0xCD,0xCF,0xBC,0xA5,0x2D,0x29,0x09,0xB3,0xD5,0x72,0xCD,0xAD,0x8B,0xCB,0x75, + 0x73,0xCD,0x8F,0xAC,0xE0,0x70,0x78,0x7C,0x73,0xCD,0x4F,0xAC,0xBD,0xBD,0x2D,0x2B, + 0x94,0xCD,0x53,0xC5,0x09,0x7D,0x7A,0xFB,0x73,0xC5,0xF1,0xBC,0xE0,0xFE,0xDF,0x5F, + 0x53,0xC5,0xD1,0xB4,0x8A,0x0F,0xA7,0xFF,0x32,0xC5,0x90,0xAC,0xF8,0xEA,0xF8,0x7E, + 0x90,0xAC,0xEE,0x9B,0x00,0x00,0xA0,0x7A,0x90,0xAC,0xCD,0x93,0x08,0xA8,0xFF,0x75, + 0xB0,0xAC,0xCD,0x93,0xA0,0xEE,0xF5,0x55,0x6F,0xAC,0xEE,0x9B,0xA0,0xFB,0xBF,0x77, + 0x0E,0xA4,0x2E,0x9C,0xB5,0xFE,0xBF,0x8A,0x2E,0xA4,0xCC,0x93,0x00,0xEA,0xFA,0x62, + 0x2F,0xA4,0xCD,0x93,0xA0,0x77,0x7F,0xB7,0x0E,0x9C,0x8C,0x8B,0xBE,0xFF,0xDF,0x20, + 0x6F,0xAC,0xAD,0x93,0x2F,0xB7,0xF5,0x55,0x6F,0xAC,0xED,0x9B,0x2A,0x0B,0x2B,0x95, + 0xB0,0xB4,0x2E,0xA4,0x22,0xA2,0xFF,0x77,0x11,0xBD,0x4F,0xA4,0x0A,0x2F,0x9F,0xD5, + 0x32,0xC5,0xB0,0xAC,0x80,0x02,0x2B,0xB5,0x32,0xC5,0x11,0xBD,0x77,0x2A,0x80,0x23, + 0x43,0x51,0x23,0x51,0xFD,0xD8,0x00,0xE0,0x43,0x51,0x23,0x51,0x4A,0xC2,0x8D,0x13, + 0x43,0x51,0xE2,0x48,0xAA,0xFA,0xF8,0xBC,0x63,0x59,0x03,0x49,0xAF,0x29,0x35,0xBF, + 0x64,0x59,0x23,0x51,0x7E,0x07,0xE5,0x6D,0x43,0x51,0x02,0x49,0x83,0x08,0x02,0x5A, + 0x23,0x51,0xE2,0x40,0x7C,0xEE,0x6E,0xAF,0x23,0x49,0xE2,0x48,0xAB,0x3F,0xAE,0x00, + 0x44,0x51,0x02,0x49,0xBE,0x9D,0xA3,0xA2,0x43,0x51,0x03,0x49,0xF2,0xE8,0xBE,0x2F, + 0x44,0x51,0x02,0x49,0x99,0xFC,0xA2,0x28,0x43,0x51,0x02,0x51,0xAA,0x0A,0xC8,0xEE, + 0x63,0x51,0x03,0x51,0x6F,0xBE,0xAE,0x2A,0x85,0x61,0x23,0x51,0xE7,0xCE,0xF7,0x57, + 0x64,0x59,0x23,0x51,0x70,0x58,0xDF,0xDD,0x64,0x59,0x23,0x51,0x8D,0xB7,0xDA,0x7A, + 0x64,0x59,0x03,0x51,0x2E,0xBB,0xFD,0xAF,0x43,0x59,0x03,0x51,0x32,0xBA,0x28,0x1A, + 0x64,0x59,0x03,0x51,0x2F,0xA7,0xAF,0xAA,0x4A,0x93,0x64,0x59,0x3D,0x2D,0x2D,0x2F, + 0xAB,0xA3,0x49,0x9B,0xB5,0xA5,0xFB,0x0F,0xAB,0xA3,0x6A,0x9B,0x02,0x02,0x2B,0xDA, + 0xCC,0xAB,0x6B,0x9B,0xE2,0xA2,0xEA,0xEA,0x8B,0x9B,0x2A,0x93,0xA2,0xEC,0xFA,0x7E, + 0x4B,0x9B,0x09,0x93,0x20,0xC0,0xFE,0x7F,0x6B,0x9B,0xE9,0x8A,0x8A,0xEE,0x7F,0x77, + 0x2A,0x93,0x87,0x7A,0x20,0xBA,0xFE,0x57,0x09,0x8B,0x87,0x7A,0x00,0x80,0xEA,0x5D, + 0x2A,0x93,0x87,0x7A,0x8A,0xFA,0x7F,0x55,0xA8,0x82,0x66,0x72,0x00,0xBF,0x7E,0x7D, + 0xA7,0x7A,0x46,0x72,0xF0,0xFA,0xF7,0xFF,0x87,0x7A,0x46,0x72,0xE0,0x7B,0x56,0xD7, + 0x66,0x72,0x26,0x6A,0xE6,0xAD,0xC8,0x3A,0x87,0x7A,0x26,0x6A,0x57,0xF5,0xF5,0xDA, + 0x66,0x72,0x25,0x6A,0x7F,0xDA,0xAF,0xBA,0x66,0x72,0x26,0x72,0xBB,0xFB,0xAA,0x0E, + 0xC8,0x82,0x46,0x72,0xB5,0xFF,0x2D,0x2A,0xE9,0x82,0x88,0x7A,0xEA,0xFB,0x72,0xEA, + 0xA7,0x7A,0x46,0x72,0xA8,0x8C,0xE8,0x7E,0x87,0x7A,0xE5,0x69,0xA0,0xEA,0x72,0x7E, + 0x26,0x6A,0xC4,0x61,0x20,0xE0,0x5E,0x7B,0x05,0x6A,0xA4,0x61,0x7C,0xE7,0xEE,0x2B, + 0x05,0x6A,0xA4,0x61,0x7F,0xF5,0xFE,0xA2,0x06,0x6A,0xA4,0x61,0xDF,0xFB,0xA3,0xAA, + 0xE5,0x69,0xA4,0x59,0x2B,0xAE,0xAD,0x82,0x06,0x6A,0xA5,0x59,0x5A,0x7B,0x7A,0xE2, + 0xA5,0x59,0x81,0x30,0x7E,0xFA,0xFA,0xE8,0xE3,0x38,0x81,0x28,0xF5,0xDA,0x7C,0xF0, + 0xE3,0x38,0x61,0x28,0x2B,0x2B,0xFF,0x5F,0x04,0x39,0xA2,0x30,0x00,0x82,0xBD,0xF5, + 0x24,0x41,0xA2,0x30,0x8A,0x0E,0xBF,0x27,0x24,0x41,0xC2,0x30,0x7E,0x7A,0xA0,0x80, + 0xE3,0x38,0xA2,0x30,0x02,0xA8,0xFC,0x58,0xE2,0x38,0xA2,0x30,0xA0,0x3B,0xBF,0x9F, + 0x24,0x41,0xE2,0x38,0x25,0xFB,0x2B,0xBF,0x64,0x49,0x03,0x41,0xF7,0xBF,0xBF,0xAD, + 0x64,0x49,0x24,0x41,0xFB,0xE2,0x88,0x00,0x65,0x49,0x24,0x41,0xDB,0x7F,0x77,0x7F, + 0x44,0x41,0xE2,0x38,0x8F,0xF7,0xFA,0xA0,0x44,0x49,0x03,0x39,0xB7,0xFF,0xAA,0xEA, + 0x23,0x41,0xE3,0x38,0x70,0xF8,0xDA,0xB8,0x24,0x41,0xE3,0x38,0x69,0x5F,0xBE,0x0A, + 0x24,0x39,0xA2,0x30,0x7B,0xFE,0xEA,0xF0,0xC3,0x30,0xA2,0x28,0x25,0x3F,0x2C,0x08, + 0x04,0x39,0xA2,0x30,0xBF,0x3F,0x3E,0xB7,0x44,0x41,0x04,0x39,0xAD,0xEF,0xE1,0x55, + 0x24,0x41,0xC3,0x30,0x80,0xA8,0xE8,0xDE,0xE3,0x38,0xC3,0x30,0xDC,0xC8,0xEA,0x17, + 0xC3,0x38,0xE3,0x30,0xBF,0xDF,0x7F,0x55,0x03,0x39,0xC3,0x30,0x77,0x8A,0xE2,0xD6, + 0x03,0x39,0xC3,0x30,0xAD,0xAF,0x3D,0x7B,0xE3,0x30,0xC2,0x28,0xAC,0x6C,0xFE,0x5C, + 0xE2,0x30,0xA2,0x28,0x9D,0xF5,0xDF,0x73,0x03,0x39,0xA2,0x28,0xBF,0xBD,0xAF,0x29, + 0x44,0x41,0xE3,0x38,0xFF,0xAB,0x0D,0x8F,0x44,0x41,0x03,0x39,0xAD,0xEB,0xFB,0x7A, + 0x24,0x39,0xE3,0x38,0xEF,0x8B,0xFA,0xFF,0xE2,0x30,0xC2,0x30,0x6E,0x57,0x57,0x57, + 0xE3,0x38,0xC2,0x30,0x55,0x5D,0xA2,0xA2,0x03,0x39,0xC3,0x30,0xFF,0x2F,0x0F,0x8F, + 0x45,0x41,0xE3,0x38,0xA5,0x2B,0x2E,0xAB,0x65,0x49,0x24,0x41,0x5D,0x55,0xAE,0xEB, + 0x64,0x49,0x03,0x39,0xFB,0x7E,0x9F,0xA2,0x44,0x49,0xE3,0x38,0xF5,0xF6,0xB8,0xA2, + 0x64,0x49,0x24,0x41,0xAF,0xBF,0xFC,0xAA,0x65,0x49,0x23,0x41,0xAF,0xFD,0x9F,0x82, + 0x64,0x49,0x03,0x39,0xF8,0x78,0xFA,0xAA,0x44,0x41,0x03,0x41,0xFA,0xA2,0x98,0xFE, + 0x44,0x41,0xC2,0x38,0x2A,0x22,0xE8,0x5E,0x44,0x49,0xE3,0x38,0xA8,0xA8,0xEF,0xDD, + 0x23,0x41,0x03,0x39,0xA2,0x60,0x2A,0x0B,0x23,0x41,0xE2,0x38,0x2E,0x2E,0x28,0xDC, + 0x64,0x49,0x03,0x39,0x8B,0xBF,0xF7,0xD5,0x44,0x41,0xE2,0x38,0x88,0xBA,0xEF,0x75, + 0x23,0x41,0xE3,0x30,0x08,0x88,0x83,0x01,0x43,0x41,0x03,0x39,0xB5,0x35,0xBD,0xD5, + 0x64,0x49,0x24,0x41,0x82,0x82,0x9B,0xFD,0x64,0x49,0x23,0x41,0xB2,0xA2,0xB8,0xDD, + 0x85,0x51,0x23,0x41,0x27,0xBA,0xFE,0xEE,0xC6,0x59,0x64,0x51,0x82,0xAE,0xFD,0xFD, + 0x06,0x62,0x84,0x51,0x2D,0xB7,0xF7,0xFF,0x47,0x6A,0xC5,0x61,0xAB,0x0B,0xA9,0xAB, + 0x47,0x72,0xC5,0x59,0xBE,0x5A,0x58,0xE8,0x47,0x72,0xC4,0x59,0x0A,0x3D,0x2F,0xAF, + 0x88,0x72,0x26,0x6A,0xE8,0xF5,0xBD,0xB5,0x0D,0xA4,0x87,0x72,0x35,0x25,0x35,0xB5, + 0x92,0xD5,0x8F,0xB4,0x8B,0x0B,0x29,0x29,0x93,0xD5,0x31,0xC5,0xAA,0xA0,0xEA,0x68, + 0x52,0xCD,0xB0,0xB4,0x5C,0x58,0x5E,0x57,0x73,0xCD,0xAF,0xB4,0xAD,0x0B,0x2B,0x0B, + 0x94,0xCD,0x73,0xC5,0x47,0x88,0xFA,0x5E,0x32,0xC5,0x90,0xAC,0xE8,0xE0,0xE0,0x78, + 0xD1,0xB4,0x2E,0xA4,0x00,0x88,0xFA,0xF7,0xB0,0xB4,0x0E,0x9C,0xC8,0xEA,0x7E,0x5F, + 0x4F,0xA4,0xAD,0x93,0xE8,0xFE,0xDF,0x77,0xCE,0x9B,0x6C,0x8B,0x08,0xFA,0x7E,0xFB, + 0xCD,0x93,0x6C,0x8B,0x08,0x2B,0xB7,0xA7,0x0E,0x9C,0xAD,0x93,0xA2,0xEA,0xFF,0xFD, + 0x0E,0x9C,0x8D,0x93,0x20,0xAA,0xFF,0x7F,0x0E,0xA4,0xAD,0x93,0x8A,0x8B,0xAD,0xF9, + 0x2E,0xA4,0xCD,0x93,0xFD,0xBF,0x0F,0xE9,0x2E,0x9C,0xEE,0x9B,0x8B,0x68,0x58,0x5E, + 0xCD,0x93,0x6C,0x8B,0xBC,0xB4,0x5E,0x5E,0x4F,0xA4,0xAC,0x93,0xAF,0x2B,0x2D,0xAD, + 0x6F,0xAC,0x0E,0xA4,0x3A,0xA2,0x0B,0xAB,0xAF,0xAC,0x4F,0xA4,0xD7,0xDD,0xBF,0xAD, + 0xF1,0xBC,0x4F,0xA4,0xB7,0xAB,0x02,0x02,0x11,0xBD,0x6F,0xAC,0x2B,0xD6,0xE8,0x00, + 0x64,0x59,0x02,0x49,0xF2,0xBE,0x78,0xEB,0x64,0x59,0x03,0x49,0xAE,0x3F,0xB9,0xBD, + 0x65,0x59,0x03,0x49,0xF4,0x7B,0xEF,0xFF,0x44,0x51,0xE3,0x48,0xAF,0x8B,0xEF,0xDB, + 0x43,0x51,0xE1,0x48,0x02,0x8A,0xAA,0x7E,0x23,0x49,0xE2,0x40,0xEC,0x5E,0xBF,0xFF, + 0x43,0x51,0xE2,0x40,0xFB,0xB9,0xF7,0x2F,0x43,0x51,0x02,0x49,0xFB,0x8B,0x0F,0xBE, + 0x43,0x51,0x23,0x49,0xC0,0x44,0xC6,0xE0,0x64,0x51,0x23,0x51,0xAD,0x5D,0xDF,0x57, + 0x43,0x51,0x03,0x51,0x2E,0xA8,0x8A,0xEB,0x44,0x59,0x22,0x49,0xB7,0xA7,0xA7,0xCF, + 0x64,0x59,0x23,0x51,0xBA,0xAB,0x8B,0xF9,0x64,0x59,0x03,0x51,0x7E,0xAA,0xA0,0xAE, + 0x43,0x59,0x23,0x51,0x3B,0xFB,0x75,0xAE,0x64,0x59,0x23,0x51,0xF2,0x5F,0xFF,0xFA, + 0x43,0x59,0x23,0x51,0x2B,0x1B,0x1E,0x8B,0x44,0x59,0x03,0x51,0xEA,0xF0,0x5A,0x5B, + 0x84,0x61,0x02,0x51,0xFF,0xBD,0x2F,0xAD,0x4A,0x9B,0xC5,0x61,0x2D,0x0D,0x29,0x09, + 0xAB,0xA3,0x6A,0x9B,0x0D,0x2D,0x2D,0xA5,0xAB,0xA3,0x6A,0x9B,0xB0,0xFC,0xFC,0x77, + 0x8B,0x9B,0x09,0x8B,0xA0,0x60,0x7E,0x5F,0x4A,0x9B,0x87,0x82,0xA0,0xAA,0x7B,0x7F, + 0x29,0x93,0x87,0x7A,0xA0,0x7B,0xDD,0x55,0xE9,0x8A,0x46,0x72,0xE8,0xFA,0xEF,0xFF, + 0xA8,0x82,0x46,0x72,0xB0,0xAA,0xFF,0xF7,0xA8,0x7A,0x46,0x72,0xE2,0xCA,0xFA,0x7D, + 0x87,0x7A,0x46,0x72,0xCA,0xEA,0xB8,0x97,0x87,0x7A,0x46,0x72,0xA3,0x88,0xE2,0x7B, + 0x87,0x7A,0x25,0x72,0xC0,0xEA,0xEA,0x89,0x66,0x72,0x27,0x72,0xAA,0xBE,0xBB,0xEE, + 0x66,0x72,0x05,0x6A,0xBC,0xFA,0xFE,0xAA,0x66,0x72,0x05,0x72,0xA0,0xE6,0x2F,0xAE, + 0x66,0x72,0x26,0x72,0x8F,0x22,0x00,0x28,0xA8,0x7A,0x46,0x72,0xD5,0xD5,0x35,0x2E, + 0xC8,0x82,0x87,0x7A,0x35,0xA7,0xEA,0xA8,0xC8,0x82,0x26,0x72,0xA0,0xAA,0xFA,0x7F, + 0x87,0x7A,0x05,0x6A,0xAC,0xFF,0x7F,0x75,0x26,0x72,0xE5,0x61,0x78,0xA8,0xF2,0xFA, + 0x25,0x6A,0xE5,0x69,0xDF,0x3F,0xBD,0x62,0x05,0x6A,0xE5,0x61,0x8E,0x88,0x90,0xB0, + 0x26,0x6A,0xE5,0x69,0xDD,0xF7,0xF3,0xAE,0x27,0x72,0xC4,0x61,0xF7,0xFF,0xBF,0x2E, + 0x26,0x72,0xC5,0x61,0x9A,0xDE,0xAA,0x02,0x26,0x72,0xC5,0x59,0x7E,0x7A,0xFE,0xEA, + 0xC5,0x61,0x24,0x49,0x7C,0x7A,0xF8,0xE8,0x45,0x49,0xA2,0x30,0x5E,0x5E,0xF8,0xF8, + 0xC3,0x30,0x61,0x28,0xDF,0x9F,0xBC,0x20,0xA2,0x30,0x82,0x28,0x02,0xFE,0x88,0x88, + 0xE3,0x38,0x81,0x28,0x2B,0x2F,0xBD,0xB9,0x24,0x41,0xC2,0x30,0xE2,0xAF,0x29,0xBD, + 0x03,0x39,0xC2,0x30,0xF8,0x78,0x7C,0x7A,0xC2,0x30,0x82,0x30,0xBC,0x2E,0x3E,0xFC, + 0x23,0x41,0xA2,0x30,0x2B,0x2D,0x8D,0x3F,0x44,0x41,0x03,0x41,0x3F,0xB2,0xA2,0x80, + 0x65,0x49,0x24,0x41,0xC2,0x8A,0xCB,0x5D,0x64,0x49,0x24,0x41,0x5F,0x7B,0xEF,0x8D, + 0x64,0x49,0x24,0x41,0xDA,0x56,0x5E,0x7E,0x24,0x41,0x03,0x41,0x50,0x7A,0x78,0x0A, + 0x24,0x41,0xE3,0x38,0xAE,0xAF,0xBE,0xFC,0x65,0x49,0x03,0x39,0xFF,0xFF,0xCF,0xA9, + 0x24,0x41,0xA2,0x28,0xF8,0xEA,0xF8,0x7A,0xC2,0x30,0x82,0x28,0xA2,0x8A,0xAF,0xED, + 0xC2,0x30,0x82,0x28,0x3A,0x5E,0x55,0x5F,0x04,0x39,0x82,0x28,0x82,0xFA,0xFD,0x75, + 0xC3,0x30,0xA2,0x30,0x00,0x02,0xE3,0x85,0x03,0x39,0xC3,0x30,0x15,0xFD,0xBD,0x1D, + 0x04,0x39,0xC3,0x30,0x20,0xA2,0x7E,0x57,0xE3,0x38,0xA2,0x28,0xE8,0xFE,0xFF,0xF7, + 0xC2,0x30,0xA2,0x28,0xA0,0x1E,0x36,0xBA,0xE3,0x30,0xA2,0x28,0xEC,0xFF,0xBB,0xBA, + 0x03,0x39,0xA2,0x28,0xDF,0xF7,0xF5,0x3B,0x03,0x39,0xC3,0x30,0x25,0x25,0xAF,0xBF, + 0x23,0x39,0xC2,0x30,0x2B,0xAA,0xEA,0x7F,0x24,0x39,0xC2,0x30,0x88,0xE2,0xFF,0x75, + 0x03,0x39,0xA2,0x30,0xA2,0xEA,0xEA,0xF7,0xE3,0x38,0xC2,0x30,0xF8,0xF0,0x2A,0x07, + 0x04,0x39,0xC3,0x30,0xDA,0xFE,0xF7,0x5F,0x03,0x39,0xC3,0x38,0xBF,0xFF,0x3F,0x35, + 0x64,0x49,0xE3,0x38,0xBF,0xF5,0xBD,0x3F,0x85,0x51,0x24,0x41,0xFF,0xB5,0x2F,0x2A, + 0x85,0x49,0x23,0x41,0xFE,0xF8,0xEC,0x60,0x44,0x49,0x03,0x41,0xAA,0xEE,0x76,0x7B, + 0x65,0x49,0x03,0x39,0x0A,0x2B,0x2B,0xB5,0x85,0x51,0x23,0x41,0xE8,0x5F,0xDE,0x7F, + 0x44,0x49,0x03,0x39,0xAA,0x70,0xF8,0xFF,0x23,0x41,0xE3,0x38,0xA0,0xB8,0xF6,0x5F, + 0x23,0x41,0xC2,0x30,0x78,0xFA,0x7B,0xFB,0x03,0x39,0xC2,0x30,0x2B,0xA5,0xFD,0x5F, + 0x23,0x41,0xC2,0x30,0x8A,0xAB,0x9F,0xF5,0x02,0x39,0xC2,0x30,0x5C,0xDF,0xFE,0x7E, + 0x03,0x31,0xA1,0x30,0x22,0xBF,0xBF,0xF9,0x23,0x39,0xC2,0x30,0xA7,0x3E,0x02,0x8F, + 0x44,0x41,0x03,0x39,0xB7,0x37,0x35,0x9D,0x44,0x41,0x03,0x39,0x5E,0x5C,0x58,0xFE, + 0x64,0x49,0x03,0x39,0xAD,0x2D,0xAD,0xFD,0x43,0x49,0x23,0x41,0xA5,0xA6,0xE8,0x7D, + 0x85,0x51,0xE2,0x38,0x2A,0x3F,0xB7,0x95,0xC6,0x51,0x64,0x51,0xFD,0xB2,0xBB,0xB9, + 0x06,0x62,0xA5,0x51,0xBD,0xAD,0x2F,0x2F,0x47,0x6A,0xC5,0x61,0xBF,0xA7,0x27,0x8F, + 0xA8,0x7A,0x06,0x6A,0x5E,0x7E,0xEB,0x83,0x47,0x6A,0xE5,0x61,0x3B,0x76,0xD7,0xF8, + 0x67,0x72,0x26,0x6A,0xFD,0xF5,0x1F,0xF7,0xCC,0x9B,0x47,0x72,0x2D,0x35,0x35,0xB5, + 0x72,0xCD,0x2E,0xAC,0x0B,0x0B,0x0B,0x29,0x93,0xD5,0xF1,0xBC,0xC0,0xE0,0x60,0x70, + 0xF1,0xBC,0x4F,0xAC,0xDC,0xBE,0xBF,0xF7,0x53,0xC5,0x90,0xAC,0x0B,0xAB,0xFF,0x5D, + 0x52,0xC5,0xED,0x9B,0x20,0xB2,0xFE,0x7F,0xD0,0xB4,0x0E,0x9C,0xE8,0xFA,0x7F,0x5D, + 0x4F,0xA4,0xCD,0x9B,0x88,0xE8,0x7F,0x5F,0x0E,0xA4,0x8D,0x93,0xE8,0xFA,0xD7,0xDF, + 0xAD,0x93,0x8C,0x8B,0x00,0x82,0xA2,0xD6,0xCD,0x93,0x8C,0x8B,0xFF,0x5F,0x7E,0x78, + 0xAD,0x93,0x6C,0x8B,0x36,0xAE,0xAE,0xAE,0xEE,0x9B,0x6C,0x8B,0x82,0x8A,0xAF,0xA7, + 0xEE,0x9B,0x8C,0x8B,0xEF,0xB9,0xAB,0xE0,0x2F,0xA4,0x8C,0x8B,0xAB,0x0A,0xBB,0xDF, + 0x0E,0x9C,0xCD,0x93,0x72,0x68,0x8A,0x6B,0xED,0x9B,0x6C,0x83,0x82,0xA8,0xFA,0x5E, + 0xCD,0x93,0x4B,0x83,0xE8,0xEA,0x7B,0x5F,0x4F,0xA4,0x4B,0x83,0x2F,0x2D,0x2D,0xB5, + 0x90,0xAC,0x2E,0xA4,0x55,0xFA,0xEB,0x8F,0xAF,0xB4,0x4F,0xA4,0xA7,0x3F,0xBF,0xBE, + 0x32,0xBD,0xB0,0xAC,0xEF,0xFF,0x29,0xA5,0x53,0xC5,0x11,0xBD,0xF5,0x95,0xF5,0x2D, + 0x43,0x51,0x23,0x51,0x58,0x7F,0x3F,0xD5,0x64,0x59,0x03,0x51,0xAE,0x7F,0xEF,0x83, + 0x44,0x51,0x02,0x49,0xFC,0xBF,0xFF,0xDA,0x23,0x51,0x03,0x49,0xBA,0x50,0x58,0x73, + 0x02,0x49,0xC2,0x40,0xA8,0xA4,0x3A,0x02,0x43,0x51,0xE2,0x40,0xDF,0x7B,0xFA,0xCF, + 0x44,0x51,0x03,0x49,0xB5,0x25,0x35,0xFF,0x44,0x51,0x23,0x49,0xBB,0xFA,0x62,0x77, + 0x64,0x51,0x23,0x51,0xDA,0xEA,0xE2,0x59,0x44,0x51,0x02,0x51,0xEA,0x80,0x8A,0xFB, + 0x43,0x51,0x03,0x49,0xFB,0xAE,0x8F,0x06,0x64,0x59,0x23,0x51,0xED,0x85,0xBD,0x3A, + 0x64,0x59,0x23,0x51,0xEF,0xA8,0x92,0xA6,0x84,0x61,0x23,0x51,0xFF,0xF3,0x6F,0x65, + 0x84,0x59,0x23,0x51,0xFF,0xEE,0xCB,0xA9,0x64,0x59,0x23,0x51,0xFE,0xAB,0xC5,0xD5, + 0x44,0x59,0x03,0x51,0xEA,0x62,0x6A,0x94,0x23,0x59,0x02,0x49,0xFF,0xED,0xAA,0xAA, + 0xA4,0x61,0x02,0x51,0xBD,0x35,0x27,0x3D,0x8B,0x9B,0x26,0x72,0x29,0x09,0x0B,0x2B, + 0x8A,0x9B,0x4A,0x93,0xC0,0x82,0xA0,0x92,0x6A,0x9B,0x09,0x8B,0x00,0x82,0xE2,0x6A, + 0x2A,0x93,0x87,0x7A,0x80,0xE8,0x7A,0x76,0x09,0x8B,0x67,0x72,0xF8,0xFF,0x77,0x7D, + 0xA8,0x7A,0x46,0x72,0xFC,0xD8,0xEA,0xBF,0x87,0x7A,0x26,0x72,0xAE,0xEB,0xDE,0xE4, + 0x45,0x82,0x67,0x72,0x5F,0xDD,0xD7,0x75,0x87,0x7A,0x46,0x72,0xA6,0x82,0xF8,0x8D, + 0x87,0x7A,0x46,0x72,0xBC,0x8A,0xB0,0x1A,0x87,0x7A,0x46,0x72,0x6F,0x8F,0xBE,0xFF, + 0x87,0x7A,0x67,0x72,0x75,0xB7,0x6E,0xF2,0x66,0x72,0x25,0x72,0xA8,0x10,0xAC,0x0F, + 0x67,0x7A,0x46,0x72,0x65,0x7F,0xA3,0xBA,0x66,0x72,0x26,0x6A,0xDF,0xBA,0x68,0x6A, + 0x66,0x72,0x25,0x72,0xAE,0x3E,0x32,0x2A,0xC8,0x82,0x67,0x7A,0xA5,0xA7,0x2F,0x6B, + 0xA8,0x82,0x25,0x6A,0x80,0xA8,0xFE,0x55,0x67,0x7A,0xC4,0x69,0xE0,0xE0,0xFB,0xFF, + 0x25,0x6A,0xE5,0x69,0xEE,0x62,0x7A,0x5E,0x05,0x6A,0xC5,0x61,0x30,0xBA,0xBF,0xFD, + 0x26,0x6A,0xC4,0x61,0x2A,0xFF,0xFF,0x7E,0x06,0x6A,0xC5,0x61,0xBE,0xEB,0xAE,0x9F, + 0x26,0x6A,0xE5,0x69,0xFF,0xBB,0x8B,0xAF,0x46,0x72,0x06,0x6A,0xD5,0xFF,0xEA,0xFD, + 0x47,0x72,0x06,0x6A,0xF9,0xA9,0xAD,0xAF,0x47,0x72,0xE6,0x69,0x6E,0x7A,0xA8,0x22, + 0x26,0x6A,0x64,0x51,0x7E,0x7A,0x78,0x68,0x44,0x49,0xC3,0x38,0xD8,0x7B,0x7A,0x78, + 0xE3,0x38,0x82,0x30,0xC2,0xCA,0x7A,0x7E,0xA2,0x30,0x81,0x28,0xC2,0x63,0xFA,0xAB, + 0xC1,0x30,0x82,0x28,0xAD,0xBD,0xF7,0xFF,0x03,0x41,0xA2,0x30,0xAB,0x2A,0x0F,0x39, + 0x03,0x39,0xE3,0x38,0x5F,0x96,0xD4,0x7E,0xE2,0x38,0xA2,0x30,0x56,0x74,0xAA,0xE2, + 0x64,0x49,0xA2,0x30,0xB5,0x29,0x2B,0x2B,0x44,0x49,0xE3,0x38,0xEA,0xE0,0xE0,0x60, + 0x03,0x41,0xE3,0x38,0x20,0x96,0x3E,0x76,0x65,0x49,0xE3,0x38,0x2A,0xFE,0xEF,0xF5, + 0x64,0x49,0xE3,0x38,0xEC,0xFB,0xFF,0xD7,0x24,0x41,0xC2,0x30,0x08,0x80,0xBC,0x57, + 0x23,0x41,0xC3,0x30,0xBE,0xF6,0xAF,0x2B,0x44,0x41,0xC3,0x30,0x2A,0xAB,0x8E,0x5E, + 0x04,0x39,0xA2,0x28,0x78,0x5C,0x7E,0x5F,0xE3,0x28,0x82,0x28,0xF5,0xBF,0xFF,0xD7, + 0xA2,0x28,0x61,0x20,0xE0,0xE0,0xF0,0xE6,0xA2,0x28,0x61,0x20,0x0F,0xBD,0xBD,0x0B, + 0xE3,0x30,0xA2,0x28,0xD5,0xBD,0xBD,0x8A,0xE3,0x30,0xA2,0x28,0x82,0xEA,0x7A,0x68, + 0x81,0x30,0xC2,0x28,0xFF,0xFA,0xEB,0x7A,0xC2,0x30,0xA2,0x28,0xBF,0xB5,0x25,0x05, + 0xE3,0x30,0xA2,0x28,0xA3,0xFB,0xAF,0x27,0xC2,0x30,0xA2,0x28,0xAE,0xCF,0x88,0x08, + 0xE3,0x30,0xC3,0x30,0x02,0xA9,0x75,0x2D,0x04,0x39,0xC2,0x30,0xDF,0x8B,0xEB,0xDF, + 0xC3,0x38,0xE3,0x30,0xFD,0xF5,0xFF,0xAD,0x04,0x39,0xC2,0x30,0x5F,0x7D,0xAD,0x2B, + 0xE3,0x38,0xC2,0x30,0x55,0x61,0x5B,0xF8,0xE3,0x38,0xC2,0x30,0x29,0x81,0xD7,0xF2, + 0xE3,0x38,0xC2,0x30,0xD6,0x7F,0x89,0x2B,0x03,0x39,0xC3,0x30,0x15,0x15,0xDA,0xF2, + 0x85,0x51,0xE3,0x38,0xAD,0x2F,0x2D,0xBD,0x85,0x51,0x65,0x49,0x55,0x7F,0xF2,0x7B, + 0x85,0x51,0x23,0x41,0xE2,0xE2,0xEA,0x62,0x44,0x49,0x03,0x39,0xF2,0x48,0x4A,0x7B, + 0x23,0x41,0xE2,0x38,0x2F,0x2F,0xE7,0xF7,0x44,0x49,0x24,0x41,0x72,0x6A,0x53,0x95, + 0x23,0x41,0xC2,0x38,0xFA,0xDF,0xEE,0xBA,0x03,0x41,0xC2,0x30,0x7E,0xEA,0xAA,0xA8, + 0x03,0x39,0xC2,0x30,0x0F,0xB5,0xD5,0xBB,0x03,0x39,0xC2,0x30,0x7E,0xD7,0xF6,0xCA, + 0x03,0x39,0xC2,0x30,0x3F,0x3E,0x27,0x2E,0x23,0x39,0xE2,0x30,0x77,0xFF,0xAB,0xBC, + 0x23,0x39,0xC2,0x30,0xFD,0x7E,0x78,0xF8,0x23,0x39,0xC2,0x30,0x8B,0x0F,0x2D,0x2B, + 0x23,0x39,0x03,0x39,0xD3,0x2F,0xFD,0x9B,0x23,0x39,0xE2,0x38,0xF8,0xF0,0xE8,0x6A, + 0x23,0x41,0xC2,0x30,0x02,0x8A,0x0B,0x89,0x43,0x41,0x03,0x39,0x9F,0xB5,0xA5,0x2B, + 0x44,0x49,0x03,0x39,0x35,0xBB,0xAA,0xA3,0xA5,0x59,0x44,0x49,0x3F,0x3D,0xDD,0x37, + 0x26,0x62,0x85,0x51,0xB7,0xBF,0x97,0x37,0x67,0x72,0x06,0x62,0xCD,0xED,0xA5,0xBE, + 0x88,0x72,0x46,0x6A,0xA9,0x29,0xED,0xF5,0x87,0x72,0xE5,0x61,0xFA,0xE8,0xE8,0x5A, + 0x47,0x6A,0xC5,0x59,0xA0,0xEE,0x7E,0x5E,0x6B,0x93,0xE5,0x61,0x3F,0x3D,0xBD,0xB5, + 0x73,0xCD,0xED,0xA3,0x2B,0x09,0x29,0x09,0x93,0xD5,0x6F,0xAC,0xE0,0x70,0x78,0x78, + 0xB0,0xB4,0x4F,0xAC,0xAF,0x37,0x7F,0x7D,0x90,0xAC,0xED,0x9B,0xA0,0xA8,0xFA,0xD7, + 0x4F,0xA4,0xEE,0x9B,0xC2,0x7F,0x57,0x77,0x0E,0x9C,0xAD,0x93,0xA2,0xEA,0xF2,0x5E, + 0xEE,0x9B,0xAD,0x93,0x7E,0x6A,0x7A,0x54,0xAD,0x93,0x6D,0x8B,0xB0,0xE8,0xA2,0xA0, + 0xAD,0x93,0x6C,0x8B,0xEA,0xEA,0x8B,0x0F,0xCD,0x93,0x8C,0x8B,0x7D,0xA9,0x7D,0x5E, + 0xAD,0x93,0x6C,0x8B,0xB6,0xEF,0xAA,0x22,0xCD,0x93,0x8C,0x8B,0x05,0x0D,0xFF,0xFF, + 0x0E,0x9C,0x8C,0x8B,0x82,0xBA,0x5B,0x7F,0xAD,0x93,0x0A,0x7B,0x20,0x88,0xA8,0x5E, + 0xCD,0x93,0x2B,0x7B,0x00,0xAA,0x6F,0x75,0x8C,0x83,0x0A,0x7B,0xBC,0xFE,0x7F,0xD7, + 0x6C,0x83,0x0B,0x7B,0xBC,0xB7,0xFD,0xB5,0xAD,0x93,0x0B,0x7B,0x2F,0xBF,0xBF,0x55, + 0x4F,0xAC,0x6C,0x8B,0x0A,0x2F,0xFF,0x55,0x6F,0xAC,0xAD,0x8B,0x20,0x8A,0xAF,0xBD, + 0x11,0xBD,0x0E,0x9C,0x2B,0x2B,0xBF,0xB5,0x32,0xC5,0x90,0xAC,0x02,0x00,0x0E,0xA5, + 0x43,0x51,0x02,0x49,0x98,0xE0,0xEC,0xBF,0x64,0x51,0x02,0x49,0x8B,0xF9,0xFF,0xBF, + 0x43,0x51,0x02,0x49,0x6B,0xF2,0x5A,0x5B,0x23,0x49,0xE1,0x40,0xF8,0xBA,0xAD,0x82, + 0x23,0x49,0xE2,0x48,0xA3,0x00,0xA2,0x9E,0x44,0x51,0x03,0x49,0x6F,0xD6,0xA7,0x25, + 0x43,0x51,0x02,0x49,0xF5,0x09,0x36,0xAA,0x64,0x51,0x23,0x49,0xEF,0xBE,0x7A,0x78, + 0x44,0x51,0x03,0x49,0xBB,0x7E,0x56,0xDA,0x43,0x51,0x03,0x49,0xFF,0xFF,0xBE,0xB7, + 0x64,0x59,0x02,0x49,0x2F,0x27,0xA3,0xAA,0x64,0x59,0x23,0x51,0xA0,0xF7,0xE5,0x77, + 0x64,0x59,0x03,0x49,0xBE,0xAF,0xAF,0x8F,0x44,0x59,0x03,0x51,0xAE,0xEE,0xF4,0xAC, + 0x44,0x59,0x23,0x51,0x01,0xEA,0x0B,0x09,0x44,0x59,0xE2,0x48,0x6E,0xE8,0xE8,0xE8, + 0x43,0x59,0xE2,0x48,0xEE,0xE2,0xFB,0xDF,0x23,0x51,0x03,0x51,0x21,0xDB,0xFA,0xFD, + 0x26,0x72,0x23,0x51,0x95,0xB5,0x35,0x35,0x4A,0x9B,0x87,0x82,0x01,0x0B,0x09,0x03, + 0x6A,0x9B,0x09,0x93,0x2A,0xFA,0xFA,0x7E,0x6A,0x9B,0x87,0x7A,0xA8,0xEE,0x7E,0x7E, + 0xC8,0x7A,0x67,0x7A,0xF8,0xFE,0xEC,0xD6,0x87,0x7A,0x46,0x72,0xBE,0xBC,0x7E,0x62, + 0x87,0x7A,0x47,0x72,0xBF,0xB2,0xFA,0xFF,0x87,0x7A,0x26,0x72,0x28,0xEA,0x35,0x0B, + 0x87,0x7A,0x46,0x72,0x48,0x2A,0xFA,0xFA,0x87,0x7A,0x26,0x72,0x0B,0x8A,0x8A,0xA7, + 0x87,0x7A,0x25,0x72,0xB8,0xB6,0xB6,0xEA,0x87,0x7A,0x46,0x72,0xFC,0xFF,0xFF,0x1E, + 0x87,0x7A,0x46,0x72,0xC9,0x63,0x78,0x6B,0x87,0x72,0x25,0x72,0x2F,0xEF,0xFE,0x7F, + 0x66,0x7A,0x26,0x6A,0xB3,0xEF,0xCB,0x8B,0x67,0x7A,0x46,0x72,0xB7,0xCF,0xAF,0x22, + 0x87,0x7A,0x46,0x72,0x89,0xAA,0x23,0xAD,0xA7,0x7A,0x46,0x72,0xA3,0xEA,0xFB,0xFD, + 0x67,0x72,0x05,0x6A,0x5E,0x58,0xFE,0x7A,0x26,0x72,0xE5,0x69,0x77,0x56,0x55,0x89, + 0x06,0x6A,0xC5,0x61,0xFE,0x8E,0xFB,0x7E,0x05,0x6A,0xC5,0x61,0xEA,0x5C,0x55,0x55, + 0x05,0x6A,0xC5,0x61,0xE2,0xA2,0xF9,0xFF,0x05,0x6A,0xC4,0x61,0xB7,0xBF,0xBF,0xBF, + 0x05,0x6A,0xE5,0x61,0x27,0x18,0x08,0x0F,0x66,0x72,0x06,0x6A,0x5F,0xF3,0xFD,0xFD, + 0x47,0x72,0x06,0x6A,0xBF,0xFE,0x6B,0x2A,0x47,0x72,0x26,0x6A,0xEB,0xAA,0x2E,0xAA, + 0x26,0x6A,0xA4,0x59,0x70,0xE0,0x00,0x00,0xE5,0x61,0xE2,0x38,0x5F,0x7A,0x78,0xF0, + 0xE2,0x38,0x82,0x28,0xFA,0xFC,0xFA,0x78,0xA2,0x30,0x81,0x28,0xC3,0x8A,0x0F,0x3F, + 0xE2,0x30,0x81,0x28,0xBD,0x2D,0x0B,0x2A,0x02,0x39,0xA1,0x30,0x3A,0x3E,0xFA,0xDA, + 0x03,0x39,0xC2,0x38,0xFA,0xFE,0xBF,0xA1,0x03,0x39,0xC2,0x38,0x5F,0xD4,0xD6,0xFB, + 0x64,0x49,0xC2,0x38,0xA9,0x2D,0x2D,0x89,0x65,0x49,0xE2,0x38,0x70,0x6A,0xF0,0x7E, + 0x03,0x39,0xC2,0x30,0x5E,0xEA,0xFA,0x7A,0x03,0x39,0xC2,0x30,0x29,0xEE,0xBB,0xA5, + 0x24,0x41,0xC2,0x30,0xAE,0xCB,0x57,0x55,0xE3,0x38,0xA2,0x28,0xAA,0xBA,0xFA,0xFF, + 0x24,0x41,0xC2,0x30,0x2B,0x2D,0xAB,0xAD,0x24,0x39,0xA2,0x28,0x78,0xF8,0xFE,0xFE, + 0xE3,0x30,0x82,0x28,0xF2,0xF8,0xFC,0x7F,0xA2,0x28,0x62,0x20,0xEC,0xF6,0xFF,0xF7, + 0x63,0x28,0xA2,0x20,0xBE,0xFA,0xEB,0x6E,0xE3,0x30,0x82,0x28,0xB5,0x2D,0x2F,0x3F, + 0x04,0x39,0xA2,0x28,0xAA,0xA0,0x72,0x6A,0xC3,0x28,0x82,0x28,0x80,0xAA,0xFB,0xF7, + 0xA2,0x28,0x82,0x20,0x2B,0x2F,0xBA,0x2C,0xC2,0x28,0xA2,0x28,0xE5,0xD5,0xAD,0xF9, + 0xE3,0x30,0xA2,0x28,0xFF,0xFB,0x3E,0x29,0xE3,0x30,0xA2,0x28,0x0E,0x2F,0x2C,0xAA, + 0xE3,0x30,0xC2,0x30,0xBF,0x0B,0xEA,0x6A,0xE3,0x38,0xA2,0x28,0x2E,0xAF,0xFF,0xFF, + 0xE3,0x30,0xA2,0x30,0x08,0x8A,0xAB,0x2F,0x03,0x39,0xE3,0x30,0xAF,0xFB,0xF7,0xFE, + 0xE3,0x38,0xC3,0x30,0xF8,0xEC,0xCA,0x70,0x24,0x39,0xC2,0x30,0xFB,0xCB,0x79,0x75, + 0xE3,0x38,0xC3,0x30,0x37,0xB5,0xD5,0x35,0x03,0x39,0xC3,0x30,0xA2,0xBF,0xBF,0xF7, + 0x44,0x41,0xE3,0x38,0x0D,0x3D,0x9F,0xDF,0x44,0x49,0xE3,0x38,0x02,0xA3,0xBF,0x7D, + 0x64,0x49,0x03,0x39,0xE2,0xFF,0xD7,0xDD,0x24,0x41,0xE3,0x38,0xAE,0xFE,0xBA,0xF9, + 0x03,0x39,0xA2,0x38,0xB8,0xA8,0xA8,0x88,0x23,0x41,0xE3,0x38,0x2A,0xAF,0xAB,0xAB, + 0x03,0x41,0xE3,0x38,0xA5,0xAA,0xEB,0x62,0x44,0x41,0xE2,0x38,0x77,0xAF,0x0F,0xEE, + 0x03,0x39,0xA2,0x30,0x9A,0x98,0xA0,0xE2,0x03,0x39,0xC2,0x30,0xE8,0xFA,0xA7,0xD5, + 0x03,0x39,0xC2,0x30,0xAC,0x7E,0x17,0x95,0x03,0x39,0xE2,0x30,0xE0,0xAD,0x2D,0x2E, + 0x23,0x39,0xC2,0x30,0xDB,0x7F,0xFE,0xE8,0x23,0x39,0xC2,0x30,0x2F,0x0D,0xBF,0xEF, + 0x64,0x41,0x03,0x39,0x66,0xEA,0xA3,0x8D,0x43,0x41,0xE2,0x30,0x7F,0xEA,0xAA,0xF8, + 0x43,0x41,0xE2,0x30,0x2D,0x35,0xFB,0xFF,0x64,0x49,0x02,0x39,0xAE,0x2B,0x01,0x2B, + 0x84,0x51,0x23,0x41,0xAD,0xBE,0x2E,0x08,0xA5,0x51,0x64,0x49,0x96,0xF2,0xE0,0x82, + 0x26,0x62,0x84,0x51,0x37,0xED,0xF5,0x57,0x26,0x6A,0x84,0x51,0x80,0xE2,0xFB,0x7E, + 0x47,0x6A,0x84,0x51,0x82,0xAB,0xF7,0xD5,0x26,0x6A,0xC5,0x59,0xF8,0xFE,0x7F,0xAD, + 0x06,0x62,0xA4,0x59,0xA8,0xFF,0x9D,0xAD,0xC9,0x7A,0xE6,0x61,0x15,0x35,0x9D,0xF5, + 0x52,0xCD,0xEA,0x7A,0x0B,0x0B,0x09,0x2D,0x52,0xCD,0x8F,0xAC,0x78,0x78,0x78,0x58, + 0xB0,0xB4,0x4E,0xA4,0x6B,0x70,0xC2,0xA8,0x4F,0xAC,0xAD,0x8B,0xFE,0xFE,0x5E,0x7C, + 0xEE,0x9B,0x8C,0x8B,0x0A,0xA7,0xD5,0x57,0xCD,0x93,0x6C,0x8B,0xA8,0xEB,0xED,0xFF, + 0xCD,0x93,0x6C,0x8B,0xBC,0xBC,0xAE,0xA9,0xCD,0x93,0x8D,0x8B,0xFB,0x7E,0xAB,0x2A, + 0xCE,0x93,0x8C,0x8B,0xE5,0xFD,0xBF,0x3F,0xEE,0x9B,0x8C,0x8B,0xDF,0x75,0xB5,0xAE, + 0xCD,0x93,0x8C,0x8B,0xED,0x8B,0x00,0xA0,0xAC,0x8B,0x4C,0x83,0xA2,0x68,0xAA,0x7B, + 0xAC,0x8B,0x2B,0x7B,0x8A,0x6A,0xEA,0x7F,0x4B,0x83,0xEA,0x72,0xB0,0xD0,0xF8,0xEE, + 0x2B,0x7B,0xEA,0x72,0x8A,0xF6,0xA6,0x15,0x2B,0x7B,0xEA,0x72,0x28,0xB0,0x92,0xB5, + 0x4C,0x83,0xEA,0x72,0x2E,0xA9,0x5F,0x5F,0x4B,0x83,0xC9,0x72,0xE8,0xFA,0xFE,0xFB, + 0x8C,0x8B,0xEA,0x7A,0x2F,0x2D,0x2B,0x2F,0xCD,0x93,0x6C,0x8B,0x3F,0x95,0x77,0xFF, + 0x2E,0xA4,0x8D,0x8B,0x0A,0x2F,0x35,0xAD,0xD1,0xB4,0x0E,0x9C,0x0B,0xBD,0xFF,0x75, + 0x43,0x51,0xE3,0x48,0x8E,0xA9,0xAA,0xBA,0x43,0x51,0x23,0x49,0xE5,0x5F,0x5F,0x7E, + 0x23,0x49,0xE2,0x40,0xAB,0xAA,0x9A,0x8E,0x44,0x51,0xE1,0x40,0x8F,0xEB,0x7F,0xFF, + 0x43,0x51,0xE1,0x40,0x2F,0x0B,0x2F,0xBD,0x43,0x51,0x02,0x49,0x2E,0xAC,0xAE,0xE6, + 0x43,0x51,0x02,0x49,0x08,0xAE,0xD6,0x7D,0x43,0x51,0xE2,0x40,0xE0,0x9A,0xFB,0xFB, + 0x43,0x51,0x02,0x49,0xEA,0xBB,0x7D,0x2D,0x64,0x59,0x02,0x49,0x3B,0xB9,0x89,0xA2, + 0x64,0x59,0x23,0x51,0xAB,0xEE,0xF7,0x76,0x43,0x51,0x23,0x51,0xD4,0xDB,0xC2,0x03, + 0x44,0x59,0x23,0x51,0xAD,0xAD,0x31,0x3F,0x44,0x51,0x03,0x51,0xB8,0x9C,0xDA,0xE8, + 0x43,0x51,0x03,0x51,0xDA,0xD3,0x7A,0xFA,0x44,0x59,0x03,0x51,0xB8,0xEA,0x7B,0xDF, + 0xE3,0x50,0x02,0x49,0xF7,0xFC,0x57,0x77,0x23,0x51,0xE3,0x48,0x8F,0xFA,0xEE,0xF2, + 0x67,0x7A,0x03,0x51,0x35,0x3D,0x35,0x35,0x6B,0x9B,0xC9,0x8A,0x29,0x09,0x2B,0xAB, + 0x4A,0x93,0xC8,0x8A,0x62,0xFA,0xE8,0x6F,0xC8,0x82,0x88,0x7A,0xE0,0xE8,0xFA,0xAC, + 0xA8,0x7A,0x67,0x7A,0xD8,0xF2,0xEA,0xBA,0xA7,0x7A,0x67,0x7A,0x5F,0xFE,0x68,0xEC, + 0x87,0x7A,0x46,0x72,0x6A,0x62,0xCA,0xA2,0x87,0x7A,0x47,0x72,0xE9,0xBE,0x3B,0xF9, + 0x87,0x7A,0x46,0x72,0xEB,0x70,0xE0,0xE8,0x87,0x7A,0x46,0x72,0x3A,0xC0,0xFA,0x3F, + 0x87,0x7A,0x46,0x72,0xEC,0xEE,0xA6,0xFF,0x87,0x7A,0x46,0x72,0xAE,0xEB,0xAD,0xBF, + 0x87,0x72,0x25,0x6A,0xF2,0x6E,0xFA,0xFA,0x87,0x72,0x25,0x72,0xFF,0xFC,0xEE,0xFD, + 0x66,0x72,0x25,0x6A,0xDF,0xAA,0xAA,0xE8,0x86,0x7A,0x25,0x72,0xE6,0xEB,0xAB,0x3F, + 0xA7,0x7A,0x26,0x6A,0xE9,0xAF,0xAA,0x2A,0x87,0x7A,0x26,0x72,0xA2,0xE8,0x78,0xD2, + 0x46,0x72,0xE5,0x61,0xE8,0xE8,0xE8,0x7A,0x06,0x6A,0xC5,0x61,0x00,0xFE,0xD7,0x72, + 0xE5,0x69,0x84,0x61,0xEC,0xFE,0x7E,0xFB,0xE5,0x61,0x84,0x59,0xAB,0xA7,0x2D,0x2E, + 0x05,0x6A,0xC5,0x61,0xF6,0xE5,0xEF,0x5A,0xE5,0x69,0xC5,0x61,0x96,0x2F,0xAE,0x57, + 0x26,0x6A,0xC4,0x61,0xAF,0x0F,0x8F,0xB9,0x46,0x72,0x05,0x6A,0xED,0xF5,0x7D,0xC5, + 0x46,0x72,0x05,0x6A,0xAA,0x82,0x03,0xA3,0x46,0x72,0x26,0x6A,0x0C,0x80,0xFB,0x1F, + 0x66,0x72,0xE4,0x61,0xBA,0x72,0xFC,0x5E,0x06,0x62,0x03,0x41,0xF8,0x78,0xE8,0x7C, + 0x03,0x41,0x81,0x28,0x5C,0x5A,0x5C,0x56,0xA2,0x30,0x81,0x28,0x17,0xB7,0xB7,0x1F, + 0xC2,0x30,0xA2,0x28,0x0B,0x06,0x0A,0x83,0x02,0x39,0xC2,0x30,0x55,0xD5,0xFD,0x2F, + 0x23,0x41,0xE2,0x38,0xE5,0xBD,0x09,0x0B,0x44,0x41,0xE2,0x38,0x55,0xF5,0xBF,0x02, + 0x44,0x49,0xE2,0x38,0x29,0xEB,0xAA,0x08,0x23,0x41,0xC2,0x30,0xC0,0xF2,0x78,0x7C, + 0x03,0x39,0xA2,0x30,0x72,0x7E,0x5F,0x77,0xE3,0x38,0xA2,0x30,0x8B,0xFB,0x55,0x55, + 0xC2,0x30,0xA2,0x28,0x0A,0x02,0xEF,0x55,0xE3,0x30,0xA2,0x28,0x3F,0xAD,0xBB,0xBD, + 0x23,0x39,0xC3,0x28,0xEF,0xFF,0xD5,0xD5,0xE3,0x30,0x82,0x28,0xA8,0xE8,0xFE,0xDC, + 0xC2,0x28,0x62,0x20,0xEA,0xFC,0x77,0xD6,0x82,0x20,0x61,0x20,0x3F,0x2A,0x0A,0xBA, + 0x61,0x30,0x82,0x20,0x5F,0x55,0x7D,0x55,0xE3,0x30,0x82,0x20,0xAF,0xEF,0xA9,0xAF, + 0xE3,0x30,0x82,0x28,0xEA,0x62,0xFA,0xFB,0xA2,0x28,0x82,0x20,0xE7,0x55,0xF7,0x08, + 0xE3,0x30,0x82,0x20,0xFD,0xED,0xBB,0x2B,0xE3,0x30,0x81,0x20,0xDF,0xFF,0xBE,0xA0, + 0xE3,0x30,0xA2,0x28,0xB5,0xBF,0xAA,0xAA,0xE3,0x30,0xA2,0x28,0xAA,0x7A,0x6E,0xEA, + 0xE3,0x30,0xA2,0x28,0xE2,0xEF,0x75,0x57,0xC2,0x30,0xA2,0x28,0xF5,0xF9,0x01,0x29, + 0xE3,0x30,0xA2,0x30,0x0F,0x01,0x0B,0x0F,0x03,0x39,0xC3,0x30,0xBA,0xB3,0xFF,0xFF, + 0xE3,0x30,0xA2,0x30,0xF0,0xFA,0xFA,0xF6,0xE3,0x38,0xA2,0x30,0x0D,0xBB,0xE2,0xF0, + 0xE3,0x38,0xA2,0x28,0x0B,0x2E,0xA7,0xB5,0x03,0x39,0xA2,0x30,0xFF,0xF7,0xAE,0x88, + 0x03,0x39,0xE3,0x38,0x73,0x7B,0xDF,0x98,0x24,0x39,0xE3,0x38,0xA5,0xB5,0xEF,0x7B, + 0x23,0x41,0xC2,0x30,0xCE,0xFE,0xFF,0x7B,0x03,0x39,0xC2,0x30,0xA3,0xAA,0xEB,0xBF, + 0xE3,0x48,0x03,0x39,0x5D,0x77,0xF7,0x55,0x23,0x41,0xE3,0x38,0xAA,0x2E,0xA5,0xF5, + 0x23,0x41,0xC2,0x30,0xA2,0xAA,0xF7,0xFF,0x24,0x41,0xE2,0x38,0xFA,0x3A,0x7B,0x7F, + 0x44,0x41,0xC2,0x30,0xE2,0xA0,0x7F,0x5F,0x03,0x39,0xC2,0x30,0xBF,0xB6,0xAF,0x2F, + 0x23,0x41,0xC2,0x30,0xB7,0xAE,0x3B,0x3E,0x44,0x41,0xE2,0x38,0xFF,0x09,0xE5,0xF7, + 0x43,0x41,0x03,0x39,0x5B,0xFD,0xB5,0xF7,0x23,0x39,0xE2,0x30,0x5F,0xFA,0xFA,0xEB, + 0x44,0x41,0xE2,0x30,0x29,0xFD,0xFF,0x55,0x44,0x41,0x03,0x39,0x7C,0xBF,0xAF,0xE5, + 0x23,0x39,0xC2,0x30,0xAA,0xE8,0x7A,0x5C,0x64,0x49,0xC2,0x30,0x0B,0xFF,0xDF,0x7D, + 0x85,0x51,0xE2,0x38,0x20,0xA3,0xAB,0xF5,0xC5,0x51,0x23,0x41,0xA2,0xE2,0xFF,0x9D, + 0x84,0x51,0x23,0x41,0x2C,0x3D,0x3D,0x2C,0xC5,0x59,0x64,0x51,0x8A,0x2B,0x9A,0xB5, + 0xE5,0x59,0x84,0x51,0xB5,0x3D,0x2E,0x2D,0x26,0x62,0xE5,0x59,0xE9,0xB5,0x2B,0x0B, + 0x46,0x6A,0xC5,0x59,0xF7,0xBE,0xAA,0x2A,0x48,0x6A,0xE5,0x61,0x25,0x2F,0xBA,0xFA, + 0x90,0xB4,0x89,0x72,0x0D,0x2D,0xB5,0xB5,0xF1,0xBC,0x0E,0xA4,0xE8,0xFE,0xED,0x95, + 0xB0,0xB4,0x6F,0xAC,0xAA,0xCB,0xFB,0x4A,0x6F,0xAC,0xAC,0x8B,0x58,0x70,0x68,0x68, + 0x8C,0x8B,0x2B,0x83,0x82,0xEE,0xFE,0x5C,0xAD,0x93,0x4B,0x83,0xCA,0xAB,0xF5,0x2D, + 0xCD,0x93,0x4B,0x83,0xAD,0xAD,0xAB,0x2A,0xCD,0x93,0x8C,0x8B,0x0B,0x2B,0x2D,0x36, + 0xEE,0x93,0xAD,0x93,0xF6,0x8A,0xC2,0xFE,0xED,0x93,0x0B,0x7B,0xA8,0xA8,0xEA,0x6A, + 0xAD,0x8B,0xCA,0x72,0x80,0x8A,0xFB,0x55,0x6C,0x83,0x0A,0x73,0x7A,0xF0,0xFB,0xDD, + 0x4B,0x83,0xCA,0x6A,0xA2,0x22,0xAE,0xB6,0x4C,0x83,0xCA,0x6A,0xE0,0xAE,0xF0,0x7A, + 0x0B,0x7B,0xCA,0x72,0xF6,0xDC,0x58,0x7A,0x2A,0x7B,0xCA,0x72,0xF9,0xF7,0x55,0x77, + 0x4B,0x83,0xEA,0x72,0xDD,0x57,0xBF,0x3B,0x4C,0x83,0xEA,0x72,0xAD,0xAB,0x2A,0xC8, + 0x6B,0x83,0x0B,0x7B,0x2F,0x97,0xF7,0xBF,0xAD,0x93,0x6C,0x8B,0xFF,0xAB,0x6D,0xF5, + 0xCE,0x93,0x6C,0x8B,0x0D,0x2F,0xF9,0x7E,0x4F,0xA4,0x6C,0x8B,0x0A,0xAB,0xAF,0xAD, + 0x43,0x51,0xE1,0x40,0x2A,0xE0,0x4A,0x7A,0x43,0x51,0xE2,0x40,0x8E,0x2B,0xAF,0xE9, + 0x64,0x51,0x02,0x49,0xFD,0x73,0x5A,0x75,0x23,0x49,0xE1,0x40,0xB2,0x9E,0x6B,0xAB, + 0x43,0x51,0xE2,0x48,0xE6,0xE7,0xAD,0x3E,0x23,0x49,0x02,0x49,0x80,0x7F,0xA4,0x94, + 0x43,0x51,0x02,0x49,0xDD,0x9F,0x52,0xE2,0x43,0x51,0xE2,0x40,0x7A,0xF8,0xDA,0xDB, + 0x64,0x59,0x02,0x49,0xB5,0x2D,0xA9,0xEA,0x64,0x59,0x23,0x51,0xAB,0xA8,0xEB,0xEF, + 0x64,0x59,0x23,0x51,0xFF,0x7C,0x7D,0x6D,0x43,0x51,0x02,0x49,0x8A,0xF8,0xFF,0x87, + 0x64,0x51,0x23,0x51,0x7A,0xBF,0xA7,0x7B,0x64,0x59,0x03,0x49,0x2E,0xA8,0xEA,0xDF, + 0x44,0x51,0x03,0x49,0xB8,0x68,0xEA,0xEA,0x23,0x51,0xE2,0x48,0xAA,0xFF,0xEF,0x0A, + 0x44,0x51,0x03,0x49,0x7F,0x5E,0x35,0xBF,0x23,0x51,0xE2,0x48,0xFB,0xBF,0x8E,0x8E, + 0x88,0x7A,0x23,0x51,0x25,0x25,0x3D,0x2D,0x2A,0x93,0xE9,0x8A,0xAB,0xFD,0xA9,0x6B, + 0x09,0x8B,0xA8,0x82,0xF8,0xF2,0x78,0x5A,0xC8,0x82,0x87,0x7A,0xF2,0xF0,0xDE,0x57, + 0xA8,0x7A,0x67,0x7A,0xFE,0x5F,0x7C,0xFF,0x87,0x7A,0x46,0x72,0x00,0x0F,0x2E,0xBB, + 0xA8,0x7A,0x67,0x7A,0xF7,0xEF,0xBF,0xAD,0x87,0x7A,0x67,0x72,0xB7,0x8A,0xC0,0xA0, + 0x87,0x7A,0x66,0x72,0x7E,0x0A,0x3E,0x12,0xA7,0x7A,0x67,0x72,0x75,0xE5,0xDF,0x37, + 0x87,0x7A,0x46,0x72,0xF5,0x0F,0x2A,0x08,0x87,0x7A,0x46,0x72,0x5D,0x5F,0x3A,0xFA, + 0x86,0x72,0x25,0x6A,0xE0,0x9E,0xFE,0xFF,0x67,0x7A,0x26,0x6A,0xBF,0xB6,0xBC,0x8A, + 0x86,0x7A,0x46,0x72,0x75,0x75,0xFD,0xED,0x87,0x7A,0x46,0x72,0xA5,0x03,0x2A,0xAF, + 0xA8,0x7A,0x46,0x72,0xEB,0x0E,0xAC,0xED,0x87,0x7A,0x25,0x6A,0x7E,0xEC,0xAE,0x6E, + 0x26,0x72,0xC5,0x61,0x62,0xBA,0xB8,0xEA,0x06,0x6A,0xA4,0x61,0xE0,0xF2,0xFE,0x77, + 0xC5,0x61,0x63,0x59,0xA2,0x27,0xAC,0x8A,0x05,0x6A,0xA4,0x61,0xAD,0x29,0xAB,0x5E, + 0x05,0x6A,0xA4,0x61,0xFA,0xA8,0xFA,0x7A,0x06,0x6A,0xA4,0x59,0xDF,0x7B,0xFF,0x2B, + 0x05,0x6A,0xA4,0x61,0xBF,0x7F,0xFF,0x80,0x46,0x72,0xC4,0x61,0x8B,0x2D,0xBE,0x2E, + 0x46,0x72,0x26,0x6A,0x2F,0x2E,0xD0,0xFA,0x87,0x7A,0x26,0x6A,0xFD,0x57,0x6B,0xA2, + 0x66,0x72,0xE5,0x61,0x7E,0x7B,0xEA,0xE0,0xA4,0x59,0xA2,0x38,0x7C,0x78,0x78,0xF8, + 0xA1,0x30,0x61,0x28,0x78,0x5F,0x5E,0x5E,0xC2,0x30,0x61,0x28,0xBF,0x3D,0xAD,0xBD, + 0x23,0x41,0xA1,0x28,0xFD,0xFB,0x2B,0x0B,0x23,0x41,0xE2,0x38,0x8D,0xF7,0xAF,0xAC, + 0x23,0x41,0xE2,0x38,0x0F,0x2F,0xF7,0xDF,0x64,0x49,0x03,0x41,0x2B,0x89,0x85,0x25, + 0x64,0x49,0x23,0x41,0xE6,0xFA,0x70,0xE0,0x43,0x41,0xA2,0x30,0xFC,0x5E,0x7A,0xFE, + 0xC2,0x30,0x81,0x28,0xFC,0xFA,0xE8,0xA8,0xA2,0x28,0x81,0x28,0xBE,0x7E,0xFC,0x68, + 0xA2,0x28,0x82,0x20,0x80,0xFA,0x5E,0x5D,0xC2,0x28,0x82,0x20,0xAF,0xBD,0x1F,0x7F, + 0xE3,0x30,0xA2,0x28,0x03,0xFF,0xFF,0x5F,0xC3,0x28,0x61,0x20,0xF8,0xF8,0x7E,0x56, + 0x83,0x20,0x61,0x20,0xDC,0x96,0xDF,0xD2,0x82,0x20,0x61,0x20,0xF8,0xBE,0xEB,0xFB, + 0xA2,0x28,0x41,0x18,0xA2,0xA8,0xBE,0xDF,0xC3,0x28,0x61,0x20,0x0B,0xEF,0xBF,0xF5, + 0xA2,0x28,0x82,0x20,0xBA,0xFE,0x0F,0x2F,0xC3,0x28,0x82,0x20,0x2E,0x89,0x3B,0xAB, + 0xE3,0x30,0xA2,0x28,0x3F,0xBF,0xFD,0xBD,0x03,0x31,0xA2,0x28,0xDA,0xFA,0xE3,0xFF, + 0xE3,0x30,0xC2,0x28,0xF2,0x78,0xDE,0x5D,0xE3,0x30,0xA2,0x28,0x2A,0xBF,0xBB,0xF7, + 0xE3,0x30,0xA2,0x28,0x7F,0xEE,0xAB,0x8A,0xE3,0x38,0xA2,0x28,0xFD,0xF5,0xFE,0x2B, + 0xE3,0x30,0xA2,0x30,0x8F,0x2B,0x88,0xEA,0xE3,0x30,0xA2,0x30,0xB8,0xF6,0xF7,0x7D, + 0xC2,0x30,0xA2,0x30,0x0E,0x0B,0x03,0x2A,0xE3,0x38,0xA2,0x28,0xF8,0xFB,0xBF,0xAA, + 0x03,0x39,0xA2,0x30,0xB5,0xFD,0xBB,0x2A,0x24,0x39,0xE3,0x30,0xB2,0xBB,0x57,0x57, + 0x03,0x39,0xC2,0x30,0x80,0xA0,0xFA,0xFE,0x03,0x39,0xC2,0x30,0xA2,0xAB,0xBF,0x3F, + 0x23,0x39,0xE2,0x30,0xEF,0xFE,0xE9,0xE2,0x03,0x39,0xC2,0x30,0xFF,0xAF,0xAB,0x00, + 0x03,0x39,0xE2,0x38,0x03,0x57,0x27,0x05,0x24,0x39,0xE2,0x38,0x95,0xF5,0x9E,0x5A, + 0x23,0x41,0xE2,0x38,0x7E,0x6E,0xA0,0x8A,0x03,0x39,0xC2,0x30,0x63,0x62,0x70,0xE8, + 0x03,0x39,0xA2,0x30,0x7B,0x3F,0x2F,0x2E,0x44,0x41,0xE2,0x30,0xB5,0xFD,0xEE,0x3A, + 0x44,0x49,0x03,0x39,0x57,0x77,0xFF,0xB0,0x44,0x49,0x03,0x39,0xD5,0x55,0x7D,0xF2, + 0x24,0x39,0xE3,0x38,0xEA,0xF2,0xB9,0xFF,0x03,0x39,0xC2,0x38,0x02,0x00,0xC0,0xC2, + 0x03,0x39,0xC2,0x30,0x77,0xAF,0xBB,0x8A,0x23,0x39,0xC2,0x30,0x8B,0xA6,0x3F,0xAB, + 0x23,0x39,0xE2,0x30,0x56,0xFF,0x6A,0xE8,0x02,0x39,0xC1,0x30,0xEA,0x63,0xA2,0x82, + 0x03,0x41,0xC2,0x30,0x2F,0xA9,0x2B,0x3F,0xA4,0x51,0x23,0x41,0xAD,0x37,0x29,0x2D, + 0xC5,0x51,0x64,0x49,0xDF,0x59,0x8A,0x22,0xC5,0x59,0x64,0x49,0xFD,0x95,0xFA,0xF8, + 0x05,0x62,0x63,0x49,0xAF,0x2F,0xAF,0xF7,0x67,0x6A,0xC5,0x59,0x8A,0xAA,0xBF,0x75, + 0x06,0x62,0x84,0x51,0x08,0xB8,0xFE,0xDF,0x47,0x6A,0xA4,0x51,0x0A,0x2A,0xBD,0x2D, + 0x8C,0x93,0x27,0x62,0x2F,0x2D,0x2D,0x2D,0xB0,0xB4,0xED,0x9B,0x3D,0xAD,0x29,0x29, + 0xD0,0xB4,0x6F,0xAC,0xEE,0x7F,0xE2,0xFA,0x6F,0xAC,0xAD,0x93,0x68,0xE0,0xE8,0xE0, + 0xAD,0x93,0x0A,0x7B,0xFE,0xAC,0xF8,0x58,0xAC,0x8B,0x2B,0x83,0x2B,0x2B,0x2F,0xBD, + 0xCD,0x8B,0x8C,0x8B,0xBC,0x68,0x82,0xC9,0xCD,0x93,0x6C,0x7B,0xA8,0xAA,0x2A,0xFF, + 0xCD,0x93,0x0A,0x73,0xA0,0xA2,0xFA,0x7E,0x8C,0x8B,0xAA,0x6A,0xA0,0xFA,0x7E,0xDF, + 0x0B,0x73,0xA9,0x6A,0x7B,0xF2,0xFE,0x5E,0x0A,0x73,0x89,0x62,0x02,0x2B,0xF9,0xDD, + 0x2B,0x73,0xEA,0x72,0xAD,0x7D,0xD5,0x5D,0x2B,0x7B,0xA9,0x6A,0xB8,0xBF,0xF7,0xB7, + 0x0A,0x73,0xC9,0x72,0x96,0xFB,0x42,0xE0,0x0A,0x7B,0xCA,0x72,0x9E,0x39,0x25,0xD5, + 0x4C,0x7B,0x0B,0x7B,0xDD,0xDD,0x89,0xB7,0x6C,0x83,0x0B,0x7B,0xDE,0xBF,0x1F,0xEF, + 0x6C,0x83,0x2B,0x83,0xFF,0xFA,0xEA,0xA8,0xEE,0x9B,0x4B,0x83,0xBD,0x0F,0x29,0x2D, + 0xEE,0x9B,0x4B,0x83,0x7E,0x7A,0x58,0xF0,0xEE,0x9B,0x4C,0x83,0x2D,0x2D,0xFD,0xF5, + 0x43,0x51,0xE1,0x48,0xDE,0xEB,0x8A,0x0B,0x22,0x49,0xE2,0x40,0xE0,0xFA,0xFF,0xEF, + 0x44,0x51,0xC2,0x40,0xFF,0x7F,0xBF,0x2B,0x43,0x51,0xE2,0x40,0xFD,0xEB,0x2F,0x08, + 0x63,0x51,0x02,0x49,0xF7,0x55,0x6D,0xFE,0x43,0x51,0x02,0x49,0xF7,0xA5,0xB5,0xBF, + 0x43,0x51,0xE2,0x40,0xE0,0x7A,0x7C,0xFA,0x43,0x51,0xE2,0x40,0xBF,0xAF,0xB9,0xE9, + 0x43,0x51,0x02,0x49,0x80,0xA8,0xAF,0x4B,0x43,0x51,0x03,0x49,0xA0,0xA3,0xBB,0x0F, + 0x65,0x59,0x23,0x51,0xED,0xBA,0x5A,0x5F,0x64,0x59,0x02,0x49,0xBB,0x8F,0xCD,0xEA, + 0x44,0x51,0x23,0x51,0x5C,0xDB,0x8D,0xED,0x43,0x51,0x03,0x49,0xF7,0xFB,0xCB,0xE2, + 0x23,0x51,0x03,0x49,0xE0,0xFC,0x5A,0x72,0x23,0x51,0xE2,0x48,0xCA,0xFA,0xAA,0xAB, + 0x23,0x51,0xE2,0x48,0xE2,0xBB,0xFF,0x75,0x23,0x51,0xE2,0x48,0xCF,0xCB,0x2B,0xED, + 0xE8,0x8A,0x23,0x51,0x2D,0x25,0x29,0x2D,0x29,0x93,0xE8,0x8A,0x72,0xF2,0x62,0x5F, + 0xC9,0x8A,0xA7,0x7A,0xE8,0xF8,0xBE,0x72,0xA8,0x7A,0x87,0x7A,0x58,0x5C,0xE0,0xFF, + 0xA7,0x7A,0x67,0x72,0xDB,0x2B,0xBF,0x77,0x87,0x7A,0x46,0x72,0x79,0xCA,0x2A,0x00, + 0xA7,0x7A,0x67,0x72,0xA9,0xB7,0xE4,0x7C,0xA8,0x82,0x26,0x72,0xA8,0xAF,0x0A,0x22, + 0xA7,0x7A,0x66,0x72,0xBB,0xDC,0xE0,0x82,0x87,0x7A,0x67,0x72,0x18,0x0C,0x2B,0x0E, + 0xA7,0x7A,0x67,0x7A,0xFF,0x5F,0xEF,0x1F,0x87,0x7A,0x46,0x72,0x2A,0x2F,0xBA,0x90, + 0x66,0x72,0x26,0x72,0xEC,0x4C,0xD0,0xC2,0x67,0x7A,0x25,0x6A,0x9A,0xC2,0xCB,0x6F, + 0x87,0x7A,0x46,0x72,0xFA,0x5E,0x7E,0x7D,0x87,0x7A,0x46,0x72,0xEF,0x8F,0xAD,0x0F, + 0x87,0x7A,0x67,0x72,0xA3,0x93,0xBD,0x6F,0x67,0x72,0x05,0x6A,0xE8,0xEC,0xFE,0xDF, + 0x26,0x72,0xC5,0x61,0xF8,0xEF,0x79,0xBE,0xC5,0x61,0x83,0x59,0xEC,0x02,0x20,0xE8, + 0x05,0x6A,0xA4,0x61,0xF5,0xE5,0x2D,0x0D,0x46,0x72,0xA4,0x61,0xD7,0xBD,0x0A,0xAA, + 0x46,0x72,0xC5,0x61,0xA5,0x8B,0x80,0x08,0x87,0x7A,0x06,0x6A,0xFD,0x2D,0x8A,0xAA, + 0xA7,0x7A,0x46,0x72,0x5F,0x2B,0x22,0xAB,0xA8,0x82,0x05,0x6A,0xFD,0xEB,0x88,0x22, + 0xA8,0x7A,0x26,0x72,0x77,0xAF,0x8A,0xAA,0xA8,0x7A,0x67,0x72,0x7F,0xCB,0x6A,0xDD, + 0x87,0x72,0x26,0x6A,0x60,0x80,0xE8,0x7F,0x06,0x62,0xE2,0x38,0x5A,0x78,0x78,0x78, + 0xC2,0x38,0x61,0x28,0x5E,0xBE,0xFA,0xB8,0xE2,0x38,0x81,0x30,0xBD,0x3D,0x2F,0x2D, + 0x64,0x49,0x03,0x39,0xA9,0x8F,0xA9,0xFD,0x64,0x49,0x03,0x39,0x7A,0x7A,0x7E,0xAF, + 0x23,0x41,0xE2,0x38,0x45,0xF7,0x7A,0xEA,0x65,0x49,0xE3,0x38,0x2D,0xAD,0xFD,0xDD, + 0x64,0x49,0x03,0x39,0xA2,0xA2,0xAB,0x87,0x23,0x39,0xA2,0x28,0x68,0x6A,0xF0,0x68, + 0xC2,0x30,0x82,0x28,0x2F,0xAE,0x20,0x22,0xC2,0x28,0xA2,0x28,0x77,0x5F,0x7F,0xEF, + 0xA2,0x28,0x82,0x20,0x72,0x62,0xAB,0xEC,0xC3,0x28,0x61,0x20,0xFE,0xFA,0xB8,0x7E, + 0xC3,0x28,0x61,0x20,0xE3,0xEF,0x7F,0x57,0x82,0x20,0x61,0x20,0x58,0xDF,0xFF,0xBF, + 0x82,0x20,0x61,0x20,0x60,0x0B,0x3F,0x3B,0xA2,0x28,0x61,0x20,0xFF,0xFA,0x8B,0x02, + 0xA2,0x20,0x61,0x20,0x57,0x9F,0xFA,0xF8,0xA2,0x28,0x41,0x18,0xBD,0xEA,0xAA,0x2A, + 0xA2,0x28,0x61,0x20,0x2B,0xAF,0x3B,0x08,0xC2,0x28,0x82,0x20,0xFF,0xFF,0x3F,0xB7, + 0xC2,0x28,0x81,0x28,0x0B,0x22,0xE8,0xA8,0xC2,0x28,0xA2,0x28,0x78,0x5A,0x5D,0xDB, + 0xC2,0x30,0xA2,0x28,0x73,0xF5,0x35,0x2B,0xC2,0x30,0xA2,0x28,0x55,0xFA,0xA0,0x80, + 0x03,0x39,0xA2,0x28,0xAB,0x8B,0xA7,0xFF,0x03,0x39,0xC2,0x30,0xAF,0xF6,0x57,0x57, + 0xE3,0x38,0xC3,0x30,0x78,0xED,0x3B,0x39,0xE3,0x30,0xA2,0x30,0xFF,0xEE,0xAA,0xAB, + 0xC2,0x30,0xA3,0x28,0x0A,0xAA,0x80,0x20,0x03,0x31,0xA2,0x30,0xFE,0x5F,0xF5,0x77, + 0x03,0x39,0xC2,0x30,0x2B,0x2F,0xA5,0x75,0x03,0x39,0xA2,0x30,0xA0,0xA8,0xFE,0xFA, + 0x03,0x39,0xC3,0x30,0xAA,0x02,0xA7,0xD7,0x23,0x39,0xE3,0x38,0x97,0xBB,0x77,0xD5, + 0x23,0x39,0xE3,0x38,0xE6,0xAA,0x13,0x3B,0x23,0x39,0xC2,0x30,0x88,0x8A,0xBA,0x9A, + 0x03,0x39,0xC2,0x30,0x03,0xBE,0x3C,0xBA,0x03,0x39,0xC2,0x30,0x00,0x2A,0xAA,0xFE, + 0x23,0x39,0xE2,0x30,0x28,0x3B,0xF5,0x57,0x23,0x41,0xE2,0x38,0xFC,0x58,0x50,0x53, + 0xE2,0x38,0xC2,0x30,0x28,0x0E,0x0E,0x2E,0x44,0x41,0xE3,0x38,0x23,0xAD,0x37,0x1F, + 0x85,0x49,0x23,0x41,0xFF,0xFB,0x9F,0x1F,0x64,0x49,0x24,0x41,0x52,0x5A,0x78,0x2A, + 0x44,0x41,0xE2,0x38,0x7F,0xDE,0xFE,0xEC,0x44,0x41,0xE3,0x38,0xED,0xAF,0xEF,0xCA, + 0x02,0x39,0xC2,0x30,0xF0,0x5A,0xC2,0xAE,0x02,0x39,0xC1,0x30,0x2A,0x25,0xB5,0xEF, + 0x23,0x39,0xE2,0x38,0xE2,0xAC,0xB7,0xBD,0x43,0x41,0xE2,0x38,0xDF,0xEB,0xA0,0xBC, + 0x23,0x41,0xE2,0x38,0x55,0xDF,0x14,0xBF,0xA4,0x51,0x02,0x39,0x29,0xAF,0xA5,0xD7, + 0xA4,0x51,0x02,0x41,0x00,0x82,0xA8,0x6E,0xA4,0x51,0x23,0x41,0xA0,0xFE,0xFF,0xFD, + 0xA4,0x59,0x22,0x41,0xAF,0xB7,0x2D,0x2F,0xC5,0x59,0x84,0x51,0x83,0xA9,0xFB,0xB3, + 0xE6,0x59,0x84,0x51,0x57,0x5F,0x7A,0xE2,0x26,0x62,0x84,0x51,0x2F,0xB5,0xAD,0xAF, + 0x8C,0x93,0x26,0x62,0x2D,0x2D,0x25,0x25,0xB0,0xB4,0x2E,0xA4,0x0D,0x09,0x29,0xAD, + 0xB0,0xB4,0x6F,0xAC,0x78,0xF8,0x7B,0xE7,0x6F,0xAC,0xCD,0x93,0x68,0x68,0xF8,0x58, + 0xAD,0x93,0xA9,0x72,0x78,0x78,0x78,0x70,0x2C,0x83,0x48,0x62,0x02,0x8A,0xAF,0xD5, + 0x8C,0x8B,0x89,0x6A,0x0A,0xFF,0xFF,0x7F,0x8C,0x83,0x69,0x62,0x20,0xAB,0xFF,0x57, + 0x2B,0x73,0x68,0x62,0xA0,0xE8,0x7F,0x55,0xCA,0x6A,0x68,0x62,0x22,0xED,0xFA,0xF7, + 0xCA,0x6A,0x68,0x62,0xF8,0x5F,0x75,0x7D,0xCA,0x6A,0x68,0x62,0x3B,0xB3,0x9D,0xE9, + 0xEA,0x72,0x89,0x62,0x82,0xAA,0x2B,0xAD,0xEA,0x72,0x89,0x62,0x2B,0x2D,0xBE,0xBE, + 0x0A,0x73,0xC9,0x6A,0xA0,0xFF,0xB5,0x15,0x4B,0x7B,0xCA,0x72,0x57,0xFD,0xAB,0x2D, + 0xAD,0x8B,0x0B,0x7B,0xF5,0xFD,0x8F,0x0A,0x0E,0x9C,0x2B,0x7B,0xF5,0xFF,0xAB,0x2A, + 0xED,0x93,0x4B,0x83,0x57,0x77,0xFE,0xFC,0xED,0x93,0x4B,0x83,0x3F,0x27,0x3D,0xBF, + 0x2E,0xA4,0x8C,0x8B,0x60,0xA2,0x02,0x03,0x0E,0x9C,0x4B,0x83,0xDD,0x5F,0x7E,0x58, + 0x43,0x51,0x03,0x49,0x8B,0xCE,0x9E,0x96,0x23,0x49,0xE2,0x48,0xFC,0x9E,0x3E,0x0A, + 0x23,0x49,0x02,0x49,0x5A,0xF8,0x88,0xA8,0x44,0x51,0x02,0x49,0xBF,0xFF,0x6A,0x52, + 0x44,0x51,0x03,0x49,0xB6,0xBA,0xF5,0xF5,0x22,0x49,0xE2,0x40,0x20,0xA8,0xAD,0xDC, + 0x43,0x51,0xE2,0x40,0xFA,0xAD,0x2B,0x8A,0x43,0x51,0x02,0x49,0xFB,0xDA,0xA8,0xFA, + 0x64,0x51,0x03,0x49,0xFE,0xFE,0xEE,0x35,0x44,0x51,0x02,0x49,0xCB,0xEF,0xF9,0xF9, + 0x64,0x51,0x23,0x51,0xFD,0xD5,0x35,0xA5,0x44,0x59,0x23,0x49,0xEA,0xE3,0x7A,0x7A, + 0x43,0x51,0x03,0x49,0xAF,0xA3,0x0F,0x6F,0x43,0x51,0x03,0x49,0x83,0x9C,0x5E,0xFD, + 0x23,0x51,0xE2,0x48,0xE8,0x68,0xFC,0x96,0x23,0x51,0xE2,0x48,0x35,0xA5,0xA9,0xCE, + 0x02,0x49,0xE2,0x48,0x70,0x02,0xB8,0xF0,0x43,0x51,0xE2,0x48,0xFF,0xF7,0x2F,0xAD, + 0xE8,0x82,0x83,0x59,0x25,0x0D,0x0D,0x0D,0x29,0x8B,0xC8,0x82,0xEA,0x7A,0xE2,0xFA, + 0xE9,0x8A,0x87,0x7A,0x62,0xEB,0xFB,0x56,0xA8,0x7A,0x67,0x72,0xE2,0x2E,0xBA,0x7F, + 0xA7,0x82,0x67,0x72,0xFF,0xEE,0xEB,0xF1,0xA8,0x7A,0x67,0x7A,0xFE,0xDA,0xDA,0xAA, + 0xC8,0x82,0x67,0x72,0x7F,0x5E,0x58,0xEB,0xA8,0x7A,0x67,0x72,0xBE,0xAB,0x2D,0xBF, + 0x46,0x82,0xA8,0x7A,0xF6,0xF7,0xFD,0xFF,0xA8,0x7A,0x46,0x72,0x8A,0xAE,0xFF,0xAB, + 0xA7,0x7A,0x67,0x72,0xFF,0x6B,0x4B,0xFF,0x87,0x7A,0x46,0x72,0xAB,0xFA,0xFA,0x7A, + 0x66,0x72,0x26,0x72,0x2F,0xAA,0x6B,0xFF,0x66,0x72,0x05,0x72,0xA8,0x8A,0x8B,0x82, + 0x67,0x7A,0x46,0x72,0xCD,0x37,0xD5,0x17,0x87,0x7A,0x46,0x72,0xB2,0xAF,0xAF,0xEF, + 0x87,0x7A,0x26,0x72,0xC2,0xDF,0x6F,0xFB,0x46,0x72,0xE5,0x61,0xB8,0xFE,0xDE,0x7C, + 0x06,0x6A,0xA4,0x61,0xDC,0x5A,0x5A,0x6A,0x25,0x6A,0x83,0x59,0x7F,0xFF,0xDD,0x3B, + 0x46,0x72,0xA4,0x59,0xFD,0x75,0x3B,0x00,0xA8,0x7A,0x05,0x6A,0xD5,0xB5,0x0F,0xEE, + 0x87,0x7A,0x05,0x6A,0x2B,0x2A,0xE8,0x56,0x88,0x7A,0x05,0x6A,0xA2,0x2C,0xAF,0xF5, + 0x87,0x7A,0x05,0x6A,0x22,0x88,0x8B,0xFD,0x87,0x7A,0x26,0x6A,0x8A,0xAA,0xBB,0xFD, + 0x67,0x72,0x26,0x6A,0xA7,0xB8,0x5A,0x78,0x87,0x7A,0xE6,0x69,0xAB,0xFE,0xBD,0x2E, + 0x67,0x72,0x06,0x6A,0x6A,0xBE,0xE0,0x80,0xE6,0x61,0x03,0x41,0x78,0x58,0x78,0x78, + 0xE2,0x38,0x81,0x30,0xD8,0x88,0xA2,0xA8,0x03,0x41,0x81,0x30,0xAD,0xAF,0xAA,0x88, + 0x23,0x41,0xE3,0x38,0x09,0x09,0xF7,0xF5,0x64,0x49,0xE2,0x38,0x8B,0x2E,0x2D,0xB5, + 0x44,0x49,0xC2,0x38,0xFE,0xF8,0x58,0xF0,0xE2,0x38,0xC2,0x30,0x00,0xEE,0xEE,0xBF, + 0x24,0x41,0xC2,0x30,0x0A,0xAB,0xAF,0x7D,0x23,0x39,0xC2,0x28,0x78,0xEA,0x7E,0x7F, + 0xC2,0x28,0x62,0x20,0xA2,0xAA,0xAA,0xEA,0xC2,0x28,0x82,0x20,0xEA,0x5B,0x5F,0x55, + 0xA2,0x20,0x61,0x18,0x2C,0xBA,0xBA,0xFF,0xA2,0x20,0x61,0x20,0x7A,0x7A,0x78,0x7F, + 0x82,0x20,0x61,0x20,0x55,0xD5,0x37,0x0B,0xA1,0x20,0x62,0x20,0xF7,0xF7,0xFE,0xEA, + 0xA2,0x28,0x61,0x20,0x5F,0xFF,0x8B,0x02,0xC2,0x28,0x82,0x20,0xBD,0x5D,0xBF,0x7E, + 0xC3,0x28,0x61,0x20,0x7A,0xEA,0xAA,0x8A,0xA2,0x28,0x81,0x20,0x07,0x7C,0x5E,0x7A, + 0xC2,0x28,0x81,0x20,0xAF,0xAF,0xB5,0xB5,0xC2,0x28,0x61,0x20,0x2A,0x20,0xA8,0xEA, + 0xE3,0x30,0xA2,0x28,0xBF,0xBB,0xBF,0xD5,0xC2,0x28,0xA2,0x28,0x7A,0xEE,0xD4,0x67, + 0xC2,0x30,0xA2,0x28,0x7E,0x5F,0x7D,0xA9,0xE3,0x30,0xA2,0x28,0xFB,0x0B,0x03,0x20, + 0xE3,0x30,0xC2,0x28,0xAB,0x8B,0xAB,0xF6,0xE3,0x30,0x82,0x28,0xEA,0xFA,0xFA,0xDE, + 0xC2,0x30,0x81,0x28,0xA0,0xB8,0x6F,0xBD,0xE3,0x30,0xA2,0x28,0xA9,0xEB,0xED,0x69, + 0xE3,0x30,0xA2,0x28,0xE3,0xA3,0xFD,0x7D,0xC2,0x30,0xA2,0x28,0x38,0x30,0x3F,0x0A, + 0xE3,0x30,0xA2,0x30,0xBE,0xB6,0xAE,0x0A,0xE3,0x38,0xC2,0x30,0xF0,0xE2,0xEA,0xD0, + 0xC2,0x38,0xE3,0x30,0xFF,0xDF,0xFE,0x2F,0xE3,0x38,0xA2,0x28,0x22,0xE0,0xDA,0xFE, + 0x03,0x39,0xC2,0x30,0x3E,0x9F,0xFF,0xB7,0x23,0x39,0xE2,0x30,0x5F,0x57,0xB5,0xB5, + 0x03,0x39,0xC2,0x30,0xDA,0xAA,0x2A,0x08,0x03,0x39,0xC2,0x30,0xFF,0xBE,0xA4,0x00, + 0x24,0x39,0xE2,0x38,0x77,0xF7,0xBF,0xF8,0x23,0x41,0xE3,0x38,0xFD,0xA9,0xAA,0x4B, + 0x23,0x41,0xC2,0x30,0xFF,0xDA,0xC2,0xA2,0x44,0x41,0x03,0x41,0xA5,0xA5,0x8D,0xFF, + 0x85,0x49,0x23,0x41,0xED,0x3D,0x9F,0xBA,0x85,0x51,0x44,0x41,0xAD,0x0D,0xBB,0xBA, + 0x64,0x49,0x03,0x39,0x76,0xCE,0xC0,0x88,0x84,0x49,0x23,0x41,0xF5,0x5F,0x5B,0x63, + 0x44,0x49,0xE2,0x38,0x7E,0xAB,0x8A,0x82,0x43,0x49,0xC1,0x38,0x7D,0xFE,0xFA,0xA0, + 0x23,0x41,0xE2,0x38,0x2F,0x29,0xAF,0xEF,0x23,0x41,0x03,0x39,0x24,0x0A,0x8F,0x2B, + 0x23,0x41,0xE2,0x38,0xBF,0x38,0x00,0xB0,0x43,0x49,0xE2,0x38,0x2C,0xEA,0xB7,0x2D, + 0x64,0x49,0x02,0x41,0x2A,0x2D,0xAF,0x0A,0xA5,0x51,0x43,0x41,0xDF,0xE7,0x8A,0x02, + 0xE5,0x59,0x22,0x41,0xA7,0x2F,0x0B,0x2A,0x27,0x62,0x84,0x51,0x7F,0xEF,0x3A,0x2F, + 0x27,0x62,0xC5,0x59,0xFD,0xEF,0xA8,0x00,0x27,0x62,0xC5,0x59,0xF7,0x79,0xBE,0xA8, + 0x2A,0x83,0xE6,0x59,0x2D,0x3D,0x35,0x35,0x32,0xC5,0xED,0x9B,0xBD,0x2D,0x29,0x2D, + 0x73,0xCD,0xD1,0xB4,0x55,0xFF,0xA2,0x00,0x52,0xC5,0x4F,0xA4,0x5F,0xEA,0xA0,0x80, + 0xB0,0xB4,0xEA,0x7A,0x7E,0xF8,0xA0,0x20,0x2F,0x9C,0x07,0x5A,0x55,0x57,0xFA,0xA0, + 0xCA,0x72,0x07,0x5A,0xA0,0xA8,0x6A,0x70,0x49,0x62,0xA6,0x51,0x80,0xAC,0xBE,0xD7, + 0x48,0x62,0xA6,0x51,0x0A,0xAB,0x7F,0x77,0x68,0x62,0xE6,0x51,0x80,0xEE,0xFF,0xDF, + 0x68,0x62,0x07,0x52,0x02,0x02,0xFB,0x77,0x89,0x62,0x27,0x5A,0x08,0x2A,0xE8,0xDF, + 0xA9,0x6A,0x68,0x62,0x2B,0xAA,0xAD,0x25,0xCA,0x6A,0x68,0x62,0x20,0x0B,0x0D,0x0B, + 0x0A,0x7B,0xA9,0x6A,0xAF,0xE7,0xB3,0x0A,0xAD,0x8B,0x0A,0x73,0x95,0x35,0x2D,0x0B, + 0x4F,0xA4,0xAD,0x8B,0xF5,0xB5,0x3A,0xAB,0x4E,0xA4,0xCC,0x93,0xD7,0xFA,0xAA,0x02, + 0x4F,0xA4,0xAC,0x8B,0x7E,0xEA,0xAA,0x82,0xCD,0x93,0x6B,0x8B,0xAA,0xB0,0x98,0x88, + 0x4E,0xA4,0xCD,0x93,0x0D,0x2F,0xAF,0x3D,0x6F,0xAC,0x8C,0x8B,0x5E,0x78,0x78,0xE8, + 0x44,0x49,0x02,0x49,0x78,0x55,0xD5,0xF5,0x23,0x49,0x03,0x49,0xEB,0xDA,0xF7,0xC8, + 0x23,0x49,0xE2,0x40,0x28,0xB7,0xD6,0xAE,0x43,0x51,0x03,0x49,0xFF,0x0B,0xBF,0xF9, + 0x43,0x51,0xE2,0x40,0xE2,0xA8,0x7A,0x9A,0x43,0x51,0xE2,0x40,0x97,0xA7,0x2F,0x0A, + 0x64,0x51,0x02,0x49,0xFB,0xFA,0xF6,0xE8,0x43,0x51,0x03,0x49,0x77,0x0A,0x20,0x5B, + 0x64,0x59,0x02,0x49,0x9F,0xBE,0xB8,0xEF,0x43,0x51,0x03,0x51,0x20,0x00,0x2C,0xEB, + 0x43,0x51,0x23,0x51,0x26,0xFE,0x56,0xF1,0x43,0x51,0x02,0x49,0x6A,0xEA,0xFA,0x52, + 0x23,0x51,0x03,0x49,0x0A,0xC7,0x2F,0x09,0xE2,0x50,0x23,0x49,0xFE,0xBB,0xAD,0xED, + 0x44,0x51,0xE2,0x48,0xFF,0xFD,0xAA,0xA8,0x23,0x51,0xC1,0x40,0x6E,0x7A,0xEA,0xE8, + 0x02,0x49,0xE2,0x48,0x39,0x0B,0x8B,0xCD,0xE6,0x69,0x02,0x49,0xD5,0xD5,0xB5,0x25, + 0x49,0x93,0xE5,0x61,0xAD,0x2D,0xAB,0x2A,0x08,0x8B,0xA7,0x7A,0xF0,0xFC,0x78,0x7A, + 0xC8,0x82,0x66,0x72,0xA8,0xE0,0x6A,0x7A,0xA7,0x7A,0x67,0x7A,0xAE,0xA2,0xFA,0x1F, + 0xA7,0x7A,0x66,0x72,0xEE,0xA8,0x66,0xAA,0xA7,0x82,0x66,0x72,0xC3,0x71,0x7D,0x75, + 0x87,0x7A,0x67,0x72,0x02,0xA3,0x21,0x23,0xA7,0x7A,0x66,0x72,0xBA,0xAB,0x29,0xDF, + 0xA7,0x7A,0x66,0x72,0xBA,0xAA,0xB6,0x77,0xA8,0x7A,0x66,0x7A,0x2F,0xBF,0xEE,0x2D, + 0xA8,0x82,0x46,0x72,0xBA,0xF2,0x78,0x78,0x67,0x7A,0x46,0x72,0xF2,0xEB,0x7D,0x69, + 0x66,0x72,0x26,0x6A,0xF7,0xFF,0xF8,0xEB,0x66,0x7A,0x26,0x6A,0x2A,0x89,0x0B,0xBA, + 0xA7,0x7A,0x26,0x72,0xBF,0xFF,0x7F,0x0A,0x09,0x8B,0x26,0x72,0xF5,0xBD,0xAD,0x2A, + 0x4A,0x93,0x46,0x72,0x55,0xFF,0xAA,0x2A,0x29,0x8B,0x46,0x72,0x55,0xEE,0xAA,0xA0, + 0xA8,0x7A,0xE5,0x61,0xDF,0xEA,0xA0,0xB8,0x67,0x7A,0xE5,0x69,0x2B,0x82,0xF0,0x56, + 0x67,0x72,0xE5,0x69,0xAC,0xFF,0xFF,0xF5,0x25,0x72,0xC5,0x61,0xE8,0xEA,0xAA,0xAA, + 0x46,0x72,0xC4,0x61,0x7F,0x7F,0xBA,0x8A,0x46,0x72,0xE5,0x61,0xD7,0xDF,0xFB,0x28, + 0x67,0x72,0x05,0x6A,0xDD,0xFD,0xF9,0x83,0x67,0x7A,0x26,0x6A,0x29,0xF5,0x5D,0xFF, + 0x87,0x7A,0x26,0x6A,0xBF,0xB5,0xAF,0x0B,0x87,0x72,0x26,0x6A,0xAE,0xFE,0xDF,0x7A, + 0x87,0x72,0x26,0x6A,0x7E,0x7C,0x57,0x57,0xE5,0x59,0x23,0x41,0x78,0x78,0x78,0x78, + 0x23,0x41,0xA1,0x30,0xDE,0xFE,0xDE,0xFC,0x04,0x39,0xC2,0x38,0xFB,0xF7,0x6B,0xE9, + 0x03,0x39,0xC2,0x38,0xAB,0xFF,0xFD,0x77,0x23,0x41,0xC2,0x30,0x3F,0xB7,0xB7,0xFF, + 0x44,0x41,0x03,0x39,0x6A,0x7A,0x7F,0x55,0x03,0x39,0xE2,0x30,0xBF,0x20,0xF8,0x34, + 0x03,0x39,0xA2,0x28,0xFA,0xFC,0x78,0x78,0xC2,0x28,0x81,0x20,0xC0,0xE8,0xF7,0x55, + 0xA2,0x28,0x61,0x20,0xEA,0xE8,0xF8,0xFA,0x82,0x20,0x61,0x18,0xDB,0x5A,0x72,0xC0, + 0x82,0x20,0x61,0x18,0xD5,0xF5,0xEF,0x8F,0xA2,0x20,0x61,0x18,0xF5,0xE9,0xAB,0xAB, + 0xA2,0x28,0x61,0x20,0xAB,0xEF,0x27,0xAE,0xC2,0x28,0x81,0x20,0xFB,0x8F,0xAD,0xAF, + 0x03,0x31,0xA2,0x28,0xF7,0xE7,0x7D,0xFF,0xE3,0x30,0x81,0x20,0x7E,0xFE,0xF2,0xAA, + 0xC2,0x28,0x82,0x28,0xFD,0x5F,0x5E,0xB6,0xA2,0x28,0x81,0x20,0xFE,0x40,0x78,0x5A, + 0xA2,0x28,0x61,0x20,0xAA,0xAC,0x7A,0xAE,0xA2,0x28,0x61,0x20,0x28,0xA8,0xFA,0xFA, + 0xA2,0x28,0x61,0x20,0x00,0x02,0x2F,0xAF,0xC2,0x28,0x81,0x28,0xAB,0x8F,0x2F,0xFF, + 0xC2,0x28,0x81,0x28,0x02,0xA8,0x7B,0x55,0xE2,0x30,0x81,0x28,0x8A,0xBE,0xE9,0xBF, + 0xE3,0x30,0xA2,0x28,0x9B,0x3B,0x3E,0xFF,0xC2,0x30,0xA2,0x28,0x5E,0xDC,0x7C,0x5F, + 0x61,0x30,0xC2,0x28,0xFB,0x77,0xFF,0x5D,0x03,0x31,0xC2,0x28,0x7D,0xF5,0x6D,0x43, + 0xE3,0x30,0xA2,0x28,0xFD,0x8E,0xA2,0x82,0x04,0x39,0xC3,0x30,0xF5,0xFF,0xDF,0xAF, + 0x24,0x39,0xE3,0x38,0xF5,0x8D,0x25,0xFF,0x24,0x39,0xC2,0x30,0x5E,0x7E,0x60,0xE8, + 0xE3,0x30,0xC2,0x30,0x72,0xDD,0xF7,0xB6,0xC3,0x38,0xE3,0x30,0xF6,0xD7,0xFD,0xFF, + 0x03,0x39,0xC2,0x30,0x2F,0x0B,0xAA,0xA3,0x23,0x39,0xE3,0x38,0xAD,0x82,0xA1,0x2F, + 0x23,0x39,0xE2,0x30,0xB8,0xEB,0xEC,0xF8,0x23,0x39,0xE2,0x30,0x2A,0x02,0xA3,0xDD, + 0x44,0x41,0xC2,0x30,0xF8,0xFE,0x7F,0x7F,0x03,0x39,0xE2,0x30,0xAA,0x1F,0x3F,0x7F, + 0x44,0x41,0xE2,0x38,0x8F,0xAF,0xBF,0xD5,0x44,0x41,0xE2,0x38,0xFE,0x7A,0xF8,0xED, + 0x44,0x49,0x03,0x39,0x23,0x83,0xA1,0xE9,0x85,0x49,0x03,0x41,0xAB,0x2D,0xBF,0x5D, + 0x85,0x51,0x44,0x49,0xFA,0xE9,0xAF,0x0A,0x85,0x51,0x23,0x41,0x02,0x2A,0xEA,0xD8, + 0x44,0x49,0x03,0x41,0x08,0x00,0x80,0xF2,0x64,0x49,0x02,0x39,0xF8,0x52,0xDE,0x9F, + 0x23,0x41,0xE2,0x38,0xFA,0x7E,0xF8,0xEC,0x23,0x41,0xE2,0x38,0xA2,0xC9,0xF9,0x6B, + 0x43,0x41,0xE2,0x38,0xDE,0xBF,0xFF,0xA3,0x43,0x41,0x03,0x41,0x0D,0xAA,0x8A,0xBF, + 0x85,0x51,0x03,0x41,0x23,0x22,0xBA,0xFD,0xA5,0x51,0x22,0x41,0x0A,0xEA,0x77,0x55, + 0xC5,0x59,0x22,0x41,0x0A,0xAA,0xAD,0xFD,0xE6,0x61,0x63,0x49,0x02,0x0F,0xF5,0xD5, + 0x27,0x62,0x84,0x51,0x2A,0xBE,0xDF,0x75,0x27,0x62,0x84,0x51,0x00,0x88,0xFB,0x95, + 0xE9,0x7A,0xE5,0x59,0x35,0x25,0x35,0xBD,0x12,0xC5,0x8C,0x93,0x29,0x29,0x29,0x2D, + 0x73,0xCD,0x32,0xC5,0x00,0xAE,0xAF,0xBD,0x73,0xCD,0x12,0xBD,0x6C,0xF8,0xFA,0xCA, + 0x52,0xC5,0x90,0xAC,0x5E,0x5E,0x78,0x7A,0xB0,0xB4,0x0E,0x9C,0x5E,0xBA,0xE8,0xAF, + 0x6F,0xA4,0x4C,0x83,0x5E,0xEA,0xA8,0xA2,0x0E,0x9C,0x68,0x62,0x57,0xA8,0x00,0x00, + 0x0E,0x9C,0xE7,0x59,0x55,0x7F,0xE8,0x00,0xCD,0x93,0xC6,0x51,0x55,0x55,0xFF,0xA8, + 0x4C,0x83,0xE6,0x51,0x55,0x55,0xFF,0x00,0x2B,0x7B,0x07,0x5A,0x75,0xDD,0xFF,0x00, + 0x6C,0x83,0x06,0x52,0xFD,0xFF,0xBF,0x00,0xAD,0x8B,0x68,0x62,0xF5,0xDF,0xEF,0x00, + 0x0D,0x94,0xEA,0x72,0x75,0xF5,0xAD,0x2E,0xED,0x93,0x6B,0x83,0x3D,0xAF,0xB7,0x20, + 0x4E,0xA4,0xCC,0x93,0xBF,0x2F,0x2D,0xAF,0x6F,0xAC,0x0E,0x9C,0x2E,0x8B,0x9A,0xA2, + 0x6F,0xA4,0x0E,0xA4,0x6A,0xA8,0xFA,0xFE,0x2E,0x9C,0x8B,0x8B,0xFE,0x5C,0xFE,0xF8, + 0x2E,0xA4,0x8C,0x8B,0x2D,0x29,0xAF,0x2F,0x6F,0xA4,0x2E,0xA4,0x67,0x7B,0xEA,0xAB, + 0x23,0x49,0xE2,0x40,0x2E,0xAF,0x3E,0x2A,0x03,0x51,0x43,0x49,0xFA,0xBF,0xFF,0xFB, + 0x43,0x51,0x03,0x49,0xE7,0x7D,0xFF,0xEB,0x43,0x49,0x03,0x49,0x2E,0xF7,0x7D,0xFB, + 0x43,0x51,0x02,0x49,0xF6,0xBC,0xBF,0xBF,0x43,0x51,0x02,0x49,0xAA,0xEA,0xEB,0xEF, + 0x63,0x59,0x02,0x49,0xEA,0xAE,0x27,0xBF,0x63,0x59,0x02,0x49,0xFF,0xEB,0xAC,0xAB, + 0x43,0x51,0x02,0x49,0xFE,0x7C,0xC2,0x08,0x43,0x51,0xE2,0x48,0xBB,0xCD,0xAB,0xAB, + 0x64,0x59,0xE2,0x48,0xAA,0xAB,0xF9,0x77,0x23,0x51,0x02,0x49,0x52,0xD4,0xD7,0x95, + 0x43,0x51,0x03,0x49,0xFD,0x3F,0xFF,0x5F,0x43,0x51,0x03,0x49,0xB8,0xE7,0xB7,0x55, + 0x23,0x49,0xE2,0x40,0xA2,0xBF,0xF3,0xDA,0x23,0x51,0xE2,0x48,0xFC,0x56,0x7F,0xAF, + 0x43,0x51,0xE2,0x48,0xD5,0xD5,0xB5,0x2F,0x09,0x8B,0x23,0x51,0xB5,0x2D,0x0F,0x03, + 0x29,0x8B,0xC8,0x82,0xBD,0xE6,0x5C,0x7C,0xE8,0x82,0x87,0x7A,0xF8,0xC8,0x68,0xEA, + 0xC7,0x82,0x87,0x7A,0x7D,0xFD,0xAD,0xBD,0xA7,0x7A,0x66,0x72,0xB6,0x72,0x80,0xC0, + 0xA7,0x7A,0x66,0x72,0xEA,0x7B,0xAE,0xEE,0xA7,0x7A,0x46,0x7A,0xAA,0x8A,0xE8,0x20, + 0xA7,0x82,0x46,0x72,0xAA,0xAE,0x0A,0x0E,0xA7,0x7A,0x66,0x72,0xFB,0xBF,0xAA,0x0A, + 0xA7,0x7A,0x66,0x72,0xFF,0xAF,0xEA,0xA8,0x87,0x7A,0x67,0x72,0x80,0xC0,0x8A,0xAF, + 0x87,0x7A,0x46,0x72,0x68,0xE6,0x76,0xAF,0x67,0x7A,0x05,0x6A,0xAA,0x68,0xA8,0x22, + 0x09,0x8B,0x05,0x6A,0xFD,0xFF,0xFD,0x0F,0x89,0x9B,0x46,0x72,0xDD,0xAD,0x2B,0x02, + 0x8A,0x9B,0xC8,0x82,0xD5,0x2B,0x80,0x02,0x8A,0x9B,0x08,0x8B,0xF5,0xAE,0x8E,0x78, + 0x29,0x8B,0x05,0x6A,0x80,0x20,0xE8,0x7E,0xC8,0x82,0xE5,0x69,0xA0,0xEA,0xDF,0x55, + 0x46,0x6A,0xE6,0x69,0xFC,0xFF,0xDD,0xFF,0x26,0x6A,0xE5,0x61,0xFE,0xDA,0xAA,0x8A, + 0x26,0x6A,0xC5,0x59,0x0A,0xAA,0xAB,0xDA,0x46,0x6A,0x84,0x51,0x2A,0x20,0xA8,0x5F, + 0x67,0x72,0xA5,0x59,0x28,0xA8,0xEE,0x55,0x67,0x72,0xA5,0x59,0x20,0x0A,0xFB,0x55, + 0x67,0x72,0x84,0x51,0x00,0x00,0xBA,0x5D,0x87,0x72,0x84,0x51,0x00,0x00,0xBA,0x55, + 0xA8,0x7A,0x64,0x51,0x02,0xA8,0xFE,0x55,0x67,0x72,0x43,0x49,0xA0,0xA8,0xFF,0x55, + 0x06,0x62,0x44,0x49,0x00,0x00,0x2E,0xE5,0xC5,0x59,0x23,0x49,0xF8,0x78,0x78,0x78, + 0x65,0x49,0xE3,0x38,0x5F,0x7F,0xAA,0xAA,0x43,0x41,0xE3,0x38,0xFD,0xEF,0xFF,0xF8, + 0x24,0x41,0xC2,0x30,0xF7,0xE7,0xAC,0xAA,0x03,0x39,0xA2,0x30,0xAA,0xA8,0xE8,0xFA, + 0xE3,0x38,0xA2,0x28,0xA8,0xFC,0x7E,0x5F,0x03,0x39,0x81,0x20,0xA8,0xAE,0xD7,0x7D, + 0x03,0x31,0x81,0x20,0xFC,0xFE,0xFF,0x55,0xC2,0x28,0x61,0x20,0xFF,0xEA,0x78,0x5E, + 0x81,0x20,0x61,0x18,0xA8,0x28,0x80,0x76,0xA2,0x20,0x61,0x18,0xEA,0x7A,0x7F,0xFD, + 0x82,0x20,0x61,0x18,0xCD,0x0B,0x3B,0xBA,0xC2,0x28,0x82,0x20,0xFD,0xFD,0xBB,0x2B, + 0xE3,0x30,0x81,0x20,0xDD,0xF7,0xAB,0x0A,0xC2,0x28,0xA2,0x28,0xA7,0x35,0x95,0xAC, + 0xE3,0x30,0xA2,0x28,0xAA,0xAB,0xF9,0x80,0x03,0x31,0xC2,0x28,0x7D,0xEF,0xAE,0x2F, + 0xE2,0x30,0xA2,0x28,0x57,0x70,0xEC,0xE8,0xE3,0x28,0x82,0x28,0x5F,0xBF,0xBB,0xE2, + 0xC2,0x28,0x81,0x28,0xF5,0xD6,0xEA,0xA8,0xA2,0x28,0x81,0x20,0xFA,0xAA,0x0A,0x0C, + 0xC2,0x30,0x61,0x20,0xE9,0x8B,0x02,0x02,0xE3,0x30,0x81,0x28,0x7D,0x7B,0xE8,0xE0, + 0xC2,0x28,0x61,0x20,0xF7,0xBF,0xAA,0x8A,0xC2,0x30,0xA2,0x28,0xD5,0x75,0x8D,0xC3, + 0xC2,0x30,0xA2,0x28,0xBB,0x1F,0xDD,0x7F,0xC2,0x30,0xA2,0x28,0xF5,0xE2,0xF7,0xE5, + 0xE3,0x30,0xA2,0x28,0x2F,0x0F,0xBD,0x85,0x03,0x31,0xC2,0x30,0xAA,0x0A,0x0B,0x3D, + 0x03,0x31,0xC3,0x30,0xAA,0x08,0x2A,0xB7,0x24,0x39,0xE3,0x30,0x6B,0xFB,0xFF,0xED, + 0x24,0x39,0xE3,0x38,0xBD,0xBB,0x97,0x55,0x44,0x41,0xE3,0x38,0xF3,0xAA,0xEE,0xFD, + 0x03,0x39,0xE3,0x30,0xB5,0x0A,0x88,0x8C,0x24,0x41,0xC3,0x30,0xEF,0x2E,0x2F,0xB7, + 0x24,0x39,0xC2,0x30,0xC9,0xAE,0xB6,0xEA,0x03,0x39,0xC2,0x30,0x1B,0xF2,0x20,0x00, + 0x23,0x39,0xE2,0x30,0x76,0xBF,0x3F,0xF8,0xE2,0x30,0xC3,0x30,0x20,0x2D,0xB6,0xA8, + 0x03,0x39,0xC2,0x30,0x7A,0xAB,0xAF,0x6B,0x02,0x39,0xC2,0x30,0xAF,0x2E,0xB7,0xFF, + 0x03,0x39,0xC2,0x30,0x0F,0xAA,0xAF,0x73,0x24,0x41,0xC2,0x30,0xAA,0x0F,0x0A,0xA7, + 0x43,0x41,0xE3,0x38,0xFF,0xEF,0xF6,0xF8,0x43,0x41,0x03,0x41,0xFF,0x3D,0x26,0xA7, + 0x85,0x51,0x44,0x49,0x2F,0x8B,0x1F,0xDF,0x84,0x51,0x23,0x41,0x5C,0xE8,0xE3,0xA2, + 0x44,0x49,0x03,0x41,0xE2,0xA2,0x2C,0xB4,0x64,0x49,0x23,0x41,0xDD,0xEB,0xAB,0xAB, + 0x44,0x49,0x02,0x39,0xFE,0xD7,0xFA,0xFC,0x44,0x41,0x02,0x41,0x7F,0xEF,0xAB,0x8B, + 0x43,0x41,0xE3,0x38,0xB2,0xAA,0x82,0x0A,0x44,0x41,0xE2,0x38,0xDB,0xFE,0xAA,0xE0, + 0x64,0x49,0x03,0x39,0xD5,0xF5,0xBF,0x2D,0x64,0x49,0x23,0x41,0xF7,0x57,0xFA,0xF0, + 0x84,0x49,0x22,0x41,0x8D,0xA7,0x29,0xAB,0x64,0x51,0x43,0x41,0x3E,0xDE,0x6F,0x2F, + 0xA5,0x51,0x44,0x49,0xBB,0xF9,0xAB,0x8A,0xC5,0x59,0x84,0x51,0x2D,0xF5,0x0B,0x0B, + 0x68,0x72,0xA4,0x51,0x2B,0x2D,0xAD,0x3F,0xD1,0xBC,0x0A,0x83,0x2F,0x2D,0xAD,0xAD, + 0x73,0xCD,0x90,0xB4,0x2A,0x2B,0xED,0xFD,0x73,0xCD,0x11,0xBD,0xE2,0x8B,0x2B,0xA5, + 0x73,0xCD,0xB0,0xAC,0x7A,0xB8,0xA0,0x80,0x12,0xBD,0x6F,0xAC,0x77,0x5F,0xDA,0x80, + 0xF1,0xBC,0x4F,0xA4,0x5D,0xBF,0xAA,0x0A,0xD0,0xB4,0x2E,0xA4,0x9D,0xBF,0xBA,0x80, + 0xD0,0xB4,0x2E,0x9C,0x7F,0xAA,0xA2,0x08,0xD0,0xB4,0x2E,0x9C,0xD5,0xAA,0x88,0x08, + 0xD0,0xB4,0x2E,0x9C,0x77,0xFA,0xA8,0x80,0xB0,0xAC,0x0E,0x9C,0x55,0xEA,0xA8,0x0A, + 0x8F,0xAC,0x0D,0x94,0xD7,0xFA,0xA8,0xAA,0x6F,0xA4,0x2E,0x9C,0xF6,0xAA,0xC0,0xBA, + 0x6F,0xA4,0x0E,0x9C,0xF5,0xE2,0xEA,0xFA,0x4F,0xA4,0xED,0x93,0x7E,0xFC,0xAE,0xA2, + 0x6F,0xA4,0x0E,0x9C,0xBD,0xAD,0x8D,0xAF,0x6F,0xA4,0x2E,0xA4,0x68,0x93,0x8E,0x77, + 0x6F,0xA4,0x0E,0x9C,0xBA,0xFF,0x8F,0x3D,0x2E,0xA4,0xCC,0x93,0x5C,0x6A,0xEA,0x80, + 0x2E,0xA4,0xCC,0x93,0x25,0x3D,0x95,0x17,0x90,0xAC,0x2E,0xA4,0xEA,0x2A,0x29,0xAB, + 0x44,0x51,0x02,0x49,0xBC,0xAC,0xE6,0xB5,0x23,0x49,0xE2,0x48,0x28,0x00,0xF0,0xF0, + 0x43,0x51,0x02,0x49,0x2F,0xB6,0x77,0x75,0x23,0x51,0xE2,0x40,0xA8,0xAF,0x2D,0x2D, + 0x23,0x51,0x43,0x49,0xA0,0x2A,0x0B,0x78,0x84,0x59,0x23,0x51,0xD5,0x55,0xD5,0xDC, + 0x63,0x59,0x02,0x49,0xAE,0xE8,0xFA,0xDA,0x43,0x51,0x02,0x49,0x3E,0xB6,0x5A,0xE3, + 0x64,0x59,0x02,0x49,0x25,0xFB,0xBF,0xEF,0x23,0x51,0x02,0x49,0xA2,0xC2,0xA8,0x2A, + 0x23,0x51,0x02,0x41,0xF2,0x72,0xFF,0xDF,0x23,0x49,0x03,0x49,0x55,0x16,0x38,0x17, + 0x23,0x49,0x02,0x49,0x5A,0xF0,0x28,0xA0,0x43,0x49,0x03,0x49,0x55,0x55,0x15,0xFB, + 0x23,0x49,0xE2,0x48,0xE2,0xA2,0xA8,0xF1,0x23,0x49,0xE2,0x48,0xB9,0xB3,0xBA,0x2A, + 0xC8,0x82,0x02,0x49,0xF5,0xB5,0x2D,0x2F,0x4A,0x93,0xA7,0x7A,0xA9,0x8B,0xA2,0x8A, + 0x29,0x8B,0xC7,0x82,0x78,0xD8,0x78,0x5E,0xE8,0x82,0xA7,0x7A,0xFA,0x58,0x6A,0xAA, + 0xA7,0x7A,0x66,0x72,0x3C,0xE2,0x22,0x00,0xC7,0x82,0x66,0x72,0x7B,0x6F,0xAB,0xAF, + 0xC7,0x82,0x66,0x7A,0xFB,0xE9,0xEA,0xFE,0xA7,0x82,0x66,0x72,0x3E,0x36,0xDF,0xB6, + 0xA7,0x7A,0x87,0x7A,0xBD,0x35,0xFF,0xDC,0x87,0x7A,0x66,0x72,0x08,0x28,0x80,0x00, + 0xA8,0x7A,0x46,0x72,0xEA,0xB2,0xFE,0xD7,0x86,0x7A,0x25,0x6A,0x83,0xFA,0xFA,0x3E, + 0xE8,0x8A,0x46,0x72,0xDD,0xED,0xAF,0x2A,0x4A,0x93,0x47,0x72,0xD5,0xB7,0x2E,0x02, + 0xAB,0xA3,0xA8,0x82,0x3D,0xAB,0x8A,0x00,0xAA,0xA3,0x49,0x93,0xAF,0x8A,0xA2,0x72, + 0x8A,0x9B,0x27,0x72,0x00,0x80,0xE8,0x7E,0x49,0x93,0xC5,0x61,0xA8,0xFA,0x5F,0x55, + 0x66,0x72,0xC4,0x61,0xF8,0x7F,0xF7,0xDD,0x06,0x6A,0xC5,0x61,0xCE,0xAD,0xB5,0xDF, + 0x26,0x6A,0xC6,0x61,0xAA,0xA3,0xEA,0xDE,0x26,0x6A,0x23,0x49,0x00,0xA0,0x7A,0x5F, + 0xE5,0x61,0x23,0x49,0xE8,0x5F,0x55,0x55,0x64,0x51,0x23,0x49,0x7A,0x5A,0x55,0x55, + 0x64,0x49,0x03,0x41,0xA9,0xBE,0xA8,0xAF,0x43,0x49,0x23,0x41,0x00,0x8E,0xC9,0xCA, + 0x64,0x49,0x23,0x49,0xF5,0xED,0x5D,0xF3,0x43,0x49,0x03,0x41,0xCA,0x6B,0xEE,0xA2, + 0x43,0x49,0xE2,0x40,0x7A,0xBB,0xFA,0xE8,0x43,0x49,0xE2,0x40,0x72,0xFA,0x8F,0x2F, + 0x85,0x51,0x03,0x41,0xAD,0x07,0xAF,0xAA,0x85,0x51,0x23,0x41,0x70,0x6C,0xFB,0xEA, + 0x65,0x49,0xE3,0x38,0x0B,0xEA,0xBA,0x5E,0x44,0x41,0xE3,0x38,0xD8,0xAE,0xA7,0xDF, + 0x24,0x41,0xC2,0x30,0x28,0xEA,0x8A,0x5E,0xE3,0x30,0x81,0x20,0xA8,0x48,0x7A,0xDF, + 0xA2,0x28,0x81,0x20,0x82,0x0B,0x8B,0xC2,0xA2,0x28,0x81,0x20,0x50,0x56,0x76,0xA3, + 0xA2,0x20,0x81,0x20,0xE5,0xEF,0xBB,0xF0,0xA1,0x20,0x61,0x18,0xDA,0x5A,0x5A,0x7A, + 0x41,0x20,0x61,0x18,0xFD,0xDD,0x7F,0x77,0x81,0x20,0x41,0x18,0xAB,0x3B,0x2F,0x2B, + 0xA2,0x28,0x61,0x18,0xBF,0x3F,0xAF,0xAB,0xE3,0x28,0x82,0x20,0xA3,0xAB,0xFF,0xE7, + 0x03,0x31,0xA2,0x28,0x8F,0xEF,0xD5,0x5F,0x24,0x39,0xC2,0x28,0xBF,0xBF,0x09,0x89, + 0x03,0x31,0xC2,0x30,0xF8,0x98,0x5A,0x5C,0x03,0x39,0xC2,0x30,0xAF,0xF7,0xEE,0x83, + 0xE2,0x30,0xA2,0x28,0xFA,0x5A,0x6E,0xE0,0xC2,0x28,0x81,0x28,0x22,0xAA,0x9F,0xDE, + 0x03,0x31,0xC2,0x28,0x55,0x95,0x9D,0xB5,0x03,0x31,0xC2,0x28,0x55,0xF5,0xB6,0xAC, + 0x03,0x31,0xC2,0x28,0xFD,0xFA,0xFA,0xBE,0xE3,0x30,0xA2,0x28,0x7A,0x7C,0xEE,0xB6, + 0xC2,0x30,0x81,0x28,0x0B,0xAA,0xFA,0xF8,0xE3,0x28,0x81,0x28,0xFB,0xFF,0xFD,0x75, + 0xA2,0x28,0x81,0x28,0x20,0x20,0x2A,0x0B,0xA2,0x28,0x81,0x20,0x00,0xA0,0xA0,0xC2, + 0xC2,0x28,0x81,0x28,0x0B,0xAB,0xBF,0xAF,0x03,0x31,0xA2,0x28,0x3F,0xFF,0xFF,0x7D, + 0xE3,0x30,0xA2,0x28,0x34,0xAE,0xEB,0xDF,0x03,0x39,0xA2,0x28,0xAA,0xBF,0xFF,0xDD, + 0xE3,0x30,0xA2,0x28,0x02,0xA7,0xAD,0xB6,0x24,0x39,0xC2,0x30,0xAF,0x8D,0x8F,0xE5, + 0x24,0x39,0xE3,0x38,0xEF,0xEB,0xEB,0x7F,0x03,0x39,0xC2,0x30,0xFF,0xDA,0xFA,0xFF, + 0x24,0x39,0xC2,0x30,0xAB,0x2F,0xBF,0xBF,0x23,0x39,0xE3,0x38,0x2B,0x3A,0x3E,0xFE, + 0x23,0x39,0xE2,0x30,0xB0,0xA0,0xEA,0xFA,0x23,0x39,0xC2,0x30,0xFE,0xF8,0xFE,0xFB, + 0x03,0x39,0xC1,0x30,0xB7,0x2B,0xB3,0xAA,0x23,0x41,0xC2,0x30,0xAF,0xAE,0x29,0x8B, + 0x23,0x41,0xC2,0x30,0x52,0x78,0xAC,0xA8,0x03,0x39,0xA2,0x30,0x2B,0x8F,0xFA,0xF2, + 0x24,0x41,0xE3,0x38,0xFA,0x7A,0x7F,0xF7,0x64,0x49,0x03,0x41,0xB5,0x25,0x35,0x05, + 0x85,0x51,0x23,0x41,0xEF,0xFE,0x5C,0x5F,0x84,0x51,0x23,0x41,0xA2,0x2B,0xFF,0x75, + 0x44,0x49,0x03,0x41,0x2C,0xB4,0xB4,0xF6,0x44,0x41,0x03,0x41,0x20,0x00,0x28,0x2F, + 0x43,0x41,0xE3,0x38,0xA2,0xAA,0x86,0xFE,0x44,0x41,0x03,0x41,0x8A,0xEF,0x3F,0xD7, + 0x44,0x41,0x03,0x39,0x2E,0xBE,0xF4,0xF6,0x64,0x49,0x03,0x41,0x42,0x82,0x03,0xED, + 0xA5,0x51,0x03,0x41,0x2D,0xAF,0xEF,0xF5,0x85,0x51,0x23,0x41,0xAA,0x88,0xE2,0xF9, + 0xA5,0x51,0x43,0x41,0xBF,0x2E,0x2F,0xA5,0xC5,0x51,0x64,0x49,0xD5,0xEA,0x0A,0x8A, + 0xE5,0x59,0x84,0x51,0xED,0x3D,0x8B,0x0A,0x26,0x62,0xC5,0x59,0xDD,0xBE,0xFB,0x35, + 0x47,0x6A,0xC5,0x59,0x3F,0xAF,0xB6,0xB7,0x0E,0xA4,0x67,0x6A,0x0F,0x0F,0x29,0x0D, + 0xD1,0xBC,0x4F,0xAC,0x0B,0x2D,0xAD,0xFD,0x32,0xBD,0xB0,0xB4,0x2F,0x3F,0xF5,0xD5, + 0x73,0xC5,0xF1,0xBC,0x8A,0xBA,0xD7,0xD5,0x53,0xC5,0x11,0xBD,0xFE,0x2A,0x2F,0x37, + 0x73,0xCD,0x11,0xBD,0x75,0xAF,0xAA,0x80,0x73,0xC5,0xF0,0xB4,0x57,0x7E,0xAA,0x22, + 0x52,0xC5,0xAF,0xAC,0x5D,0x5E,0x5E,0x7C,0xD0,0xB4,0x8F,0xAC,0x2B,0x8B,0x3F,0x15, + 0xD0,0xB4,0x6F,0xAC,0xB2,0xBA,0xF8,0x7A,0xB0,0xAC,0x4E,0xA4,0xE8,0xE0,0xFA,0x56, + 0x8F,0xAC,0x2E,0xA4,0xBA,0xAB,0xEA,0x7D,0x6F,0xA4,0x2E,0xA4,0x3F,0xEA,0xA9,0x29, + 0x90,0xAC,0x2E,0x9C,0x7B,0x7E,0xAA,0x28,0x6F,0xAC,0xED,0x9B,0xFF,0x5F,0xEE,0xB0, + 0x4F,0xA4,0x0E,0x9C,0x3B,0xEA,0xDE,0x56,0x4F,0xA4,0x0D,0x9C,0x38,0x3C,0x23,0xFB, + 0x4E,0xA4,0x0E,0x9C,0x0A,0x0A,0xEB,0x7F,0x6F,0xAC,0x0D,0x9C,0x68,0xEA,0xBF,0xFF, + 0x2E,0xA4,0xCD,0x93,0x36,0xB8,0xAC,0xE0,0x8F,0xAC,0x2E,0x9C,0xAB,0x0D,0x39,0x25, + 0x23,0x49,0xE2,0x48,0x9C,0xC3,0x6B,0x2F,0x23,0x49,0xE2,0x40,0xB8,0x23,0xFE,0xEA, + 0x23,0x51,0xE2,0x40,0xFE,0xFF,0x9D,0x3D,0x43,0x51,0xE2,0x48,0xAD,0x2B,0xAB,0x88, + 0x63,0x51,0x23,0x51,0xFA,0x16,0x4F,0x6D,0x64,0x59,0x23,0x51,0xFE,0x67,0xEF,0xEE, + 0x63,0x59,0x03,0x49,0xF7,0xFF,0x7A,0xE8,0x43,0x51,0x02,0x49,0xB0,0xE0,0xBA,0xA9, + 0x43,0x51,0xE1,0x40,0xE2,0xEA,0xA2,0xF8,0x23,0x51,0x02,0x49,0x69,0x0A,0x2D,0x5D, + 0x43,0x51,0xE2,0x40,0xDE,0xFF,0x2E,0xBE,0x02,0x49,0xE2,0x40,0xBC,0x28,0x38,0xB0, + 0x23,0x49,0xE2,0x40,0xB0,0x0A,0x0A,0xBE,0x03,0x49,0x22,0x41,0x0A,0x08,0x8A,0xA0, + 0x23,0x49,0xC2,0x40,0xBE,0xAF,0x3F,0x97,0x47,0x72,0x02,0x49,0xD5,0xF5,0xB5,0x2D, + 0x29,0x8B,0xA4,0x61,0x2D,0x0B,0x02,0x00,0x4A,0x93,0xC8,0x82,0xAA,0xEA,0x7E,0xDC, + 0x09,0x8B,0xC8,0x82,0x78,0xAF,0xEF,0x77,0xE8,0x82,0xA7,0x82,0xAA,0x58,0x5B,0xFB, + 0xE8,0x82,0x87,0x7A,0x7E,0xFB,0xF2,0x80,0xC8,0x82,0x87,0x7A,0xFE,0x6A,0x42,0xAB, + 0xC8,0x82,0x87,0x7A,0xDF,0x7F,0x5B,0xF8,0xC8,0x82,0x87,0x7A,0x55,0xD5,0xAF,0xBB, + 0xC7,0x7A,0x66,0x7A,0xBA,0xA2,0x6A,0x7A,0xA7,0x7A,0x46,0x72,0xE2,0xFA,0xFB,0x7A, + 0x66,0x7A,0x46,0x72,0x75,0x56,0xD8,0x1E,0x6B,0x9B,0x45,0x72,0xD5,0xF5,0xBD,0x2B, + 0xAB,0xA3,0xC7,0x82,0xB5,0xAF,0x2A,0x00,0xCB,0xA3,0x6A,0x9B,0xA9,0x8B,0x28,0xA8, + 0xAB,0xA3,0x09,0x8B,0x88,0xA0,0xE8,0x58,0x6A,0x9B,0xE5,0x69,0x80,0xE0,0x78,0x5F, + 0x87,0x7A,0xA5,0x61,0xF8,0x5E,0xD5,0x57,0xE6,0x69,0xA5,0x61,0x72,0x7E,0xFA,0xEF, + 0xE6,0x61,0xA4,0x61,0x5E,0x9F,0xA9,0x2A,0x26,0x6A,0x83,0x59,0xF7,0xBF,0xAA,0xCA, + 0xE5,0x61,0x43,0x51,0xE8,0xF8,0x7A,0xFB,0x64,0x51,0x03,0x41,0xFC,0xF6,0xFA,0x8A, + 0x64,0x49,0x03,0x41,0x5D,0x57,0xBF,0x2F,0x64,0x49,0x03,0x41,0xED,0x82,0x20,0xB0, + 0x64,0x49,0x23,0x41,0xEF,0xEB,0x7C,0xFE,0x43,0x49,0x03,0x41,0x8C,0xEA,0xBA,0xC6, + 0x44,0x49,0x03,0x41,0xAA,0xCA,0x7B,0x5D,0x43,0x41,0x03,0x41,0xFA,0xFA,0x79,0x7F, + 0x43,0x49,0x03,0x41,0x7A,0xFE,0x5F,0xDD,0x44,0x49,0xE3,0x38,0x27,0xAB,0xEF,0xBE, + 0x64,0x49,0x03,0x41,0x0A,0xAA,0xA9,0x8B,0x85,0x51,0x23,0x41,0xF0,0xFF,0xF7,0x55, + 0x23,0x41,0xC3,0x30,0xF8,0xAA,0xA8,0x7C,0x03,0x39,0xA2,0x30,0x2A,0xA8,0xBE,0xD7, + 0xE3,0x30,0xA2,0x28,0xEC,0xFE,0x7A,0xC0,0xA2,0x28,0x61,0x20,0xA8,0xFA,0xF8,0xFA, + 0xA1,0x20,0x60,0x20,0x82,0x02,0x29,0xAB,0xC2,0x28,0x81,0x20,0xE2,0x75,0xF7,0x55, + 0xA2,0x20,0x81,0x20,0xF0,0x7B,0x58,0x57,0x81,0x20,0x61,0x18,0xE8,0xAC,0xAA,0xCF, + 0xA2,0x20,0x41,0x18,0xFE,0xBE,0xA7,0x2F,0xA2,0x20,0x61,0x20,0xAF,0xBA,0xA0,0x00, + 0xA2,0x28,0x81,0x20,0x35,0xED,0xCA,0x08,0xE3,0x30,0xA2,0x28,0xF5,0xE5,0x3D,0x2A, + 0x03,0x31,0xA2,0x28,0x7F,0x7F,0x78,0xE0,0x24,0x39,0xA2,0x28,0x0F,0x09,0x09,0x2F, + 0x44,0x41,0xC2,0x30,0x5C,0x58,0xFC,0x5C,0x03,0x39,0xC2,0x30,0x81,0x80,0x8A,0xFA, + 0x03,0x39,0xA2,0x28,0x5A,0xFA,0xFA,0xFE,0xC2,0x30,0x81,0x28,0x5B,0x7E,0xBF,0xAA, + 0xE2,0x30,0x81,0x20,0x25,0x8B,0xBF,0xFF,0x03,0x31,0xA1,0x28,0xAE,0x2E,0x9D,0xD5, + 0xE2,0x30,0xA2,0x28,0x22,0xA0,0xFA,0x7E,0xC2,0x30,0xA2,0x28,0x2A,0x2A,0xEE,0xBE, + 0xE3,0x30,0xA2,0x28,0x5F,0x5F,0x7A,0x5A,0xA2,0x28,0x82,0x20,0xF2,0x60,0xC0,0x00, + 0xA2,0x28,0x81,0x20,0x2E,0x9E,0x7F,0xCB,0xC2,0x28,0x81,0x20,0xEB,0x8F,0x89,0xA3, + 0xC2,0x28,0xA2,0x28,0xF7,0x6D,0xC9,0xE9,0xC1,0x28,0x82,0x28,0xAA,0xDA,0xFE,0xFE, + 0xE3,0x30,0xA2,0x28,0x57,0x7F,0x6B,0x59,0xC2,0x30,0xA2,0x28,0xAB,0xAF,0xC9,0x88, + 0xC2,0x30,0xA2,0x28,0xAC,0xAC,0xAB,0x8B,0xE2,0x38,0xA2,0x28,0xAB,0x3F,0xBF,0xBF, + 0x03,0x39,0xC2,0x30,0xAA,0x5F,0x7F,0x55,0xE3,0x38,0xA2,0x30,0x88,0xEA,0xDA,0xFF, + 0xE3,0x38,0xC2,0x30,0x3E,0x59,0xFF,0x6D,0x03,0x39,0xC2,0x30,0xF2,0xB2,0xB5,0x0D, + 0x23,0x39,0xE3,0x38,0x8F,0xB7,0xFE,0x8F,0x23,0x39,0xC3,0x30,0xF8,0xAA,0xBE,0xEB, + 0x02,0x41,0xE3,0x30,0x55,0x7F,0xDF,0xFD,0x23,0x41,0xE2,0x30,0x09,0x2F,0x3F,0xAF, + 0x24,0x41,0xE2,0x38,0xE8,0xEC,0x77,0x4D,0x03,0x39,0xC2,0x30,0xAC,0xE7,0x6B,0x7F, + 0x23,0x41,0xC2,0x30,0xAA,0x2F,0x3D,0xD5,0x64,0x49,0xE3,0x38,0x2F,0xAA,0x03,0x0F, + 0xA5,0x51,0x43,0x41,0x5B,0x60,0xFE,0xAA,0x64,0x49,0x03,0x41,0xFB,0xDA,0xA8,0xBC, + 0x44,0x49,0xC2,0x38,0xAF,0xFE,0xD4,0xFA,0x44,0x41,0xE2,0x38,0x2B,0x2F,0xEF,0x7F, + 0x44,0x41,0xC2,0x38,0xFC,0x5E,0xF7,0xEF,0x03,0x39,0xC2,0x38,0xBA,0xFF,0x7A,0xE2, + 0x24,0x41,0xE3,0x38,0xEA,0x7F,0xDD,0xFF,0x23,0x41,0xE3,0x38,0x89,0x5D,0x5F,0xCD, + 0x03,0x39,0xC2,0x30,0x8A,0xFF,0xFF,0xAA,0x43,0x41,0xE2,0x38,0x37,0x27,0xED,0xAD, + 0x64,0x49,0x02,0x41,0xA8,0xEB,0xEF,0xF5,0xA4,0x51,0x23,0x41,0x8B,0x2E,0x7B,0xDF, + 0xC5,0x51,0x43,0x41,0x2A,0xAF,0xEB,0x5D,0xE6,0x61,0x63,0x49,0x0A,0xAA,0xFF,0xD5, + 0xE6,0x61,0x43,0x49,0x20,0xBB,0xDF,0xDF,0xED,0x9B,0x06,0x62,0x2F,0x29,0x2D,0x2D, + 0x8F,0xAC,0xED,0x9B,0x0B,0xAA,0xA9,0xAB,0xD0,0xB4,0x4E,0xAC,0x2E,0xAF,0x37,0xDD, + 0xF1,0xBC,0x90,0xAC,0x00,0x00,0xAB,0xBD,0x52,0xC5,0xB0,0xB4,0x2E,0x9F,0x57,0xFB, + 0x73,0xCD,0xF1,0xB4,0x82,0x02,0xAD,0xB5,0x73,0xC5,0x32,0xC5,0xFD,0xD6,0x7E,0xA9, + 0x52,0xC5,0xB0,0xB4,0x5A,0x7A,0xE8,0xA8,0xF1,0xBC,0x6F,0xAC,0xF7,0xD7,0xFE,0x58, + 0x90,0xAC,0x4F,0xA4,0x0F,0xFA,0x6A,0xF8,0x8F,0xAC,0x2E,0xA4,0xEA,0x6F,0x6A,0x3A, + 0x6F,0xAC,0x0E,0x9C,0xFF,0xFD,0xAE,0xA8,0x4E,0xA4,0x0D,0x9C,0x2A,0x72,0xFA,0xA0, + 0x90,0xAC,0x2E,0xA4,0x2E,0xA3,0xA5,0xBF,0x90,0xAC,0x0D,0x9C,0x9A,0x82,0x0A,0x0A, + 0x90,0xAC,0x2E,0x9C,0x5F,0xFB,0xA2,0xA8,0x6F,0xAC,0x0D,0x9C,0xEF,0xDE,0xDE,0xBC, + 0x4E,0xA4,0x0E,0x9C,0xFF,0xEE,0xA8,0x00,0x4F,0xA4,0xED,0x9B,0x2A,0x8A,0xCE,0x60, + 0x4E,0xA4,0x0E,0x9C,0x7F,0x5F,0xB8,0x3F,0x6F,0xAC,0x0E,0x9C,0x09,0x29,0xA9,0xAD, + 0x23,0x49,0xE2,0x40,0xA3,0x35,0xFE,0xF6,0x43,0x51,0xC2,0x40,0xFA,0xDE,0xAD,0x2B, + 0x43,0x51,0xE2,0x40,0xAD,0x3F,0x0B,0x02,0x64,0x59,0x23,0x51,0xBD,0x8A,0x2A,0xAB, + 0x84,0x59,0x02,0x49,0xFE,0xF6,0xFC,0xEA,0x64,0x51,0x22,0x51,0xBF,0xB7,0x15,0xF7, + 0x63,0x59,0x23,0x51,0xD0,0xB8,0xDA,0xFF,0x43,0x51,0x23,0x49,0x53,0x63,0x68,0x7E, + 0x23,0x49,0x03,0x49,0xB8,0xAF,0x31,0xAF,0x23,0x49,0x02,0x49,0xD7,0x97,0x24,0x8C, + 0x23,0x49,0xE2,0x48,0x90,0xA2,0xA8,0xAA,0x23,0x49,0xE2,0x40,0x76,0xBA,0xA2,0x0A, + 0x23,0x49,0xE2,0x40,0xF3,0xF2,0xF0,0xB8,0x44,0x51,0xE2,0x40,0xD7,0xFF,0xCF,0xE8, + 0xA4,0x59,0x03,0x49,0x55,0x55,0xD5,0x15,0xAC,0xA3,0x43,0x51,0xA5,0x2F,0x83,0x0A, + 0x49,0x93,0x08,0x8B,0x5B,0x5E,0x5E,0x56,0x08,0x8B,0xC8,0x82,0xD8,0xDA,0x02,0x03, + 0xE8,0x8A,0xC8,0x82,0xFE,0xFE,0x40,0x6B,0xC7,0x82,0xA7,0x82,0xC0,0x88,0xC9,0xEE, + 0xC7,0x82,0xA7,0x7A,0x00,0xEC,0xF9,0x1A,0xC7,0x82,0x87,0x7A,0x1B,0x88,0xA0,0x00, + 0xC7,0x82,0x86,0x7A,0xEF,0x9E,0xDA,0xDC,0xE7,0x82,0x86,0x7A,0xF7,0x77,0x54,0x5F, + 0xA7,0x82,0x45,0x7A,0xE8,0xFB,0x7F,0xFE,0xE8,0x8A,0x45,0x72,0x55,0xF5,0xBF,0x2F, + 0xAB,0xA3,0x66,0x7A,0xD5,0xB5,0x2B,0x02,0xCB,0xA3,0x29,0x93,0xA5,0xA3,0x00,0x00, + 0xCB,0xA3,0x6A,0x9B,0x2B,0x0A,0x02,0x78,0xCB,0xA3,0xA7,0x7A,0x80,0xA0,0xE8,0x5E, + 0x49,0x93,0x06,0x6A,0xE0,0x7E,0x5F,0x57,0x27,0x72,0x84,0x59,0xA8,0xEE,0xFE,0x5E, + 0xC5,0x61,0x64,0x59,0x28,0xE8,0xAB,0xA7,0x06,0x6A,0xA4,0x59,0xEF,0xBD,0x9D,0x35, + 0x06,0x6A,0xC5,0x61,0x0B,0x6A,0x7B,0x58,0x06,0x6A,0xA5,0x59,0xC8,0xEA,0x6A,0x5C, + 0xA5,0x59,0x44,0x49,0x48,0xFC,0xEC,0x7C,0x64,0x51,0x44,0x49,0xAD,0xF2,0xD0,0xF5, + 0x64,0x49,0x23,0x49,0xFA,0x5C,0xF7,0xAE,0x64,0x49,0xE2,0x40,0xAA,0xAB,0xAE,0xFC, + 0x43,0x49,0x03,0x41,0xAA,0xAA,0xEA,0x7A,0x43,0x49,0x02,0x41,0x0A,0xCB,0xEB,0xFA, + 0x43,0x49,0x03,0x41,0x5A,0xEF,0xFF,0x7F,0x24,0x49,0xE3,0x40,0x8E,0xEF,0xAF,0xAF, + 0x23,0x49,0xE2,0x40,0x9F,0xAE,0x3A,0xFE,0x43,0x41,0xE3,0x40,0x1F,0xB7,0xBF,0xEF, + 0x64,0x49,0x03,0x41,0xC2,0xE2,0xFB,0xFA,0x44,0x49,0xE2,0x38,0xF8,0xFC,0x5E,0x75, + 0x03,0x39,0xA2,0x30,0xF8,0xB8,0xDB,0xFD,0xC2,0x30,0xA2,0x30,0x3E,0x3E,0x2C,0x8A, + 0xE3,0x30,0xC2,0x30,0xEB,0xDF,0x89,0x83,0xC2,0x28,0x61,0x20,0xFE,0xD8,0xD8,0xF8, + 0x81,0x20,0x61,0x18,0x00,0x28,0x28,0xA0,0x81,0x20,0x61,0x18,0x28,0xA8,0xAA,0xCB, + 0x81,0x20,0x61,0x18,0x80,0xE8,0xFF,0x55,0x82,0x20,0x61,0x18,0xEB,0x2B,0x89,0x35, + 0x82,0x20,0x61,0x18,0x0A,0x0F,0x28,0x08,0xA2,0x28,0x82,0x18,0x22,0x01,0x02,0x82, + 0xA2,0x28,0x82,0x20,0x0A,0x8B,0xAF,0xFA,0xE3,0x30,0x81,0x28,0x28,0xA2,0xFF,0x97, + 0x03,0x31,0xA2,0x28,0x80,0x8F,0x8D,0xAF,0x24,0x39,0xC2,0x30,0x35,0xB7,0xB5,0x55, + 0x03,0x39,0xA2,0x28,0xF0,0xF0,0x7E,0xDA,0xE2,0x38,0xA2,0x30,0xF2,0xE2,0xEB,0x60, + 0x04,0x39,0xA2,0x28,0xFE,0xEA,0x8F,0xB5,0x03,0x39,0xA2,0x28,0xFF,0xEF,0xA2,0xA2, + 0x02,0x31,0x80,0x28,0x7F,0x7E,0xB8,0xA8,0xC2,0x30,0xA1,0x28,0x9D,0xD5,0x7F,0xE8, + 0xC2,0x28,0x81,0x20,0xF8,0xEE,0x7A,0xE0,0xE3,0x28,0x81,0x28,0xFF,0xFF,0xB5,0xF5, + 0xC2,0x28,0x82,0x20,0xE0,0x68,0x6A,0xAE,0xC2,0x30,0xA2,0x28,0xD5,0xB5,0xE5,0xA9, + 0xC2,0x30,0xA2,0x28,0x75,0x55,0xBD,0xFE,0xE3,0x30,0x81,0x28,0xFF,0xF7,0xBF,0x8B, + 0xC2,0x30,0xA2,0x28,0x75,0xF4,0xE0,0x5F,0xC2,0x28,0x81,0x20,0xF6,0x8F,0x82,0xEA, + 0xC2,0x30,0xA2,0x28,0x2B,0xAA,0x81,0xDB,0xE3,0x30,0xA2,0x28,0xFB,0x2F,0x3A,0x56, + 0xE2,0x30,0xA2,0x28,0xEF,0xF5,0x37,0xAF,0x03,0x39,0xC2,0x30,0x55,0x65,0xCB,0xAF, + 0xE2,0x30,0xA2,0x28,0xBB,0xF5,0xEF,0xF8,0xE2,0x30,0xA2,0x30,0xFF,0xAA,0xA3,0xA8, + 0x03,0x39,0xC2,0x30,0xE9,0xF9,0x7F,0xDD,0x44,0x41,0xC2,0x30,0xB5,0x3D,0x2F,0xBF, + 0x44,0x41,0x03,0x39,0x6F,0xAA,0x8E,0x09,0x44,0x41,0xE3,0x38,0xFB,0x6B,0xEA,0xE2, + 0x03,0x39,0xC2,0x30,0xAB,0x87,0x3F,0xBB,0x23,0x39,0x02,0x39,0xE9,0x69,0x59,0x42, + 0x03,0x39,0xC2,0x30,0x68,0xB8,0x0E,0xAC,0x03,0x39,0xC2,0x30,0xDF,0xBE,0x9C,0xCC, + 0x03,0x39,0xA2,0x30,0x7D,0xF7,0xEB,0xF3,0x64,0x49,0xC2,0x30,0x0D,0x3D,0x2D,0x2F, + 0xC5,0x59,0x64,0x49,0x73,0xE8,0xEB,0x8E,0x85,0x51,0x03,0x41,0xDA,0x7A,0xD0,0xA8, + 0x24,0x41,0xC2,0x38,0xA0,0x82,0x60,0xEA,0x03,0x39,0xC2,0x30,0xE0,0xE2,0xA9,0x25, + 0x03,0x41,0xE2,0x30,0x37,0x8F,0xF9,0xF5,0x44,0x41,0xE3,0x38,0xE5,0xA9,0x29,0x0B, + 0x23,0x39,0xE2,0x38,0xAA,0xEA,0x78,0xE8,0x23,0x39,0xE2,0x38,0x95,0x97,0xBF,0xFB, + 0x24,0x41,0xC2,0x30,0xB7,0xBE,0xFF,0x2B,0x64,0x49,0xE3,0x38,0xE5,0xEF,0xAB,0x2A, + 0x85,0x49,0x23,0x41,0xFF,0xF5,0x2B,0x0A,0x84,0x49,0x44,0x49,0x5F,0x8B,0x01,0x8A, + 0x64,0x49,0x23,0x41,0xE2,0x68,0xE2,0x08,0xE6,0x59,0x44,0x49,0xFD,0x7F,0xEF,0x0B, + 0xC5,0x59,0x64,0x49,0x96,0xF5,0xA2,0x0C,0xAC,0x93,0xA4,0x51,0x2D,0x3D,0xAD,0xAD, + 0x6F,0xAC,0xCD,0x93,0x8A,0x89,0xA9,0x8D,0x6F,0xAC,0x2E,0xA4,0x8A,0x3A,0x27,0xA5, + 0xB0,0xB4,0x2E,0xA4,0x0A,0xAA,0xBF,0x5F,0x31,0xBD,0x4F,0xA4,0x22,0x2A,0xAD,0xF5, + 0x52,0xC5,0xD0,0xB4,0xAF,0xAA,0xA2,0x89,0x32,0xC5,0xD0,0xB4,0x0A,0x00,0x6E,0xF8, + 0x52,0xC5,0xD0,0xB4,0xE8,0xAA,0xFF,0x7F,0xD0,0xB4,0x6F,0xAC,0x78,0xF8,0xE8,0xAE, + 0xB0,0xAC,0x6F,0xAC,0x7F,0xEB,0xBE,0xAA,0xB0,0xB4,0x4E,0xA4,0xF5,0xFE,0xB2,0xE0, + 0x8F,0xAC,0x4F,0xA4,0x7A,0x7A,0xBD,0xDD,0x6F,0xAC,0x2E,0xA4,0x9E,0x2E,0x28,0x2A, + 0x90,0xAC,0x4F,0xA4,0x55,0x0A,0x0E,0xAC,0x8F,0xAC,0x4F,0xA4,0xBF,0xFE,0xE9,0xAF, + 0x8F,0xAC,0x4F,0xA4,0xDB,0xEE,0xFE,0xAA,0x8F,0xAC,0x2E,0xA4,0xDA,0xF2,0x2A,0xCB, + 0x90,0xAC,0x4E,0xA4,0xFF,0x5A,0xD2,0xB7,0x6F,0xAC,0x2E,0xA4,0x5C,0xEE,0xC2,0xA3, + 0x8F,0xB4,0x0E,0xA4,0xF5,0x6B,0xEB,0x8A,0x6F,0xAC,0x2E,0xA4,0xAD,0xF9,0x9A,0x80, + 0x02,0x49,0xE2,0x40,0xF6,0xDC,0xF5,0x35,0x84,0x59,0x03,0x49,0xAD,0x35,0xB5,0xAD, + 0x63,0x59,0x43,0x51,0x6F,0xC2,0xE9,0x77,0x64,0x59,0x23,0x51,0xF2,0xE3,0xFF,0xFE, + 0x84,0x59,0x22,0x51,0x56,0xD7,0xF7,0xF7,0x63,0x59,0x02,0x49,0x7A,0x3E,0xFA,0xF8, + 0x43,0x51,0x02,0x49,0x8A,0xA8,0x3A,0x7E,0x43,0x49,0x02,0x49,0x7B,0xF8,0xD8,0x95, + 0x23,0x49,0x02,0x49,0x36,0x0F,0x07,0x1F,0x43,0x51,0x03,0x49,0x6F,0x6A,0x5E,0x55, + 0x23,0x49,0xE2,0x40,0xFE,0xAB,0x0A,0x2E,0x23,0x49,0xC1,0x40,0x8E,0xB6,0x8E,0xA8, + 0x43,0x49,0xE2,0x40,0x3E,0xDF,0xDF,0xFF,0x23,0x49,0xE2,0x40,0xE0,0xE0,0xE2,0xF2, + 0xA7,0x7A,0x02,0x41,0x95,0xB5,0x25,0x25,0x0C,0xAC,0x2A,0x8B,0x89,0x83,0x02,0x02, + 0xAB,0xA3,0x08,0x8B,0x5F,0xE8,0xF8,0xBA,0x69,0x93,0xE7,0x8A,0x5F,0xFE,0x68,0xA2, + 0x08,0x8B,0xC8,0x8A,0xEF,0xF8,0xE0,0xB0,0xE8,0x8A,0xA7,0x82,0xBF,0xAE,0xFC,0xDA, + 0xE7,0x82,0x86,0x7A,0x6B,0xEA,0x2A,0xAF,0xE8,0x82,0xA7,0x7A,0x77,0x57,0xF8,0x6E, + 0xC7,0x82,0x86,0x7A,0x6E,0x7A,0xF8,0x58,0xA6,0x82,0x66,0x7A,0x92,0xDA,0xE5,0xEB, + 0x29,0x93,0x86,0x7A,0x55,0x55,0xF5,0x0F,0xAB,0xA3,0x87,0x82,0xA5,0x2F,0x0A,0x02, + 0xCB,0xA3,0x8A,0x9B,0xA9,0x0F,0x28,0x00,0xEC,0xAB,0x8A,0x9B,0xE8,0xB8,0xFE,0x5E, + 0x8B,0x9B,0x26,0x72,0x80,0xE0,0x78,0x56,0xC8,0x82,0x26,0x6A,0x78,0x56,0x55,0x55, + 0x47,0x72,0x05,0x6A,0x7E,0xB7,0x75,0x57,0xE5,0x69,0x84,0x59,0x7A,0x78,0x7C,0xD6, + 0xC5,0x61,0x84,0x59,0x2F,0x2D,0x2A,0xAF,0x05,0x6A,0xA4,0x59,0x2B,0xAF,0x2F,0x2D, + 0x26,0x6A,0xC5,0x61,0x5E,0xDC,0x7E,0x5E,0x06,0x6A,0x64,0x51,0x78,0x7B,0x5F,0x5F, + 0x85,0x59,0x23,0x41,0xF0,0xFA,0x7E,0x5F,0x64,0x49,0x23,0x49,0xA9,0x15,0xB5,0x2E, + 0x64,0x49,0x23,0x41,0xB7,0xB6,0x3A,0x82,0x64,0x49,0x03,0x41,0xFC,0x60,0xAB,0xAA, + 0x43,0x49,0x03,0x41,0x5B,0x7D,0x72,0xAA,0xA5,0x51,0x02,0x41,0x7F,0x7F,0xBF,0x0B, + 0xC5,0x61,0xC2,0x38,0xFF,0xFF,0x8A,0x00,0xE6,0x61,0xE2,0x40,0xD5,0xFF,0xAB,0x00, + 0xE5,0x59,0x23,0x41,0x55,0xDF,0xAA,0x00,0xC6,0x59,0x03,0x41,0x55,0xFF,0xA0,0x80, + 0x64,0x49,0x03,0x41,0x7A,0xFE,0xBC,0xFE,0x23,0x41,0xC2,0x38,0xFB,0x9A,0xFE,0xF0, + 0x03,0x39,0xA2,0x28,0xFF,0x7C,0x74,0x56,0xE3,0x30,0xA2,0x28,0xB9,0x2B,0xB9,0xFD, + 0xE3,0x30,0xA2,0x28,0xA8,0xFA,0xF0,0x79,0xC2,0x28,0x81,0x20,0x5A,0x7E,0x7A,0x5F, + 0xA2,0x20,0x61,0x20,0xFF,0xFA,0xEA,0x83,0xA2,0x20,0x61,0x18,0xCB,0xEA,0x7F,0xEE, + 0x61,0x18,0x41,0x18,0xAB,0x2F,0x0F,0x08,0xA2,0x20,0x41,0x18,0xFF,0xDF,0xFF,0x2E, + 0xC2,0x28,0x82,0x20,0xF9,0xA9,0xAB,0x8A,0xC2,0x28,0x81,0x20,0xEB,0xBA,0xE8,0xEE, + 0xA2,0x28,0x82,0x20,0xBC,0x94,0x3D,0x3F,0xA2,0x28,0x81,0x28,0x0E,0x88,0xB8,0x80, + 0xE3,0x30,0x81,0x28,0x8B,0xAB,0x7F,0xFF,0xC2,0x30,0x82,0x28,0x3A,0xAF,0x8F,0x0F, + 0xE2,0x30,0xA2,0x28,0xDE,0x9D,0x2D,0x8B,0xE3,0x30,0xA2,0x30,0xF0,0xFA,0xFE,0xDF, + 0xE3,0x30,0xA2,0x30,0xAD,0xAA,0xBA,0xFE,0x03,0x39,0xC2,0x30,0xAA,0x83,0x03,0xA1, + 0xE2,0x30,0xC2,0x30,0xF8,0xE0,0x00,0x00,0x03,0x39,0xA1,0x28,0xFF,0xDF,0xD7,0x72, + 0x03,0x39,0xA2,0x28,0x7B,0xFF,0xAB,0x2B,0x04,0x39,0xA2,0x28,0x55,0x57,0x7E,0xF8, + 0xC2,0x30,0xA2,0x28,0xFD,0x3D,0x9A,0x9A,0xE3,0x30,0xA2,0x28,0xE9,0x7F,0xFA,0x68, + 0xC2,0x30,0xA2,0x28,0xAA,0xAF,0x2D,0xAE,0xE2,0x30,0xA2,0x28,0x8B,0xEF,0xEE,0xFF, + 0xC2,0x30,0xA2,0x28,0xD7,0xA5,0xA6,0xF7,0xE3,0x30,0x81,0x28,0x2B,0x7A,0x7F,0xFF, + 0xC2,0x28,0x81,0x28,0x3B,0xA9,0xFD,0xAD,0xC3,0x30,0x82,0x28,0xB8,0xAE,0xFA,0xFE, + 0xC2,0x28,0x81,0x28,0x00,0x22,0xAF,0x0F,0xE2,0x30,0xC2,0x28,0xAF,0x9F,0x27,0x25, + 0xE2,0x30,0xC2,0x30,0xD4,0xF0,0xA2,0xFD,0xE2,0x30,0xA2,0x30,0xC8,0x80,0x80,0xA2, + 0x03,0x39,0xA2,0x30,0xEF,0xFD,0xAA,0xE8,0x03,0x39,0xC2,0x30,0xA7,0xD7,0xEF,0xEF, + 0x24,0x39,0xC3,0x30,0xAB,0x2F,0x3B,0xFF,0x44,0x41,0x03,0x39,0xEA,0xEA,0xEB,0x7D, + 0x03,0x39,0xC2,0x30,0xBA,0x3E,0xE6,0x54,0x23,0x39,0xE2,0x30,0xA0,0xEA,0xB5,0xF7, + 0x02,0x39,0xC2,0x30,0xBE,0x9E,0xBB,0xFA,0x03,0x39,0xC2,0x30,0x08,0xA2,0xD8,0xDA, + 0xE2,0x38,0x03,0x31,0x08,0x80,0x80,0x6A,0x85,0x51,0x03,0x39,0x25,0x25,0xBD,0xBD, + 0xA5,0x51,0x44,0x41,0x02,0xCA,0x7B,0x5F,0x85,0x49,0x24,0x41,0xE8,0xE2,0xEA,0xDF, + 0x44,0x49,0xC3,0x38,0xEE,0x7A,0x7A,0xEC,0x03,0x39,0xC2,0x30,0x24,0x0F,0x2F,0xA9, + 0x03,0x39,0xC2,0x30,0x3C,0xE8,0xEF,0xAF,0x23,0x39,0xE3,0x38,0x02,0x3D,0xFB,0xE6, + 0x24,0x41,0xE3,0x38,0xC8,0xFA,0xF7,0xF5,0x03,0x39,0xC2,0x30,0xA2,0x2C,0xF7,0xFF, + 0x24,0x41,0x03,0x39,0xB7,0xA3,0x0B,0xA5,0x64,0x49,0x24,0x41,0xBD,0xF5,0xAD,0x29, + 0xA5,0x51,0x23,0x41,0xA9,0x0B,0x03,0x00,0xE6,0x59,0x85,0x51,0x55,0xFD,0xAD,0x3F, + 0xE6,0x59,0x43,0x49,0xD7,0xBA,0xB8,0xA0,0xE6,0x59,0xA5,0x51,0x89,0x0A,0x82,0xAB, + 0x06,0x62,0xA5,0x49,0xBF,0xB2,0xAF,0xFE,0x4B,0x83,0xE5,0x59,0x2D,0x2D,0x2D,0x2D, + 0x2E,0xA4,0x8C,0x8B,0x2B,0xAD,0xAF,0xAD,0x4F,0xA4,0xED,0x9B,0x0E,0xA7,0xBD,0xF5, + 0x6F,0xAC,0x0E,0xA4,0x0B,0xAF,0x7F,0xDF,0x8F,0xAC,0x2E,0xA4,0x27,0xAA,0xAB,0xFD, + 0xF1,0xBC,0x0E,0xA4,0x0A,0xAF,0xBF,0xD7,0xF1,0xBC,0xB0,0xB4,0xA8,0xBB,0xBB,0x95, + 0x11,0xBD,0xB0,0xB4,0x02,0x0A,0x2A,0xBD,0x31,0xBD,0xB0,0xB4,0x57,0x7C,0xFA,0xAA, + 0xF0,0xBC,0x8F,0xAC,0xDF,0xDE,0xBE,0xFA,0xB0,0xB4,0x6F,0xAC,0x7B,0xAA,0xEF,0xBC, + 0x90,0xAC,0x4F,0xA4,0xD7,0xFA,0x90,0xB8,0x8F,0xAC,0x2E,0xA4,0x8F,0x9A,0x82,0xA2, + 0xAF,0xB4,0x4F,0xA4,0xBD,0xFF,0xFF,0x73,0x8F,0xAC,0x4F,0xA4,0xAB,0xBF,0xF7,0x75, + 0x8F,0xAC,0x2E,0xA4,0x0A,0x2A,0x2B,0xE9,0x90,0xAC,0x4E,0xA4,0xE7,0xEE,0xE2,0xAB, + 0x8F,0xAC,0x4E,0xA4,0xE2,0xAA,0xAB,0xF7,0x6F,0xAC,0x2E,0xA4,0xBB,0x0C,0xA0,0xBA, + 0x8F,0xAC,0x2E,0xA4,0x2C,0xFF,0x6F,0xFB,0x6F,0xAC,0x0D,0x9C,0x28,0xBB,0x9F,0xFF, + 0x64,0x59,0xE2,0x40,0xF5,0xAB,0x2A,0xAA,0x64,0x51,0x23,0x51,0xBD,0xB9,0x2F,0xE3, + 0x84,0x59,0x43,0x51,0x7F,0xDC,0xEE,0xBF,0x84,0x59,0x43,0x51,0x7D,0x79,0xAB,0xEE, + 0x64,0x59,0x22,0x51,0xF5,0x56,0xBC,0xE8,0x43,0x51,0x02,0x49,0xB8,0xDA,0xE8,0xFA, + 0x64,0x51,0x02,0x49,0xFF,0xBF,0x7F,0xF2,0x23,0x49,0xE2,0x40,0x29,0x3E,0xDA,0x02, + 0x43,0x51,0x03,0x49,0xF6,0xFF,0xBA,0xAF,0x23,0x49,0x02,0x41,0x80,0x42,0xA0,0x7A, + 0x23,0x49,0xE2,0x40,0x3B,0x23,0xAF,0x9F,0x23,0x49,0xE2,0x40,0xA0,0x3E,0xBE,0x2E, + 0x23,0x49,0x02,0x41,0x1B,0xF6,0xD6,0xFC,0x44,0x49,0x02,0x49,0x5F,0x57,0x95,0x95, + 0x8A,0x9B,0x43,0x51,0xB5,0x2D,0x2D,0x2D,0x0C,0xAC,0x8A,0x93,0x82,0xAA,0x62,0xE2, + 0xAB,0x9B,0x49,0x93,0xFC,0xF8,0xFA,0xDD,0x69,0x9B,0x08,0x8B,0xE0,0x78,0xFC,0x78, + 0x08,0x8B,0xE8,0x8A,0x80,0x77,0xFE,0x9C,0x08,0x8B,0xA7,0x82,0xBF,0x6F,0xEF,0xB2, + 0xE8,0x82,0xA7,0x82,0xBE,0x7B,0xAE,0xAB,0xC7,0x82,0x86,0x7A,0xEE,0xEA,0x83,0xCA, + 0xC7,0x82,0x87,0x7A,0xBA,0xEF,0xBF,0xAA,0x8A,0x9B,0x87,0x7A,0x5D,0xB7,0x2F,0x0B, + 0xCB,0xA3,0x08,0x8B,0x25,0x09,0x02,0x00,0xEA,0xAB,0xAB,0xA3,0x65,0xEF,0xFB,0xFA, + 0xEC,0xAB,0xC8,0x82,0x20,0xA8,0xF0,0x7E,0x8A,0x9B,0x46,0x72,0xE0,0x78,0x5E,0x55, + 0x67,0x7A,0x05,0x6A,0xDC,0xFF,0x7F,0x77,0x67,0x72,0x06,0x6A,0xFD,0xAD,0xAD,0x8B, + 0x26,0x6A,0x84,0x51,0x80,0xE8,0x40,0x60,0xC5,0x59,0x43,0x51,0xDC,0xFF,0xBF,0x2F, + 0xE5,0x61,0x84,0x51,0xED,0xAB,0xAA,0xAA,0x06,0x62,0xC5,0x59,0xA7,0xFB,0x72,0x7B, + 0xE5,0x61,0x44,0x51,0xA8,0x68,0x78,0x77,0xA5,0x59,0x23,0x49,0xCA,0xEA,0xED,0xFE, + 0x64,0x49,0x24,0x49,0xD6,0xD6,0xD2,0xF5,0x84,0x51,0x44,0x49,0x99,0xB5,0xF5,0xB5, + 0x85,0x51,0x23,0x41,0xFC,0xFF,0xFE,0xFA,0x64,0x51,0x23,0x41,0xFE,0xF6,0xFE,0x33, + 0x26,0x6A,0x43,0x49,0xD5,0xBD,0x2B,0x0A,0x26,0x6A,0xA5,0x51,0xB5,0xEE,0xE0,0xA0, + 0xE6,0x61,0x43,0x51,0x00,0x82,0xE0,0xFA,0x06,0x62,0x43,0x49,0x8A,0x2A,0xBF,0x55, + 0xC5,0x59,0x63,0x49,0x00,0xA8,0xEA,0x5D,0xC5,0x59,0x22,0x41,0xE0,0xFA,0xFE,0x7F, + 0x23,0x41,0xE2,0x38,0x00,0xAC,0x5E,0x5E,0x03,0x39,0xC2,0x38,0xC0,0xAA,0xFC,0xBC, + 0xE2,0x30,0x81,0x28,0xFE,0x78,0xFA,0xEA,0xC2,0x30,0x61,0x20,0xAA,0xEA,0xFA,0x7A, + 0xC2,0x28,0x81,0x20,0xE3,0x8D,0x7D,0x7D,0xA2,0x28,0x61,0x20,0xBA,0x7E,0x56,0x5F, + 0xA2,0x20,0x61,0x18,0xEA,0xDB,0xD7,0x57,0x81,0x20,0x41,0x18,0x02,0xE0,0xFE,0xE2, + 0x81,0x20,0x41,0x18,0xFF,0x5F,0xBF,0x2E,0xC2,0x28,0x61,0x18,0xBD,0x3D,0x2F,0x2E, + 0xC3,0x28,0xA2,0x28,0xCB,0xFE,0xE0,0x80,0xC2,0x28,0x81,0x20,0xFA,0xFA,0xDE,0xA2, + 0xA2,0x28,0x82,0x20,0x2F,0xAB,0xE3,0x2E,0xC2,0x28,0x81,0x28,0xFB,0xEF,0xAB,0xAA, + 0xC2,0x28,0x61,0x28,0x2B,0xAA,0x8A,0x02,0x03,0x31,0xA2,0x28,0xF5,0xB5,0x39,0x3A, + 0x03,0x31,0xC2,0x30,0x57,0x7E,0xBC,0x82,0x03,0x31,0xC2,0x30,0xD7,0x65,0xAF,0xEB, + 0xC2,0x30,0x82,0x28,0xA8,0xFC,0xF0,0x78,0xE2,0x30,0x81,0x28,0x02,0xAE,0xEB,0xBF, + 0xE2,0x30,0xA1,0x28,0x88,0xB8,0xBF,0x55,0x03,0x39,0xC2,0x30,0xE2,0xBA,0xBF,0xFD, + 0x03,0x39,0xC2,0x30,0xEF,0xF8,0xFA,0xA2,0x03,0x39,0xC3,0x30,0x7A,0xFF,0x7F,0xDF, + 0xE2,0x30,0xA2,0x28,0xDF,0xDF,0xDE,0xF8,0xE3,0x30,0xA2,0x28,0xE3,0xAF,0xA6,0xE5, + 0x82,0x30,0xC2,0x28,0xBD,0xD5,0x77,0xDD,0xA2,0x28,0x81,0x20,0x62,0xFE,0x0A,0x00, + 0xC2,0x28,0x81,0x28,0x8F,0xEF,0xEF,0xAE,0xC2,0x28,0x82,0x28,0x20,0x02,0x09,0x02, + 0xE3,0x30,0xA2,0x28,0xFD,0xAE,0xAE,0xBE,0xC2,0x30,0xA2,0x28,0x58,0x50,0xEA,0xAF, + 0xC2,0x30,0xA2,0x28,0xD5,0xC3,0xF5,0xF5,0xC2,0x30,0xA2,0x28,0x02,0xBA,0x9B,0xAB, + 0xE3,0x30,0xC2,0x28,0xEF,0x4D,0x4D,0x3D,0xE2,0x30,0xA1,0x28,0xFA,0xCB,0xA3,0x0A, + 0x03,0x39,0xC2,0x30,0xF7,0xFF,0x81,0x03,0x03,0x39,0xC2,0x30,0xAB,0xAF,0xBF,0xF6, + 0xE2,0x30,0xA1,0x30,0x20,0xA0,0xAF,0x2B,0x23,0x39,0xE3,0x38,0xBD,0xDF,0xEF,0xED, + 0x03,0x39,0xC2,0x30,0xEE,0xAB,0x06,0xB7,0x03,0x39,0xC2,0x30,0x8F,0x88,0xC0,0xD2, + 0x03,0x39,0xE2,0x30,0xFF,0xE7,0xE3,0xE8,0x03,0x41,0xE2,0x30,0x55,0x7F,0xD7,0xD7, + 0x43,0x41,0x03,0x39,0x95,0x7D,0xFD,0xED,0x44,0x41,0xE2,0x30,0xA3,0xA9,0xEA,0xEA, + 0x64,0x49,0xE3,0x38,0xA0,0xBA,0xFE,0xDD,0x44,0x41,0xE3,0x38,0x28,0xFE,0x57,0x55, + 0x24,0x41,0xC2,0x30,0xE8,0xDE,0xDB,0xDB,0xE3,0x38,0xC2,0x30,0xAE,0x9E,0xB8,0x80, + 0x03,0x39,0xC2,0x30,0x2F,0x2E,0xAD,0x3F,0x03,0x39,0xE3,0x30,0xAA,0x0A,0x2F,0xE7, + 0x24,0x39,0xC2,0x30,0xAA,0x3A,0xDE,0xFB,0xE3,0x38,0xC2,0x30,0xFE,0x54,0x76,0x8E, + 0x03,0x39,0xC2,0x30,0x03,0xA9,0xDD,0x8A,0x23,0x41,0xE3,0x30,0x0F,0x35,0xA3,0x89, + 0xA5,0x51,0x03,0x39,0x02,0x0A,0xE9,0xBD,0xC5,0x51,0x44,0x49,0x2A,0x8F,0xA5,0xB5, + 0x06,0x5A,0x64,0x49,0x8E,0xFA,0xFF,0x75,0xA5,0x51,0x64,0x49,0x20,0xB8,0x3B,0x2B, + 0xE6,0x59,0x85,0x51,0x2B,0x2B,0x3D,0x97,0x4B,0x83,0x06,0x5A,0x35,0xA5,0x35,0x2D, + 0xED,0x9B,0x8C,0x8B,0x2D,0xBD,0xB5,0x6F,0xED,0x9B,0xAC,0x93,0x22,0x88,0x2A,0xD5, + 0x0E,0xA4,0xAC,0x93,0x0A,0x2E,0xAE,0xDD,0x2E,0xA4,0xCD,0x93,0x00,0xCE,0xAF,0x7D, + 0x4E,0xA4,0xED,0x9B,0x08,0x2B,0xB5,0xB5,0xB0,0xAC,0x0D,0x9C,0x0B,0xBB,0xD7,0x57, + 0xD0,0xB4,0x4E,0xA4,0x0A,0xAB,0x09,0xAD,0x11,0xBD,0xB0,0xB4,0x8B,0x8A,0xFB,0x55, + 0x11,0xBD,0xB0,0xAC,0x7A,0x7E,0x83,0x8B,0xF1,0xBC,0x8F,0xAC,0xD7,0x9E,0x7F,0xEC, + 0xB0,0xB4,0x6F,0xAC,0xFE,0xA8,0xAB,0xAA,0xB0,0xB4,0x6F,0xAC,0x7F,0x7E,0xE0,0xAA, + 0xAF,0xB4,0x4F,0xA4,0x6F,0xFD,0x6E,0xA8,0x8F,0xAC,0x4F,0xA4,0xF7,0xDF,0xFD,0xB0, + 0x90,0xAC,0x2E,0xA4,0x7B,0x5A,0xFE,0xDC,0x6F,0xA4,0x2E,0xA4,0x33,0xE9,0x6A,0x9E, + 0x6E,0xAC,0x2E,0xA4,0x2E,0xCB,0xED,0xF9,0x6F,0xAC,0x2E,0xA4,0xA2,0xBB,0xDA,0x42, + 0x4F,0xA4,0x0E,0x9C,0xF8,0xF8,0x50,0xAF,0x2E,0xA4,0x0E,0x9C,0x7B,0xDD,0xCB,0x82, + 0x64,0x51,0x23,0x51,0xEB,0xA2,0xBA,0xBF,0x64,0x59,0x43,0x51,0xFD,0xAD,0x50,0xF8, + 0x64,0x59,0x43,0x51,0xA2,0x88,0x6B,0xFD,0x84,0x59,0x23,0x51,0xEA,0xEA,0xEA,0x4A, + 0x63,0x51,0x22,0x51,0xFF,0xBF,0x6F,0xA0,0x43,0x51,0x02,0x49,0xE8,0xBA,0xF6,0x7A, + 0x43,0x51,0x02,0x49,0xBA,0x68,0xF9,0xDD,0x43,0x49,0x02,0x49,0xAA,0xAB,0xED,0xE5, + 0x43,0x49,0xE2,0x40,0x8A,0xB8,0xFF,0xDF,0x43,0x51,0xE2,0x40,0x3B,0xBE,0xFB,0xF9, + 0x23,0x49,0xE2,0x40,0xBF,0xBE,0xFE,0xF8,0x23,0x49,0xE2,0x40,0x3A,0xFA,0xF8,0xFA, + 0x43,0x49,0x02,0x49,0x5E,0x55,0x55,0xD5,0x63,0x59,0xE2,0x40,0xDD,0x3F,0xAF,0x2F, + 0xCB,0xA3,0xC5,0x61,0x2D,0x2D,0x0D,0xA9,0xEB,0xA3,0x49,0x93,0xE2,0x8A,0xEE,0x7E, + 0x8A,0x9B,0x49,0x93,0xA2,0xE2,0xFD,0xED,0x69,0x9B,0x08,0x8B,0x48,0xF2,0x7A,0x5E, + 0x28,0x93,0xC7,0x82,0xBA,0x6E,0x78,0xFA,0xC8,0x8A,0x07,0x83,0xAF,0xEE,0xAE,0xBF, + 0xE8,0x8A,0xC7,0x82,0xD6,0x96,0x8A,0x1A,0x29,0x93,0xA7,0x82,0x57,0x57,0xBF,0x2B, + 0xAB,0xA3,0xE8,0x8A,0x55,0x55,0xAD,0x02,0xEB,0xAB,0x4A,0x93,0xAD,0xAB,0xAB,0x88, + 0x0B,0xAC,0xAB,0xA3,0xFE,0xF3,0x6B,0x5A,0xCB,0xA3,0x66,0x72,0x00,0xA0,0xE8,0x7E, + 0x4A,0x93,0x26,0x72,0x78,0x7E,0x57,0x55,0x46,0x72,0x05,0x6A,0xEF,0xEB,0x8D,0xAB, + 0x67,0x72,0x26,0x72,0x5E,0x65,0x7D,0x07,0x67,0x72,0x06,0x62,0x03,0x2A,0xBB,0x7E, + 0x26,0x6A,0x84,0x51,0x50,0x5E,0xDC,0x7F,0x06,0x62,0x84,0x51,0xB5,0x37,0xAA,0xAB, + 0xE5,0x61,0xC5,0x59,0xB2,0xD4,0x57,0xFA,0xE6,0x61,0x43,0x49,0xA0,0xF8,0x7F,0x57, + 0x84,0x59,0x44,0x49,0x7C,0xD7,0x5F,0x7F,0x64,0x51,0x03,0x41,0xEC,0xDA,0xBA,0xA0, + 0x64,0x49,0x03,0x41,0xBD,0x87,0x8B,0x2A,0x84,0x49,0x44,0x49,0xBD,0xDD,0x56,0x55, + 0x85,0x51,0x03,0x41,0xEC,0xB8,0xFE,0x7F,0xC5,0x61,0x23,0x41,0xBD,0xB7,0x3D,0x3D, + 0x27,0x6A,0xE6,0x61,0xE9,0xAB,0xD5,0x57,0x26,0x6A,0x84,0x51,0xAA,0x6F,0x7C,0x7A, + 0xA4,0x59,0x02,0x41,0xF8,0x7F,0x5E,0x7E,0x63,0x49,0xE2,0x40,0x2B,0xBD,0xF5,0xF5, + 0x63,0x49,0xE2,0x40,0x22,0xEE,0xFF,0x77,0x63,0x49,0x03,0x41,0xCC,0x6A,0x7D,0x5D, + 0x03,0x41,0xC2,0x30,0xB8,0x6C,0xF8,0xF8,0xE2,0x38,0xA2,0x30,0xAA,0xE2,0xFB,0x8A, + 0xE2,0x30,0xA2,0x28,0xFA,0x5E,0x7A,0x7A,0xC2,0x28,0x61,0x20,0xFC,0x7A,0xFF,0xAE, + 0xC2,0x28,0x61,0x20,0xFB,0xE9,0xBA,0xA8,0xA2,0x28,0x61,0x20,0x57,0xFE,0x6C,0xFA, + 0x81,0x20,0x41,0x18,0xFB,0xFE,0xFE,0xF8,0x81,0x20,0x41,0x18,0xFB,0x7E,0x7F,0x3F, + 0xC3,0x28,0x61,0x18,0xB5,0xAD,0xA9,0x0A,0xE3,0x30,0xA2,0x28,0xE5,0xE9,0xAB,0xFB, + 0xC2,0x28,0xA2,0x28,0x83,0x88,0x08,0xEA,0xC2,0x28,0x81,0x28,0xE8,0xA0,0x00,0x00, + 0xC2,0x28,0x82,0x28,0xEF,0x2E,0x28,0x02,0xC2,0x30,0x81,0x28,0xEF,0xDE,0xE6,0x2B, + 0x03,0x39,0xA2,0x28,0xFD,0xBD,0xAF,0x8B,0x03,0x39,0xC2,0x30,0x3F,0xAB,0x68,0x6A, + 0x23,0x39,0xC2,0x28,0xA2,0x2A,0xFD,0xD5,0xE3,0x30,0xC2,0x28,0x80,0x5C,0x56,0xFE, + 0xC2,0x30,0x82,0x28,0x70,0xF8,0xA2,0xA2,0xE3,0x30,0x81,0x28,0xF5,0xFF,0xFA,0xA2, + 0xC2,0x30,0xA2,0x30,0xDB,0xDF,0x29,0x02,0xE3,0x38,0xC2,0x30,0xA2,0xAA,0xA7,0x2D, + 0x03,0x39,0xC2,0x30,0xEB,0xBD,0xBB,0xAE,0xE3,0x30,0xC2,0x30,0xFC,0xFA,0xFF,0x16, + 0xE3,0x30,0x82,0x20,0xBA,0xDE,0xFA,0xA0,0xE3,0x30,0xA2,0x28,0x3D,0xAB,0x2B,0x3F, + 0x03,0x31,0xA2,0x28,0xFB,0xF8,0x77,0x7E,0xC2,0x30,0xA2,0x28,0xF9,0xE5,0x45,0x75, + 0xA2,0x30,0xC2,0x28,0xFA,0xFF,0xDF,0xFF,0xC2,0x28,0xA2,0x28,0xEF,0xEB,0xA3,0x80, + 0xE3,0x30,0xA2,0x28,0xF7,0x7D,0xFF,0x3F,0xE3,0x30,0xA2,0x28,0xD5,0xEB,0x72,0x5A, + 0xC2,0x30,0xA2,0x28,0xBE,0xAE,0x8D,0xEF,0xC2,0x30,0xA2,0x28,0x88,0xB8,0xD8,0x9F, + 0xE3,0x30,0xA1,0x28,0x2F,0x8B,0xEB,0xA7,0xE3,0x30,0xA2,0x28,0x20,0xBE,0x77,0x55, + 0x03,0x39,0xA2,0x28,0x0A,0x0F,0x2F,0xAF,0x03,0x39,0xC2,0x30,0xA2,0xDA,0x60,0xCE, + 0xE3,0x30,0xC2,0x30,0xB7,0xD5,0xD5,0x57,0x02,0x39,0xC3,0x30,0xFE,0xFA,0x3B,0xAF, + 0xE2,0x30,0xA2,0x30,0xFE,0xDF,0xEC,0xB2,0x03,0x39,0xC2,0x30,0xEB,0x9D,0xAB,0x57, + 0x03,0x39,0xC2,0x30,0xCA,0x8A,0xAF,0x95,0x23,0x39,0xC2,0x30,0xFF,0xF7,0x3F,0xEF, + 0x23,0x39,0xE3,0x30,0x23,0x3F,0xBD,0xFD,0x24,0x39,0xE3,0x30,0x7E,0x72,0xC8,0x6B, + 0x24,0x39,0xC2,0x30,0xF7,0xBD,0xFF,0xAF,0x03,0x39,0xC3,0x30,0xEE,0xF2,0xC0,0xC2, + 0x03,0x39,0xC3,0x30,0xBD,0x3F,0xED,0xAB,0x03,0x31,0xC3,0x30,0xEA,0x80,0x08,0x68, + 0x03,0x39,0xE3,0x30,0x3F,0x3D,0x67,0xB5,0x23,0x39,0xE3,0x30,0xDF,0xFD,0xDD,0xC5, + 0x03,0x39,0xE3,0x30,0x71,0xFD,0xF5,0x59,0x44,0x41,0xE3,0x30,0x7D,0x6F,0xEB,0xA9, + 0x23,0x39,0xE3,0x30,0xEF,0xFD,0x29,0x8B,0x64,0x41,0xE3,0x38,0xED,0xEF,0x8A,0xAA, + 0x64,0x49,0x03,0x39,0xAD,0xA9,0x3D,0x1E,0x84,0x49,0x23,0x41,0xBF,0x77,0xB6,0xBE, + 0x84,0x51,0x44,0x49,0xFE,0xB5,0xBD,0x27,0xE5,0x59,0x85,0x51,0x7D,0xF5,0xB5,0x0E, + 0xE6,0x59,0xA5,0x51,0x15,0xA5,0x0F,0x20,0x6C,0x8B,0xE5,0x59,0x2D,0x2D,0x2D,0x2F, + 0xEE,0x9B,0xAC,0x93,0x7D,0xEB,0x23,0x23,0xED,0x9B,0x8C,0x8B,0xFF,0xDF,0x7A,0x5C, + 0xCD,0x93,0x6B,0x8B,0xA0,0xB8,0xFB,0xFD,0xED,0x9B,0x8C,0x8B,0x8E,0x39,0xB9,0xF7, + 0x0E,0xA4,0xAC,0x93,0x2A,0x3D,0xAF,0xBF,0x2D,0xA4,0xCC,0x93,0xB8,0x2E,0xAB,0xF7, + 0x6F,0xAC,0xED,0x9B,0x0B,0xAD,0xFF,0x75,0xAF,0xAC,0x0D,0x9C,0x28,0xAF,0xBD,0xD5, + 0xF1,0xBC,0x4E,0xA4,0x02,0x2A,0xBD,0x9D,0xF0,0xBC,0x8F,0xAC,0x70,0xEA,0xAE,0xFB, + 0xD1,0xB4,0x8F,0xAC,0x5F,0x5F,0xA0,0xAC,0xB0,0xB4,0x90,0xAC,0x2E,0x8B,0x04,0x36, + 0xD0,0xB4,0x6F,0xAC,0xA7,0xBF,0xB7,0xF4,0xB0,0xB4,0x6F,0xAC,0xF8,0xE2,0xA8,0xE8, + 0xB0,0xB4,0x4F,0xA4,0x5A,0xB8,0xBA,0xEE,0x8F,0xAC,0x4E,0xA4,0x57,0x4F,0xC3,0xCE, + 0x6F,0xAC,0x0E,0xA4,0x28,0x88,0x88,0x7A,0x6F,0xAC,0x2E,0xA4,0xEA,0x72,0xFE,0x7D, + 0x4E,0xA4,0x0D,0x9C,0xEF,0xBF,0xBE,0x4B,0x2E,0xA4,0xED,0x9B,0x80,0xCB,0x7F,0x7E, + 0x64,0x59,0x02,0x49,0xEF,0xEA,0x3C,0x7F,0x84,0x59,0x23,0x51,0xAF,0x3B,0xBE,0xFD, + 0x84,0x59,0x43,0x51,0x77,0x56,0xF4,0x2F,0x84,0x59,0x43,0x51,0xEB,0xED,0xF8,0x7E, + 0x84,0x59,0x22,0x49,0x7E,0x5E,0xEE,0x73,0x43,0x51,0x02,0x49,0x5E,0xCE,0x7E,0x5E, + 0x23,0x49,0x02,0x41,0xFB,0x20,0x02,0x00,0x22,0x49,0x02,0x41,0xCB,0x56,0x8B,0xF6, + 0x23,0x49,0xE2,0x40,0xAB,0xEB,0xFA,0xA8,0x23,0x49,0xE2,0x40,0xAB,0xBB,0xDE,0x7E, + 0x23,0x49,0xE2,0x40,0xC8,0x78,0xEF,0x8D,0x02,0x49,0xE2,0x40,0xA0,0xB9,0x25,0x87, + 0x23,0x49,0xE1,0x40,0xBF,0xA5,0x0A,0x2B,0x05,0x6A,0x43,0x49,0xD5,0xD5,0x15,0x35, + 0xAB,0x9B,0x66,0x7A,0x29,0x89,0x2F,0x23,0xAB,0xA3,0x49,0x93,0x7B,0xF8,0x6E,0x7A, + 0x69,0x9B,0x29,0x93,0xA6,0xBE,0x6B,0xFA,0x69,0x9B,0x08,0x8B,0xDA,0xE8,0xE3,0x7E, + 0x28,0x93,0xC7,0x82,0xEA,0xA8,0x88,0x28,0x28,0x8B,0xE8,0x8A,0x50,0x52,0x7D,0xFB, + 0x8A,0x9B,0xE8,0x82,0x55,0xBD,0xAD,0x2B,0x0C,0xAC,0xE8,0x8A,0xBD,0xAB,0x2A,0x0A, + 0x0C,0xAC,0xAA,0xA3,0xDD,0x3E,0xBA,0x28,0x0C,0xAC,0x69,0x9B,0xA2,0xEA,0xA8,0x7A, + 0xCB,0xA3,0x66,0x72,0xA0,0xE0,0x7A,0x5E,0xC8,0x82,0x25,0x6A,0xF0,0xDE,0x77,0x5E, + 0x46,0x72,0x05,0x6A,0x2C,0xAF,0x0B,0x02,0x67,0x7A,0x26,0x6A,0xFA,0xAF,0xA7,0x0A, + 0x67,0x72,0x26,0x72,0x9E,0xDE,0xFC,0x88,0x47,0x72,0xA5,0x59,0xE8,0xF8,0x62,0x7A, + 0xC5,0x59,0x84,0x59,0x2C,0x2F,0xAE,0x8E,0xC5,0x61,0x43,0x51,0x20,0xA0,0xA8,0xDE, + 0xC5,0x59,0x23,0x49,0x80,0xFA,0x5E,0x5D,0xA5,0x51,0x02,0x41,0x9F,0x2F,0x2F,0x82, + 0x84,0x51,0x43,0x49,0x78,0x78,0x7C,0x5A,0x84,0x51,0x44,0x49,0x6F,0xFF,0xBF,0xAD, + 0x64,0x49,0x23,0x41,0x32,0x2A,0x9E,0x5C,0x64,0x49,0x23,0x41,0xE3,0x8B,0xAF,0xBF, + 0x64,0x49,0x03,0x41,0x7F,0x7E,0xDC,0x78,0xA5,0x59,0x03,0x41,0x3D,0x2D,0x29,0x2F, + 0x05,0x62,0xC5,0x61,0x5E,0xD7,0xCA,0xA2,0x06,0x6A,0xA4,0x59,0x5A,0x7C,0xC8,0xAB, + 0xA4,0x59,0x23,0x49,0x7E,0x7C,0x78,0x5E,0x23,0x49,0xC1,0x38,0x88,0xBB,0xFE,0x6C, + 0x23,0x41,0xE2,0x40,0xDF,0xBA,0x0B,0x43,0x23,0x41,0xE2,0x38,0x5A,0xDA,0x5F,0x55, + 0x23,0x41,0xC2,0x30,0xFB,0xA3,0xFF,0x7D,0x03,0x39,0xC2,0x30,0xFA,0xFA,0xFF,0xFD, + 0xE3,0x30,0xA2,0x28,0x5E,0xFA,0xAE,0xF8,0xA2,0x28,0x81,0x28,0x0E,0x0E,0x08,0x00, + 0xC2,0x28,0x81,0x20,0xEA,0x82,0xE2,0x5E,0xA2,0x20,0x40,0x18,0xA8,0xAA,0xF8,0x7E, + 0x82,0x20,0x61,0x18,0x5B,0x5D,0xF9,0x3D,0xC2,0x28,0x61,0x18,0xD5,0xD5,0x9D,0x0F, + 0xE3,0x30,0xA2,0x20,0xFF,0xEF,0xEB,0xA2,0xE3,0x30,0xC2,0x28,0x57,0x52,0x2B,0xF7, + 0xA2,0x30,0xC2,0x28,0xDF,0xFD,0x6D,0xF5,0x03,0x31,0xA2,0x28,0xFF,0xDF,0xBE,0x3B, + 0x23,0x39,0xC2,0x28,0x55,0x7F,0xEF,0x8A,0x03,0x31,0xC2,0x30,0x55,0x7A,0xF8,0xFA, + 0xE3,0x30,0xA2,0x30,0x0A,0x2A,0xEA,0x7A,0xE3,0x38,0x81,0x28,0xE8,0xEE,0x5B,0x5F, + 0xC2,0x30,0x81,0x28,0x02,0x8B,0xAF,0xAD,0xA2,0x30,0xE2,0x28,0xBF,0xBE,0xEA,0xEA, + 0x03,0x31,0xC2,0x30,0x95,0x9D,0xD7,0xB5,0x03,0x39,0xC2,0x30,0xFA,0xEA,0xEF,0xEB, + 0xE3,0x38,0xC2,0x30,0xF7,0xDF,0x2F,0x0E,0x03,0x39,0xC2,0x30,0x37,0xBB,0x6A,0xAA, + 0x03,0x39,0xC2,0x30,0xA2,0xEB,0xEB,0x00,0x03,0x39,0xC3,0x30,0x9A,0xBB,0xB3,0xF8, + 0x24,0x39,0xE3,0x30,0x57,0xE3,0xEA,0xAB,0x03,0x31,0xC3,0x30,0x5E,0xDE,0xBE,0xDE, + 0xE3,0x30,0xA2,0x28,0x7A,0xB8,0xF8,0xF0,0xC2,0x28,0xA2,0x28,0x75,0x66,0xF7,0x1F, + 0xE2,0x30,0x81,0x28,0xFF,0x5D,0x75,0xFE,0xE3,0x30,0x81,0x20,0x2B,0xAB,0xFF,0xFD, + 0xE3,0x30,0xA2,0x28,0xB7,0xEA,0xB3,0xB9,0xE3,0x30,0xA2,0x28,0xFA,0xFA,0x74,0xDF, + 0xA2,0x28,0x81,0x20,0x28,0xB0,0xA8,0x80,0xE2,0x28,0x82,0x28,0xBF,0xFF,0x75,0xFF, + 0xC2,0x28,0xA2,0x28,0xEA,0x7A,0x55,0x9D,0xE3,0x30,0x81,0x28,0xFF,0x7F,0xA2,0xA2, + 0xE3,0x30,0xA2,0x28,0x0B,0x89,0x09,0xBD,0xE3,0x30,0xA2,0x30,0x80,0xAA,0xFF,0xFE, + 0xE2,0x30,0xA2,0x28,0xFA,0xFA,0xF7,0x56,0xE2,0x30,0xC2,0x30,0x3B,0x9F,0x5F,0xDE, + 0x03,0x39,0xC2,0x30,0xFA,0x82,0x7A,0x55,0xE3,0x30,0xC2,0x30,0xFF,0xB9,0x4B,0x77, + 0xE3,0x30,0xA1,0x28,0xB8,0xBC,0xAE,0xB7,0x23,0x39,0xC2,0x28,0xAF,0xBF,0xBF,0xD7, + 0x03,0x31,0xC2,0x28,0x7A,0x50,0x9C,0xBC,0x03,0x31,0xE3,0x30,0xE9,0xDD,0x56,0x5E, + 0x24,0x31,0xC2,0x30,0xFF,0xF5,0x6F,0xDF,0x24,0x31,0xC2,0x30,0xFB,0xDF,0xFD,0xE3, + 0x03,0x31,0xC3,0x30,0xF2,0xFF,0xFA,0x7F,0xE3,0x30,0xC2,0x28,0xC0,0x60,0x60,0x43, + 0x03,0x31,0xA2,0x28,0xAA,0x2A,0xEB,0xF9,0x03,0x39,0xA2,0x28,0x2E,0xAE,0xF7,0xF7, + 0xE3,0x30,0xC2,0x28,0x18,0xAA,0x72,0xFB,0x45,0x39,0xE3,0x30,0xCB,0xFD,0xD5,0xD5, + 0x03,0x31,0xC2,0x30,0xE2,0x9E,0xBC,0xB8,0x23,0x41,0xE2,0x30,0x20,0x3E,0xBF,0x36, + 0x65,0x41,0x23,0x41,0x9F,0xBF,0xDE,0x9F,0xA5,0x51,0x43,0x41,0x57,0xDD,0xBD,0xFF, + 0xC5,0x59,0x44,0x49,0xBB,0x39,0xBF,0xFD,0x06,0x62,0xC5,0x51,0xAB,0x8A,0xCD,0xE5, + 0x26,0x62,0xC5,0x59,0xDE,0xBB,0x2F,0x8F,0x4B,0x83,0x26,0x62,0x2D,0x2D,0x29,0x2F, + 0xED,0x9B,0x8C,0x8B,0x03,0x81,0x8B,0xAB,0xED,0x9B,0x8C,0x8B,0x7C,0xEF,0xBA,0xAE, + 0xAC,0x93,0x6B,0x8B,0xAF,0xC4,0x48,0x80,0xCD,0x9B,0x4B,0x8B,0x2A,0x3B,0x9D,0xD7, + 0xED,0x9B,0x8C,0x8B,0x83,0xAA,0xAF,0xF5,0xED,0x9B,0xAC,0x93,0xAB,0xF3,0x92,0xEA, + 0x0D,0x9C,0x8C,0x93,0x80,0x0A,0xA9,0x9D,0x2E,0xA4,0xCD,0x93,0xEA,0x2E,0xAD,0xEA, + 0x6E,0xA4,0xED,0x9B,0x23,0xEF,0xEF,0xDD,0xB0,0xB4,0x0D,0x9C,0x8A,0xAB,0xF5,0xFD, + 0xB0,0xB4,0x0E,0x9C,0xA0,0xAE,0xBE,0xF7,0x8F,0xAC,0x2E,0xA4,0x0A,0x0E,0xAF,0x7D, + 0xB0,0xB4,0x0E,0x9C,0x88,0xEA,0xAF,0x7F,0x8F,0xAC,0x2E,0xA4,0x80,0xEF,0xBF,0x55, + 0x8F,0xAC,0x0D,0x9C,0x88,0xAA,0xEB,0x55,0x8F,0xAC,0xCC,0x93,0x8A,0xEA,0x77,0x7F, + 0x4E,0xA4,0xCD,0x93,0xA8,0xBB,0xFF,0xFD,0x2E,0xA4,0xED,0x9B,0x23,0xE0,0x59,0x55, + 0x4E,0xA4,0xED,0x9B,0xFE,0x73,0xDD,0xD5,0x4F,0xA4,0xED,0x9B,0x5E,0xFE,0xEF,0x82, + 0x64,0x51,0x02,0x51,0x9E,0xEA,0xAA,0xBC,0x63,0x51,0x22,0x51,0xBF,0xBA,0xA2,0xA8, + 0x84,0x59,0x43,0x51,0xAE,0xCE,0xE9,0xEF,0x64,0x51,0x23,0x51,0xFA,0xC8,0xA2,0xAA, + 0x64,0x51,0x23,0x49,0xCA,0x55,0x57,0x7F,0x43,0x49,0x02,0x49,0x6A,0x7E,0x55,0x7D, + 0x23,0x49,0xE1,0x40,0x82,0x2D,0xA9,0xBB,0x23,0x49,0xE2,0x40,0xAA,0xE0,0x78,0xF7, + 0x23,0x49,0x02,0x41,0xB2,0xFD,0x5D,0x5D,0x23,0x49,0xC2,0x40,0xFA,0xDA,0xBA,0x8A, + 0x23,0x49,0xC2,0x40,0x0D,0x2F,0xEA,0xBA,0x44,0x49,0xE2,0x40,0x8E,0x9B,0xAF,0xBB, + 0x23,0x49,0xE3,0x40,0xEF,0xE3,0xEE,0x6A,0x08,0x8B,0x03,0x49,0xB5,0xB5,0xAD,0x2D, + 0xAB,0x9B,0x08,0x8B,0xA9,0x0D,0x0B,0xAB,0xAB,0x9B,0x49,0x93,0xC8,0x62,0x58,0x7C, + 0x6A,0x9B,0x29,0x93,0xEB,0xEA,0xBE,0x7E,0x49,0x93,0xE8,0x8A,0x60,0xF0,0xEA,0x80, + 0x49,0x93,0xE7,0x8A,0xFE,0xDB,0xBF,0x00,0x6A,0x9B,0x08,0x8B,0xDD,0x95,0x9F,0x2E, + 0xCB,0xA3,0x69,0x93,0x25,0x2F,0xEF,0xB7,0x0C,0xAC,0xAA,0x9B,0xAB,0xF7,0x75,0xF5, + 0xEC,0xA3,0x49,0x8B,0x00,0x00,0x8A,0x7A,0xCB,0xA3,0x86,0x7A,0xE8,0x78,0x5E,0x57, + 0x86,0x7A,0x26,0x6A,0xF8,0xAA,0xDC,0xFF,0x66,0x72,0x25,0x6A,0xF0,0xFE,0x5A,0x82, + 0x66,0x72,0x25,0x72,0x21,0xEB,0xEF,0xCE,0x87,0x7A,0x46,0x72,0x71,0x7B,0xDD,0x72, + 0x67,0x72,0xC5,0x61,0xC2,0xA8,0xF8,0x72,0xE5,0x61,0x63,0x51,0xC0,0xF8,0xFE,0x5C, + 0xC4,0x59,0x22,0x41,0xA8,0xEA,0xFF,0x55,0x84,0x51,0x23,0x49,0xF8,0x6A,0x7E,0x55, + 0xA5,0x51,0x02,0x41,0xBD,0xBF,0x2B,0xAB,0xA5,0x59,0x43,0x49,0xAA,0xEA,0x68,0xEA, + 0x84,0x49,0x23,0x41,0xAC,0xFE,0xAB,0xAA,0xA5,0x51,0x44,0x49,0x8F,0xEB,0xFA,0x7F, + 0x64,0x49,0x23,0x41,0xFE,0xFA,0xFA,0x5F,0x64,0x49,0x23,0x41,0xAA,0xA0,0xB5,0xBB, + 0x44,0x49,0x03,0x39,0xA8,0xB2,0x7C,0x56,0x84,0x51,0xE2,0x38,0x2F,0xBF,0x9D,0x55, + 0xE5,0x61,0x23,0x49,0x00,0x02,0x03,0x29,0xE5,0x61,0xA4,0x59,0xFA,0x5A,0xBA,0x78, + 0xC5,0x61,0x23,0x49,0x78,0x7A,0xF0,0xF0,0x23,0x49,0xE2,0x40,0xEA,0x6C,0xA8,0x00, + 0x23,0x41,0xE2,0x38,0x63,0xE1,0x7E,0x6A,0x03,0x41,0xC2,0x38,0xFF,0x5B,0x7A,0xEE, + 0xE2,0x38,0xC2,0x30,0xF8,0xEF,0x67,0xDF,0xE3,0x30,0xC2,0x30,0xBF,0xBA,0x7E,0x5A, + 0x03,0x39,0xA2,0x28,0x6A,0x8A,0xAB,0x3A,0xE3,0x30,0x81,0x20,0xFF,0x7B,0xF8,0x68, + 0xA2,0x28,0x40,0x18,0x68,0xFA,0xEA,0xFE,0x82,0x18,0x41,0x18,0x7A,0xFF,0xAF,0xAF, + 0xA1,0x20,0x40,0x18,0xBD,0x2A,0x2B,0x2B,0xC2,0x28,0xA2,0x20,0x0B,0xE2,0x61,0xDB, + 0x03,0x31,0xA2,0x28,0xBF,0xAF,0xBD,0x2D,0x24,0x39,0xC2,0x28,0xD5,0xDD,0xB7,0x0A, + 0x65,0x41,0xC2,0x28,0x57,0xDF,0xEF,0x02,0x65,0x41,0xC1,0x28,0xF5,0xEF,0x82,0x80, + 0x44,0x41,0xE3,0x30,0xFB,0x7E,0xBC,0xBC,0x23,0x39,0xC2,0x30,0x55,0x76,0xFE,0xE8, + 0x03,0x39,0xA2,0x28,0x5F,0xDF,0xFB,0x60,0xC2,0x30,0x81,0x28,0xD0,0xE0,0xF0,0x0A, + 0x03,0x39,0xA2,0x30,0xD5,0xDD,0xBD,0x83,0xE3,0x38,0xA2,0x28,0xBE,0xFE,0xF8,0xE8, + 0x03,0x39,0xC2,0x30,0xA9,0xEB,0x77,0xB5,0x03,0x39,0xE2,0x30,0x7A,0x72,0x61,0x78, + 0x24,0x39,0xC2,0x30,0xEF,0xA3,0xBB,0xFD,0x23,0x39,0xE2,0x30,0x8F,0xFA,0xEF,0x75, + 0x23,0x39,0xE3,0x30,0xA2,0xBA,0xAB,0xF9,0x03,0x39,0xA2,0x28,0xE8,0xF8,0xF8,0xDC, + 0x03,0x39,0xA2,0x28,0x22,0xAF,0xFD,0xF7,0xE2,0x30,0xA3,0x28,0xFE,0xAA,0xEA,0x02, + 0xE3,0x30,0xA2,0x28,0xEA,0xA7,0xAF,0x2F,0xE3,0x30,0xA2,0x28,0xE7,0xFF,0xEF,0x2E, + 0xE2,0x30,0xA2,0x28,0xF7,0xDF,0xFF,0xF8,0xC2,0x28,0x61,0x20,0x7F,0xFA,0x08,0x00, + 0xC2,0x28,0x81,0x20,0xBD,0xFD,0xEB,0x8B,0xC2,0x30,0x81,0x20,0xAA,0xEB,0xFD,0x7A, + 0xA2,0x28,0x61,0x20,0xB0,0xEF,0xBE,0xFE,0xA2,0x28,0x81,0x20,0x0A,0x8D,0xED,0x7D, + 0xC2,0x28,0x61,0x20,0x0A,0x2A,0x01,0x0A,0xE2,0x30,0xA2,0x28,0x8E,0xB7,0xCB,0x88, + 0xE3,0x30,0xA2,0x28,0x6F,0xAC,0x2F,0x2F,0x04,0x31,0xC3,0x30,0x55,0xDA,0x5E,0xFF, + 0xE3,0x30,0xA2,0x28,0x5F,0x2C,0x9B,0xBB,0x03,0x39,0xC2,0x30,0x7F,0xDA,0xEA,0x6A, + 0xE2,0x30,0xA2,0x28,0xBA,0xAF,0xA5,0xD7,0xE2,0x30,0xA2,0x28,0xFA,0xFE,0xEE,0xBF, + 0xC2,0x28,0xA2,0x28,0xD7,0xBD,0xAE,0xA0,0x03,0x31,0xC2,0x28,0xF7,0xBF,0x2A,0xAB, + 0x03,0x31,0xE3,0x30,0xF5,0xE7,0xFF,0x7B,0x24,0x39,0xE3,0x30,0xEB,0xB2,0xAF,0x29, + 0x24,0x39,0xC2,0x28,0x7E,0xEA,0xE2,0xC3,0x24,0x39,0xC2,0x28,0xE3,0xAD,0x6B,0x5E, + 0xE3,0x30,0xC2,0x28,0xBA,0x3C,0x29,0x8D,0x03,0x31,0xC2,0x30,0x6B,0xFA,0xFE,0xFF, + 0x23,0x31,0xC2,0x30,0xFD,0xFB,0xFF,0x57,0xE3,0x30,0xC2,0x28,0xD7,0xF7,0xFA,0x02, + 0x03,0x31,0xA3,0x30,0xAB,0x0A,0xAA,0x08,0x03,0x31,0xC3,0x30,0x2C,0xBC,0xFE,0x82, + 0x03,0x31,0xE2,0x30,0xD8,0x55,0xAF,0xFB,0x44,0x41,0xE2,0x30,0x2F,0xA5,0xBD,0xF7, + 0x64,0x49,0x03,0x39,0xAA,0x02,0xAE,0xF7,0xA5,0x51,0x23,0x41,0x3E,0x2B,0xDF,0xFD, + 0xA5,0x51,0x44,0x49,0xFF,0xAA,0xAC,0xD6,0xC5,0x51,0x64,0x49,0xAA,0x3F,0xAD,0x29, + 0x48,0x6A,0xC5,0x51,0xFD,0xBF,0x3D,0x39,0xAC,0x93,0x88,0x72,0xAD,0x2D,0x29,0x2F, + 0x0E,0x9C,0xAD,0x93,0xDD,0x5F,0xAB,0xAB,0xED,0x9B,0x8C,0x8B,0x27,0xEF,0x7E,0xA8, + 0xCD,0x93,0x8C,0x8B,0xFA,0x7A,0x6A,0x76,0xAD,0x93,0x6B,0x8B,0xB6,0xDF,0xFB,0x5E, + 0x8C,0x93,0x4B,0x83,0xC0,0xBD,0xB7,0x6A,0xCD,0x93,0x4B,0x83,0x02,0x0A,0x3B,0x2D, + 0xCD,0x93,0xAC,0x93,0x9A,0x30,0x98,0x5C,0x2E,0xA4,0xCD,0x93,0xEB,0xFD,0xDF,0x35, + 0x2E,0xA4,0xCD,0x93,0xFF,0xFF,0x6F,0xCD,0x2E,0xA4,0xCD,0x93,0x8B,0xEF,0x9B,0xBF, + 0x2E,0xA4,0xEE,0x9B,0xFA,0x82,0xAE,0x6B,0x2E,0xA4,0xCD,0x93,0x02,0xAB,0x7A,0xF9, + 0x2E,0xA4,0xCD,0x93,0xA8,0xA8,0x2B,0xAD,0x0D,0x9C,0xCC,0x93,0x00,0x20,0xA8,0x5A, + 0x2D,0x9C,0xAC,0x93,0xE8,0xE8,0xFA,0x5F,0xCD,0x93,0xAC,0x93,0x83,0xEF,0xAC,0x39, + 0xED,0x9B,0xAC,0x93,0x3F,0xDF,0xEB,0x7A,0xED,0x9B,0xCC,0x93,0x00,0x2A,0xFF,0x95, + 0x0D,0x9C,0xCC,0x93,0x8A,0x28,0x2B,0x2B,0x4F,0xA4,0xED,0x9B,0x0F,0xAF,0xDF,0x6D, + 0x43,0x51,0x23,0x49,0x17,0x95,0xAA,0x39,0x63,0x51,0x23,0x49,0x6A,0xEA,0xEE,0x7D, + 0x64,0x51,0x23,0x49,0xCB,0x73,0xEE,0x69,0x64,0x51,0x23,0x49,0xAA,0x6A,0x7F,0xED, + 0x43,0x49,0x02,0x49,0x6C,0x5F,0x57,0x58,0x22,0x49,0xE1,0x40,0xEC,0xDE,0xEB,0xAE, + 0x02,0x49,0xE2,0x40,0xFE,0x8A,0xF2,0x8A,0x23,0x49,0xE2,0x40,0xE7,0xAF,0x99,0x55, + 0x23,0x49,0xC1,0x38,0x0A,0x82,0xAA,0xB7,0x22,0x49,0xE3,0x40,0xAA,0x2B,0xAB,0xFF, + 0x23,0x49,0xE2,0x40,0x77,0xB7,0x17,0xFB,0x23,0x49,0xE3,0x40,0xC3,0x8B,0x8E,0x2F, + 0x43,0x51,0x03,0x49,0xDD,0x43,0xED,0xBD,0x49,0x93,0x43,0x51,0x25,0x2D,0x2D,0x0D, + 0xAA,0x9B,0x69,0x93,0xF7,0xAE,0xE3,0x6B,0x8A,0x9B,0x49,0x93,0xBA,0xF8,0xFA,0xEF, + 0x69,0x9B,0x49,0x93,0xD6,0x55,0xE5,0x55,0x89,0x9B,0x28,0x93,0xD7,0x67,0x17,0x3D, + 0x8A,0x9B,0x29,0x93,0x7D,0x7F,0x7A,0xC0,0x6A,0x9B,0x29,0x93,0x6B,0x3E,0xBA,0xBE, + 0x8A,0x9B,0x49,0x93,0x27,0x0F,0xAA,0xBF,0xCB,0xA3,0x29,0x8B,0x8A,0xAA,0xEA,0xFF, + 0x8A,0x9B,0x66,0x7A,0xA0,0x78,0x7E,0x57,0xA7,0x7A,0x46,0x72,0xF8,0x7B,0xFE,0xFF, + 0x87,0x7A,0x25,0x6A,0xFF,0x6A,0xAB,0xAB,0x86,0x7A,0x45,0x6A,0xEB,0xAD,0xB6,0xE8, + 0x87,0x72,0x46,0x72,0xF7,0x87,0x08,0x6A,0x87,0x7A,0x06,0x62,0x82,0x80,0x82,0x72, + 0x46,0x6A,0x23,0x49,0xE0,0xFA,0x7A,0xD6,0x84,0x59,0x02,0x41,0xA8,0xBE,0x77,0x7F, + 0x43,0x49,0x23,0x41,0xDC,0xD7,0xA5,0x89,0x63,0x49,0x23,0x49,0x97,0x2F,0x2A,0x0A, + 0xA5,0x59,0x64,0x51,0xBD,0x2D,0x8F,0xBB,0x84,0x51,0x43,0x49,0xEE,0x68,0xFE,0xFC, + 0x64,0x49,0x43,0x49,0x1A,0x95,0x37,0x98,0x85,0x49,0x44,0x49,0xFF,0xAE,0xBA,0xEB, + 0x64,0x49,0x24,0x41,0x7F,0xEC,0x6E,0x7E,0x44,0x49,0x24,0x41,0x2A,0x6F,0xE5,0x2D, + 0x23,0x41,0x03,0x41,0xEC,0xFA,0x23,0xE0,0x23,0x41,0xC2,0x38,0x2E,0xAE,0xAA,0xF4, + 0xA5,0x59,0x03,0x41,0x09,0x05,0xF5,0x55,0xC5,0x59,0x23,0x49,0xA8,0xAA,0xAA,0xBD, + 0xA4,0x51,0x43,0x51,0xE8,0xFA,0xFE,0x7E,0x64,0x51,0x03,0x41,0xFF,0xEA,0xFA,0x6C, + 0x23,0x41,0xA1,0x30,0xE8,0xEA,0x7A,0x7E,0x03,0x39,0xA1,0x30,0xAB,0x8B,0xAD,0xBE, + 0xE2,0x38,0xA1,0x28,0x02,0x28,0xEE,0x78,0x03,0x39,0xC2,0x30,0x5E,0xAA,0x82,0x53, + 0xE3,0x30,0x81,0x28,0x82,0x8A,0xEF,0xDF,0xE3,0x30,0x81,0x20,0xFC,0xFE,0xF7,0x5D, + 0xA1,0x20,0x40,0x18,0xF8,0xF8,0xF8,0x7A,0x82,0x20,0x40,0x18,0xB9,0x2F,0xAB,0xAF, + 0xC2,0x28,0x61,0x18,0xB7,0x2F,0x2B,0x03,0x03,0x31,0xA2,0x28,0x9F,0x87,0x2B,0x2A, + 0x44,0x41,0xC3,0x30,0x2D,0xBB,0x8A,0xBA,0x44,0x41,0xC2,0x28,0x02,0x08,0xBE,0xDE, + 0x85,0x41,0xA2,0x28,0x0A,0xA8,0xFE,0xF7,0x44,0x41,0xC2,0x30,0x80,0xAA,0xEF,0x5D, + 0x24,0x39,0xE3,0x30,0x88,0xAB,0x3D,0xD5,0x23,0x41,0x03,0x39,0x5D,0x5F,0x7B,0x55, + 0x03,0x39,0xC2,0x30,0x72,0x98,0xAA,0xA0,0x03,0x39,0xA2,0x30,0xE5,0x2E,0x8A,0x8A, + 0x03,0x39,0xC3,0x30,0xE2,0xEA,0xFE,0xF5,0xC2,0x38,0xE3,0x30,0xF5,0xBF,0xFD,0xFF, + 0xE3,0x38,0xA1,0x28,0x03,0xAA,0xB6,0x9F,0x03,0x39,0xC2,0x30,0xEA,0xAA,0x22,0xF2, + 0x03,0x39,0xA2,0x30,0xAB,0xAB,0xEE,0x78,0xE2,0x30,0xC2,0x30,0xE1,0xA0,0x23,0xBB, + 0x03,0x31,0xC2,0x28,0xB9,0xB5,0xA7,0xD5,0xE3,0x30,0x81,0x28,0xB8,0xF8,0x7A,0x7F, + 0xC2,0x28,0x82,0x28,0x28,0x2F,0xAF,0xF5,0xE3,0x30,0xA2,0x28,0x0A,0xAF,0xBD,0xE9, + 0x04,0x31,0xC3,0x30,0xBF,0xED,0xFF,0xAD,0xE3,0x30,0xC2,0x28,0xCC,0x98,0xF0,0xC0, + 0x03,0x39,0xE3,0x30,0x57,0x7B,0xEB,0xA5,0xE3,0x30,0xA2,0x28,0x7F,0xFF,0x2E,0xE2, + 0xE3,0x30,0x81,0x28,0xAD,0xAB,0xAA,0xEA,0xC2,0x28,0x82,0x28,0x78,0xB0,0xC2,0x80, + 0xE3,0x30,0x81,0x20,0x55,0x7F,0xEA,0xA0,0xC2,0x28,0x61,0x20,0xFD,0xFB,0xAA,0x00, + 0xE2,0x30,0x81,0x20,0xAF,0xAD,0xBE,0x28,0x23,0x39,0xC2,0x28,0xFD,0xFF,0xEB,0x8F, + 0xE3,0x30,0xA2,0x28,0x2A,0xA0,0xA0,0xF8,0x03,0x31,0xC2,0x30,0x15,0xB5,0xA7,0xAF, + 0x03,0x31,0xA2,0x28,0x9C,0xFE,0xFF,0x56,0xE3,0x30,0xA2,0x28,0x02,0x02,0xEA,0xDF, + 0xC2,0x30,0xA2,0x28,0xAE,0x0E,0x2E,0xB7,0xE3,0x30,0xC2,0x28,0xDE,0x96,0x2F,0xFF, + 0x03,0x31,0xA2,0x28,0x6A,0xE2,0xA0,0xAB,0x03,0x31,0xA2,0x30,0xA9,0x22,0x82,0xA8, + 0x03,0x31,0xE3,0x30,0x22,0x6A,0xF1,0xB2,0x24,0x39,0xA1,0x28,0x0A,0xAA,0xDF,0x5F, + 0x24,0x39,0xC2,0x30,0xF8,0x7A,0x7F,0x5D,0xE3,0x30,0xA2,0x28,0xF0,0xF8,0xFA,0x7B, + 0xE3,0x30,0xA2,0x28,0x05,0xED,0x9F,0xAF,0xE3,0x30,0xC2,0x28,0x8E,0x2F,0x0D,0xA5, + 0xE3,0x30,0xC2,0x28,0x56,0x2A,0x39,0x2F,0xE3,0x30,0xA2,0x28,0x08,0xBE,0x3E,0x2A, + 0x23,0x31,0xE2,0x30,0x97,0xC7,0x95,0xF5,0x03,0x31,0xE2,0x30,0xE0,0x68,0x40,0xD7, + 0x03,0x31,0xA1,0x28,0x22,0x82,0xC2,0xFA,0x03,0x39,0xC1,0x28,0x82,0x03,0x09,0x05, + 0x44,0x41,0x03,0x39,0xFB,0x2B,0xAB,0xED,0x64,0x49,0x23,0x41,0x8F,0xAD,0x9D,0xF5, + 0x64,0x49,0x23,0x41,0x79,0xEE,0xE2,0xE0,0xE5,0x59,0x43,0x41,0x2F,0xAD,0xAB,0xAA, + 0xC8,0x7A,0xE4,0x51,0xB7,0xBD,0x2D,0x2F,0xCD,0x9B,0xC9,0x7A,0x2D,0x0D,0x29,0x0B, + 0x0F,0x9C,0xCD,0x93,0xAF,0xA9,0xC3,0x2F,0xED,0x9B,0xAD,0x93,0xC8,0xA2,0x6A,0x82, + 0xEE,0x9B,0x8C,0x8B,0x5E,0x5A,0xE8,0xAA,0xAC,0x93,0x4B,0x83,0xDA,0xFB,0xFF,0xF6, + 0x8B,0x8B,0x4B,0x83,0xBA,0x99,0x77,0xAF,0xAD,0x93,0x2A,0x83,0x37,0x97,0xD5,0xF5, + 0xCD,0x93,0x6C,0x8B,0x80,0xBA,0x2F,0x2D,0xED,0x9B,0xCD,0x93,0x26,0x2F,0x35,0xF5, + 0x0D,0x9C,0xAC,0x93,0x80,0x0A,0x39,0x2B,0x0E,0x9C,0xCD,0x9B,0xAA,0xB9,0xE0,0xE2, + 0xED,0x9B,0xCD,0x93,0x68,0x20,0x0A,0xE2,0x0E,0x9C,0xCD,0x93,0x62,0xDE,0xCB,0xCE, + 0xED,0x9B,0xCD,0x93,0xE3,0x68,0x57,0x97,0xED,0x9B,0xAD,0x93,0xF6,0xEE,0x3A,0xAC, + 0xED,0x93,0x8C,0x93,0xDA,0xAA,0x2A,0xA8,0x0D,0x9C,0xAC,0x93,0xFD,0x55,0xD4,0x5F, + 0xCD,0x93,0x6B,0x8B,0xE0,0x2A,0x22,0xA2,0xCD,0x93,0x8C,0x93,0x2A,0x02,0xAE,0x2D, + 0xED,0x9B,0x8C,0x8B,0x02,0x0A,0x2A,0xB6,0x2E,0xA4,0xCD,0x93,0x8E,0xFE,0xDF,0xFD, + 0x44,0x51,0x03,0x49,0xF2,0xE8,0xFB,0x97,0x43,0x51,0x03,0x49,0x3A,0xAB,0x2F,0xA6, + 0x63,0x51,0x03,0x49,0xEB,0xA0,0xFB,0xD7,0x44,0x51,0x23,0x49,0x6B,0xEF,0x52,0x55, + 0x22,0x49,0x02,0x41,0x80,0x0F,0xBA,0xB8,0x23,0x49,0x02,0x41,0xD6,0xDC,0x0C,0xBE, + 0x23,0x49,0xC1,0x38,0xA2,0xE6,0x62,0xAA,0x23,0x49,0xC1,0x38,0xFA,0x6F,0x2F,0x0A, + 0x23,0x41,0xC1,0x40,0xF6,0x88,0xEA,0xCE,0x02,0x41,0xC2,0x38,0x28,0xCD,0xAB,0x8B, + 0x23,0x41,0xE3,0x40,0xEE,0x0F,0x27,0x3E,0x23,0x49,0xE2,0x40,0xB2,0xD0,0xEA,0xFB, + 0x43,0x51,0xE2,0x40,0x2B,0x0F,0x3D,0xBF,0x69,0x93,0xC4,0x59,0x2D,0x09,0x29,0x0D, + 0xA9,0x9B,0x69,0x93,0x7F,0x53,0x7E,0x54,0x8A,0x9B,0x49,0x93,0xEF,0xEA,0xE8,0x6D, + 0x69,0x93,0x28,0x8B,0xFE,0xA9,0xFE,0x0E,0x8A,0x9B,0x49,0x93,0xA5,0x2D,0x0D,0xA0, + 0xAB,0x9B,0x49,0x93,0x42,0xBA,0xFA,0xD5,0x8A,0x9B,0x4A,0x93,0x9F,0xAB,0xFA,0xDF, + 0x8A,0x9B,0xE9,0x8A,0xBA,0xE8,0xF8,0xFA,0x2A,0x93,0x06,0x6A,0x80,0xE8,0xFA,0x7E, + 0x87,0x7A,0x25,0x6A,0xBC,0xF8,0xEE,0x7F,0x87,0x72,0x46,0x72,0xAD,0x83,0x8A,0x58, + 0x87,0x72,0x46,0x72,0xAA,0xBA,0xAB,0xDD,0xA7,0x7A,0x46,0x72,0x5F,0x9A,0xBF,0x0A, + 0xA7,0x7A,0x46,0x6A,0xEB,0xEE,0xC2,0x68,0x46,0x72,0x64,0x51,0xE0,0xE0,0x78,0x5E, + 0x84,0x59,0x02,0x41,0xFC,0x5E,0xFF,0xDC,0x43,0x49,0x02,0x41,0xC2,0xAA,0xAD,0xBF, + 0x64,0x51,0x02,0x41,0xA9,0x8F,0xAF,0x2A,0xA5,0x51,0x43,0x49,0xBF,0xA9,0xBB,0x82, + 0xA4,0x51,0x43,0x49,0xA8,0xC8,0x6A,0xFE,0xA4,0x51,0x43,0x49,0xDA,0x35,0x25,0xEF, + 0x84,0x49,0x44,0x49,0x7A,0x78,0xA0,0x80,0x85,0x49,0x44,0x49,0xEB,0x8B,0x37,0x17, + 0x84,0x49,0x44,0x49,0x77,0xFE,0xF6,0xDB,0x44,0x41,0x03,0x41,0xA8,0xAE,0xAE,0xEA, + 0x44,0x49,0x03,0x41,0xEE,0x2F,0xAD,0xBA,0x24,0x41,0xE3,0x38,0xD6,0xFB,0xFC,0xAA, + 0x03,0x41,0xC2,0x38,0xA8,0x5A,0x77,0x5E,0x64,0x51,0xA2,0x38,0x0B,0xAF,0xB5,0xF5, + 0x84,0x51,0x03,0x41,0xA0,0xA2,0x8A,0xA5,0x64,0x51,0x02,0x41,0xE8,0xEE,0x6A,0xEB, + 0x23,0x41,0xC2,0x30,0x5F,0x7B,0xEB,0xE8,0x03,0x39,0xC2,0x38,0xFF,0xFF,0xA7,0x8F, + 0x03,0x39,0xC2,0x30,0x57,0xDF,0xFE,0xFA,0xE3,0x30,0x81,0x28,0xA2,0xEA,0xEA,0x5A, + 0xA2,0x28,0x61,0x20,0xA0,0xA2,0x7A,0x7F,0x81,0x20,0x41,0x18,0x80,0xE8,0x7E,0x7F, + 0x61,0x20,0x41,0x18,0xE2,0xEF,0xFD,0x95,0xA2,0x28,0x41,0x18,0xBD,0xAF,0xAF,0x3F, + 0xE3,0x28,0x81,0x20,0x8B,0xAD,0xFF,0x57,0xE3,0x30,0x81,0x20,0x0A,0xAB,0xED,0xF9, + 0xE3,0x30,0x81,0x20,0x80,0xEF,0xFD,0x57,0xC2,0x28,0x81,0x20,0x20,0xF2,0xAF,0xAF, + 0xC3,0x30,0x82,0x20,0xA7,0x97,0xFF,0xBE,0xC3,0x28,0x82,0x28,0xEA,0xEB,0xFE,0x76, + 0x03,0x39,0x81,0x20,0xAB,0x2F,0xFD,0xF5,0x24,0x39,0xE2,0x30,0xBF,0xBE,0xAE,0xB5, + 0x24,0x39,0xE3,0x38,0x7A,0xF3,0xDD,0x77,0x03,0x39,0xC2,0x30,0xFF,0xFB,0xF8,0xEE, + 0xE3,0x30,0xA1,0x28,0x3E,0xF8,0x70,0xA2,0x03,0x39,0xA2,0x28,0x8F,0xEB,0xFB,0x7F, + 0xC2,0x30,0x81,0x28,0x28,0x28,0xA8,0xBD,0xE2,0x30,0xA2,0x30,0xEA,0xAA,0x8F,0x26, + 0xE3,0x30,0xA2,0x30,0x40,0x82,0x00,0x02,0xC2,0x30,0xE3,0x28,0xBA,0x2A,0x0E,0xBE, + 0xC2,0x30,0xA2,0x28,0x5A,0x5E,0xE8,0x58,0xA2,0x28,0x81,0x20,0x7B,0x6B,0x58,0x70, + 0xA2,0x28,0x61,0x20,0xDF,0xBF,0x1B,0x2B,0xC3,0x30,0xA2,0x28,0x2D,0xDF,0xCA,0x2B, + 0xE3,0x30,0xA2,0x28,0x2B,0xEA,0xAB,0x3F,0x03,0x31,0xC2,0x30,0xEA,0xFB,0xEA,0x09, + 0x03,0x31,0xC3,0x30,0x8F,0xBF,0xAF,0xAF,0xE3,0x30,0xA1,0x28,0xB2,0xBC,0xF0,0xFA, + 0xE3,0x30,0xA2,0x28,0xEB,0xAB,0xB9,0xBB,0xE3,0x30,0xA2,0x28,0xAF,0x26,0x2A,0xAA, + 0x03,0x39,0xE3,0x30,0x57,0x9F,0x39,0x43,0x24,0x39,0xC2,0x28,0x7E,0xEE,0xFE,0xDC, + 0x23,0x39,0xE3,0x30,0xC5,0xBD,0xEF,0xF5,0x03,0x39,0xC2,0x30,0xEE,0x7A,0xE8,0xE8, + 0xE3,0x30,0xC2,0x28,0x52,0x15,0xF7,0xFB,0x02,0x31,0xA2,0x28,0x3F,0xFF,0xBD,0xFF, + 0xE3,0x30,0xA2,0x28,0xFC,0xFC,0x5F,0x57,0xE3,0x30,0xA2,0x28,0xBD,0xE3,0x7B,0xEA, + 0xC2,0x28,0xA2,0x28,0xDF,0xD6,0xA5,0x8F,0xC2,0x30,0xA2,0x28,0xD6,0x95,0xA5,0xAD, + 0x03,0x31,0xC2,0x28,0x35,0xA5,0xAD,0x9D,0x03,0x31,0xC3,0x30,0x08,0x80,0xAA,0xDE, + 0x24,0x39,0xE3,0x30,0x7E,0xA7,0xED,0x6B,0x03,0x31,0xA2,0x28,0x7E,0xF8,0xFA,0xAA, + 0xE3,0x30,0xC2,0x28,0x79,0xFF,0x6B,0xC0,0x03,0x31,0xC2,0x28,0x55,0xDD,0xF3,0xB8, + 0xC2,0x30,0xE3,0x28,0xAE,0xA9,0xAF,0xB7,0xE3,0x30,0xA2,0x28,0xF9,0x3E,0xBA,0x3A, + 0x03,0x31,0xC2,0x30,0xB7,0x36,0xF8,0xB8,0x03,0x31,0xC2,0x30,0xA7,0xAA,0xBE,0xFE, + 0x03,0x31,0xC2,0x28,0x2B,0x8E,0x27,0x0F,0x43,0x39,0xE2,0x30,0x55,0x7F,0xEF,0xF2, + 0x02,0x31,0xC2,0x30,0x72,0x42,0x76,0x7E,0x03,0x39,0xA1,0x28,0x3D,0xAD,0x3D,0xA7, + 0x64,0x49,0x03,0x39,0xF9,0xBF,0x3D,0x2D,0xA5,0x51,0x43,0x41,0x55,0xD5,0x8B,0x83, + 0xA5,0x51,0x64,0x49,0x57,0x07,0x2D,0xAE,0x06,0x5A,0x84,0x49,0xB7,0xEF,0xAF,0x2D, + 0x0A,0x83,0xE5,0x59,0x2F,0xAD,0x29,0x2F,0xED,0x9B,0x4B,0x8B,0x2F,0x0F,0x3D,0x99, + 0x0E,0x9C,0x8C,0x93,0xAA,0x0A,0xEF,0x5F,0xED,0x9B,0x8C,0x93,0x20,0xAA,0xAA,0xEF, + 0xCD,0x93,0x8C,0x93,0xC0,0xC4,0x6B,0x5E,0x8C,0x8B,0x4B,0x83,0xE0,0xBE,0xE8,0xF6, + 0x8C,0x8B,0x4B,0x83,0xEF,0x7E,0xFF,0xD5,0x6B,0x8B,0x0A,0x7B,0xBE,0xD8,0xDE,0x7C, + 0xCC,0x93,0x29,0x7B,0x2F,0xAF,0xAD,0xFD,0xED,0x9B,0x8B,0x8B,0xAA,0xAA,0x3B,0x3D, + 0xED,0x9B,0xAC,0x93,0x22,0x38,0xAA,0xF5,0x0E,0x9C,0x8C,0x8B,0xA8,0x2A,0xAB,0x7F, + 0x2E,0xA4,0xAC,0x93,0xF8,0xBE,0xF7,0x75,0x0E,0x9C,0xAC,0x93,0x3A,0xBE,0xEB,0x9F, + 0xCD,0x93,0x8C,0x8B,0x00,0x02,0x0A,0x2C,0xCD,0x93,0x8C,0x8B,0x38,0xD0,0x6F,0xEE, + 0xCD,0x93,0x8C,0x8B,0xA0,0x30,0xFA,0xF7,0xCD,0x93,0x8C,0x8B,0x28,0x0C,0x08,0x88, + 0xCD,0x93,0x6C,0x8B,0xAA,0xFE,0xA6,0x22,0xCC,0x93,0x6B,0x8B,0x32,0xFA,0xE2,0xE8, + 0xED,0x9B,0x8C,0x8B,0xEF,0xEB,0xCF,0x5D,0x0E,0x9C,0xAC,0x93,0xBD,0xBC,0xFF,0xF5, + 0x43,0x51,0x03,0x49,0xEA,0xEA,0xFB,0x6A,0x43,0x51,0x03,0x41,0xEB,0xA2,0xD3,0xFF, + 0x23,0x49,0xE2,0x40,0x0B,0x0F,0xA2,0x88,0x43,0x49,0xE2,0x40,0xAC,0xFC,0x7F,0xEE, + 0x23,0x49,0xE2,0x40,0xAB,0x8F,0xBB,0x29,0x23,0x49,0xE2,0x40,0x62,0xDC,0x98,0xF8, + 0x03,0x49,0xE1,0x38,0xAA,0xF2,0xF2,0xD6,0x23,0x41,0xC1,0x38,0x82,0x8A,0xE3,0xFE, + 0x02,0x41,0xE2,0x38,0x89,0xE5,0xAF,0x25,0x23,0x49,0xE2,0x38,0xA5,0x8D,0xFF,0xFB, + 0x03,0x41,0xE2,0x38,0x08,0x02,0x28,0x07,0x23,0x49,0xE2,0x40,0xFB,0xFC,0xFE,0x7F, + 0x43,0x51,0xE2,0x40,0x3F,0xBF,0x2F,0x2D,0x6A,0x93,0xA5,0x59,0x0B,0x09,0x0B,0x0B, + 0x8A,0x9B,0x69,0x93,0x68,0xC0,0xA2,0x29,0x8A,0x9B,0x49,0x93,0x87,0x05,0x2A,0xB0, + 0x8A,0x9B,0x28,0x8B,0x29,0x0A,0xE8,0xFE,0x6A,0x9B,0xE8,0x82,0xC0,0x68,0x7E,0x57, + 0x29,0x8B,0xC8,0x82,0x0A,0x2F,0xAF,0xDD,0x6A,0x93,0x09,0x8B,0x20,0x03,0xAF,0xF5, + 0x4A,0x93,0x05,0x6A,0x80,0xA0,0xE0,0x78,0x67,0x7A,0xE5,0x61,0xE2,0xFE,0xDE,0xDF, + 0x66,0x72,0x05,0x6A,0x8B,0xEF,0xB5,0x7F,0x66,0x72,0xE4,0x61,0xA8,0x2B,0x2B,0xA9, + 0x87,0x72,0x26,0x72,0x9A,0xEA,0xE2,0xCA,0xC8,0x7A,0x46,0x6A,0x29,0xCF,0xFF,0xD7, + 0xA7,0x72,0x84,0x59,0xA0,0xEA,0x78,0x5E,0xE5,0x61,0x23,0x49,0xD8,0xDF,0x7F,0xFF, + 0x63,0x51,0x22,0x41,0x5C,0x76,0x6A,0xEE,0x43,0x49,0x02,0x41,0xFF,0x9F,0x9A,0x58, + 0x64,0x51,0xE2,0x38,0x0A,0x0B,0x2F,0xAD,0xA5,0x51,0x64,0x49,0xC0,0x8E,0x77,0x75, + 0x84,0x49,0x44,0x49,0xFA,0xD8,0x2A,0x2F,0xA5,0x51,0x43,0x49,0xA6,0xA8,0x88,0xAA, + 0x84,0x51,0x64,0x49,0xE2,0x42,0x7E,0x5E,0x85,0x51,0x23,0x41,0xBC,0xF7,0x56,0x77, + 0x64,0x49,0x23,0x41,0xA0,0x78,0xA3,0xA3,0x64,0x49,0x23,0x41,0x7F,0xCD,0xFF,0xDE, + 0x64,0x49,0x03,0x39,0xAF,0xB7,0xE6,0xFE,0x64,0x41,0x03,0x41,0x57,0x7E,0x7F,0xDF, + 0x23,0x41,0xE3,0x38,0x7B,0xA2,0xEB,0xBF,0x03,0x39,0xC2,0x38,0x55,0x5E,0x5A,0xF8, + 0x03,0x41,0xA1,0x30,0x2E,0x37,0xAF,0x3B,0x43,0x41,0x03,0x41,0x22,0xA8,0xAB,0x0A, + 0x43,0x41,0xE2,0x38,0xFE,0xFA,0xE2,0xFA,0x03,0x39,0xC2,0x38,0x8A,0x2D,0x2F,0x2B, + 0x23,0x39,0xC2,0x30,0xFB,0x7C,0xFA,0xEB,0xE3,0x30,0x81,0x28,0x52,0x5A,0x7F,0xDF, + 0xA1,0x28,0x40,0x20,0xF8,0x6E,0xFA,0xBA,0x61,0x20,0x41,0x18,0xEA,0xAA,0xB0,0x00, + 0xA2,0x28,0x41,0x18,0x55,0xFF,0xFF,0x2F,0xA2,0x20,0x61,0x20,0xB5,0xA9,0xAB,0x88, + 0xA1,0x20,0x61,0x20,0xBE,0xAF,0xA7,0x0B,0xA2,0x28,0x81,0x20,0x8D,0xB7,0xBB,0xB8, + 0xA2,0x28,0x81,0x20,0xBE,0x3E,0xAA,0xE2,0xC2,0x28,0x81,0x20,0x2F,0xA2,0xAF,0xBF, + 0xA2,0x28,0x82,0x20,0x08,0x8A,0x7E,0xE9,0xA2,0x28,0x81,0x20,0xAC,0x7A,0xFF,0xFB, + 0xA2,0x28,0x81,0x20,0xBF,0x5E,0x6F,0x9F,0x24,0x39,0xA2,0x28,0xAF,0xBD,0xB5,0xD5, + 0x03,0x39,0xA2,0x28,0xA0,0x88,0xAA,0xA9,0x03,0x39,0xC2,0x30,0xEF,0xA7,0x7E,0x97, + 0xA1,0x38,0xE2,0x30,0xF7,0xD5,0xA7,0xF7,0xC2,0x30,0x81,0x28,0x68,0xFA,0xBF,0xF8, + 0xC2,0x30,0x81,0x28,0x35,0xEC,0xFF,0xBA,0xE2,0x30,0xA2,0x30,0x07,0x21,0x2D,0xBB, + 0xE2,0x30,0xA2,0x28,0x0C,0x80,0x20,0xBE,0xE3,0x30,0xC2,0x28,0x3B,0xBC,0x2E,0xDF, + 0x03,0x31,0xA2,0x28,0x56,0xD7,0xE2,0xBF,0xC2,0x30,0xA2,0x28,0x5D,0x7D,0x62,0x58, + 0xA2,0x28,0x81,0x20,0x2F,0x25,0x2F,0x0A,0xC2,0x28,0xA2,0x28,0xBE,0x53,0x5D,0x55, + 0xE3,0x30,0xA2,0x28,0xF7,0xFA,0xAB,0x27,0xE3,0x30,0xA2,0x28,0x0B,0x6E,0xAF,0xCA, + 0x24,0x39,0xC2,0x30,0xEF,0xC9,0xA5,0xD5,0x03,0x31,0xA2,0x28,0x5E,0xFA,0x7E,0xAA, + 0xE3,0x30,0xA2,0x28,0xBE,0x1F,0x97,0xB5,0xE3,0x30,0xC2,0x30,0x64,0xE0,0xA0,0x3D, + 0x04,0x39,0xC2,0x30,0xFF,0xE5,0xC3,0xAE,0x03,0x39,0xC2,0x30,0xD4,0xD6,0x77,0xB7, + 0x03,0x39,0xC2,0x30,0x2D,0xBD,0xFD,0x6B,0x03,0x39,0xC2,0x30,0xCA,0x82,0xC8,0x82, + 0x03,0x39,0xA2,0x28,0xBA,0xBA,0xE8,0xFC,0x03,0x31,0xC2,0x30,0x77,0xF5,0xA5,0x55, + 0xE3,0x30,0xA2,0x28,0x7D,0xFF,0xF6,0xBE,0x24,0x39,0xC2,0x28,0x75,0xFD,0xAD,0x25, + 0x03,0x31,0xA2,0x28,0xFD,0xDF,0xF2,0xE8,0xC2,0x28,0x82,0x28,0x22,0x0A,0xA8,0xBE, + 0xE3,0x30,0xA2,0x28,0x02,0x82,0x7B,0xDD,0x03,0x31,0xC3,0x28,0x7E,0xEF,0xAF,0xCD, + 0x03,0x39,0xC3,0x30,0xC2,0x8B,0xFB,0x9A,0x03,0x31,0xC2,0x30,0xEB,0xF7,0x5E,0xD7, + 0x03,0x31,0xA2,0x28,0xA8,0xBA,0x7B,0xFB,0x03,0x39,0xC2,0x28,0x9A,0xA0,0x5E,0x5D, + 0xE2,0x30,0xC2,0x28,0xAF,0x3E,0x6D,0xF9,0x03,0x31,0xC2,0x28,0x97,0xD7,0x95,0x15, + 0x03,0x31,0xC2,0x28,0xFB,0x36,0x2A,0x88,0x23,0x39,0xE3,0x30,0x7D,0xEA,0x6B,0xBF, + 0x03,0x31,0xE2,0x30,0xB5,0xF3,0xA3,0x35,0x43,0x39,0x03,0x31,0x7F,0xFF,0x8F,0x6D, + 0x23,0x39,0xC2,0x30,0xDA,0xAC,0x8A,0x2E,0x02,0x39,0xC2,0x30,0x65,0x32,0xA2,0x28, + 0x64,0x49,0xE2,0x38,0x2D,0x29,0xAF,0xA7,0x85,0x51,0x44,0x49,0x8B,0xAA,0xDF,0xDD, + 0x84,0x51,0x23,0x41,0x8A,0xFF,0x3D,0x8A,0x68,0x6A,0x64,0x49,0xBD,0xBD,0xBD,0x3F, + 0x8C,0x93,0x88,0x72,0xA5,0x2D,0x29,0x2D,0xAC,0x93,0x4C,0x8B,0xA1,0xAE,0x2A,0xEE, + 0xAC,0x93,0x4B,0x8B,0xA0,0xAB,0xEE,0x7F,0xAD,0x93,0x2B,0x83,0xA2,0x88,0xF8,0xDD, + 0xCC,0x93,0xEA,0x7A,0x22,0xAA,0xFE,0x7F,0x6B,0x8B,0xA9,0x72,0xA8,0xA0,0xA2,0x7E, + 0x4B,0x83,0x47,0x62,0x00,0x8A,0xAA,0x77,0x4B,0x83,0x07,0x5A,0x20,0x88,0xFE,0x55, + 0x4B,0x83,0x27,0x62,0x02,0x02,0xAB,0xF5,0xAC,0x8B,0x89,0x6A,0x00,0x8A,0xAB,0xFD, + 0xAC,0x8B,0x89,0x72,0x00,0xA0,0xFA,0x5F,0x8C,0x8B,0x07,0x5A,0xA0,0xFA,0x5F,0x57, + 0x6B,0x8B,0x27,0x62,0x00,0xBD,0x75,0x55,0xAD,0x93,0x68,0x62,0x00,0x0A,0xBD,0x55, + 0xED,0x93,0xEA,0x7A,0x82,0x8A,0xAA,0xBD,0xAD,0x93,0x8C,0x8B,0xA8,0xA8,0xEF,0xFD, + 0xAC,0x93,0x6C,0x8B,0x2B,0xA1,0xCD,0xA5,0xCC,0x93,0x6C,0x8B,0xAA,0xEA,0xED,0x3F, + 0xCD,0x93,0x8C,0x8B,0xAC,0x4F,0xA9,0x7B,0xCC,0x93,0x8B,0x8B,0x8C,0xFD,0xEB,0xCA, + 0xAC,0x93,0x8C,0x8B,0xD2,0xF2,0x9F,0x36,0xED,0x9B,0x8C,0x8B,0x89,0xF9,0x95,0xDE, + 0x43,0x51,0xE2,0x40,0xCA,0x7F,0xEA,0xFE,0x43,0x49,0xE2,0x40,0xF9,0x61,0xEF,0xAD, + 0x43,0x49,0xE2,0x40,0xEE,0xEB,0xB7,0xBF,0x23,0x49,0x02,0x41,0xDA,0xDF,0xF2,0xEA, + 0x43,0x49,0xE2,0x40,0xBB,0x6B,0x78,0x5F,0x22,0x41,0xC1,0x38,0x2A,0xAF,0xBF,0xB5, + 0x23,0x49,0xE2,0x38,0x5F,0x2B,0x3B,0xD7,0x03,0x41,0xC2,0x38,0xEA,0x7C,0xFC,0xF6, + 0x02,0x41,0xC2,0x38,0x0B,0x8B,0xED,0xEB,0x02,0x41,0xA1,0x38,0x00,0x01,0x09,0x0B, + 0x23,0x49,0xE2,0x40,0x37,0x3A,0xBE,0xF6,0x03,0x49,0x22,0x41,0xAA,0xB9,0xF7,0xAE, + 0x64,0x51,0xE2,0x40,0x35,0x17,0xBF,0xAE,0x6A,0x93,0xA5,0x59,0x0B,0x0B,0x2D,0xF5, + 0xAA,0x9B,0x87,0x7A,0x8A,0x82,0xEE,0x7D,0x6A,0x93,0xC7,0x82,0x80,0xA0,0xFF,0x5D, + 0x49,0x93,0xA7,0x7A,0x80,0x2A,0xFE,0x5F,0x29,0x8B,0xA7,0x82,0xF8,0xEA,0xBF,0xD7, + 0xE8,0x82,0xA7,0x7A,0x7E,0xFE,0xA0,0x50,0x09,0x8B,0x66,0x72,0x22,0xAA,0xDA,0x7F, + 0x09,0x8B,0xC5,0x61,0xF0,0xFE,0x7F,0x5F,0x06,0x6A,0xE5,0x61,0xBC,0x3E,0x7C,0x57, + 0x26,0x6A,0xC4,0x61,0x28,0x20,0x0A,0xFD,0x46,0x6A,0xE5,0x61,0x0A,0xAA,0xB6,0xF7, + 0x67,0x72,0xA4,0x59,0x00,0xA8,0xFA,0x5E,0x25,0x6A,0x63,0x51,0x00,0xF8,0x5E,0x55, + 0xA5,0x59,0x03,0x49,0xB0,0xFC,0xFF,0xBF,0x84,0x51,0x23,0x49,0xA0,0xAA,0x0D,0x2E, + 0x84,0x51,0x02,0x41,0x7A,0x72,0x7E,0xFE,0x64,0x49,0x02,0x41,0x7D,0xFF,0x3D,0x0F, + 0xC5,0x51,0xE2,0x40,0xFD,0xBF,0xAE,0xA0,0x85,0x51,0x23,0x41,0xAA,0x2A,0xA9,0xAB, + 0xA5,0x51,0x44,0x49,0xBF,0xA7,0x2F,0xFE,0xA5,0x51,0x44,0x49,0xFF,0xD6,0x78,0xFB, + 0x84,0x49,0x44,0x49,0xEF,0x7F,0x5B,0x6B,0x64,0x49,0x23,0x41,0x6F,0xCA,0xAA,0xE2, + 0x64,0x49,0x03,0x41,0xAE,0xFF,0xFE,0xDC,0x44,0x49,0xE2,0x38,0xA0,0xAA,0xEE,0xDE, + 0x44,0x49,0xE3,0x40,0xA2,0xAB,0xEB,0xBF,0x23,0x41,0x03,0x41,0xF0,0xBE,0x57,0xD0, + 0x44,0x41,0xE2,0x38,0xDF,0xFF,0xFE,0xB8,0x23,0x41,0xE2,0x38,0x7E,0xFF,0xD8,0xBA, + 0x44,0x49,0xE3,0x38,0x9D,0xB7,0xAB,0x82,0x64,0x49,0x03,0x41,0x2B,0xEA,0xEF,0x55, + 0x43,0x41,0xE2,0x38,0x70,0x7A,0x7A,0x7F,0x03,0x39,0xA1,0x30,0xAA,0xBB,0x2B,0xF5, + 0x03,0x39,0xC2,0x30,0xE2,0x6A,0x78,0x7A,0xE3,0x38,0x81,0x28,0x7C,0x5E,0x77,0xEF, + 0xA2,0x28,0x61,0x20,0xFE,0x7A,0x7B,0x7A,0xA2,0x28,0x61,0x20,0xF7,0xED,0x2D,0x09, + 0xA2,0x20,0x61,0x20,0x25,0x0C,0x08,0x2A,0xC2,0x28,0x81,0x20,0xBA,0xEA,0x02,0x25, + 0xC2,0x28,0x81,0x20,0xBD,0xA5,0xBB,0xFF,0xA2,0x28,0x81,0x20,0x1A,0xBA,0xFF,0xCA, + 0xA2,0x28,0x81,0x20,0xE2,0xCB,0x2B,0xAF,0xA2,0x28,0x81,0x20,0xA8,0xBE,0xFB,0xD7, + 0xA2,0x28,0x82,0x20,0xAE,0xEF,0xEF,0xBF,0xA2,0x28,0x61,0x20,0xAA,0xFB,0xDF,0xFC, + 0xA2,0x28,0x61,0x20,0x3E,0xAE,0xBF,0x3F,0xA2,0x30,0x81,0x20,0x3F,0xBE,0x37,0x3E, + 0x03,0x39,0xA2,0x28,0xBD,0xAF,0xA9,0xAF,0xE3,0x38,0xC2,0x30,0xAD,0xA9,0x08,0x80, + 0xE2,0x38,0xC2,0x30,0xEA,0x66,0xFE,0xF4,0xE3,0x38,0xA2,0x28,0x5E,0xFB,0xFA,0xF8, + 0xC2,0x30,0xA2,0x28,0xFA,0xBF,0x3C,0x13,0xE2,0x30,0xA3,0x28,0xEE,0xEB,0xAA,0xEA, + 0xE3,0x30,0xA2,0x28,0xB7,0xEB,0x25,0xF5,0xC2,0x28,0xA1,0x28,0x30,0xF8,0x57,0x55, + 0xC2,0x28,0x61,0x28,0x02,0x88,0xAA,0xAE,0xC2,0x28,0x81,0x20,0xA8,0xFA,0x7A,0x7E, + 0xC2,0x28,0x82,0x28,0xAB,0x0E,0x0D,0x2B,0xE3,0x30,0xA2,0x28,0x5D,0xC3,0xFB,0xBB, + 0xE3,0x30,0xA2,0x28,0xB5,0xD5,0x55,0x56,0xE3,0x30,0xA2,0x28,0xAE,0xAB,0x01,0x03, + 0x03,0x31,0xA2,0x28,0x3F,0xFF,0xDE,0xBF,0xE3,0x30,0xC2,0x30,0x82,0x73,0xE3,0x00, + 0x03,0x39,0xA2,0x28,0xF7,0xA7,0x3F,0x0E,0x03,0x39,0xC3,0x30,0xB5,0xFE,0xCE,0xAA, + 0x24,0x39,0xE3,0x30,0x59,0x6B,0x59,0x7F,0xE2,0x30,0xA2,0x30,0x0A,0x0A,0x2F,0xB5, + 0x03,0x39,0xC2,0x30,0xEB,0xAA,0xFF,0xFD,0x44,0x41,0xA2,0x30,0xAF,0x8D,0xAF,0xEF, + 0x23,0x39,0xC2,0x30,0x5E,0x7A,0xAC,0x28,0x03,0x31,0xC2,0x30,0x75,0x5E,0xBC,0xEA, + 0xE3,0x30,0xA1,0x28,0xBA,0xE0,0xBA,0xD6,0x03,0x31,0xC2,0x30,0x2B,0xEE,0x2F,0xDF, + 0x03,0x31,0xC2,0x30,0x7A,0x88,0x2A,0xFB,0xE3,0x30,0xA2,0x28,0x55,0x57,0xDC,0x28, + 0xC2,0x30,0xA2,0x28,0x79,0x62,0x72,0x52,0xE3,0x30,0x81,0x20,0x0B,0xB7,0xB5,0xEF, + 0xE3,0x30,0xC2,0x28,0xE0,0xB0,0xEF,0xE5,0xE3,0x30,0xC2,0x28,0xBA,0xEF,0x8E,0xAD, + 0xE3,0x30,0xC2,0x28,0xA6,0x07,0xFE,0x6F,0x03,0x31,0xC2,0x30,0x55,0xD7,0xBD,0x9B, + 0xE2,0x30,0xC2,0x28,0xED,0xB3,0x00,0x00,0x23,0x39,0xC2,0x28,0xDD,0xFF,0xFF,0xCA, + 0x23,0x39,0xE3,0x30,0x8F,0x2F,0x7F,0xFB,0x03,0x31,0xC2,0x30,0x88,0xFE,0xFE,0xBF, + 0x03,0x39,0xC2,0x28,0x37,0xB7,0xBF,0xFB,0x03,0x39,0xE2,0x30,0x82,0xA2,0xFD,0xB5, + 0x23,0x39,0xE2,0x30,0x9F,0x9E,0x1F,0x3F,0x23,0x41,0xE2,0x38,0xD5,0xB7,0x9B,0x06, + 0x85,0x49,0x03,0x39,0xBD,0xBD,0xAF,0x2F,0xC5,0x51,0x64,0x49,0x55,0x9D,0xEB,0x32, + 0xE5,0x59,0x64,0x49,0xFD,0xB5,0xEB,0x2A,0xC9,0x7A,0xA5,0x51,0xB5,0xBD,0xAF,0x2F, + 0x8C,0x93,0xA8,0x72,0xAD,0xFD,0xFF,0x8A,0x4A,0x8B,0x87,0x72,0x88,0xDF,0x57,0xA0, + 0x0A,0x83,0x47,0x6A,0x00,0xFE,0xDF,0xF8,0xE9,0x7A,0x26,0x62,0x08,0xFD,0xDD,0xAA, + 0xC8,0x72,0x26,0x62,0xE8,0x5F,0xFF,0xBF,0xA8,0x72,0x06,0x5A,0xF8,0x77,0xFE,0x02, + 0xA9,0x72,0xE6,0x51,0x57,0x75,0xEB,0x02,0xC9,0x72,0xE6,0x51,0x55,0x77,0xBA,0x00, + 0xA9,0x72,0x07,0x5A,0xF5,0xBF,0xBB,0x00,0xC9,0x72,0x27,0x62,0xF7,0xFF,0xE8,0x2A, + 0xA9,0x72,0x47,0x62,0xEB,0xE9,0xEF,0x0A,0xA9,0x72,0x07,0x62,0xFF,0x7F,0xF8,0xB8, + 0x68,0x6A,0x06,0x5A,0xB9,0xEA,0x82,0x88,0x68,0x6A,0x27,0x62,0x56,0xFE,0xB0,0x20, + 0x0A,0x7B,0x06,0x5A,0x2D,0xF7,0xFF,0x7F,0x8C,0x8B,0x47,0x62,0x00,0x2B,0xAD,0xB5, + 0xAD,0x93,0x4B,0x83,0x2F,0xAE,0xFF,0x75,0xAD,0x93,0x6B,0x8B,0x0A,0x3F,0xB5,0x7B, + 0xAC,0x8B,0x6B,0x8B,0x2C,0x2F,0xB5,0x25,0xAC,0x93,0x6C,0x8B,0x00,0xEC,0xAA,0x7E, + 0xCD,0x93,0x6B,0x8B,0x5C,0x57,0xA5,0xDB,0xAD,0x93,0x6B,0x8B,0x2C,0xAE,0xAE,0x1E, + 0x23,0x49,0xC2,0x40,0xF6,0x82,0xA8,0xA8,0x23,0x49,0xE2,0x40,0xAB,0xAE,0xBA,0xE2, + 0x43,0x51,0xE2,0x40,0x8A,0xE3,0xEF,0xE7,0x23,0x49,0xE2,0x40,0xCF,0xB7,0x2B,0xAA, + 0x23,0x49,0xE2,0x40,0x57,0xD5,0xDC,0xAA,0x23,0x49,0xC1,0x38,0xA7,0xAE,0xEA,0x8A, + 0x23,0x49,0xE2,0x38,0xBF,0xBD,0xAF,0x2E,0x24,0x41,0xE2,0x40,0xD5,0x47,0xFB,0xEF, + 0x03,0x41,0xE2,0x38,0x5E,0x5C,0x28,0x80,0x23,0x41,0xC1,0x40,0x2D,0xAF,0xAA,0xAA, + 0x43,0x49,0xE2,0x40,0xBE,0xBE,0x9B,0x00,0x22,0x49,0x03,0x41,0x62,0x60,0xEA,0xAE, + 0x23,0x49,0xE2,0x40,0x0A,0x2A,0xF7,0xF7,0xC4,0x59,0x02,0x41,0x2F,0xA5,0x55,0x55, + 0x46,0x72,0x02,0x49,0x0A,0xBF,0xFD,0x75,0xA7,0x7A,0xA3,0x59,0x02,0x2F,0xAD,0xB5, + 0xC8,0x82,0x25,0x72,0xA0,0xF2,0xBE,0xD5,0xC7,0x82,0x45,0x72,0xA8,0xAA,0xFD,0x75, + 0xE7,0x82,0x46,0x72,0xA0,0xAA,0xAB,0xFD,0x86,0x7A,0xC4,0x61,0xC0,0x40,0x78,0x5E, + 0x06,0x6A,0x64,0x51,0xA2,0xBE,0xDF,0x57,0xE5,0x61,0x43,0x51,0x80,0xAC,0xFE,0x55, + 0xE5,0x61,0x43,0x51,0x00,0x0A,0xAE,0xA5,0x05,0x6A,0x84,0x51,0xA8,0xEE,0x7F,0xDA, + 0xC5,0x61,0x43,0x51,0xF2,0x6A,0x78,0xFA,0x83,0x51,0x03,0x49,0xAA,0xFF,0x7A,0xAA, + 0x64,0x51,0x23,0x49,0xAD,0xE5,0xC5,0x7D,0x64,0x49,0x23,0x49,0x08,0x02,0x03,0x03, + 0x63,0x49,0x22,0x41,0xE6,0x8C,0x00,0x0E,0xC6,0x59,0x23,0x41,0xBD,0x2D,0x2F,0x8B, + 0xC5,0x59,0x44,0x41,0xA2,0xA8,0x6A,0xDE,0xA5,0x51,0x64,0x49,0x6A,0xE6,0x3D,0xBB, + 0x85,0x49,0x44,0x49,0xE2,0xE8,0xF8,0x9E,0x64,0x49,0x44,0x49,0xA2,0x7A,0xF8,0xFB, + 0x85,0x51,0x24,0x41,0xA3,0xEF,0xFB,0xFD,0x64,0x49,0x23,0x49,0x30,0x83,0xA9,0xED, + 0x43,0x49,0x03,0x41,0xFC,0xBC,0xAA,0xB2,0xE6,0x61,0x23,0x41,0x55,0x55,0xF7,0x2D, + 0xE6,0x61,0x03,0x41,0x55,0xDF,0xBF,0x00,0xE6,0x61,0x23,0x41,0x55,0xFA,0x82,0x00, + 0xC5,0x61,0x03,0x41,0x55,0x77,0xFE,0x80,0x64,0x49,0x03,0x41,0x75,0xFF,0xBF,0xA8, + 0x85,0x49,0x03,0x41,0x7B,0x5A,0xFB,0xCA,0x23,0x41,0xE2,0x38,0x2F,0x2F,0xBE,0x7A, + 0x23,0x41,0xC2,0x30,0xEB,0x6B,0xA0,0xE2,0x03,0x39,0xA2,0x30,0xFD,0x2F,0x2A,0xAA, + 0x03,0x39,0xC2,0x30,0xE2,0xE2,0x80,0x00,0x03,0x39,0xA2,0x28,0x77,0x7F,0x7C,0x78, + 0xC2,0x28,0x61,0x20,0x7E,0xFE,0xBE,0x3F,0xE3,0x30,0x61,0x20,0xFD,0xAF,0x2A,0x00, + 0x04,0x31,0x81,0x20,0x5D,0xD7,0xA8,0x80,0xE3,0x30,0x81,0x20,0xD5,0xFE,0xA2,0xE8, + 0xE2,0x28,0xA2,0x28,0x5F,0x7B,0xFE,0xF2,0xA2,0x28,0x81,0x20,0xC8,0x48,0x40,0xE0, + 0xA2,0x28,0x81,0x20,0xFD,0x69,0xBF,0xB7,0xA2,0x28,0x61,0x20,0xAE,0xAF,0x0F,0x0A, + 0xA2,0x28,0x82,0x28,0xB7,0x3F,0x3F,0xF3,0xC2,0x30,0x82,0x28,0x54,0xF6,0x7F,0xF5, + 0xA1,0x28,0x61,0x20,0xBE,0xCF,0xFD,0xEF,0xC3,0x30,0x82,0x28,0xF7,0xFD,0xDD,0x49, + 0x03,0x41,0x82,0x28,0xAF,0x0D,0x3F,0x0B,0x23,0x41,0xC3,0x38,0x6F,0xFB,0xE0,0x08, + 0x23,0x41,0xA1,0x30,0xDD,0xAF,0xE8,0x28,0xE2,0x38,0xA2,0x30,0xF8,0xFA,0xE8,0xE8, + 0xC2,0x30,0xA2,0x28,0xBF,0xDE,0xD8,0x58,0xC2,0x30,0x81,0x28,0x00,0xAA,0xF8,0xFA, + 0xC2,0x28,0x81,0x28,0x3A,0xBB,0xBB,0xAB,0xE2,0x30,0x81,0x28,0x7F,0xEB,0xA3,0xAA, + 0xC3,0x30,0x81,0x28,0xF5,0xFF,0xBE,0x02,0xC2,0x28,0x81,0x28,0xE7,0xF7,0xFF,0xA8, + 0xA2,0x28,0x81,0x20,0x02,0x05,0x2D,0x80,0xC3,0x30,0x81,0x28,0x0A,0xAB,0x7F,0xD5, + 0xC2,0x28,0x81,0x20,0x2A,0x2B,0xD7,0xDD,0x03,0x39,0xA2,0x28,0x2B,0x23,0xAD,0x0D, + 0x03,0x39,0xE3,0x28,0xFF,0x94,0xA6,0x08,0xE2,0x30,0xC2,0x28,0x80,0x88,0x26,0x26, + 0x03,0x39,0xC2,0x30,0xAA,0xFC,0xF8,0xF6,0x03,0x39,0xC3,0x30,0x5E,0xAB,0xA3,0xF8, + 0x03,0x39,0xE3,0x30,0x61,0x7A,0x78,0x68,0xE3,0x30,0xA2,0x30,0xDA,0x7A,0xAA,0x02, + 0xC2,0x30,0xA2,0x30,0x22,0xAB,0xB8,0x2C,0x03,0x39,0xC2,0x30,0xF3,0x25,0x25,0xED, + 0x23,0x39,0xE2,0x30,0x6A,0xFE,0xFA,0xA3,0x03,0x39,0xE2,0x30,0xAD,0xAD,0xF6,0xB8, + 0x03,0x31,0xC2,0x30,0xD7,0x6B,0x7A,0x7A,0xE2,0x30,0xA2,0x28,0xA2,0xBE,0xEF,0xFA, + 0x03,0x39,0xC2,0x28,0x9D,0xFC,0xFA,0x59,0xE2,0x30,0xA2,0x28,0xAC,0xBE,0xCE,0xAF, + 0xE2,0x30,0xA1,0x28,0x5A,0xFA,0xFB,0xBA,0xC2,0x28,0xA1,0x28,0x27,0x0E,0x00,0x00, + 0xE3,0x30,0xC2,0x28,0xCD,0x0B,0x25,0x2D,0xE3,0x30,0xC2,0x30,0xE5,0xBE,0xA0,0x20, + 0x03,0x39,0xC2,0x28,0xF7,0xFB,0x2A,0x6A,0x03,0x31,0xC2,0x28,0xDA,0xFA,0xAB,0xAA, + 0x03,0x31,0xC2,0x28,0x3F,0xBD,0xAF,0xF7,0x03,0x31,0xE2,0x30,0xC4,0x3E,0xF9,0x63, + 0x03,0x31,0xC2,0x30,0x08,0x2C,0xC0,0x82,0x03,0x31,0xC2,0x28,0xAC,0x70,0x60,0x80, + 0x03,0x31,0xC2,0x30,0xB4,0xAB,0xFD,0x7A,0x23,0x39,0xC2,0x30,0xFE,0x97,0xAD,0x27, + 0x44,0x41,0x03,0x39,0xDD,0xB6,0xE3,0xE3,0x64,0x49,0x23,0x41,0x5F,0x5D,0x4F,0xA3, + 0x85,0x51,0x03,0x39,0x25,0xBD,0xAF,0xEC,0xC5,0x51,0x43,0x41,0xE2,0xAA,0xBF,0xD5, + 0x26,0x62,0x43,0x49,0xAF,0x2F,0x2F,0xBD,0x0D,0xA4,0x26,0x62,0xBD,0xAD,0x2F,0x0F, + 0x6E,0xAC,0x6B,0x8B,0xED,0xAF,0x0A,0x00,0x6E,0xAC,0xED,0x9B,0x57,0x2A,0x82,0x00, + 0x6E,0xAC,0x2A,0x83,0x7F,0xA8,0x20,0x00,0x6E,0xAC,0x2A,0x83,0x55,0xFE,0xAA,0x00, + 0x6F,0xAC,0xE9,0x7A,0x55,0xFE,0xA2,0x08,0x2E,0xA4,0xE9,0x7A,0x55,0x7F,0xEC,0x80, + 0x8B,0x8B,0xA9,0x72,0xFD,0xFA,0xA2,0xA0,0x4B,0x8B,0xC9,0x72,0x77,0xFE,0x72,0xF8, + 0x09,0x7B,0xC9,0x72,0xBB,0xEB,0x82,0x6A,0xE9,0x7A,0xA8,0x72,0x35,0x17,0xEE,0xFA, + 0xE9,0x7A,0xA8,0x72,0x69,0xBA,0x02,0xA6,0xE9,0x72,0x67,0x6A,0xD6,0x7F,0xAE,0xE8, + 0xC9,0x72,0x67,0x6A,0x56,0xDE,0xFE,0xD0,0xA8,0x72,0x67,0x6A,0x4F,0xA3,0xF7,0xBB, + 0x88,0x6A,0x47,0x62,0x67,0x4B,0x76,0xA8,0xA8,0x72,0x06,0x5A,0x2F,0x5F,0xFA,0xBB, + 0x6C,0x8B,0x47,0x62,0x0A,0x2D,0xB5,0x55,0x8B,0x8B,0xA8,0x6A,0x80,0x00,0x0B,0xAD, + 0xAC,0x93,0x6B,0x83,0xFF,0xAB,0xE9,0xBD,0x8B,0x8B,0x4B,0x83,0xEE,0xEA,0xEA,0x26, + 0x8C,0x8B,0x2A,0x83,0xAE,0xF7,0xAB,0xA2,0xAC,0x93,0x4B,0x83,0xAB,0xAB,0x6A,0xFA, + 0x23,0x49,0xE2,0x40,0x3A,0xBA,0xAC,0x7A,0x23,0x49,0xE2,0x40,0x2C,0x0A,0xAD,0x41, + 0x02,0x49,0xE2,0x40,0x28,0xBA,0xBE,0x07,0x23,0x49,0xE2,0x40,0xB0,0xEE,0xE7,0x8B, + 0x23,0x49,0xE2,0x40,0x8A,0x08,0x28,0xAE,0x23,0x49,0xC2,0x38,0x2B,0x26,0xAA,0xBA, + 0x23,0x49,0xE2,0x40,0x8B,0xAE,0x2E,0x3C,0x22,0x41,0xE2,0x40,0x6B,0x3E,0x20,0x2A, + 0x23,0x49,0x02,0x41,0x61,0xEB,0xEC,0x77,0x23,0x41,0xE2,0x38,0x2B,0xBA,0xAF,0xEB, + 0x43,0x49,0x02,0x41,0x3F,0xFD,0xCF,0x85,0xE2,0x48,0x22,0x41,0xBD,0xA9,0xEB,0xBF, + 0x23,0x49,0xE2,0x40,0xFD,0xBF,0xEE,0x62,0x03,0x49,0xC2,0x40,0x0A,0xFA,0xFE,0xFF, + 0x63,0x51,0xC2,0x40,0xBD,0xB5,0x3F,0xBF,0x25,0x6A,0x63,0x51,0x09,0x8D,0x8F,0xAD, + 0x25,0x6A,0xC4,0x61,0x0F,0xED,0x0F,0x22,0x47,0x72,0xE5,0x61,0xA2,0xED,0xE5,0xD7, + 0x46,0x72,0xC5,0x59,0x8A,0xAE,0xFB,0x56,0xE5,0x61,0x43,0x51,0x20,0xF8,0xB8,0x5E, + 0xA4,0x59,0x02,0x49,0xF8,0x5E,0x57,0x57,0x24,0x49,0xA3,0x40,0xE8,0xFE,0xDF,0xB7, + 0x84,0x59,0xE2,0x40,0x0F,0x2D,0x2D,0x2D,0xC4,0x59,0x84,0x59,0xC2,0xAA,0x8D,0xEB, + 0xC5,0x59,0x63,0x51,0xDE,0xEA,0x82,0xA2,0xA4,0x59,0x63,0x51,0xD7,0xDC,0x60,0x72, + 0x84,0x51,0x43,0x49,0xF5,0xCF,0x8A,0x2B,0xA4,0x51,0x64,0x51,0x79,0xED,0x7B,0x5D, + 0xA4,0x51,0x43,0x49,0xB7,0xB5,0xAF,0x2B,0xA5,0x51,0x44,0x49,0x80,0xA0,0xB8,0xD8, + 0x84,0x51,0x44,0x49,0xAA,0xE8,0xF7,0xFF,0x84,0x49,0x44,0x49,0x01,0xA1,0xFD,0xDE, + 0x64,0x49,0x23,0x41,0x08,0xAA,0x7A,0x80,0x64,0x49,0x23,0x41,0x2E,0xE2,0xEF,0xDF, + 0x64,0x51,0x23,0x49,0xAF,0x0A,0xBE,0x27,0xA4,0x59,0x23,0x49,0xDF,0x7F,0xDE,0x3B, + 0x06,0x6A,0x02,0x41,0xF5,0xBF,0x2B,0x0E,0x06,0x6A,0x64,0x51,0x0D,0x0B,0x82,0xA0, + 0x47,0x72,0x43,0x51,0x8A,0xA2,0xA3,0xD7,0xE5,0x61,0x83,0x59,0x88,0xBA,0xE2,0x55, + 0xE6,0x61,0x84,0x51,0xE0,0xAB,0xED,0x7F,0x85,0x51,0x03,0x41,0xD8,0xF8,0x7A,0x5A, + 0x64,0x49,0x02,0x41,0x2A,0xFF,0x7D,0x55,0x23,0x41,0xC2,0x38,0x68,0xE0,0xEA,0xBA, + 0x23,0x41,0xE3,0x38,0x82,0x03,0xEB,0xF9,0x03,0x39,0xC2,0x30,0x8A,0xA8,0xF0,0x7E, + 0x23,0x39,0xC2,0x30,0xAB,0xAF,0xFF,0xD5,0x03,0x39,0x82,0x20,0x70,0xF0,0xF0,0xFA, + 0xC2,0x28,0x61,0x20,0x3F,0xB7,0xBD,0x17,0x03,0x31,0xC3,0x28,0x0A,0x03,0x03,0xFD, + 0x03,0x31,0xC3,0x28,0x20,0x62,0x77,0x55,0xC3,0x28,0x62,0x28,0xA8,0x2A,0xA8,0xE8, + 0xC2,0x30,0x81,0x28,0x02,0xBC,0xAC,0xB7,0xC2,0x28,0x81,0x28,0xFA,0x7A,0x6F,0xAF, + 0xA2,0x30,0x81,0x20,0xEF,0xFD,0x5F,0x28,0xC3,0x30,0x81,0x28,0xED,0xF5,0x35,0x3C, + 0x44,0x41,0x81,0x28,0xD5,0xBF,0xBB,0x82,0x24,0x41,0xA2,0x30,0x57,0x5A,0xA8,0x82, + 0xE3,0x38,0x61,0x28,0x57,0xFF,0xEA,0xA0,0xA2,0x30,0x82,0x28,0x8D,0xB7,0xBB,0x88, + 0x24,0x41,0xA2,0x30,0xAD,0x2F,0xAD,0xAD,0x44,0x49,0x03,0x41,0xAF,0xBA,0xAB,0x9F, + 0x44,0x49,0x03,0x39,0xDE,0x7C,0x7E,0xC0,0x23,0x41,0xA2,0x30,0xFE,0xEA,0xEA,0xFC, + 0xE2,0x38,0x81,0x28,0x7A,0xEA,0xAA,0x00,0xC2,0x30,0x81,0x28,0xFF,0x7A,0xE8,0xDA, + 0xE2,0x30,0x81,0x20,0xFF,0xAD,0x0B,0x2A,0x24,0x39,0xC2,0x28,0xFD,0xBF,0xAF,0x0A, + 0x24,0x39,0xE3,0x30,0x55,0xE7,0x0B,0x02,0x44,0x39,0xC2,0x30,0x5F,0x7A,0xE8,0x0A, + 0x44,0x39,0xA2,0x28,0x57,0x57,0xFF,0xE8,0x03,0x31,0x82,0x28,0x77,0xFF,0xE2,0xAA, + 0xE3,0x30,0x81,0x28,0x77,0xFF,0xBE,0x02,0x04,0x39,0xA2,0x28,0x09,0xAD,0x2F,0x3A, + 0x24,0x39,0xE2,0x30,0xAA,0xEF,0xEF,0xFD,0xE2,0x30,0xA2,0x28,0x00,0x02,0x00,0xF8, + 0xE3,0x30,0xA2,0x28,0xBE,0xA6,0xFA,0xE3,0xC2,0x30,0xA2,0x28,0x00,0x0E,0x2D,0x2F, + 0x03,0x39,0xC3,0x30,0xC2,0xEB,0xFF,0xF7,0xE2,0x30,0xA1,0x30,0xC8,0xA9,0xE6,0xAE, + 0xE2,0x30,0xC2,0x30,0x57,0x57,0xD5,0x8D,0x03,0x39,0xC2,0x30,0xB5,0x3D,0x97,0xD7, + 0x44,0x39,0xE2,0x30,0xFB,0xDE,0xAE,0xF7,0x03,0x31,0xE2,0x30,0x03,0x82,0xBE,0xB6, + 0x03,0x31,0xC2,0x30,0x8F,0x8A,0x62,0xF8,0xE2,0x30,0xA2,0x28,0xEA,0x7A,0x6F,0xEC, + 0xE3,0x30,0xA2,0x28,0xFD,0xA9,0xAD,0x8B,0xE3,0x30,0xA2,0x28,0xAD,0xEB,0x6B,0x7A, + 0xE2,0x28,0xA1,0x28,0xBF,0x6F,0x55,0xA5,0xC2,0x28,0xA2,0x28,0x80,0x8B,0xF9,0xF8, + 0xE2,0x28,0xA1,0x28,0xAA,0xDA,0xF7,0x55,0xE3,0x30,0xA1,0x28,0x23,0x0E,0xAB,0x9B, + 0x03,0x31,0xC2,0x28,0xE3,0xB2,0xEB,0xDF,0x03,0x31,0xE3,0x30,0xCD,0xEF,0xA5,0xF7, + 0x02,0x31,0xC2,0x30,0x5B,0xCA,0xDE,0xFE,0x03,0x31,0xC2,0x28,0xA8,0xBB,0xFD,0xEB, + 0x23,0x31,0xC2,0x30,0xFF,0x7E,0xF7,0xD5,0x23,0x31,0xC2,0x30,0xCB,0xFF,0xFB,0x9E, + 0x02,0x39,0xC2,0x30,0x7A,0xE2,0xFA,0xAC,0x24,0x39,0xC2,0x30,0xB5,0xA5,0x25,0xB5, + 0x64,0x41,0xE2,0x38,0xF3,0xFF,0xD7,0x57,0x85,0x49,0x24,0x41,0xFB,0xAD,0xAD,0x29, + 0xA5,0x51,0x43,0x41,0xDD,0xFD,0x6B,0x8A,0xC6,0x59,0x43,0x49,0x75,0xFD,0x97,0x27, + 0x09,0x83,0x43,0x49,0xFD,0xBD,0x2F,0x2F,0xAF,0xB4,0xA8,0x72,0xAD,0xAF,0x2F,0x2A, + 0xD0,0xBC,0x6E,0xAC,0x75,0xFF,0xA3,0xA2,0xAF,0xB4,0x4E,0xAC,0xFF,0x7E,0xBA,0xFE, + 0x8F,0xB4,0x6E,0xAC,0xDD,0xBA,0x0A,0x0F,0xAF,0xB4,0x4E,0xAC,0xDF,0xBA,0x00,0xA2, + 0xAF,0xB4,0x6E,0xAC,0x57,0xF5,0x2A,0x00,0xAF,0xB4,0x0D,0xA4,0x6A,0xAA,0xE8,0x20, + 0x4F,0xAC,0x6B,0x8B,0x57,0x58,0x78,0xC0,0x4B,0x8B,0x0A,0x83,0xEE,0xFA,0x5F,0x5A, + 0x0A,0x7B,0xC9,0x72,0xA2,0xE0,0xE8,0x68,0xE9,0x7A,0xA8,0x72,0xFA,0x62,0x5A,0x7A, + 0xA8,0x72,0x47,0x62,0x20,0x00,0xEA,0xDA,0xC9,0x72,0x47,0x62,0x02,0x8E,0x8F,0xB5, + 0xE9,0x7A,0x88,0x6A,0x7F,0x9E,0x83,0xCA,0xC9,0x72,0x67,0x6A,0xFD,0xBF,0x38,0xAA, + 0xC9,0x72,0x67,0x62,0x5A,0xFA,0x88,0xC0,0xA8,0x72,0x47,0x62,0xDF,0xF8,0xE0,0xE8, + 0x87,0x6A,0x27,0x62,0x56,0xF7,0x6E,0xCB,0xE9,0x7A,0x06,0x5A,0x2F,0xFF,0xD5,0x57, + 0x6B,0x83,0x06,0x5A,0x00,0x02,0x2D,0x35,0x8C,0x8B,0x4B,0x83,0xEA,0x3A,0x2C,0x35, + 0x8C,0x8B,0x4B,0x83,0xB8,0xE8,0x30,0x9A,0x8C,0x8B,0x4B,0x83,0x9E,0xBA,0xAE,0xDC, + 0x23,0x49,0xE3,0x40,0xFA,0xE8,0xBF,0x2D,0x23,0x49,0xE2,0x40,0xA5,0xAD,0xFA,0x5E, + 0x23,0x41,0xC2,0x40,0x7F,0xFC,0xBE,0xFA,0x23,0x41,0xC2,0x40,0xAA,0xA9,0x2A,0xAB, + 0x23,0x49,0xE2,0x40,0xBE,0x9E,0xFE,0xEA,0x23,0x49,0xE2,0x40,0x56,0xDE,0x1E,0xED, + 0x23,0x49,0xE2,0x40,0xAF,0xFF,0xFE,0x88,0x43,0x49,0xE2,0x40,0xFF,0xEF,0xA7,0xAC, + 0x43,0x49,0xE2,0x40,0xFB,0x6B,0xE0,0xD0,0x23,0x41,0xE2,0x40,0xAB,0x89,0x8B,0xAA, + 0x43,0x49,0x03,0x41,0xF5,0xD7,0xB7,0xA4,0x43,0x49,0x03,0x41,0x9F,0x3E,0xA8,0xBF, + 0x43,0x49,0xE3,0x40,0x78,0xC8,0xAF,0xEF,0x02,0x41,0xC2,0x40,0xBF,0xDF,0x5C,0xA0, + 0x23,0x49,0xE2,0x40,0x3F,0x3F,0xDD,0xF7,0xE5,0x61,0x03,0x49,0x2F,0x3F,0xB5,0xF5, + 0x05,0x6A,0xA4,0x59,0x0A,0xAE,0xC2,0x2D,0x26,0x6A,0x84,0x59,0xA8,0xE2,0x7A,0x7A, + 0xE5,0x61,0x03,0x49,0xA8,0xEA,0xFE,0x7F,0x84,0x59,0xE2,0x40,0xA0,0xE0,0xFF,0xDD, + 0x03,0x49,0xC2,0x40,0xA8,0xEA,0xFE,0x9A,0x03,0x49,0xC2,0x40,0xBA,0x88,0x78,0x9A, + 0x85,0x59,0xE2,0x40,0x3D,0x3D,0x35,0x27,0xE6,0x61,0xA5,0x59,0xED,0xD6,0xB6,0x09, + 0xE6,0x61,0xA5,0x59,0x5D,0x76,0xDA,0xBB,0xC5,0x59,0x64,0x51,0x5A,0x60,0xFC,0xF8, + 0x84,0x51,0x43,0x51,0xAA,0x8B,0x8B,0x04,0xC5,0x51,0x64,0x51,0xFD,0xFD,0xED,0xBF, + 0xC5,0x59,0x84,0x51,0xB5,0xBA,0x6D,0xD8,0xA5,0x51,0x64,0x49,0xF8,0xEE,0xD6,0x58, + 0x85,0x51,0x44,0x49,0xEC,0xBA,0xEF,0xBF,0x84,0x49,0x23,0x41,0xF8,0x5E,0xFA,0x80, + 0x85,0x51,0x23,0x49,0xFB,0xFB,0x6A,0xFA,0x64,0x49,0x23,0x49,0x97,0x6F,0xDF,0xFA, + 0x25,0x6A,0x23,0x49,0xF5,0x3D,0x0F,0x23,0x65,0x72,0xC4,0x59,0xB5,0x8E,0x22,0xEA, + 0x66,0x72,0xA3,0x59,0xAA,0xA8,0xF8,0x7E,0x06,0x6A,0x84,0x51,0xA8,0xA8,0xEA,0x5F, + 0xC5,0x59,0x64,0x51,0x56,0xD4,0x7E,0x7B,0x64,0x51,0x23,0x49,0x80,0x08,0xFA,0x57, + 0xC5,0x59,0x43,0x49,0xCA,0xAB,0xEB,0xFD,0x64,0x49,0x03,0x41,0xFA,0x5E,0x7C,0xDC, + 0x23,0x41,0xA2,0x30,0xAA,0xAA,0xFA,0x7A,0x03,0x39,0xC2,0x38,0xA2,0xAE,0xB7,0x25, + 0x03,0x39,0xC2,0x30,0x3B,0xBF,0x5F,0xD0,0xE3,0x38,0x61,0x28,0xB0,0xE8,0xA8,0xAA, + 0xC2,0x30,0x61,0x28,0x2A,0xAB,0xEE,0xFA,0xC2,0x28,0x81,0x28,0xAA,0xFD,0xB5,0xDD, + 0xA2,0x28,0x61,0x20,0x3F,0xBA,0xB8,0x2A,0xE3,0x30,0xA2,0x28,0x2F,0xAB,0xAB,0xFD, + 0xE3,0x30,0xA2,0x28,0x7E,0x7A,0xBC,0xB6,0xC3,0x30,0x82,0x28,0xFF,0xEA,0x0A,0x80, + 0xE3,0x30,0x82,0x20,0xDF,0xD5,0xFB,0xEF,0x44,0x41,0xA2,0x28,0xD5,0xFD,0xAD,0x2F, + 0x44,0x41,0xA2,0x30,0xBD,0x2F,0x88,0x80,0x65,0x49,0x03,0x39,0xD7,0xFF,0xEF,0x3D, + 0x65,0x49,0xC3,0x38,0xEA,0xE8,0xFA,0x58,0x24,0x41,0xC2,0x38,0x0A,0x2A,0x3E,0xFD, + 0x23,0x41,0xE3,0x38,0xDF,0xE6,0xE8,0xA0,0x23,0x41,0xA2,0x30,0xD7,0xEF,0xAA,0x0A, + 0x03,0x41,0xE2,0x38,0x7D,0x6D,0xD7,0x5C,0x44,0x49,0xE2,0x38,0xFF,0xCD,0xB5,0xB5, + 0x85,0x51,0x23,0x41,0xFF,0xFD,0x8D,0xC9,0x84,0x51,0x03,0x39,0x57,0xFF,0xAB,0xA2, + 0x43,0x49,0xE2,0x38,0x5F,0x7E,0x78,0x60,0xE2,0x30,0xA2,0x30,0x7F,0x7F,0xFC,0xD7, + 0xE2,0x30,0xA1,0x28,0x3D,0xB5,0xBD,0xDF,0x03,0x39,0xA2,0x28,0x02,0x2F,0xBF,0x57, + 0x24,0x39,0xC2,0x30,0xA0,0x82,0xEF,0xF5,0x44,0x41,0xE3,0x30,0x2D,0x2D,0xAD,0xFD, + 0x45,0x39,0xC3,0x30,0xEC,0xFA,0x7A,0xDE,0x23,0x39,0xC2,0x30,0xF8,0xFB,0xAB,0xAD, + 0xE3,0x30,0xA2,0x28,0x28,0xC2,0xB8,0xE0,0xE3,0x30,0xC2,0x28,0x08,0x02,0x20,0x0D, + 0x24,0x39,0xC2,0x28,0xBF,0xFF,0xFF,0x54,0x03,0x31,0xA2,0x28,0x5A,0x54,0x76,0x7F, + 0xE3,0x30,0xA2,0x28,0xE9,0xFB,0x7D,0x7E,0xC2,0x30,0x82,0x28,0x3E,0x3F,0xAB,0xC2, + 0x03,0x39,0xC2,0x30,0xAF,0x8F,0xFB,0xDB,0x03,0x39,0xC2,0x30,0xAF,0x02,0xA2,0xF8, + 0xE2,0x30,0x81,0x28,0xC2,0xC8,0x60,0xC8,0xE2,0x30,0xA1,0x28,0x2A,0xAD,0xEF,0xBD, + 0xE2,0x30,0xC2,0x30,0x02,0xDB,0xEB,0x63,0x03,0x31,0xC2,0x30,0x28,0xA8,0xA0,0x8B, + 0x03,0x31,0xC2,0x30,0x52,0x5E,0xBB,0xF7,0xE3,0x30,0xA2,0x28,0xA8,0xE2,0x80,0x7C, + 0xE3,0x30,0xA2,0x28,0x62,0xFB,0x97,0xF7,0xE3,0x30,0xC2,0x28,0x5D,0x45,0x8D,0x25, + 0xE2,0x30,0xC2,0x28,0x89,0xAB,0x7F,0x77,0xE2,0x30,0xA1,0x28,0x5A,0xDA,0xAA,0x20, + 0xE3,0x30,0x81,0x20,0xDF,0xAE,0x8A,0x8A,0xE2,0x30,0xA2,0x28,0xFB,0xE9,0x8A,0x22, + 0x03,0x31,0xC2,0x30,0x7F,0xF2,0xCA,0xFE,0x23,0x39,0xE3,0x30,0x7F,0xFE,0xDD,0x3F, + 0x23,0x39,0xE3,0x30,0x5F,0xFD,0xEF,0x8B,0x23,0x39,0xC2,0x28,0xFB,0xD7,0xEF,0xB8, + 0x03,0x39,0xC2,0x30,0x57,0x57,0x5C,0x78,0x23,0x39,0xC2,0x30,0xD7,0xD5,0xBF,0xBD, + 0x03,0x39,0xC2,0x30,0x96,0xFF,0xAB,0xBE,0x03,0x39,0xC2,0x30,0xBF,0xBD,0xB7,0x17, + 0x03,0x39,0xC2,0x30,0x3E,0xEE,0xB8,0xBA,0xA5,0x49,0x03,0x39,0xAB,0x2D,0x2D,0xBD, + 0xC5,0x59,0x84,0x49,0xB9,0xFA,0xBB,0xF9,0x06,0x62,0x84,0x51,0xB5,0xAD,0x27,0x2D, + 0xAD,0x93,0x26,0x62,0xB5,0x2D,0x2D,0x0B,0xF0,0xBC,0x0E,0xA4,0xA9,0x2F,0x0F,0x2A, + 0xF0,0xC4,0xAF,0xB4,0x7B,0xEE,0xBE,0x78,0xF0,0xC4,0x8F,0xB4,0x7F,0x78,0xFA,0xBF, + 0xD0,0xBC,0x6E,0xB4,0xF7,0xF7,0xEC,0xFE,0xD0,0xBC,0x8F,0xB4,0xFF,0xBB,0x3D,0xBD, + 0xD0,0xBC,0x8F,0xB4,0xFB,0xBA,0xA8,0xA8,0xCF,0xBC,0x8F,0xB4,0xB6,0xEB,0xE2,0xAB, + 0xAF,0xB4,0x2E,0xA4,0x78,0x68,0xA8,0xA0,0x6E,0xAC,0x2B,0x83,0x57,0x5E,0xFA,0xE8, + 0x6C,0x8B,0xEA,0x7A,0x5F,0x57,0xAF,0xA8,0x2B,0x83,0xA9,0x72,0x5B,0x7A,0x78,0x68, + 0xC9,0x72,0x47,0x62,0xF6,0x7F,0x3A,0xE0,0x87,0x6A,0x26,0x62,0xBE,0xAE,0xBA,0x48, + 0xC9,0x72,0x46,0x62,0xAE,0x2E,0xAF,0x2D,0xE9,0x7A,0xA8,0x72,0x7D,0x7C,0x7E,0x7D, + 0x09,0x7B,0xA8,0x72,0x5B,0x89,0x8B,0x8B,0xE9,0x7A,0x88,0x6A,0x7E,0xFE,0xE2,0x20, + 0xC9,0x72,0x68,0x6A,0x77,0xEB,0xEE,0x80,0x88,0x6A,0xE6,0x59,0x7E,0x7A,0xEA,0x80, + 0x27,0x62,0xC5,0x51,0x29,0xAF,0xDE,0xAC,0x4B,0x83,0xE6,0x51,0x0B,0x35,0xD5,0x55, + 0x6B,0x83,0x06,0x5A,0x00,0x00,0x0A,0xB5,0x8C,0x8B,0x2A,0x7B,0xBA,0xAA,0xB8,0xF5, + 0x02,0x49,0xE2,0x40,0x8B,0x8E,0x9E,0x37,0x22,0x49,0xC2,0x38,0xB7,0xDF,0xBB,0xFC, + 0x03,0x49,0xE2,0x38,0xDA,0xFC,0x7A,0xE2,0x03,0x49,0xE2,0x38,0xAA,0xFA,0xBF,0x2E, + 0x23,0x41,0xE2,0x40,0xCA,0x8A,0x9C,0x3C,0x23,0x49,0xE2,0x40,0x07,0x88,0xBA,0xE8, + 0x23,0x49,0xE2,0x40,0xA8,0xA8,0xB8,0xD7,0x23,0x49,0x02,0x41,0x75,0x54,0x78,0xD8, + 0x64,0x49,0x02,0x41,0xDE,0xBB,0xB3,0xEB,0x43,0x49,0xE2,0x40,0x96,0xFA,0xE2,0xA8, + 0x23,0x49,0xE2,0x40,0x2C,0xDE,0xAE,0x3E,0x23,0x41,0xE2,0x40,0xAE,0xFA,0xF3,0x56, + 0x23,0x49,0xC2,0x38,0xAA,0xA2,0xB5,0x37,0x23,0x49,0xE2,0x40,0x72,0x40,0xA8,0xEE, + 0x23,0x49,0xE2,0x40,0x17,0xBB,0xAB,0xB3,0x23,0x49,0xE2,0x40,0xA6,0xAF,0xA1,0x80, + 0xA5,0x59,0x02,0x41,0x2F,0x2D,0xBD,0xF7,0xC5,0x61,0x23,0x49,0xE0,0xFA,0x7F,0x55, + 0x44,0x49,0xE3,0x40,0xE6,0xBC,0xFA,0xE6,0x03,0x49,0xC2,0x40,0x2A,0xA8,0xFA,0x5F, + 0xE2,0x40,0xC2,0x38,0xA8,0x26,0x1F,0x3B,0x03,0x49,0xC2,0x40,0xBF,0xAE,0x7A,0xFA, + 0xA5,0x59,0x03,0x49,0x35,0x25,0x35,0xA5,0x06,0x62,0xA4,0x59,0xAF,0xEB,0x89,0x8D, + 0x06,0x62,0xA4,0x59,0xEF,0xFF,0xDF,0x5C,0xE5,0x61,0x84,0x51,0x7A,0x7E,0x6B,0xEA, + 0xC5,0x59,0x63,0x51,0xD7,0xBB,0x03,0x09,0xC5,0x59,0x84,0x51,0xD7,0xBE,0xBF,0xFC, + 0xC5,0x59,0x64,0x51,0xE8,0xD8,0xFF,0xFE,0x84,0x51,0x44,0x49,0xF8,0xEE,0xBF,0xBE, + 0xA5,0x51,0x64,0x49,0x5D,0x7D,0xA3,0x7B,0xA4,0x49,0x44,0x49,0xEF,0x7F,0x5F,0xF9, + 0x64,0x49,0x23,0x41,0xA0,0x80,0x22,0x0E,0x64,0x51,0x23,0x49,0x1C,0x3F,0x2A,0x0B, + 0x88,0x7A,0xC5,0x59,0xFD,0xAF,0x29,0x35,0x46,0x72,0xC3,0x61,0xCA,0x6A,0xC0,0xE0, + 0x05,0x6A,0xA3,0x59,0x7E,0xFA,0xE8,0xE8,0x84,0x59,0xE2,0x38,0x00,0xA0,0xF0,0x70, + 0x64,0x51,0xA1,0x30,0x80,0xFA,0xFA,0x57,0x44,0x49,0xA2,0x30,0x2A,0xAF,0x35,0xDF, + 0x64,0x49,0x23,0x41,0x20,0x0A,0x03,0xBD,0x84,0x49,0x03,0x39,0x5B,0x7A,0xF8,0x7A, + 0x03,0x39,0xA2,0x30,0xE8,0xA8,0x2A,0x00,0x23,0x41,0xC2,0x30,0xF5,0xFB,0x82,0x02, + 0x03,0x39,0xC2,0x30,0xF2,0xF0,0xF7,0xE6,0xE3,0x30,0xA2,0x30,0xFE,0xFE,0xFC,0xCA, + 0xC2,0x30,0x82,0x28,0x5C,0xE8,0xA2,0x22,0xC2,0x28,0x81,0x20,0xFB,0xF2,0xEA,0xF8, + 0xC2,0x28,0x81,0x20,0xB5,0x97,0xA5,0xAD,0xA2,0x30,0xC3,0x28,0xFF,0xD7,0x55,0xD7, + 0xE3,0x28,0xA2,0x28,0xBF,0x1D,0x97,0xFF,0xE3,0x30,0xA2,0x28,0xFA,0xFE,0x57,0xDD, + 0xE3,0x30,0xA2,0x28,0x77,0xA7,0xB5,0xBD,0x44,0x41,0xE3,0x30,0x29,0x0B,0x02,0x03, + 0x85,0x51,0x03,0x39,0x5F,0xBA,0x2A,0x2A,0x64,0x49,0x23,0x41,0x15,0x2F,0x8A,0xA0, + 0x65,0x49,0xC2,0x38,0x7A,0xFE,0xFE,0x68,0x03,0x39,0xC2,0x38,0xF9,0xE1,0xAA,0xAA, + 0x23,0x41,0xE3,0x38,0xA3,0xBF,0xBF,0xFF,0x23,0x41,0xE2,0x38,0xEA,0xFC,0x76,0x76, + 0x03,0x41,0xE2,0x38,0x0A,0x09,0xAB,0x83,0x23,0x49,0xC2,0x40,0x2E,0x3A,0xFE,0x5F, + 0x65,0x49,0xE2,0x40,0x0B,0xBB,0xAF,0x5D,0x64,0x49,0x03,0x41,0x00,0x02,0x2D,0xB5, + 0x64,0x49,0x03,0x41,0x48,0x40,0xE0,0x6B,0x23,0x41,0xA1,0x30,0xD5,0x5F,0x7E,0xE8, + 0xC2,0x30,0x61,0x28,0xE8,0x6A,0xA2,0xA2,0xC2,0x30,0x81,0x28,0xF5,0xFD,0xAA,0x0A, + 0xE3,0x38,0x61,0x28,0x0B,0x2F,0xAA,0xA2,0x03,0x39,0xA1,0x28,0x80,0x82,0xAA,0xAB, + 0x03,0x31,0xA2,0x30,0xEA,0x8A,0x0A,0x8A,0x03,0x31,0xA2,0x28,0x8A,0xBE,0xFA,0x7E, + 0xE3,0x30,0x81,0x20,0xE2,0xEF,0xF7,0x7F,0xC2,0x30,0x81,0x28,0x0A,0x3B,0xAF,0xCD, + 0xE3,0x30,0xA2,0x28,0xEA,0x8B,0x89,0x5D,0xE3,0x30,0xA2,0x28,0xFB,0xFF,0xFF,0xDA, + 0xC2,0x30,0xA2,0x28,0xEE,0x7D,0xEA,0xE2,0xE2,0x30,0xA2,0x28,0x6B,0xF9,0x57,0x55, + 0xE2,0x30,0xA2,0x28,0x02,0xAB,0xC9,0x89,0x03,0x39,0xA2,0x28,0xB8,0xCB,0xBF,0x7D, + 0xE3,0x30,0xA2,0x28,0xAB,0x2B,0xEF,0xFD,0xE2,0x30,0xA2,0x28,0xEE,0xF4,0xEA,0x2B, + 0xE2,0x30,0xA2,0x28,0xEB,0xE8,0xBA,0x7A,0xE2,0x30,0xC2,0x28,0x09,0x09,0x87,0x7D, + 0xE2,0x30,0xC2,0x28,0x28,0x72,0x7F,0xE5,0xE2,0x30,0xA2,0x28,0xBC,0x82,0xA2,0xAE, + 0xE2,0x30,0xC2,0x28,0xF5,0x77,0xA0,0x3B,0xE3,0x30,0xA1,0x28,0x0D,0xCD,0xFF,0x5B, + 0xE2,0x30,0xA2,0x28,0xBA,0xBF,0xAF,0xBB,0x03,0x31,0xC2,0x28,0x7E,0x7F,0xF7,0xEB, + 0x03,0x31,0xA1,0x28,0x2F,0xAF,0xA7,0x1E,0x03,0x39,0xE2,0x30,0xB7,0xB2,0x5E,0xFF, + 0xE2,0x30,0xA2,0x28,0xB0,0xF0,0xF2,0xF8,0x03,0x31,0xC2,0x28,0x0B,0x3D,0x95,0xD5, + 0x03,0x31,0xC2,0x30,0x02,0xBB,0xF7,0x7D,0x23,0x39,0xE3,0x30,0xF8,0xFE,0xE5,0xF5, + 0x23,0x39,0xE3,0x38,0x5E,0xF3,0x7D,0x55,0x03,0x39,0xC2,0x30,0x87,0xAE,0xBE,0x3E, + 0x03,0x39,0xE3,0x30,0xBF,0x21,0x21,0x31,0x03,0x39,0xA1,0x28,0xFE,0x7C,0xD8,0xB8, + 0x03,0x39,0xC2,0x30,0xB3,0xAF,0xB9,0xD5,0x44,0x49,0xC2,0x30,0x29,0x07,0x2D,0xBD, + 0xA4,0x51,0x23,0x41,0x22,0xAF,0xBF,0x3D,0x6B,0x8B,0xA4,0x51,0xF5,0xA5,0x25,0x2D, + 0xF0,0xC4,0x4B,0x8B,0xBD,0x2F,0x02,0x02,0x31,0xCD,0xB0,0xB4,0xBD,0xAB,0x82,0x02, + 0x31,0xC5,0xAF,0xBC,0xDF,0xF8,0xA8,0x80,0x10,0xC5,0x8E,0xB4,0x57,0x77,0xFA,0x80, + 0xD0,0xBC,0x4E,0xAC,0xBA,0xFE,0xFE,0x78,0xCF,0xB4,0x6E,0xB4,0xDF,0xFD,0xED,0x75, + 0xAF,0xB4,0x6E,0xB4,0x3C,0xBA,0x7A,0x7D,0xCF,0xBC,0x4E,0xAC,0xA2,0xEA,0xBE,0xDF, + 0xAF,0xB4,0x4E,0xAC,0xF8,0x7E,0x7F,0x57,0x6E,0xAC,0xCC,0x9B,0x58,0xEE,0xAA,0xAA, + 0x4E,0xA4,0x2B,0x83,0x77,0x7F,0xA8,0x80,0xCC,0x9B,0xA9,0x72,0x7F,0x7E,0x7A,0xE8, + 0xEA,0x7A,0x68,0x6A,0xFE,0xFF,0xDA,0xF0,0xA8,0x72,0x47,0x62,0x5E,0xFA,0xCA,0x20, + 0xC8,0x72,0x46,0x62,0xA5,0x2B,0xEA,0xFA,0xE9,0x7A,0x87,0x6A,0xEB,0x8F,0xAD,0x2A, + 0x09,0x7B,0xC9,0x72,0xA9,0xA9,0x3B,0x09,0x2A,0x83,0xC9,0x72,0x7B,0xFB,0xB3,0xCB, + 0x0A,0x7B,0x88,0x6A,0xBF,0xEA,0xDA,0xFC,0xC9,0x72,0x68,0x62,0x7C,0xEA,0x8A,0xB8, + 0xA9,0x6A,0x06,0x5A,0x5F,0xDE,0xF8,0xC8,0x47,0x62,0xC5,0x51,0x7F,0x72,0xF0,0xE0, + 0x88,0x6A,0xA5,0x49,0x37,0x57,0x57,0x5F,0xEA,0x72,0x64,0x41,0x02,0xAF,0xFD,0x55, + 0x43,0x49,0xE2,0x38,0xF7,0xAE,0xE8,0xEB,0x23,0x49,0xE2,0x38,0x7E,0xEE,0xEB,0xFA, + 0x23,0x49,0xE2,0x40,0xAB,0x09,0xC5,0xF7,0x23,0x49,0xC1,0x38,0xA8,0xE8,0xBA,0xBD, + 0x23,0x49,0x02,0x41,0x1F,0xA9,0xDF,0xDE,0x23,0x49,0x02,0x41,0xE0,0xE0,0xD8,0x57, + 0x23,0x49,0xE2,0x40,0xD7,0xBD,0x80,0x00,0x43,0x49,0x02,0x41,0x5F,0x69,0xE3,0xFB, + 0x43,0x49,0x02,0x41,0xA3,0xFE,0xEB,0xEB,0x23,0x49,0x02,0x41,0xAA,0x9A,0x2A,0xB7, + 0x43,0x49,0xE2,0x40,0xBB,0x2E,0xDB,0x5F,0x23,0x41,0xE2,0x40,0x5A,0xDE,0x57,0x77, + 0x23,0x49,0xC2,0x40,0xF5,0xAE,0xAB,0xAB,0x23,0x49,0xC2,0x38,0xCA,0x2B,0xE8,0x5A, + 0x23,0x49,0xE2,0x40,0x3B,0xAB,0xAB,0xED,0x23,0x49,0xE2,0x40,0xAE,0xCA,0xCA,0x4F, + 0x03,0x49,0xE1,0x38,0x23,0xA9,0xE7,0x6F,0x03,0x41,0xC2,0x40,0x02,0x20,0x32,0x02, + 0x23,0x49,0xC2,0x38,0xCA,0x6A,0x68,0xE8,0x03,0x41,0xA1,0x38,0xF2,0xA6,0xAD,0x8A, + 0x03,0x49,0xC2,0x38,0xDF,0xEA,0x82,0xBA,0x23,0x49,0xE3,0x40,0xFA,0xEA,0xBD,0xBD, + 0xA5,0x59,0x03,0x49,0x2D,0x35,0x35,0x25,0x46,0x6A,0xC5,0x59,0x65,0xAF,0x8F,0x0F, + 0x26,0x6A,0xC4,0x59,0xDE,0xFB,0x7B,0xFC,0xE5,0x59,0x84,0x51,0x6A,0xEA,0xAB,0xAB, + 0xE5,0x61,0x84,0x51,0xFD,0xF7,0x32,0x2A,0xA4,0x59,0x64,0x49,0xFE,0xFF,0x08,0x00, + 0xA4,0x51,0x23,0x49,0x8A,0xEA,0xFE,0x7F,0x64,0x49,0x23,0x41,0xC0,0x60,0xAA,0xBE, + 0x85,0x51,0x64,0x49,0x4F,0x95,0x99,0x59,0x84,0x49,0x44,0x49,0xC5,0x5E,0x5A,0xF7, + 0x64,0x49,0x23,0x41,0xAA,0x6B,0x2B,0xA8,0x64,0x51,0x03,0x41,0x8B,0xBE,0xFC,0xDE, + 0x47,0x72,0x44,0x49,0x0F,0xAD,0xB9,0xB5,0x88,0x7A,0xE5,0x61,0xE8,0xF7,0x77,0xDD, + 0x05,0x62,0x43,0x49,0xA0,0xE0,0x68,0x5E,0x63,0x51,0x41,0x28,0xE0,0xF8,0x7A,0x7E, + 0xC2,0x38,0x41,0x20,0x22,0xAA,0xFF,0x7D,0xE2,0x38,0x61,0x28,0xB0,0xF2,0xAB,0xFD, + 0x44,0x41,0xC2,0x30,0x0B,0xBD,0xFD,0xF5,0x43,0x41,0xC2,0x30,0x62,0x7F,0xFF,0x7F, + 0x44,0x41,0xE2,0x30,0xE9,0xAF,0x39,0xCF,0x24,0x41,0xE3,0x30,0x8B,0x8B,0xFE,0xFE, + 0x03,0x39,0xE3,0x30,0xFC,0xA0,0x9E,0x57,0x03,0x31,0xC3,0x30,0xA7,0xF6,0x7C,0xF0, + 0xC2,0x28,0xA2,0x28,0xBE,0xFE,0xBA,0x5D,0xC2,0x28,0x81,0x20,0xF0,0x0B,0x29,0xBD, + 0xC2,0x28,0x81,0x20,0xAA,0xAA,0xBE,0xFF,0xC3,0x28,0xA2,0x28,0x0B,0x09,0x03,0xA2, + 0xC2,0x28,0xA2,0x28,0x90,0x7C,0x68,0xC8,0xC3,0x30,0x82,0x20,0xA2,0xEB,0xAF,0x3F, + 0xE3,0x30,0xA2,0x28,0x3D,0xBB,0x3A,0x3F,0x65,0x49,0x03,0x39,0xA9,0x29,0xAD,0x2D, + 0x85,0x51,0x03,0x39,0x8A,0xBA,0xFE,0x5E,0x44,0x49,0xC2,0x30,0x00,0xA0,0xAA,0xFF, + 0x44,0x49,0xC2,0x30,0x70,0xE8,0xAF,0x55,0x23,0x41,0xC3,0x30,0xB2,0xAA,0x8A,0x6F, + 0x03,0x41,0xE3,0x38,0xF8,0x5A,0x5B,0x55,0x23,0x41,0xC2,0x38,0xFF,0xF5,0xD7,0x56, + 0x23,0x41,0xE2,0x38,0xEA,0xE9,0xE9,0xAE,0x03,0x41,0xC2,0x38,0x5F,0xFE,0xEC,0xE0, + 0xE3,0x40,0xC2,0x38,0x69,0xDA,0xBA,0xBE,0x24,0x49,0xC2,0x38,0x0B,0x27,0xAF,0xAB, + 0x44,0x49,0xE2,0x38,0xC2,0xEB,0x77,0x7F,0x23,0x41,0xC2,0x38,0xE2,0xE0,0x6A,0xAD, + 0xE2,0x38,0xA1,0x28,0xFA,0x7C,0xEA,0xC0,0xC2,0x30,0xA2,0x28,0xEE,0x75,0x4F,0xFA, + 0xE3,0x30,0x81,0x28,0xFA,0x6A,0x70,0xEA,0xE3,0x30,0x82,0x28,0x29,0xAB,0xBB,0xD7, + 0xE3,0x30,0x81,0x20,0xA0,0xA2,0xD6,0x5D,0xC2,0x28,0x81,0x28,0xA0,0x80,0x3E,0xBD, + 0xE3,0x30,0xA2,0x28,0x7D,0xF7,0xFF,0x07,0xC2,0x30,0x81,0x28,0xF5,0xDD,0xBF,0x00, + 0xE3,0x30,0x81,0x28,0x7D,0xAF,0xAB,0x82,0xE3,0x30,0xA2,0x28,0x55,0x57,0xFF,0xAA, + 0xE3,0x30,0xA2,0x28,0xFF,0xFD,0x5F,0xE0,0xC3,0x30,0x81,0x28,0x6E,0x75,0x57,0x78, + 0xE2,0x30,0x82,0x28,0x89,0xFD,0x75,0x55,0xC2,0x28,0x81,0x28,0xEA,0x7B,0xBE,0x8B, + 0xC2,0x28,0xA2,0x28,0x35,0x55,0x55,0x7B,0xC2,0x30,0xA2,0x28,0x2D,0x25,0xED,0xFF, + 0xE2,0x30,0xC2,0x28,0xEB,0xBF,0xFD,0xA3,0x23,0x31,0xC2,0x28,0x7D,0x7F,0x5B,0xEB, + 0xE2,0x30,0xA2,0x28,0x2F,0xFF,0xD7,0xEA,0xE3,0x30,0xA2,0x28,0xAE,0xAF,0xAD,0xAA, + 0xE3,0x30,0xA2,0x28,0xAE,0x97,0xF7,0xEA,0x03,0x31,0xC2,0x28,0xFB,0xAF,0x89,0xAF, + 0x03,0x31,0xC2,0x30,0xDF,0xEA,0xC8,0xA2,0x03,0x31,0xC2,0x28,0xE3,0xEF,0xBF,0xBF, + 0x24,0x39,0xC2,0x30,0xB7,0x0D,0xBE,0xBF,0x44,0x41,0xE3,0x30,0xBD,0x27,0xAF,0xAB, + 0x23,0x39,0xC2,0x30,0x5E,0x7A,0x68,0xFC,0x03,0x39,0xA1,0x28,0xFD,0xFF,0xAD,0x0F, + 0x03,0x39,0xC2,0x30,0xFB,0xBB,0xEF,0xEE,0x03,0x39,0xC2,0x30,0xFF,0x7A,0x7A,0xBB, + 0xE3,0x30,0xC2,0x30,0xFB,0xAB,0x2F,0xE7,0xE3,0x38,0x03,0x31,0xC2,0x8A,0xE2,0xEA, + 0x03,0x39,0xC3,0x30,0xAA,0x7B,0x28,0x2A,0x23,0x39,0xE2,0x38,0x55,0x5D,0x7F,0x7C, + 0x03,0x39,0xC2,0x30,0xFF,0xFB,0x95,0xAB,0x44,0x49,0xE3,0x38,0xBD,0xBF,0xBB,0x2B, + 0x26,0x62,0x44,0x49,0xFD,0xBD,0xBD,0x29,0xEC,0x9B,0xC4,0x59,0x2D,0x2D,0x2F,0x2F, + 0x31,0xC5,0x8E,0xB4,0x2B,0x0B,0x8D,0x05,0x31,0xCD,0x10,0xC5,0xAA,0xBF,0xFC,0xC3, + 0x31,0xCD,0x10,0xC5,0x40,0xA9,0x82,0x2B,0x31,0xCD,0x10,0xC5,0xDE,0x6A,0xF0,0x60, + 0x30,0xC5,0xAF,0xB4,0x5E,0xFA,0xAA,0x88,0xEF,0xC4,0x6E,0xAC,0x5D,0x7A,0xE8,0x00, + 0xEF,0xBC,0x4D,0xAC,0x7F,0x5F,0x7F,0xE8,0x8F,0xB4,0x4D,0xAC,0xBF,0xAD,0x55,0x55, + 0x8F,0xB4,0x2D,0xAC,0xFF,0x78,0xFF,0xDF,0x8F,0xB4,0x4E,0xAC,0x55,0xF9,0xBA,0xB8, + 0x8F,0xB4,0xEC,0x9B,0x7E,0x72,0x68,0xFA,0x0D,0x9C,0x0A,0x83,0x78,0xE0,0xE8,0xA0, + 0x6B,0x8B,0xA9,0x72,0x7F,0x7A,0xEA,0xA0,0xE9,0x7A,0x67,0x6A,0x77,0xDA,0xA8,0xE8, + 0xC9,0x72,0x66,0x6A,0xBD,0xAF,0xAA,0x22,0xE9,0x72,0xA8,0x72,0xBD,0xAB,0x0F,0x35, + 0x0A,0x7B,0xC8,0x72,0x2D,0xBF,0x2D,0xAF,0x4B,0x83,0xE9,0x7A,0x3D,0xBF,0xAB,0xAF, + 0x4B,0x83,0xE9,0x7A,0x5E,0x7E,0xDE,0xFC,0x2A,0x83,0x89,0x6A,0x5A,0xFA,0xA8,0xA0, + 0xEA,0x7A,0x88,0x6A,0x55,0x76,0xBC,0xB8,0xA9,0x6A,0x06,0x5A,0x5E,0xF2,0xA8,0x88, + 0x47,0x62,0xA5,0x49,0x5E,0xEF,0xEA,0xE0,0xE6,0x51,0x24,0x39,0xFF,0x6E,0xEA,0x60, + 0x23,0x49,0xC2,0x38,0xAA,0x20,0xAB,0xAD,0x23,0x49,0xE2,0x40,0x8E,0xAE,0x96,0x57, + 0x23,0x49,0xC1,0x38,0x68,0x72,0xDA,0xFE,0x44,0x49,0xE2,0x40,0x55,0x75,0xFF,0x37, + 0x23,0x49,0xE2,0x40,0x2F,0xE1,0xE2,0xF8,0x23,0x49,0xE2,0x40,0xDE,0x55,0x55,0x1D, + 0x23,0x49,0xE2,0x40,0x23,0x0B,0x2B,0xAD,0x23,0x49,0xE2,0x40,0xCA,0x9A,0xFB,0xFB, + 0x43,0x49,0x02,0x41,0x2B,0xE5,0xD5,0x7E,0x22,0x41,0xC2,0x38,0xA0,0x28,0xA8,0x7E, + 0x23,0x49,0xC2,0x38,0xDF,0xD6,0xDC,0xAF,0x02,0x41,0xE2,0x38,0xAD,0x02,0x02,0x02, + 0x03,0x41,0xE2,0x40,0x43,0x76,0xD7,0xE9,0x03,0x41,0xC1,0x38,0xFB,0xED,0xCF,0x80, + 0x02,0x49,0xE2,0x38,0x2A,0xAB,0xBD,0x75,0x02,0x41,0xE1,0x40,0x73,0x0A,0x80,0xC0, + 0x02,0x41,0xC1,0x38,0xCA,0x26,0x2F,0x8B,0x22,0x41,0xE2,0x38,0xFB,0xEB,0xB7,0x95, + 0x02,0x41,0xC2,0x38,0xE0,0x00,0xAE,0x5E,0x02,0x41,0xC2,0x38,0xEB,0xE8,0xD8,0xFA, + 0x03,0x49,0xE2,0x40,0x7F,0x55,0x95,0x97,0x03,0x49,0xC2,0x40,0x0A,0xE7,0xA8,0xFE, + 0xE5,0x61,0x03,0x49,0xA5,0x35,0xB5,0xB5,0x26,0x6A,0xC5,0x59,0x0B,0x29,0x82,0x80, + 0x26,0x6A,0xC5,0x59,0xE8,0xFA,0x7E,0xFF,0xE5,0x61,0xA4,0x59,0xEE,0x8C,0xC0,0x02, + 0xE5,0x61,0xA4,0x51,0x2B,0xBF,0xDA,0x60,0xE5,0x59,0x43,0x49,0xFA,0xE8,0x6A,0xEA, + 0x64,0x49,0x23,0x41,0x78,0xEE,0xF8,0xCA,0x44,0x49,0xE2,0x38,0x2A,0x26,0xAA,0xAA, + 0x64,0x49,0x02,0x39,0xA8,0xAA,0xFE,0xD7,0x65,0x49,0x24,0x41,0xB5,0xB5,0xE5,0xF7, + 0x64,0x49,0x03,0x39,0x28,0xBB,0xDF,0xDE,0x64,0x49,0x03,0x41,0x7A,0x7C,0xD2,0xE2, + 0xA5,0x59,0x03,0x41,0x2D,0x95,0x95,0x55,0x06,0x6A,0x84,0x51,0x2A,0x62,0xEF,0xFD, + 0xC5,0x59,0xE2,0x40,0xF8,0x7E,0x5A,0xAA,0x64,0x49,0x41,0x28,0x7F,0x5F,0x7F,0xA8, + 0xE3,0x38,0x41,0x28,0xDD,0x7D,0xFB,0xC8,0xA2,0x30,0x41,0x20,0x2B,0xA9,0x0A,0x22, + 0x03,0x39,0xA1,0x28,0x2D,0x29,0xFD,0xDD,0x22,0x39,0xC2,0x30,0x57,0xF6,0xDF,0xF5, + 0x43,0x41,0xE2,0x30,0xAF,0xA9,0x8B,0xFF,0x03,0x39,0xA2,0x28,0x88,0xEE,0xBE,0xF5, + 0xE3,0x30,0xA2,0x28,0x3A,0xB6,0xD7,0xD5,0xE3,0x30,0x61,0x20,0x80,0xA8,0x6A,0x5A, + 0xA2,0x28,0x61,0x20,0xBE,0xFE,0xDF,0x57,0xA2,0x28,0x61,0x20,0xA3,0xAB,0xBF,0xE9, + 0xA2,0x28,0x82,0x20,0xA4,0x35,0xEB,0x09,0xC2,0x28,0x82,0x20,0x02,0x02,0x0B,0x0F, + 0xE2,0x28,0xA2,0x28,0xF8,0x6A,0x7A,0x7F,0xC2,0x28,0x82,0x28,0x2F,0xAF,0xEA,0x22, + 0x03,0x39,0xA2,0x28,0xAD,0x27,0x2F,0x3F,0x44,0x41,0x03,0x39,0x25,0xAD,0xF3,0xCB, + 0x44,0x41,0xA2,0x28,0xE0,0xFE,0x7E,0x7F,0xC2,0x30,0x61,0x20,0x80,0xFE,0x5A,0x5F, + 0xC2,0x30,0x61,0x20,0xA2,0xBE,0xFF,0xF5,0xE2,0x38,0x81,0x28,0xA3,0x3B,0xBD,0xFF, + 0xE2,0x38,0x81,0x28,0x2A,0xAA,0xEF,0x75,0xE3,0x38,0x81,0x28,0x08,0xAA,0xBE,0xD7, + 0x23,0x41,0xA2,0x30,0x22,0xBB,0xAD,0xAD,0x23,0x41,0xE3,0x38,0xF8,0xAA,0x9B,0x5F, + 0x23,0x41,0xC3,0x38,0x7F,0xFA,0x3E,0xBF,0x23,0x41,0xE3,0x38,0x0D,0xED,0x9E,0xDF, + 0x23,0x41,0xE2,0x38,0xFA,0x6B,0xEA,0xEA,0x24,0x41,0xE2,0x38,0xED,0x2F,0xBD,0x7D, + 0x23,0x41,0xC2,0x30,0xFA,0xEA,0xF8,0xFB,0xE2,0x38,0xA2,0x28,0xFE,0x7A,0xF8,0xFE, + 0xC2,0x30,0xA2,0x28,0xFD,0xFD,0xBA,0x20,0xC3,0x38,0x61,0x20,0x5E,0xFE,0xFE,0xF8, + 0xA2,0x28,0x61,0x20,0xFA,0xEE,0xBE,0x20,0xC2,0x28,0x81,0x28,0xB5,0xA5,0xE9,0x7C, + 0xC3,0x28,0x82,0x28,0x0B,0xAF,0xD5,0x75,0xE3,0x30,0x81,0x28,0x0A,0x2B,0xAF,0x75, + 0xE3,0x30,0xA2,0x28,0x02,0x00,0xAF,0x75,0xE3,0x30,0xA2,0x28,0xA8,0x2A,0x2E,0x3F, + 0x03,0x31,0xC2,0x30,0x7A,0x7A,0xFE,0x00,0x03,0x39,0xA2,0x28,0x7E,0xEA,0xFA,0xE8, + 0xC2,0x30,0x82,0x28,0x56,0xBA,0x8A,0x00,0xC1,0x28,0x82,0x28,0xBB,0xFE,0xFA,0x3E, + 0xE3,0x30,0xA2,0x28,0xBF,0xD7,0x7B,0xBF,0xE3,0x30,0xA2,0x28,0xFA,0x0A,0x3A,0xAA, + 0x03,0x31,0xC2,0x30,0x8A,0x82,0xBB,0x17,0x03,0x31,0xC2,0x28,0xA2,0xF0,0xFE,0xD6, + 0xE2,0x30,0xC2,0x28,0xE8,0x8A,0x2A,0x20,0x03,0x31,0xE2,0x30,0x7C,0x40,0x0A,0x0B, + 0x03,0x31,0xC2,0x30,0xF7,0xA7,0xBF,0x0E,0xE2,0x30,0xC2,0x28,0x3F,0x3F,0xB5,0x95, + 0x03,0x31,0xC2,0x28,0x3A,0xDA,0xDC,0xAE,0x03,0x31,0xC2,0x28,0xDA,0xD7,0xEE,0xEB, + 0x03,0x39,0xC2,0x30,0x0A,0x3E,0x9D,0xF5,0x24,0x39,0xE3,0x30,0x83,0xAA,0xFA,0x59, + 0x03,0x39,0xC2,0x30,0xA8,0x80,0x6C,0x7E,0x23,0x39,0xA2,0x28,0xB7,0xA7,0x8A,0x2A, + 0x44,0x41,0xC2,0x30,0x77,0xFF,0xFA,0xF3,0x23,0x39,0xE2,0x30,0xB5,0x5D,0x6F,0xAB, + 0x23,0x39,0xC2,0x30,0xEF,0x7E,0x7A,0xA0,0x03,0x39,0xC3,0x30,0x8A,0xFF,0xFF,0x3E, + 0x23,0x41,0xC2,0x30,0x8B,0xA1,0xBB,0xD7,0xE2,0x40,0x03,0x39,0xB7,0xD7,0x5F,0xDE, + 0x43,0x41,0xE3,0x38,0xFD,0x3F,0xED,0xF7,0x85,0x49,0x03,0x39,0xBF,0xBF,0x3D,0x0F, + 0x47,0x6A,0x65,0x49,0x2D,0xAD,0x2F,0x2F,0x2D,0xA4,0x67,0x6A,0x2D,0x2D,0x2F,0x0B, + 0x10,0xC5,0x8E,0xB4,0x0D,0x8B,0x89,0xAD,0x31,0xC5,0xF0,0xC4,0x83,0xED,0xF5,0xFF, + 0x10,0xC5,0xCF,0xBC,0x00,0x08,0x0F,0x97,0x31,0xC5,0xCF,0xBC,0x0A,0xBB,0xFE,0xB6, + 0x30,0xC5,0xF0,0xBC,0xEE,0x5A,0x5F,0x7F,0x30,0xC5,0xF0,0xBC,0xBF,0x79,0xF2,0xEE, + 0x10,0xC5,0xAF,0xB4,0x60,0x80,0x82,0x88,0x10,0xC5,0x4D,0xAC,0x7F,0xFA,0xA8,0x22, + 0xF0,0xC4,0x2D,0xA4,0xD7,0xD7,0xEA,0xE0,0xAF,0xBC,0x4E,0xAC,0xAE,0xFD,0xDD,0x9C, + 0x8F,0xB4,0x4E,0xAC,0x5E,0xBE,0x83,0xB7,0x6F,0xAC,0xCD,0x9B,0x5A,0x78,0xEA,0xE8, + 0xCC,0x9B,0x6B,0x8B,0x5E,0x5A,0xFA,0xE0,0xAB,0x93,0xC9,0x72,0x57,0x7E,0xEA,0x80, + 0x4A,0x83,0xA8,0x72,0x75,0xD5,0xD6,0xF8,0xE9,0x7A,0x88,0x6A,0x36,0x2D,0x32,0x22, + 0x2A,0x83,0xC9,0x72,0x7E,0xEE,0x3B,0xFF,0x4A,0x83,0xE8,0x7A,0xBD,0x2F,0x2F,0x17, + 0x6B,0x83,0x0A,0x83,0xEE,0xEE,0x2F,0xB6,0x4B,0x83,0xE9,0x7A,0xBD,0xFA,0xB8,0x08, + 0x4B,0x83,0xC9,0x72,0x5F,0x6B,0xEA,0x20,0x2B,0x83,0x88,0x6A,0x57,0x7F,0x7F,0xF8, + 0xC9,0x72,0x27,0x5A,0x5A,0x5E,0xAA,0xE8,0x27,0x5A,0x44,0x41,0x78,0xE0,0xA0,0x80, + 0x23,0x49,0xE2,0x38,0xB7,0xF7,0xA9,0xC1,0x03,0x49,0xE2,0x38,0xB4,0x27,0x2D,0x3F, + 0x02,0x49,0xE2,0x40,0x5A,0xC8,0x6C,0xFB,0x23,0x49,0xE2,0x40,0x2B,0x32,0x77,0xBF, + 0x02,0x49,0xE2,0x40,0x8F,0xAC,0xAD,0x0A,0x23,0x49,0xE2,0x40,0xAD,0xFB,0xE8,0x5A, + 0x23,0x49,0xE2,0x40,0xBB,0xAA,0x38,0x77,0x43,0x49,0x03,0x41,0x57,0x7E,0x7D,0xD5, + 0x23,0x49,0xE2,0x40,0xDA,0x7F,0xAF,0x0B,0x02,0x41,0xC1,0x38,0xFA,0x8B,0xAB,0xEA, + 0x23,0x41,0xC2,0x38,0xB0,0xEE,0xAB,0xA9,0x44,0x41,0xE2,0x40,0xF7,0xBF,0xFD,0xF5, + 0x23,0x41,0xC2,0x40,0xAF,0xBA,0xFC,0x7E,0x23,0x49,0xE2,0x38,0xEA,0xEA,0xEE,0xED, + 0x03,0x41,0xE2,0x38,0x99,0x0B,0x01,0x01,0x23,0x41,0xE2,0x40,0xDB,0x57,0xD7,0x97, + 0x23,0x41,0xC2,0x38,0xDF,0x9E,0xBA,0x2A,0x23,0x41,0xE2,0x40,0xD5,0xFF,0x2F,0xAB, + 0x03,0x41,0xC2,0x38,0xFF,0xB8,0x20,0xA0,0x23,0x49,0xE2,0x40,0xDF,0xFB,0xFA,0xA9, + 0x03,0x49,0xE2,0x38,0xA8,0x22,0x8A,0xA2,0x03,0x49,0xE2,0x40,0x7F,0xE8,0xF8,0x5A, + 0xA4,0x59,0xE2,0x40,0x3D,0xBD,0xA5,0x35,0x46,0x6A,0xE5,0x61,0xBE,0xFB,0xA1,0x09, + 0x46,0x6A,0xC5,0x59,0x7F,0x6E,0xFF,0xA0,0x06,0x62,0xC5,0x59,0xDF,0xF5,0x3F,0x25, + 0x05,0x62,0x83,0x51,0xE2,0xFA,0x68,0xE8,0xA5,0x51,0x43,0x49,0x70,0x7E,0xDE,0xD7, + 0x43,0x49,0x03,0x41,0xE2,0xEA,0xC8,0x9C,0x64,0x49,0x03,0x39,0x2B,0xAA,0xE9,0xF9, + 0x64,0x49,0x03,0x39,0x7C,0xB7,0xBF,0xFF,0x44,0x41,0x23,0x41,0xAF,0xA7,0x29,0x20, + 0x44,0x49,0x23,0x39,0xDF,0xB7,0xB6,0x09,0x44,0x41,0x03,0x41,0x7A,0x58,0xFC,0x9C, + 0x44,0x41,0xE2,0x38,0x77,0xF6,0xE3,0xEB,0x84,0x51,0xE2,0x38,0x02,0x39,0x97,0x55, + 0xE5,0x59,0x43,0x49,0x0E,0x0A,0x23,0xD5,0xE5,0x59,0x43,0x41,0x78,0xC0,0x80,0xE2, + 0x23,0x41,0xA2,0x30,0x6C,0xF8,0xFC,0x58,0xE3,0x38,0x81,0x28,0x5F,0x7E,0xF8,0x7B, + 0xC1,0x30,0x81,0x20,0x6B,0x9F,0xDE,0x3A,0xC2,0x30,0xA1,0x28,0x9B,0x2A,0x2A,0xFC, + 0x03,0x31,0xA2,0x28,0x88,0xFB,0xBF,0x5F,0xC2,0x28,0x82,0x20,0x26,0xAE,0xE8,0xCA, + 0xC2,0x28,0x61,0x20,0x0A,0x8A,0x7F,0x57,0x81,0x20,0x41,0x18,0xE0,0xE8,0xFF,0xFF, + 0x82,0x20,0x61,0x20,0xDD,0xDF,0xAF,0x08,0xC2,0x28,0x81,0x20,0xF5,0xBD,0xB5,0x95, + 0xC2,0x28,0x81,0x20,0x2F,0x2F,0x0B,0x2F,0xC2,0x28,0xA2,0x28,0x0F,0x2A,0x3B,0x28, + 0xE3,0x28,0xA1,0x20,0xEE,0x2B,0xEF,0x6F,0xE3,0x30,0xA2,0x28,0xFA,0x83,0xF5,0x95, + 0x03,0x31,0xA2,0x28,0x35,0x95,0xFF,0x5A,0x44,0x41,0xC2,0x30,0x8A,0xEF,0xFF,0xDD, + 0x03,0x39,0xA2,0x28,0xFC,0xFA,0x7A,0x7F,0xC2,0x28,0x61,0x28,0x7E,0xE8,0x28,0x82, + 0xC2,0x30,0x61,0x20,0xF5,0xEF,0x32,0xB2,0xC2,0x28,0x81,0x28,0x7F,0xFA,0xCA,0x80, + 0xA1,0x28,0x61,0x20,0xFB,0x7C,0x7A,0x7C,0xA2,0x28,0x61,0x28,0xBF,0x57,0xEA,0xCA, + 0xE3,0x38,0x61,0x20,0x0B,0x0B,0x8F,0xED,0xE2,0x38,0xC2,0x30,0x80,0x00,0x07,0x85, + 0x24,0x41,0xE2,0x38,0xD5,0x95,0x8D,0xBF,0x23,0x41,0xE3,0x38,0xBF,0xF6,0xBF,0x97, + 0x23,0x41,0xE3,0x38,0xFA,0xA6,0x2E,0x28,0x23,0x41,0xC2,0x38,0xBE,0xF6,0x3A,0x20, + 0x03,0x39,0xC2,0x38,0x60,0x68,0xF8,0xC2,0xC2,0x30,0xA2,0x30,0x02,0x00,0xB8,0xFE, + 0xE3,0x38,0xA2,0x30,0xDE,0x5A,0x7B,0x6D,0xC2,0x30,0x81,0x28,0xA8,0xAF,0xB4,0xAE, + 0xE3,0x30,0xA2,0x28,0xD3,0xB8,0xAB,0x35,0xE3,0x30,0x61,0x20,0x78,0x7A,0xE8,0xA0, + 0xA2,0x28,0x61,0x20,0xBB,0xFF,0xFB,0xA0,0xA2,0x28,0x81,0x20,0xBD,0xFF,0x5E,0xFF, + 0xA2,0x28,0x61,0x20,0x02,0x0A,0x2F,0xA7,0xC2,0x28,0x81,0x28,0x0B,0xA2,0xFA,0xFA, + 0x03,0x39,0x81,0x28,0x02,0xBF,0xAD,0xFD,0x04,0x39,0xA2,0x28,0xE0,0xF8,0xFB,0xFE, + 0xC2,0x28,0x82,0x28,0xA8,0xAA,0xF8,0xDA,0xC2,0x28,0x81,0x20,0xAA,0x8B,0xEB,0x7F, + 0xC2,0x28,0x82,0x28,0x0E,0x28,0xF8,0x65,0xE3,0x30,0x81,0x28,0x8A,0x2F,0xB7,0xED, + 0xE3,0x30,0xA2,0x28,0x3C,0x7E,0x7F,0x7D,0xE3,0x30,0xA2,0x28,0x3E,0x35,0x2D,0xF5, + 0x03,0x31,0xA2,0x28,0x2A,0xAB,0x3F,0xB5,0x24,0x39,0xE2,0x30,0x7F,0xFF,0xDF,0xEB, + 0x03,0x31,0xC2,0x30,0xAA,0xB8,0x76,0xD7,0xE2,0x30,0xC2,0x28,0x78,0xE2,0xCB,0x88, + 0x03,0x31,0xC2,0x30,0x2D,0xEF,0xCF,0xEF,0x03,0x31,0xA2,0x28,0xC2,0xAA,0xFF,0x5E, + 0xE2,0x30,0xA2,0x28,0x2A,0xAA,0xAA,0xA9,0x03,0x39,0xC2,0x30,0x52,0x5F,0xB6,0xB5, + 0x04,0x39,0xC3,0x30,0xEF,0x2D,0xAB,0xBE,0x23,0x39,0xC2,0x30,0xB7,0xFA,0xFA,0x82, + 0x23,0x39,0xC2,0x30,0xA0,0x82,0x02,0x62,0x23,0x41,0xC2,0x30,0x1E,0xBC,0xA0,0x20, + 0x23,0x41,0x03,0x39,0x2B,0x19,0x85,0x29,0x44,0x49,0xC2,0x38,0xFE,0xDF,0xFF,0x02, + 0x23,0x41,0xC2,0x38,0xD6,0xBE,0xA2,0x2A,0x64,0x49,0xE3,0x38,0xD7,0xFF,0xAB,0xAB, + 0x85,0x51,0x03,0x39,0x75,0xFF,0xAB,0x0A,0xC6,0x59,0x24,0x49,0xBD,0x3B,0x2B,0x2B, + 0x89,0x72,0xE6,0x59,0x35,0x25,0xBD,0xBF,0x2E,0xAC,0xC9,0x7A,0x09,0x2D,0xBD,0xF5, + 0x10,0xC5,0xCC,0x9B,0x0A,0x0A,0xAD,0xF5,0x10,0xC5,0x8F,0xB4,0x22,0x22,0x0A,0xFD, + 0xF0,0xC4,0xCF,0xBC,0x37,0x57,0x7A,0x8B,0x10,0xC5,0xCF,0xBC,0xBF,0xF9,0xE3,0xAA, + 0x10,0xC5,0xCF,0xBC,0xAA,0xEF,0xFE,0x9A,0x10,0xC5,0xF0,0xBC,0xA2,0x90,0x34,0x32, + 0x31,0xC5,0xF0,0xBC,0xFE,0x7B,0xEB,0xFE,0x10,0xC5,0xD0,0xBC,0xB1,0x2A,0x28,0xAB, + 0xF0,0xBC,0xAF,0xBC,0xE8,0x88,0xEA,0x82,0xF0,0xC4,0x6E,0xB4,0x5F,0xEA,0xA0,0x00, + 0x10,0xC5,0x4E,0xAC,0x57,0xFF,0xEA,0x88,0x8F,0xB4,0x2D,0xA4,0x5F,0xF8,0xF8,0xF0, + 0x2D,0xA4,0xAC,0x93,0xFB,0xFA,0xA8,0x82,0x0D,0x9C,0x8B,0x93,0x57,0x77,0xFA,0xA8, + 0xED,0x9B,0x09,0x7B,0x7F,0xA2,0x00,0x00,0xED,0x9B,0xC8,0x72,0xD5,0x5F,0xE8,0xA0, + 0x8B,0x8B,0xC9,0x7A,0xFF,0xFF,0xBF,0x88,0x4A,0x83,0xE9,0x7A,0x97,0xBB,0xFF,0xE8, + 0x6B,0x8B,0x0A,0x7B,0xDF,0xBF,0xAF,0x2B,0x6B,0x8B,0x2A,0x83,0xB6,0xEA,0xD3,0xDE, + 0x6B,0x8B,0x2A,0x83,0x9E,0xFE,0xDB,0xFA,0x6C,0x8B,0xC9,0x72,0x5E,0x7A,0xE0,0xAA, + 0x0A,0x7B,0xA9,0x6A,0x6D,0x7B,0xBC,0xB0,0xE9,0x72,0x26,0x5A,0x57,0x5A,0x7A,0x78, + 0x23,0x41,0xE2,0x40,0x6B,0xED,0xF4,0xAE,0x23,0x49,0xE2,0x40,0x96,0x2A,0xAE,0xCB, + 0x44,0x49,0xE2,0x40,0xF9,0xEC,0xF2,0xFF,0x23,0x49,0x02,0x41,0x7D,0xDD,0x77,0xAE, + 0x23,0x49,0xE2,0x40,0xB8,0x25,0xBD,0xB8,0x23,0x49,0xE2,0x40,0xF2,0xD8,0xD8,0xF8, + 0x23,0x49,0xE2,0x40,0xAB,0x0F,0xBA,0xA9,0x43,0x49,0xE2,0x40,0xB7,0xAF,0x82,0xFE, + 0x03,0x41,0xC2,0x38,0x00,0x80,0xD0,0xDA,0x03,0x41,0xC2,0x38,0x62,0xBF,0xB7,0xBF, + 0x03,0x41,0xC2,0x38,0x8B,0xD8,0x92,0xAC,0x03,0x41,0xE2,0x40,0xB3,0xC2,0x8A,0xDD, + 0x02,0x41,0xC2,0x38,0x7E,0xBB,0xB2,0xA2,0x03,0x41,0xE2,0x38,0x0A,0xE5,0x7D,0xED, + 0x03,0x41,0xE2,0x40,0xBA,0x00,0x09,0xDF,0x23,0x41,0xE2,0x40,0x3F,0xAE,0xD6,0x75, + 0x03,0x41,0xA2,0x38,0x08,0xA8,0xA8,0xB7,0x03,0x41,0xC1,0x38,0x82,0xBE,0xE2,0x78, + 0x02,0x41,0xE2,0x40,0x51,0xC3,0x8D,0xD5,0x23,0x41,0xE2,0x40,0xBD,0xAD,0xBD,0x73, + 0x02,0x41,0xE1,0x40,0xC0,0xC0,0xEA,0xE2,0x22,0x41,0xC1,0x40,0xFD,0x9F,0xD7,0xDF, + 0xC5,0x59,0xE2,0x40,0x37,0x3D,0xB5,0xB5,0x47,0x6A,0xE5,0x61,0xAF,0xC2,0xC9,0x89, + 0x47,0x6A,0xE5,0x61,0x63,0x7B,0x7B,0x6E,0x05,0x62,0xA4,0x59,0xAF,0xFA,0xE2,0x82, + 0x06,0x62,0x64,0x51,0xEC,0xFC,0xFA,0x7A,0x43,0x49,0x03,0x41,0x78,0x78,0xF8,0x5C, + 0x23,0x41,0xE2,0x38,0xBE,0xB5,0xE5,0xAA,0x23,0x41,0xC2,0x30,0xA2,0xFB,0x7A,0xFA, + 0x44,0x41,0xE2,0x30,0xBF,0xAB,0xAF,0xA9,0x44,0x41,0x24,0x39,0x02,0x8A,0x02,0xC2, + 0x44,0x41,0x03,0x39,0x02,0xCB,0x83,0x82,0x44,0x41,0x03,0x41,0xDC,0xFE,0xEB,0xAA, + 0x43,0x41,0xE3,0x38,0x6B,0xF2,0xFA,0xBA,0xE2,0x38,0xA1,0x30,0x8E,0xBA,0x4A,0x68, + 0x44,0x49,0xC2,0x30,0xAF,0xAD,0xBD,0xBD,0x84,0x49,0xE3,0x38,0x82,0xB9,0xEF,0x5D, + 0x23,0x41,0xA2,0x28,0x58,0xF8,0x7E,0xFF,0xC2,0x28,0x81,0x28,0xAA,0xEF,0xF7,0xEA, + 0xE2,0x28,0x81,0x20,0x3E,0x3F,0xFF,0xED,0xE2,0x30,0xA2,0x28,0x7E,0xF8,0xFE,0xFF, + 0xC2,0x28,0xA2,0x28,0xDF,0xFF,0xFF,0x22,0xA2,0x28,0x61,0x20,0x80,0xF0,0x70,0x78, + 0x81,0x20,0x41,0x18,0x78,0xFE,0xFE,0xFB,0x81,0x20,0x41,0x18,0xFB,0xAA,0x8A,0x0A, + 0xA2,0x28,0x61,0x20,0xEF,0x6F,0xAA,0x2B,0xC2,0x28,0x61,0x20,0xAD,0xAB,0x37,0xAE, + 0xC2,0x28,0x81,0x20,0x29,0x85,0xAA,0xBA,0xE3,0x30,0xA2,0x28,0xFF,0xCA,0xCE,0xAA, + 0x03,0x29,0xA2,0x28,0xF7,0x5F,0xFD,0xFE,0xE2,0x30,0xA2,0x28,0xB7,0xB5,0xDD,0x5A, + 0xE3,0x30,0xA2,0x28,0x6A,0x62,0x72,0xFF,0xC2,0x30,0xA2,0x28,0xE3,0x66,0x75,0x65, + 0xA2,0x28,0x81,0x20,0x02,0xB8,0x56,0x7C,0xC2,0x28,0x81,0x20,0xA2,0xB3,0xF5,0xFD, + 0xC2,0x28,0xA2,0x28,0x33,0x01,0x28,0x23,0xE3,0x30,0x81,0x20,0xCA,0xEA,0xFF,0x7E, + 0xA2,0x28,0x81,0x20,0x57,0x69,0x7D,0xBF,0xA2,0x28,0x61,0x20,0xFB,0xFA,0xAA,0x80, + 0xA1,0x28,0x61,0x20,0x09,0x3F,0x8B,0x0E,0xE2,0x30,0x81,0x28,0x0F,0x9F,0xAF,0xBB, + 0x03,0x39,0xA2,0x30,0x20,0x0A,0xBF,0xFD,0x03,0x39,0xC2,0x30,0x0C,0x02,0x0B,0xBF, + 0x44,0x41,0x03,0x39,0xFA,0xFE,0x6B,0xFD,0x44,0x41,0x03,0x39,0x5E,0x77,0xDD,0x3B, + 0x44,0x41,0xE2,0x38,0x6F,0x7B,0x6B,0x63,0xE3,0x38,0xA2,0x30,0xDF,0x5F,0x7B,0x78, + 0xA2,0x28,0x61,0x28,0x00,0x00,0x2A,0x3E,0xE3,0x30,0xA2,0x30,0xDD,0x5F,0xFE,0x2D, + 0xE2,0x30,0x81,0x28,0x27,0xAF,0xBF,0xEE,0x03,0x31,0xC2,0x28,0xE2,0xED,0xDD,0x7D, + 0xE3,0x30,0xA2,0x28,0x54,0xAF,0x0F,0x8F,0xC3,0x28,0x81,0x28,0xF7,0xFE,0xFC,0xF0, + 0xA2,0x30,0x61,0x20,0xF7,0xFB,0xBE,0x2A,0x81,0x30,0xA2,0x28,0xD7,0x5C,0x56,0x5F, + 0xE3,0x30,0xA2,0x30,0xBD,0x2F,0x0B,0x2B,0xE3,0x30,0xC2,0x28,0x7C,0xF0,0xFA,0xBA, + 0xE3,0x30,0x81,0x20,0xFF,0xF6,0xDC,0x7E,0xA2,0x28,0x81,0x20,0x78,0x5C,0xA0,0x23, + 0xC2,0x28,0x61,0x20,0xFF,0xFD,0xAA,0x2A,0xC2,0x30,0x82,0x28,0x0D,0x0D,0x0F,0x00, + 0xC2,0x30,0x82,0x28,0xE0,0xE8,0xFC,0xF8,0xE3,0x30,0xA2,0x28,0xD5,0xB5,0x3D,0xEF, + 0xE3,0x30,0xA2,0x28,0xBF,0x9F,0x2F,0xBF,0x03,0x31,0xC3,0x30,0xAA,0xEA,0xBB,0xAF, + 0x03,0x31,0xA2,0x28,0x9F,0xF5,0x37,0xB7,0x03,0x31,0xA2,0x28,0x22,0xF2,0x7F,0x55, + 0x03,0x31,0xA2,0x28,0x8B,0xA2,0xBB,0x9D,0xE2,0x30,0xA2,0x28,0x5E,0xE0,0xE0,0xAA, + 0xE3,0x38,0xC2,0x28,0x57,0x7D,0xDD,0x7D,0x03,0x31,0xA2,0x28,0xA7,0xDD,0x5F,0x2B, + 0x03,0x39,0xC2,0x30,0x35,0xAF,0xBF,0x3F,0x44,0x41,0xE2,0x30,0xAB,0xA2,0x9A,0xF7, + 0x23,0x39,0xE2,0x30,0xE0,0xE2,0xE0,0x62,0x44,0x41,0xC1,0x30,0xAA,0xAF,0x2B,0x89, + 0x24,0x41,0xE2,0x38,0x36,0x26,0xBB,0x7A,0x64,0x49,0xE3,0x38,0xAB,0xBF,0xED,0xFF, + 0x64,0x49,0x03,0x41,0x95,0x37,0x2D,0x3D,0x44,0x49,0x03,0x41,0x08,0x38,0x27,0x2A, + 0xC6,0x59,0x24,0x41,0xAD,0xED,0xEB,0x2B,0x07,0x62,0x64,0x49,0xB7,0x3D,0xFF,0x0B, + 0xCA,0x7A,0x27,0x6A,0xA5,0x2F,0x8D,0x0B,0x2B,0x8B,0xCA,0x7A,0x3D,0x25,0xFD,0xEF, + 0xAC,0x9B,0x0A,0x83,0x2A,0xBD,0xD5,0x55,0x8F,0xB4,0x2A,0x8B,0x0A,0xBF,0xFF,0x55, + 0xF0,0xBC,0x8B,0x93,0x02,0x2A,0xBD,0x55,0xF0,0xC4,0x0D,0xAC,0x00,0x00,0x0B,0xBD, + 0x10,0xC5,0xAF,0xBC,0xAA,0x28,0x2A,0x2D,0x10,0xC5,0xF0,0xBC,0xD6,0x2A,0x86,0xAF, + 0x10,0xC5,0xCF,0xBC,0x9A,0x62,0xF8,0xFE,0x10,0xC5,0xAF,0xB4,0xAA,0x8E,0x7E,0xFB, + 0xF0,0xBC,0xAF,0xB4,0x2A,0xB2,0xB3,0xAF,0xF0,0xBC,0xD0,0xBC,0x05,0x2A,0x2E,0xBA, + 0x11,0xC5,0xAF,0xB4,0xAE,0xA6,0xAA,0xEB,0xF0,0xBC,0x4D,0xA4,0x58,0x78,0x48,0xE0, + 0x6D,0xAC,0x0D,0xA4,0xDF,0x7F,0x7A,0xF8,0x2D,0xA4,0xCC,0x9B,0x7C,0xAA,0xAA,0x0A, + 0x2D,0xA4,0xEC,0x9B,0xF5,0xBD,0x97,0x2E,0x2D,0xA4,0x0D,0x9C,0xCF,0x7F,0xFE,0xB3, + 0x4E,0xA4,0xCC,0x93,0x67,0xAA,0xA2,0x28,0x0D,0x9C,0x2A,0x83,0x7F,0xE8,0x00,0x00, + 0x0D,0x9C,0x2A,0x83,0x75,0xFF,0xEA,0x80,0xCC,0x93,0x2A,0x83,0x5F,0xFF,0xFA,0x00, + 0x0D,0x9C,0x2A,0x83,0x77,0xDF,0xEF,0x2A,0xEC,0x9B,0x2A,0x83,0x5D,0x7F,0xFE,0x20, + 0x8A,0x8B,0xE9,0x7A,0x5F,0xEB,0x58,0xA0,0x4A,0x83,0x68,0x6A,0x5F,0x5B,0xEA,0xA8, + 0x23,0x49,0xC2,0x38,0xAB,0xA6,0xA4,0x2A,0x44,0x49,0xE2,0x38,0xAD,0xB7,0xEA,0xAA, + 0x23,0x49,0xE3,0x40,0x38,0xAE,0xEE,0xCE,0x23,0x49,0x03,0x41,0x60,0xCE,0x2C,0x5A, + 0x23,0x49,0xE2,0x40,0xAA,0x0A,0xE0,0xFA,0x23,0x51,0x03,0x41,0xFA,0x7F,0xDD,0x55, + 0x43,0x49,0x02,0x41,0xFB,0x3B,0xA3,0xBB,0x23,0x49,0xC2,0x38,0xEA,0xBA,0x58,0xE8, + 0x23,0x41,0xA1,0x38,0xEA,0xAA,0xFA,0x68,0x03,0x41,0xA2,0x38,0xFF,0xBE,0xAB,0x89, + 0x03,0x41,0xC2,0x38,0xBC,0xB7,0xD4,0x2A,0x23,0x41,0xE2,0x40,0xD7,0x5E,0xDC,0xE7, + 0x03,0x41,0xC2,0x38,0x7A,0xFF,0xB7,0x2F,0x03,0x41,0xE2,0x40,0x05,0x15,0xA9,0x5C, + 0x03,0x41,0xE2,0x38,0x03,0xCA,0xD5,0x5D,0x03,0x41,0xC2,0x38,0xFE,0xA6,0xD6,0xD6, + 0x02,0x41,0xC2,0x38,0x3D,0x3B,0xAF,0xBF,0x03,0x41,0xE2,0x38,0x70,0x70,0x5C,0x5D, + 0xE2,0x40,0x02,0x39,0xE0,0x38,0xAA,0xB2,0x02,0x41,0xE2,0x38,0xF8,0xAB,0xBD,0xDD, + 0x02,0x41,0xC2,0x40,0xA2,0x22,0x00,0xAC,0x03,0x41,0xC2,0x40,0x2B,0x07,0x0E,0xA8, + 0x84,0x51,0xE2,0x40,0x35,0x3F,0x9D,0xF5,0x67,0x72,0xA4,0x59,0x2B,0x0B,0x09,0x81, + 0x67,0x72,0x05,0x62,0x5B,0x71,0xE8,0x6A,0x05,0x62,0xC5,0x59,0x2B,0x08,0x80,0xE8, + 0x05,0x62,0x63,0x49,0x60,0x7A,0xFA,0x6A,0x64,0x49,0xE2,0x38,0xF0,0xF8,0xF8,0x5A, + 0x44,0x41,0xE2,0x38,0xFE,0xDF,0xD7,0x3D,0x44,0x41,0x03,0x39,0x75,0xCE,0xA2,0x98, + 0x23,0x39,0xE2,0x38,0x8B,0xA2,0x03,0x20,0x23,0x39,0xC3,0x30,0x2A,0x6E,0xFE,0xF2, + 0x44,0x41,0xE3,0x30,0x0A,0x2B,0xBD,0xE7,0x44,0x41,0xE2,0x38,0xAA,0x20,0x8F,0xAD, + 0x44,0x41,0x23,0x39,0x57,0x18,0xD8,0x71,0x23,0x39,0xC2,0x30,0x5E,0xFC,0xF8,0xA8, + 0x03,0x39,0xC2,0x30,0xE9,0x7A,0xBA,0xA2,0x03,0x39,0xA1,0x28,0xE2,0xEA,0xF3,0x7B, + 0xC2,0x30,0xA1,0x28,0xA0,0xE8,0xBC,0xA5,0xE2,0x28,0x81,0x28,0xEA,0xA2,0xA8,0x6A, + 0xE2,0x30,0xA2,0x20,0xED,0xEF,0xBE,0x7B,0xE3,0x28,0x81,0x20,0x8A,0xA2,0xEA,0xDF, + 0xE3,0x28,0x82,0x20,0xE2,0x7A,0x77,0xFF,0xC2,0x20,0x61,0x20,0x5E,0x57,0x7F,0xFF, + 0xA2,0x28,0x61,0x20,0x7D,0xF3,0x8B,0x03,0xE3,0x30,0x81,0x20,0xD5,0xFD,0xA9,0x0A, + 0xC3,0x28,0x81,0x20,0xFD,0xFE,0xFC,0xA8,0x02,0x29,0xA2,0x28,0x75,0x7D,0xFF,0xDE, + 0xC2,0x28,0xA2,0x28,0xCA,0x80,0x8E,0xBA,0x03,0x31,0xC2,0x28,0xFD,0xED,0xD5,0x95, + 0x03,0x31,0xC2,0x28,0xF7,0x7F,0x7B,0xEA,0x03,0x29,0xA2,0x28,0xDF,0x5F,0xFE,0xFF, + 0x03,0x31,0xA2,0x28,0xDD,0x5D,0x5B,0xFB,0xE2,0x28,0xA2,0x28,0xED,0x7F,0xBE,0xEA, + 0xC2,0x28,0x81,0x20,0x97,0xFC,0x82,0xE0,0x81,0x28,0xC2,0x20,0xA7,0xBF,0xBA,0xEA, + 0xE3,0x30,0x81,0x20,0xBF,0x2F,0xFD,0xB7,0xC2,0x28,0x81,0x20,0x54,0x5E,0x58,0xFE, + 0xC2,0x28,0x81,0x20,0xFF,0x5F,0xFE,0x38,0xC2,0x28,0x81,0x20,0xEB,0x72,0x7A,0xF8, + 0xC2,0x28,0x81,0x20,0xDF,0xAB,0x83,0xEB,0xE2,0x30,0xA2,0x28,0x52,0x6B,0x7B,0x75, + 0xC2,0x30,0x81,0x20,0xAA,0xFE,0x75,0x57,0xC2,0x30,0x81,0x20,0x08,0x2F,0xAD,0xED, + 0x03,0x39,0x81,0x28,0x00,0xAA,0xAF,0xF5,0x23,0x41,0xC2,0x30,0x20,0x08,0x2D,0x9F, + 0x65,0x49,0x24,0x41,0x41,0xA2,0xBB,0xEB,0x44,0x41,0xA2,0x28,0x7A,0xF8,0xCA,0x78, + 0xC2,0x30,0x61,0x20,0xD6,0xFE,0xB8,0xAA,0xA2,0x30,0x82,0x20,0x08,0xA0,0x20,0xA0, + 0xC3,0x30,0x82,0x28,0xEA,0xEB,0xEB,0xFD,0xC2,0x30,0x81,0x28,0xB2,0x9F,0x7F,0xAF, + 0xC2,0x30,0x82,0x28,0x8A,0xAE,0xBD,0xFA,0x03,0x39,0xA2,0x28,0xD9,0xAF,0xAF,0xBD, + 0x03,0x39,0xA2,0x28,0xD5,0xBF,0x2E,0x0A,0x24,0x39,0xA2,0x30,0xD5,0xFB,0xAA,0xAA, + 0x03,0x39,0xA2,0x30,0xF7,0xFF,0xFE,0x22,0xE2,0x30,0xA2,0x28,0xFF,0xDF,0x53,0xC0, + 0xC2,0x30,0x82,0x28,0xBC,0x7E,0xBE,0xA2,0xE3,0x28,0x81,0x28,0xBD,0xF7,0x57,0xFF, + 0x03,0x31,0x82,0x28,0x3F,0xAF,0xBD,0xBD,0x03,0x39,0xC2,0x28,0x68,0xE0,0xC2,0x83, + 0xE3,0x30,0xA2,0x28,0x58,0xEA,0xC0,0xB0,0xE2,0x30,0xA2,0x28,0x27,0xF7,0xDF,0x7F, + 0xC2,0x30,0xA2,0x28,0x80,0xBA,0x59,0xA3,0xE3,0x30,0x81,0x28,0x0A,0xCA,0xDA,0xDF, + 0xC2,0x28,0x81,0x28,0x88,0x2A,0x0A,0xAD,0xC2,0x28,0xA2,0x28,0x77,0xB9,0xE2,0x22, + 0xC2,0x28,0x81,0x20,0x3E,0xEA,0xFE,0xF2,0xC3,0x30,0x81,0x20,0x02,0xAB,0xEE,0x6F, + 0xE3,0x30,0x81,0x20,0xA2,0xBB,0xBD,0xA5,0xE3,0x30,0xC2,0x28,0xA7,0xF7,0x65,0x75, + 0x03,0x39,0xC2,0x28,0x3B,0x3D,0x75,0xAD,0x02,0x39,0xA2,0x28,0x28,0xFF,0xBF,0xFF, + 0x03,0x39,0xA1,0x28,0xA0,0x8B,0xA9,0xAA,0x44,0x41,0xC1,0x30,0x29,0xFB,0x7D,0xF5, + 0x44,0x41,0xE2,0x38,0xDA,0x5B,0xD7,0x3D,0x84,0x49,0x03,0x39,0x5D,0xFF,0xC1,0xCA, + 0x44,0x49,0x03,0x41,0xAD,0xA5,0x25,0xFF,0x85,0x51,0x23,0x41,0xFD,0xBF,0x2F,0x0B, + 0xC6,0x59,0x64,0x49,0xA5,0xB5,0x3F,0x0F,0x27,0x6A,0xC5,0x59,0xAD,0x35,0xF5,0x2B, + 0xEA,0x82,0x48,0x6A,0x2D,0x2D,0x2D,0x09,0x2A,0x83,0xEA,0x7A,0xE9,0x7F,0x76,0x6A, + 0x2B,0x83,0xC9,0x7A,0xAE,0xAF,0xB5,0xBF,0x2A,0x8B,0xC9,0x7A,0x2F,0xE6,0xA6,0xAE, + 0x8C,0x9B,0xE9,0x7A,0x2B,0xBF,0xD7,0xFF,0xED,0xA3,0x2A,0x83,0x0B,0xB7,0xFD,0x55, + 0xAF,0xBC,0x2B,0x83,0x02,0xAF,0xFD,0xD5,0xF0,0xBC,0xAC,0x9B,0x00,0x02,0xAD,0x55, + 0xF0,0xBC,0x4D,0xAC,0x00,0x00,0x0A,0xE5,0xF0,0xBC,0xAF,0xB4,0x72,0xA2,0x0A,0x2F, + 0x11,0xC5,0xD0,0xBC,0xFD,0x7B,0xCA,0xEF,0x10,0xC5,0xD0,0xBC,0x7E,0x7F,0x6B,0xEA, + 0x10,0xC5,0xD0,0xBC,0xE5,0xFF,0xAF,0x6B,0xF0,0xBC,0x6E,0xAC,0xE8,0xA8,0xE0,0x60, + 0x8F,0xAC,0x0D,0xA4,0x74,0xDC,0xDA,0xFA,0x4E,0xAC,0x2D,0xA4,0x5E,0x5E,0x67,0x24, + 0x2D,0xA4,0xEC,0x9B,0x18,0x2E,0x00,0x00,0x2D,0xA4,0x0D,0xA4,0x50,0x08,0x9D,0x0A, + 0x4E,0xAC,0x0D,0x9C,0xFD,0x96,0xAE,0xDA,0x4E,0xA4,0x0D,0xA4,0xEA,0xAB,0xA7,0x9F, + 0x6E,0xA4,0x2D,0xA4,0x7D,0xE9,0x7D,0xB5,0x4E,0xA4,0xEC,0x9B,0x9E,0x22,0x80,0x0A, + 0x6E,0xAC,0x0D,0x9C,0xD7,0xB8,0x2A,0x02,0x6F,0xAC,0x0D,0x9C,0x7F,0xCF,0xAA,0xEE, + 0x4E,0xA4,0xAB,0x8B,0x57,0xA8,0xC0,0x02,0x4E,0xA4,0x2A,0x83,0x57,0xFE,0xAA,0xA0, + 0x44,0x49,0xE2,0x40,0xA5,0x6F,0x5A,0xFC,0x23,0x49,0xC2,0x38,0x88,0xEA,0xEA,0x7A, + 0x23,0x49,0xC2,0x38,0xE2,0xFA,0xFA,0xAD,0x23,0x49,0xE3,0x40,0x8A,0xEA,0xFA,0xBF, + 0x23,0x49,0xE3,0x40,0x9A,0xBB,0xE9,0xF0,0x23,0x49,0xE3,0x40,0x96,0x25,0xBF,0x9B, + 0x23,0x49,0xE2,0x40,0x82,0xA0,0x2E,0x7A,0x23,0x41,0xE2,0x40,0xAA,0x36,0xD7,0xF5, + 0x03,0x41,0xC1,0x38,0xF8,0xE8,0xA8,0x3E,0x02,0x41,0xA1,0x38,0xDA,0xF8,0xBA,0xEE, + 0x03,0x41,0xA2,0x38,0x03,0xAB,0xEF,0xFA,0x03,0x41,0xC2,0x38,0x88,0x9E,0x57,0x5F, + 0x03,0x41,0xC2,0x38,0x2F,0xFA,0xB9,0xF9,0x02,0x41,0xC2,0x38,0xEA,0xEB,0x6A,0xEF, + 0x23,0x49,0xC2,0x38,0xDA,0xFE,0xDC,0x7A,0xE2,0x40,0xC2,0x38,0x98,0x78,0x68,0xA8, + 0x02,0x41,0xC2,0x38,0xFF,0xFE,0xB3,0x03,0x02,0x41,0xC2,0x38,0xFE,0xB7,0xBA,0xB8, + 0x03,0x41,0xE2,0x40,0x95,0xF5,0xCD,0x06,0x03,0x41,0xE2,0x40,0xFF,0xF8,0x70,0x5C, + 0x02,0x41,0xC2,0x38,0x97,0xFE,0xAE,0xAA,0x03,0x41,0xA1,0x38,0x18,0x3A,0x0A,0x82, + 0x23,0x49,0xA0,0x38,0x2E,0xA8,0x2E,0x2D,0x66,0x72,0x84,0x51,0x0B,0x0B,0x09,0xA9, + 0x46,0x6A,0xE5,0x61,0xAA,0x9C,0x80,0x8A,0x27,0x6A,0xC5,0x59,0x6F,0xB7,0xAF,0xAC, + 0x06,0x62,0x63,0x49,0xFE,0x58,0x78,0x78,0x44,0x49,0xE2,0x38,0x7E,0x5E,0x5E,0x7C, + 0x44,0x41,0xE2,0x38,0xBD,0xD5,0xB5,0xCD,0x43,0x41,0x03,0x39,0x74,0x5F,0x5F,0x5F, + 0x23,0x39,0xE3,0x38,0x2A,0x57,0x5A,0xAB,0x24,0x39,0x03,0x39,0x81,0xD3,0x7F,0xD7, + 0x24,0x41,0xE3,0x30,0xBA,0xAA,0xED,0x6E,0x03,0x39,0xE3,0x30,0x2D,0xEF,0x7E,0xA2, + 0x23,0x39,0xE3,0x38,0x00,0x2A,0xBD,0x9F,0x43,0x41,0x03,0x39,0x4A,0x69,0xFF,0x7F, + 0x44,0x41,0xE2,0x30,0xFB,0x7A,0xEF,0xE3,0x23,0x39,0xC1,0x30,0x7F,0xFD,0xFB,0x28, + 0x03,0x39,0xA1,0x28,0x5F,0x56,0xDE,0xA8,0xC2,0x28,0x81,0x20,0x7A,0xBA,0xA3,0x02, + 0xE3,0x30,0x81,0x20,0x6D,0xBF,0xFC,0xEA,0xE3,0x30,0x81,0x20,0x5F,0xFF,0x8A,0x2A, + 0x03,0x31,0xA2,0x28,0xD5,0xF7,0xBE,0xA8,0xE2,0x30,0x82,0x20,0x5F,0xAE,0x2E,0x22, + 0xE3,0x30,0xA2,0x28,0xE5,0xFF,0x2F,0x28,0xE3,0x30,0xC2,0x28,0x6B,0x69,0x6F,0x55, + 0xE3,0x30,0xA2,0x28,0xEB,0xA9,0xEB,0xFA,0xE3,0x30,0xA2,0x28,0xAA,0xA9,0xAB,0xB8, + 0x03,0x31,0xC2,0x28,0xF7,0xF7,0xF5,0xB5,0xE3,0x30,0xA2,0x28,0xF2,0xBA,0xFE,0xA8, + 0x03,0x31,0xC2,0x28,0xEA,0x6B,0x7F,0xFB,0xE3,0x30,0xC2,0x28,0x9A,0x27,0x23,0x8B, + 0x03,0x31,0xA2,0x28,0xAA,0xFA,0xF8,0xDE,0xE3,0x28,0xA2,0x28,0xBA,0xBB,0xAE,0xAE, + 0xE2,0x28,0xA2,0x28,0x5E,0xFA,0xAA,0x0E,0xE3,0x28,0xA2,0x28,0xD5,0xDE,0xD6,0xEE, + 0xA2,0x28,0x61,0x20,0x8A,0xE8,0xD8,0x98,0xC2,0x28,0x81,0x20,0x2B,0xB9,0xED,0x5D, + 0xE2,0x28,0xA2,0x20,0xDE,0xF2,0x5D,0x55,0xC2,0x28,0x82,0x20,0xC2,0x62,0xFA,0x68, + 0xA2,0x20,0x61,0x20,0x00,0x82,0xB8,0x3A,0xC2,0x28,0x81,0x20,0xEA,0xFF,0xD7,0x57, + 0xA2,0x28,0x61,0x20,0xFA,0xFA,0x7A,0xF2,0xA2,0x28,0x81,0x20,0x3F,0x97,0x95,0x3F, + 0xC2,0x30,0x61,0x20,0x2F,0xFA,0x6E,0xBA,0xC2,0x30,0x81,0x28,0x28,0xF7,0xB5,0xED, + 0x44,0x41,0xC2,0x30,0x0B,0xAD,0xBD,0xDD,0x24,0x39,0xC2,0x30,0xD8,0xBA,0xAA,0xFE, + 0xE3,0x30,0xA2,0x30,0x97,0xA8,0xA0,0xA2,0xE3,0x38,0xA2,0x30,0x5E,0x5F,0xDE,0xB8, + 0xE2,0x30,0x81,0x28,0x7F,0xEE,0xAA,0xA2,0xE3,0x30,0xA2,0x28,0x95,0x37,0x2E,0xAB, + 0x03,0x39,0xA2,0x28,0xDF,0xB6,0xEA,0x8A,0xE2,0x30,0xA2,0x30,0x01,0x0A,0x2A,0x9A, + 0x03,0x39,0xC2,0x30,0xFA,0xBF,0xAE,0x0F,0x43,0x41,0xE3,0x38,0xFB,0x7D,0x78,0xEA, + 0x44,0x41,0x03,0x39,0xF5,0x2D,0xF9,0xA2,0x64,0x41,0xE3,0x38,0x57,0xA8,0x8A,0x2A, + 0x44,0x41,0xC2,0x30,0x5D,0x5F,0xEC,0xAA,0x24,0x41,0xA2,0x28,0xD5,0xF7,0xAA,0xE8, + 0xE3,0x30,0xA2,0x28,0x83,0x08,0x2E,0xA7,0xE3,0x30,0xC2,0x28,0x00,0xE8,0xB8,0x7E, + 0xE3,0x30,0xA2,0x28,0xA0,0xBC,0x3E,0xFA,0xC2,0x30,0xA2,0x28,0x5E,0x5E,0x7C,0xFE, + 0xE2,0x28,0x82,0x28,0xC7,0xFF,0xFB,0xBE,0xA2,0x28,0x81,0x20,0xA8,0x6E,0x36,0x32, + 0xC2,0x28,0x61,0x20,0x2F,0xBF,0xD7,0xBB,0xC2,0x28,0x81,0x28,0x02,0x8A,0xF2,0xE8, + 0xC2,0x28,0xA2,0x28,0x3E,0x27,0xB9,0x0D,0xC2,0x30,0x82,0x28,0x6E,0xA8,0xFA,0xC0, + 0xC2,0x28,0x81,0x28,0xB5,0x97,0x9F,0xBE,0xE2,0x30,0xA2,0x28,0xBF,0x9F,0x9F,0x95, + 0x03,0x31,0xC2,0x28,0xFB,0xFF,0xEF,0x2B,0x03,0x39,0xC2,0x30,0x5F,0x5A,0xF8,0xC0, + 0xE2,0x30,0xA2,0x30,0x88,0xBB,0xBB,0xA2,0x03,0x39,0xC1,0x30,0xBD,0xBF,0xAB,0xA3, + 0x23,0x41,0xE2,0x38,0xAD,0xE7,0xF7,0xBF,0x64,0x49,0x03,0x39,0x80,0xE3,0xFB,0xED, + 0x64,0x49,0x02,0x39,0x7E,0xFA,0xA9,0x8B,0xC5,0x51,0x43,0x41,0xBD,0x0F,0xAF,0xFF, + 0xE6,0x59,0x64,0x51,0xA5,0xBE,0xEA,0x37,0x68,0x6A,0xC6,0x59,0xBD,0x2B,0x3D,0x2B, + 0xEA,0x82,0x68,0x6A,0x29,0x2B,0x0D,0x2F,0x2A,0x83,0xCA,0x7A,0xAA,0xA8,0xBB,0xB6, + 0x2A,0x83,0xEA,0x7A,0xEE,0x62,0x6A,0xFB,0x2A,0x83,0xEA,0x7A,0xDE,0xFF,0xDD,0xC9, + 0x2B,0x83,0xC8,0x7A,0xAB,0x2B,0xA5,0x77,0x2A,0x83,0xC9,0x7A,0x0F,0xBC,0xFE,0x6F, + 0x6B,0x8B,0xC9,0x7A,0x2F,0xAF,0xED,0xFD,0x8C,0x93,0xEA,0x7A,0x00,0x02,0xEB,0xF5, + 0x0D,0xA4,0x0A,0x83,0x02,0xAE,0xFD,0x7D,0xEF,0xBC,0x6B,0x8B,0x0A,0xAB,0xF5,0xD5, + 0xF0,0xBC,0x8C,0x93,0x00,0x00,0xAB,0xBD,0xF0,0xBC,0x90,0xB4,0x20,0x02,0x03,0xFD, + 0x30,0xC5,0xCF,0xBC,0xEF,0xBB,0xBA,0xF1,0x10,0xC5,0x8F,0xB4,0x6C,0xF8,0xE8,0xE8, + 0xAF,0xB4,0x2D,0xA4,0xDA,0xE8,0xE8,0xFB,0x6E,0xAC,0x0C,0xA4,0xA6,0x23,0x2F,0x88, + 0x6E,0xAC,0x2E,0xA4,0x7E,0xE0,0xF3,0x80,0x6F,0xAC,0x2E,0xA4,0x7F,0x57,0xD7,0xFE, + 0x6E,0xAC,0x0D,0xA4,0x76,0x7F,0xBF,0xCA,0x4E,0xAC,0x0D,0x9C,0xAD,0xE3,0x02,0x8A, + 0x4E,0xAC,0x0D,0xA4,0x2B,0x3B,0xCA,0xA0,0x6E,0xAC,0x0D,0xA4,0xAD,0xFA,0x22,0x2E, + 0x8F,0xB4,0x2D,0xAC,0xBA,0xE6,0xBB,0xAA,0x6E,0xAC,0x2E,0xA4,0x6A,0xEA,0x6E,0x3A, + 0x6E,0xAC,0x2E,0xA4,0xEF,0xBF,0xAA,0xA8,0x4E,0xA4,0x0D,0x9C,0xF0,0x68,0xF8,0x00, + 0x23,0x49,0xC2,0x38,0x88,0xFA,0xFB,0x68,0x02,0x41,0xC2,0x38,0x7B,0xFD,0xFD,0xB7, + 0x03,0x41,0xC2,0x38,0xB2,0xEA,0xBC,0x0E,0x23,0x41,0xC2,0x40,0x7E,0xFA,0xA2,0xAA, + 0x23,0x49,0xE3,0x40,0x23,0x0B,0xAF,0xF7,0x23,0x49,0xE3,0x40,0x3B,0x28,0x8F,0x8C, + 0x23,0x41,0xE2,0x40,0xDF,0x20,0x88,0x77,0x03,0x41,0xE2,0x38,0xAF,0xF0,0xEB,0x89, + 0x02,0x41,0xC2,0x38,0xAF,0xEF,0xC7,0xFB,0xE2,0x40,0xC2,0x38,0x36,0x9F,0xE7,0x77, + 0x03,0x41,0xC2,0x38,0xC2,0xE3,0xB5,0xB5,0x04,0x41,0xC2,0x38,0xE2,0xFA,0x76,0x57, + 0x03,0x41,0xC2,0x38,0xBF,0xB6,0xBE,0xAF,0x23,0x41,0xE2,0x40,0xED,0xFD,0x95,0x8B, + 0x23,0x49,0xC2,0x38,0xDE,0xFF,0xDF,0x35,0x03,0x41,0xC2,0x38,0xFA,0xAE,0xFF,0xAA, + 0x03,0x41,0xE2,0x38,0xFB,0x6B,0x8A,0x25,0x23,0x41,0xC2,0x38,0xA7,0x2F,0x8B,0xFB, + 0x02,0x41,0xC2,0x38,0xA8,0x9A,0xFF,0xDB,0x23,0x41,0xC2,0x38,0xFA,0xFD,0xFD,0x35, + 0x03,0x41,0xE2,0x38,0xEF,0x42,0x6F,0x8E,0x03,0x41,0xA1,0x38,0x88,0xA2,0xBF,0x27, + 0x23,0x49,0xC2,0x40,0xB5,0x17,0x9E,0xBF,0x66,0x72,0x44,0x51,0x2B,0xA9,0x2D,0x0D, + 0x87,0x72,0x06,0x62,0xFF,0x7A,0x78,0xFC,0x26,0x6A,0xE5,0x59,0xEA,0x98,0xAA,0x8A, + 0x06,0x62,0x64,0x49,0x68,0x70,0x6C,0xFA,0x44,0x41,0xE3,0x38,0x7E,0x7C,0xFF,0xDF, + 0x03,0x39,0xC2,0x30,0x03,0x0A,0x02,0xAB,0x03,0x39,0xE2,0x30,0x00,0x20,0x0F,0x03, + 0x23,0x39,0xE3,0x38,0x01,0x2B,0xFE,0x5F,0x24,0x41,0x03,0x39,0x56,0x77,0x73,0x57, + 0x23,0x41,0xE3,0x30,0x8E,0xFD,0xB2,0xAA,0x24,0x39,0x03,0x39,0x42,0x5F,0xA9,0x7E, + 0x44,0x41,0x03,0x39,0x5F,0x4B,0x82,0x03,0x44,0x41,0xE2,0x30,0x5F,0x7F,0xE2,0xE0, + 0x23,0x39,0xE3,0x38,0xF5,0x7D,0xFF,0x82,0x23,0x39,0xE3,0x38,0x02,0x02,0xFE,0xF9, + 0x44,0x39,0xE3,0x30,0xFF,0xFF,0xAF,0x89,0x24,0x39,0xC2,0x30,0xDF,0xFA,0xE8,0x2A, + 0x03,0x31,0xC2,0x28,0xD5,0xFD,0xBA,0x80,0x03,0x31,0xC2,0x28,0xBF,0xFF,0x6A,0x60, + 0x03,0x31,0xE3,0x30,0x6D,0xAD,0xFE,0xF9,0x03,0x31,0xC2,0x28,0xEE,0xAF,0x0A,0xC2, + 0x03,0x31,0xC2,0x28,0xB9,0x88,0x00,0x00,0x24,0x39,0xC2,0x30,0x77,0xF2,0xA2,0xE2, + 0x24,0x31,0xC2,0x30,0x7F,0xEF,0xAE,0xA2,0xE3,0x30,0xC2,0x30,0xDB,0xAB,0x20,0x82, + 0x03,0x39,0xA2,0x28,0xFF,0xF7,0xA8,0xCA,0x24,0x39,0xC2,0x30,0x7C,0xF5,0x75,0xFD, + 0x23,0x31,0xE3,0x30,0x5D,0xDB,0x7B,0x5D,0x03,0x31,0xC2,0x28,0xBF,0x2E,0xFF,0xF5, + 0x03,0x31,0xA2,0x28,0xFE,0xB8,0xFA,0xA9,0xE3,0x30,0xA2,0x28,0xAA,0xEA,0x40,0x82, + 0xE3,0x30,0xC2,0x28,0x9D,0x9F,0xAD,0x0D,0xA2,0x30,0xE3,0x28,0xB9,0x79,0x7D,0xFD, + 0xE3,0x28,0x82,0x20,0xDF,0x9E,0x88,0x08,0xC3,0x28,0x81,0x20,0x5B,0xF3,0xE2,0xA8, + 0xC3,0x28,0x82,0x20,0xFB,0xFF,0xFA,0x6B,0xC2,0x28,0x82,0x20,0x7E,0x5F,0x7E,0x7A, + 0xA2,0x28,0x82,0x20,0x55,0xD9,0xB6,0xAA,0x61,0x28,0xA2,0x20,0xBF,0xA5,0xBD,0xFD, + 0xA2,0x20,0x61,0x20,0xB8,0xBF,0xDE,0xF8,0xA2,0x28,0x82,0x20,0x2A,0xF3,0x59,0xD5, + 0xA2,0x28,0x82,0x20,0xAE,0x97,0xDF,0x7B,0xA2,0x28,0x82,0x20,0x0B,0x0D,0x02,0xC2, + 0xE3,0x30,0x82,0x28,0x2F,0x3F,0x3D,0x3D,0x23,0x39,0xC2,0x30,0x7A,0xEB,0xFA,0xF8, + 0xE3,0x30,0xA2,0x28,0xAE,0xBF,0xF7,0xE0,0xE3,0x30,0xA2,0x28,0x82,0x3E,0x2F,0x2F, + 0x23,0x39,0xC2,0x30,0xDF,0x9F,0x7E,0xFC,0xE2,0x30,0xC1,0x30,0x80,0x80,0xA7,0x56, + 0x03,0x39,0xC2,0x30,0xAB,0xAA,0xAB,0x0F,0x23,0x39,0xC2,0x30,0xDF,0xBE,0xEA,0xE8, + 0x23,0x39,0xC2,0x30,0x23,0x09,0xAB,0xF7,0x44,0x41,0xE2,0x38,0x3A,0xBE,0xFE,0xBD, + 0x64,0x49,0x24,0x41,0x8E,0xAD,0xAD,0xA5,0x64,0x41,0x24,0x41,0xBF,0x8B,0x88,0xC0, + 0x64,0x41,0xE3,0x30,0xFE,0x7C,0x7A,0xF0,0x24,0x39,0xC2,0x30,0x62,0xFF,0x77,0x77, + 0xE2,0x30,0x82,0x28,0x2E,0xAE,0xE7,0xFE,0xE3,0x30,0xA1,0x28,0xD7,0xBD,0xEB,0x0B, + 0x03,0x39,0xA2,0x28,0xAD,0x8B,0xBF,0xCB,0xE3,0x30,0xA2,0x28,0xAF,0x2E,0x3A,0x9C, + 0xC2,0x30,0x82,0x28,0xEE,0xFC,0xB8,0xBA,0xA2,0x28,0x81,0x20,0x30,0xF8,0x3E,0x06, + 0xC2,0x28,0x81,0x20,0xAA,0x1B,0xDE,0x2E,0xC2,0x28,0x61,0x28,0xE8,0x2A,0xA0,0xA8, + 0x02,0x31,0xA2,0x28,0x35,0xF5,0xFF,0xFF,0xE2,0x30,0xA2,0x28,0x7A,0x5A,0x78,0x5A, + 0xC2,0x28,0x81,0x20,0xB6,0xEE,0xAF,0x0D,0x03,0x31,0x82,0x28,0xFF,0xBE,0xEB,0x8D, + 0x23,0x39,0xC2,0x30,0x2D,0x0F,0x89,0xAF,0x23,0x39,0xE3,0x30,0xC0,0x80,0x01,0x0F, + 0x23,0x39,0xE2,0x30,0x57,0xFA,0xFE,0x28,0x44,0x41,0xE2,0x38,0x7B,0xE8,0x83,0x82, + 0x23,0x41,0xE2,0x38,0x6F,0xFA,0x22,0x00,0x64,0x49,0x02,0x39,0xCD,0xBD,0xBF,0xFF, + 0x85,0x51,0x23,0x41,0xA9,0x8B,0x8B,0x2A,0x85,0x51,0x64,0x49,0x09,0xCA,0xF2,0x2E, + 0x06,0x62,0x64,0x51,0xAF,0x39,0xAD,0x2F,0xC9,0x7A,0x26,0x62,0xBD,0xA5,0xAD,0x2D, + 0xE9,0x7A,0xA9,0x72,0x25,0x21,0xAA,0xAC,0x0A,0x83,0xA9,0x7A,0x28,0xA2,0x5A,0x6A, + 0x0A,0x83,0xC9,0x7A,0xB0,0xA1,0xB5,0xBD,0x0A,0x83,0xC9,0x7A,0xAB,0xFF,0xEB,0x7F, + 0x0A,0x83,0xC9,0x7A,0xEC,0x02,0x23,0x2D,0x2B,0x83,0xC9,0x7A,0xAF,0xFF,0xA0,0xA0, + 0x2B,0x83,0xA9,0x7A,0x8B,0xFA,0x7A,0xF0,0x0A,0x83,0xC9,0x7A,0x6E,0xBA,0x01,0x29, + 0x2A,0x83,0xEA,0x82,0x8D,0x8D,0xA2,0xF0,0x6C,0x8B,0x0A,0x83,0x09,0xB5,0xBD,0xB7, + 0xAD,0x93,0x0A,0x83,0x0A,0xAF,0x9F,0xD7,0x6F,0xAC,0x0A,0x83,0x02,0xAF,0xFF,0xFD, + 0xD0,0xBC,0x4B,0x8B,0x00,0x2A,0xAF,0xF5,0x10,0xBD,0x0D,0xA4,0x20,0xA8,0xCB,0xF5, + 0xCF,0xB4,0x4E,0xAC,0x5C,0x7C,0xFA,0x7F,0x8F,0xB4,0x4E,0xAC,0x69,0xB1,0x2F,0xD7, + 0xAF,0xB4,0x4E,0xAC,0x7F,0x9B,0xD3,0xB3,0x8F,0xB4,0x4E,0xAC,0xD7,0x7F,0xBE,0x88, + 0x8F,0xB4,0x4E,0xAC,0x57,0x3A,0x8A,0xCA,0x6E,0xAC,0x2D,0xA4,0xB6,0xBC,0x2C,0x2A, + 0x8F,0xAC,0x4E,0xAC,0x5E,0x7F,0x6B,0xAF,0xAE,0xAC,0x4E,0xAC,0x5D,0xFD,0x7D,0xFE, + 0x8F,0xB4,0x2D,0xA4,0xBA,0xB9,0xAB,0xA0,0xAF,0xAC,0x4D,0xAC,0x9F,0xF5,0xF7,0xFF, + 0x6E,0xB4,0x4E,0xA4,0x2A,0xEA,0xF8,0xF8,0x8F,0xAC,0x4E,0xAC,0x5E,0x5D,0xF9,0x6A, + 0x23,0x49,0xC2,0x40,0xFE,0xBA,0xFE,0xE7,0x02,0x41,0xC2,0x38,0xBF,0xEE,0xBF,0xBA, + 0x03,0x41,0xE2,0x40,0x0B,0x01,0x81,0xAA,0x23,0x41,0xE2,0x40,0x27,0xB9,0x0F,0xFD, + 0x23,0x49,0xE2,0x40,0xBF,0x2F,0x87,0x39,0x23,0x49,0xE2,0x38,0xE8,0x58,0xDF,0x96, + 0x23,0x41,0xC2,0x40,0xB9,0xAB,0xBA,0xB8,0x03,0x41,0xC2,0x38,0xAB,0x7F,0xD8,0x5C, + 0x03,0x41,0xC2,0x38,0x8B,0xC1,0xF3,0x5E,0x03,0x41,0xA1,0x38,0xAF,0xA8,0x02,0x2F, + 0x03,0x41,0xC2,0x38,0xEF,0xA2,0x60,0xAA,0x03,0x41,0xC2,0x38,0x37,0x82,0xC3,0xAF, + 0x03,0x41,0xC2,0x38,0x3E,0xFA,0xF9,0xBF,0x03,0x41,0xC2,0x38,0xC2,0x68,0x4E,0xFF, + 0x02,0x41,0xA1,0x38,0x3D,0xAE,0xAE,0xAA,0x03,0x41,0xC2,0x38,0x02,0xB2,0xAD,0x8E, + 0x03,0x41,0xE2,0x38,0x7F,0x7F,0xED,0xAD,0x02,0x41,0xC1,0x38,0xE9,0x38,0xF2,0xEB, + 0xE2,0x40,0xC2,0x38,0xDA,0xF0,0x02,0x0B,0x02,0x41,0xC2,0x38,0xEE,0xF7,0x5E,0x9A, + 0xE2,0x40,0xC2,0x38,0x08,0x2C,0x1B,0x02,0xE2,0x40,0xC2,0x38,0x27,0xA2,0xE0,0xCA, + 0x03,0x49,0xE2,0x38,0xB6,0xB7,0xBF,0xAD,0x46,0x6A,0x43,0x49,0x0B,0x09,0x0D,0x0D, + 0x86,0x72,0x25,0x6A,0xFE,0xFE,0x6A,0x60,0x26,0x6A,0xE5,0x61,0xF8,0x7C,0x70,0x12, + 0x05,0x62,0x23,0x41,0x70,0xE0,0xE8,0xA0,0x23,0x41,0xC2,0x30,0xAA,0x98,0xD8,0xF8, + 0x03,0x39,0xE2,0x30,0xEF,0xEA,0x7A,0x5B,0x03,0x39,0xE2,0x30,0xAB,0x2D,0x35,0x95, + 0x24,0x39,0xC3,0x30,0xFE,0x9E,0xF2,0xFA,0x03,0x39,0xE3,0x30,0xE8,0x6E,0xE3,0xEE, + 0x23,0x39,0xE3,0x38,0x2B,0xBD,0xEF,0xFD,0x23,0x39,0xE2,0x38,0xA8,0x08,0xBE,0x7F, + 0x23,0x39,0xE2,0x38,0x02,0x0E,0xAF,0xAB,0x44,0x39,0xE3,0x30,0xCA,0x8A,0xF7,0xBE, + 0x44,0x41,0xE3,0x30,0xE2,0xAA,0x3A,0xBF,0x64,0x41,0xE3,0x30,0x7D,0x7B,0xF0,0xE2, + 0x44,0x41,0xE3,0x30,0xF5,0x55,0xFB,0xA2,0x24,0x39,0xE3,0x30,0x2B,0x87,0x5B,0x7B, + 0x24,0x39,0xE3,0x30,0xA0,0xA8,0xEB,0xB9,0x24,0x39,0xE3,0x30,0x7A,0xFA,0xBE,0xB2, + 0x24,0x39,0xE3,0x30,0xE7,0xFE,0xBA,0xBA,0x23,0x39,0xE3,0x30,0x1F,0xBB,0xA2,0x80, + 0x44,0x39,0xE3,0x30,0xFC,0xDF,0xD5,0xFB,0x24,0x39,0xE3,0x30,0x82,0xAA,0xBD,0xAE, + 0x23,0x39,0xE2,0x30,0x8A,0x3A,0xAB,0xED,0x24,0x39,0xE3,0x30,0x7F,0xFC,0xFC,0xFE, + 0x24,0x39,0xC2,0x30,0x4B,0x8A,0x8A,0xAE,0x03,0x39,0xE3,0x30,0x59,0x82,0x06,0x25, + 0x24,0x39,0xC2,0x28,0x5B,0xFB,0xA2,0xE2,0x03,0x31,0xC2,0x28,0xF5,0xFF,0xEE,0xA8, + 0xE3,0x30,0xC2,0x28,0xBA,0xEA,0xE7,0xA8,0x03,0x31,0xC2,0x28,0x4B,0xBD,0xB5,0xAF, + 0x03,0x31,0xC2,0x28,0xAF,0xDE,0x94,0xF8,0x03,0x31,0xC3,0x28,0x5A,0xFA,0xFE,0xBE, + 0x03,0x31,0xC3,0x28,0x75,0x55,0xDE,0x6B,0xE3,0x28,0xA2,0x20,0xDE,0xBE,0xBA,0xAA, + 0xC3,0x28,0x82,0x20,0x8A,0xE0,0x40,0x80,0xC2,0x28,0x82,0x20,0x7A,0xAA,0xAA,0x30, + 0xC2,0x28,0xA2,0x20,0x7D,0x35,0xAB,0xEC,0xC3,0x28,0x82,0x20,0x57,0xDC,0xD8,0x7B, + 0xC3,0x28,0x82,0x20,0x5E,0x5F,0xFB,0x2A,0xC2,0x28,0x62,0x18,0xAF,0xAB,0xEA,0xA8, + 0xA2,0x28,0x62,0x20,0x3A,0xF8,0xBE,0xBE,0xA2,0x28,0x82,0x20,0xA0,0xEE,0xEF,0xDF, + 0xC3,0x30,0x81,0x20,0x0B,0x2B,0xBF,0xED,0x03,0x31,0xA2,0x28,0x80,0x22,0xFB,0x55, + 0xE3,0x30,0xA2,0x28,0xC0,0xC0,0xE3,0xA5,0xE3,0x30,0xA2,0x28,0x9F,0xFB,0x6B,0xEE, + 0x03,0x39,0xA2,0x28,0x2B,0x2F,0xAD,0xEF,0x03,0x39,0xC2,0x30,0xFA,0x8A,0x8B,0xAB, + 0x03,0x39,0xE3,0x30,0xFD,0xAE,0x23,0x02,0x03,0x39,0xA2,0x28,0xA2,0xEA,0xEA,0x7E, + 0xC2,0x30,0x81,0x28,0x08,0x8A,0xEB,0xEA,0x03,0x39,0xA1,0x30,0xAA,0x2F,0xEB,0xAD, + 0x44,0x41,0xC2,0x30,0x02,0x2B,0xEF,0xD7,0x65,0x49,0xE2,0x30,0xA0,0xA2,0xAF,0xD5, + 0x65,0x49,0x03,0x39,0xF2,0xF2,0x8B,0xE9,0x24,0x41,0xA2,0x30,0x72,0xE8,0xE8,0xFA, + 0xE3,0x30,0x82,0x28,0xFE,0xDF,0xFA,0xB8,0xE3,0x30,0x81,0x28,0x09,0xAF,0xBB,0xAE, + 0x03,0x39,0xA2,0x28,0x8B,0xBB,0xF6,0xBF,0x03,0x39,0xA2,0x28,0xFE,0xAE,0xFA,0x72, + 0xC2,0x30,0x82,0x28,0xFE,0xEC,0x98,0xF8,0xC2,0x30,0x81,0x28,0x37,0xF6,0xE2,0xA0, + 0xE2,0x30,0xA2,0x28,0xA6,0xAB,0x89,0xAD,0xE2,0x30,0xA1,0x28,0xF5,0xF5,0xEE,0xA8, + 0xE2,0x30,0x82,0x28,0xB9,0xEA,0xBA,0x02,0xE3,0x30,0xA1,0x28,0x5A,0xB3,0xEA,0xEA, + 0xC2,0x28,0x81,0x28,0x05,0xAF,0xBF,0xBE,0x23,0x39,0xC2,0x28,0x25,0xF5,0x5D,0xD7, + 0x24,0x39,0xC3,0x30,0x36,0xAB,0xE9,0xEE,0x23,0x39,0xC2,0x30,0x0F,0xF9,0x5F,0xEF, + 0x23,0x39,0xE2,0x30,0x38,0x0D,0x2B,0x03,0x64,0x49,0x23,0x41,0xB5,0x05,0xA5,0xD5, + 0x63,0x49,0x03,0x39,0xFF,0xFF,0xEF,0xFC,0x44,0x49,0x03,0x41,0xF5,0x05,0xFD,0x97, + 0xA5,0x51,0x23,0x41,0x2F,0x2F,0x2D,0x35,0x47,0x6A,0x84,0x49,0xF5,0xBD,0xA7,0x0F, + 0x68,0x6A,0xC5,0x59,0xF5,0x2D,0x02,0x08,0xC9,0x7A,0x68,0x6A,0x1D,0x9D,0xA9,0x8F, + 0xE9,0x7A,0xA9,0x72,0xB6,0x27,0xCD,0x0B,0x0A,0x83,0xC9,0x7A,0x5A,0x62,0x59,0x55, + 0xE9,0x7A,0xA9,0x7A,0x8A,0x8E,0xAA,0xFE,0x0A,0x83,0xA9,0x72,0x3D,0xAF,0x03,0xB8, + 0x0A,0x83,0xA9,0x72,0x89,0x8E,0xBB,0xEB,0x2A,0x83,0xC8,0x7A,0x20,0xEA,0xAB,0x2D, + 0x4B,0x8B,0xEA,0x7A,0xE3,0xEE,0xDE,0xFA,0x2A,0x83,0xEA,0x7A,0xBF,0xBE,0x8B,0xAB, + 0x4B,0x8B,0xEA,0x7A,0xBF,0x8F,0xEE,0x57,0x2A,0x83,0xE9,0x7A,0x28,0x2A,0xEE,0xB7, + 0x4A,0x8B,0xE9,0x7A,0xF8,0xFB,0xF3,0xFB,0x4B,0x8B,0xEA,0x7A,0x01,0xBB,0x3A,0xB8, + 0x6B,0x8B,0x0A,0x83,0x02,0xFE,0xD7,0xDE,0xEC,0x9B,0x2A,0x83,0x0A,0xBB,0x9D,0x75, + 0x2D,0xA4,0x29,0x83,0x00,0x2A,0xFF,0x55,0x4E,0xAC,0x6B,0x8B,0x00,0x00,0x2B,0xDD, + 0x8F,0xB4,0xCD,0x9B,0x00,0x0A,0x0A,0xA9,0xAF,0xB4,0x4E,0xAC,0xEE,0x8A,0xAA,0x7F, + 0x8F,0xB4,0x6E,0xAC,0x7D,0xAD,0xA2,0x6E,0x8F,0xB4,0x2D,0xA4,0xDA,0xAA,0xA8,0xB2, + 0x8F,0xB4,0x6E,0xAC,0xD6,0xBC,0xE5,0x3E,0x8F,0xB4,0x4E,0xAC,0x0A,0xAE,0x8E,0xA4, + 0xAF,0xB4,0x6E,0xAC,0xFF,0x75,0xE7,0xFA,0xAF,0xB4,0x4D,0xAC,0x37,0xA7,0x2A,0xAA, + 0xAF,0xB4,0x4D,0xAC,0xF7,0x6E,0x28,0x28,0xD0,0xB4,0x6E,0xAC,0x77,0x7E,0xEA,0xAA, + 0x23,0x41,0xE2,0x40,0x75,0xBD,0xCB,0xA2,0x23,0x41,0xE2,0x40,0x7F,0xEF,0x6C,0xFB, + 0x03,0x41,0xE2,0x40,0x4B,0xF3,0x53,0x73,0x23,0x49,0xC2,0x38,0xFF,0xFF,0xFF,0x3E, + 0x23,0x41,0xC2,0x38,0x2B,0x7F,0xEA,0xEF,0x23,0x41,0xC2,0x40,0x3C,0xAF,0xED,0xAD, + 0x23,0x49,0xC2,0x38,0xFE,0xFF,0xEB,0xE2,0xE2,0x40,0xC2,0x38,0x9C,0xAC,0xEA,0x56, + 0x02,0x41,0xC2,0x38,0xD5,0xFD,0xEF,0x2F,0x03,0x41,0xA1,0x30,0x35,0xBF,0x2B,0x0A, + 0x03,0x41,0xE2,0x38,0xEC,0xFE,0xFE,0xF8,0x23,0x41,0xC2,0x38,0xBD,0x37,0xDE,0xBB, + 0x03,0x41,0xC2,0x38,0xEF,0x8A,0xA2,0xE8,0xE2,0x40,0xC2,0x38,0x27,0x8F,0x02,0x00, + 0xE2,0x40,0xC2,0x38,0x22,0xAA,0xFE,0xEE,0x03,0x41,0xC2,0x38,0xBB,0xE2,0xDF,0x55, + 0x03,0x41,0xC2,0x38,0x02,0xCA,0x55,0x79,0x03,0x41,0xA1,0x30,0x8A,0xFF,0xBF,0xAA, + 0x03,0x41,0xE2,0x38,0x57,0xEC,0xD2,0x5A,0x03,0x41,0xC2,0x38,0xB2,0x82,0x09,0x2D, + 0x03,0x41,0xC2,0x38,0x8B,0xAF,0xCE,0x62,0xE2,0x40,0xA2,0x38,0xC2,0xE0,0xC8,0x9A, + 0x02,0x41,0xC2,0x38,0x0D,0x95,0xBF,0x2F,0xA7,0x7A,0x43,0x49,0x29,0xAD,0x2D,0x2D, + 0x86,0x72,0x46,0x6A,0x6A,0x92,0xE2,0xF6,0x26,0x6A,0x05,0x62,0x90,0xD2,0x70,0x50, + 0x05,0x62,0x63,0x49,0x60,0x78,0xE0,0x60,0x63,0x49,0xC2,0x30,0x7B,0x7E,0xFC,0x7E, + 0xE2,0x38,0xC2,0x30,0xBA,0xEF,0x76,0xA2,0x03,0x39,0xC2,0x30,0x97,0xFE,0xAD,0xA7, + 0x23,0x39,0xE2,0x38,0x55,0x79,0xCB,0x6A,0x23,0x39,0xE2,0x30,0x5D,0xFE,0x2F,0xAA, + 0x23,0x39,0xE3,0x38,0xEF,0xAF,0x2D,0xEF,0x23,0x39,0xC2,0x38,0x63,0xAA,0xAA,0xAE, + 0x43,0x41,0x03,0x39,0xF9,0xEF,0x78,0xFE,0x24,0x39,0x03,0x39,0xBC,0x27,0xA5,0x95, + 0x44,0x41,0x03,0x39,0x06,0x3F,0xBE,0xEA,0x65,0x41,0x03,0x39,0xE3,0xAA,0x2F,0xFA, + 0x44,0x41,0x03,0x39,0xBA,0xF8,0xFE,0xEE,0x44,0x41,0x03,0x31,0x7B,0xBA,0xE3,0xA0, + 0x44,0x39,0x03,0x31,0x5D,0x92,0x00,0x88,0x44,0x39,0x03,0x31,0x5D,0x57,0x57,0x78, + 0x24,0x39,0xE2,0x30,0xAA,0xAA,0xA7,0x9F,0x44,0x39,0xE2,0x30,0xA2,0xAA,0xFF,0xDF, + 0x23,0x39,0x03,0x39,0xB2,0x22,0xC1,0x79,0x24,0x39,0xE3,0x38,0xEA,0x78,0x70,0xA2, + 0x03,0x39,0xA2,0x28,0x82,0xA2,0xAC,0xAA,0x24,0x39,0xC3,0x30,0xBF,0xFD,0xBF,0xA8, + 0x03,0x39,0xE3,0x30,0xAB,0xB0,0xA0,0xA0,0x23,0x39,0xE3,0x30,0xAD,0xAF,0xEF,0xD7, + 0x24,0x39,0xE3,0x30,0x8A,0xAB,0xDF,0x57,0x23,0x39,0xE3,0x30,0xFE,0xFF,0xA3,0xBF, + 0x03,0x31,0xE3,0x30,0xDA,0x78,0x5E,0xFE,0x03,0x31,0xA2,0x28,0xAA,0xEA,0xAA,0x08, + 0x24,0x39,0xC2,0x28,0x7F,0x7F,0xDB,0x62,0x23,0x31,0xE3,0x30,0xF5,0x7F,0xFF,0x73, + 0x24,0x31,0xC2,0x28,0xEC,0xE2,0xEB,0x7F,0xE3,0x28,0xC3,0x28,0xD7,0xBE,0x5E,0x57, + 0x04,0x31,0xC3,0x28,0x7F,0x5E,0xEB,0x2C,0xE3,0x28,0xC3,0x28,0x5F,0xC8,0x62,0x80, + 0xE3,0x28,0xA2,0x20,0xBF,0x8E,0x8A,0x82,0xE3,0x28,0xA2,0x20,0x6B,0xB2,0xF2,0xAA, + 0xC2,0x28,0x82,0x20,0xAB,0xF0,0xBA,0xA8,0xC2,0x28,0xA1,0x28,0x6E,0x53,0xB7,0x02, + 0xC2,0x28,0x82,0x20,0x7F,0x76,0xFE,0x6E,0xC2,0x28,0x82,0x20,0xD5,0xF5,0xBF,0xAB, + 0xC3,0x28,0x82,0x20,0x6F,0xFA,0xFE,0x5A,0xA2,0x28,0x82,0x20,0xBF,0xAF,0xF6,0xA5, + 0xC2,0x28,0x82,0x20,0x0E,0xFB,0xFA,0xD5,0xC2,0x30,0xA2,0x28,0x89,0x2B,0x97,0x5B, + 0xE3,0x30,0xA2,0x28,0xBE,0xBC,0xAF,0x9B,0x03,0x31,0xC2,0x30,0x29,0x29,0x05,0xAB, + 0x03,0x39,0xE3,0x30,0xFF,0x7C,0xFE,0xFF,0x44,0x41,0x81,0x28,0x7F,0x7F,0x7A,0xEC, + 0x03,0x31,0xA2,0x30,0x7D,0xFD,0xF5,0xBF,0xE2,0x30,0xA2,0x28,0xA1,0xA7,0xB7,0xFE, + 0xE3,0x30,0xA2,0x30,0xFF,0xBF,0xAE,0xE2,0x82,0x38,0xE3,0x30,0x77,0xFD,0xF7,0xBF, + 0x03,0x39,0xC2,0x30,0xA2,0xF2,0x59,0xDD,0xE2,0x30,0xA1,0x30,0xA0,0xF0,0x5A,0x6A, + 0xC2,0x30,0x81,0x28,0xB8,0x5C,0xFE,0x0F,0xE2,0x30,0xC2,0x30,0xF5,0x6D,0xAD,0xAB, + 0xE3,0x30,0xA2,0x30,0x1A,0x0E,0x08,0x2A,0xE3,0x30,0xC2,0x30,0x7A,0x72,0x45,0xCA, + 0xC2,0x30,0xA2,0x28,0xDF,0x66,0xFF,0x48,0xC2,0x28,0xA2,0x28,0x3B,0x8A,0x8B,0xFE, + 0xE2,0x30,0xA2,0x28,0x2F,0xAD,0x75,0x29,0x23,0x39,0xC2,0x28,0xFF,0xDF,0xB9,0xA2, + 0x03,0x39,0xC2,0x28,0xAE,0x7E,0xB8,0x28,0x23,0x39,0xC2,0x28,0x5F,0x6A,0xA8,0xA0, + 0x03,0x31,0xA1,0x28,0x75,0x5F,0xBC,0xAA,0xE3,0x30,0xA2,0x28,0x2B,0x8B,0xAA,0x88, + 0x03,0x39,0xC3,0x30,0xAA,0xBD,0xFA,0xBE,0x43,0x41,0xE2,0x30,0xB5,0x95,0xFF,0xAA, + 0x44,0x41,0x02,0x39,0xCE,0x80,0xCA,0xEB,0x64,0x49,0x03,0x39,0xBF,0xCF,0x7B,0x55, + 0x44,0x49,0xE2,0x38,0xB8,0xAA,0xA5,0x35,0xA5,0x51,0x03,0x41,0x55,0x5D,0xBB,0x2A, + 0x67,0x6A,0x23,0x41,0xF5,0xBD,0xAF,0x2A,0x67,0x6A,0xC5,0x51,0x25,0x2F,0xAB,0x00, + 0xA8,0x72,0x47,0x6A,0xBD,0x3F,0xFF,0xEF,0xE9,0x7A,0x67,0x72,0xAB,0x0F,0xE9,0xEF, + 0xC9,0x7A,0x88,0x72,0x08,0xA8,0x2A,0xBF,0xC9,0x7A,0xA9,0x72,0xC5,0x61,0xFA,0x5C, + 0xEA,0x7A,0x89,0x72,0x2F,0x3D,0xA5,0xAF,0x0A,0x83,0xA9,0x7A,0x3A,0xB8,0xFA,0xFF, + 0xE9,0x7A,0xA8,0x7A,0x7A,0x40,0xEE,0x3F,0xE9,0x7A,0xA9,0x72,0x01,0xEF,0xA4,0xB8, + 0x0A,0x83,0xC9,0x7A,0x8F,0xB5,0xBF,0xFF,0x2A,0x83,0xC9,0x7A,0xAA,0x2A,0x0B,0x25, + 0x2A,0x83,0xC9,0x7A,0x5E,0xFC,0xEE,0xE2,0x2A,0x83,0xE9,0x7A,0x76,0xD5,0xCD,0xAD, + 0x0A,0x83,0xEA,0x7A,0xEA,0x02,0x32,0x5F,0x29,0x83,0xEA,0x7A,0xD8,0xEC,0x82,0x03, + 0x4B,0x8B,0xA8,0x72,0xA0,0x80,0xA2,0xFE,0x4B,0x8B,0xC9,0x72,0x2B,0x3E,0x3F,0xFD, + 0x4A,0x8B,0x0A,0x83,0xFC,0xEE,0xD5,0xDD,0x8B,0x93,0xE9,0x7A,0x2B,0xAB,0xFF,0x7D, + 0x0D,0xA4,0x2A,0x83,0x0A,0xBD,0xF5,0x55,0x4E,0xAC,0x2A,0x8B,0x02,0xAB,0xBF,0xF5, + 0x8F,0xAC,0xAC,0x93,0x00,0x8A,0xA9,0xB5,0x8F,0xAC,0x4E,0xAC,0xA5,0xF5,0xFF,0x55, + 0x8E,0xB4,0x4E,0xAC,0xAC,0x8B,0xB2,0xFF,0x8E,0xB4,0x4D,0xA4,0xBF,0x1D,0x07,0xAE, + 0xAF,0xB4,0x6E,0xAC,0x9A,0x2A,0x2B,0x02,0xCF,0xBC,0x6E,0xAC,0xFE,0xFF,0x9F,0xF7, + 0xAF,0xB4,0x8F,0xAC,0x1B,0x2E,0xE0,0xC0,0xCF,0xB4,0x8F,0xB4,0xCA,0xC0,0xAB,0xF2, + 0x23,0x49,0xC2,0x38,0xAA,0xFE,0xDD,0xBF,0x23,0x41,0xE2,0x40,0x7B,0x7F,0x9D,0xA7, + 0x03,0x41,0xE2,0x38,0x95,0x92,0xEA,0xA3,0x23,0x41,0xE2,0x38,0xDA,0x7F,0x5A,0x78, + 0x02,0x41,0xA2,0x30,0xAE,0xAA,0x2D,0xAE,0x03,0x41,0xA1,0x30,0x0A,0xAC,0xDA,0xFA, + 0x03,0x41,0xA1,0x30,0xB0,0xA2,0xAF,0xAF,0x03,0x41,0xA1,0x30,0xEF,0xFE,0xBA,0x08, + 0x03,0x41,0xC2,0x38,0xAB,0xEF,0xAF,0x37,0x03,0x41,0xA2,0x38,0x48,0xBA,0x2B,0x20, + 0x03,0x41,0xE2,0x38,0xB3,0x5A,0x76,0xAE,0x03,0x41,0xC2,0x38,0xB0,0xB8,0x6E,0x7E, + 0x03,0x41,0xE2,0x38,0x62,0xCB,0x85,0xAD,0x24,0x41,0xC2,0x38,0xD7,0xD6,0x7F,0xFB, + 0xE2,0x38,0xC2,0x38,0xFC,0x16,0x15,0x2B,0x23,0x41,0xC2,0x38,0xFF,0x8B,0xBE,0x5F, + 0x03,0x41,0xA1,0x30,0xE2,0xAB,0xDE,0xAF,0x03,0x41,0xE2,0x38,0xC3,0x63,0x50,0xDC, + 0x02,0x41,0xE2,0x38,0x5F,0x7D,0x38,0xB9,0x03,0x41,0xC2,0x38,0xB3,0xDB,0x9A,0xAA, + 0x03,0x41,0xC2,0x38,0xF0,0xC2,0xEE,0xDE,0x03,0x41,0xC2,0x38,0x55,0xED,0x2F,0xAF, + 0x03,0x41,0xC2,0x38,0xF3,0xE3,0xEA,0xFA,0x67,0x72,0x02,0x41,0x2D,0x2D,0x2D,0x2D, + 0x87,0x72,0x05,0x62,0xA8,0xE0,0x78,0xFA,0x46,0x72,0xE5,0x61,0xDF,0xB6,0xFF,0xFC, + 0x05,0x62,0x43,0x49,0xE0,0xE0,0x60,0xE0,0x63,0x41,0xE2,0x38,0x7F,0x5F,0x5E,0xDC, + 0x03,0x39,0xC2,0x30,0x2A,0x2A,0x8A,0x27,0x03,0x39,0xE3,0x30,0x7B,0xE2,0xBC,0xAE, + 0x03,0x39,0xE3,0x30,0x1E,0x6E,0x73,0x58,0x23,0x39,0xE2,0x30,0xC0,0xCB,0xE3,0xFA, + 0x23,0x39,0xE2,0x30,0x6B,0xAA,0x3D,0x95,0x23,0x39,0xE3,0x38,0xD7,0xD7,0xFC,0xD5, + 0x23,0x39,0xE2,0x30,0x82,0xEA,0xAE,0x7B,0x44,0x41,0xE3,0x30,0xAB,0xAE,0xE7,0xFB, + 0x23,0x39,0x03,0x39,0x01,0x42,0xC2,0x66,0x44,0x41,0x03,0x39,0xFA,0xAB,0xEB,0xD5, + 0x44,0x41,0x03,0x39,0x27,0x0F,0xAB,0xAB,0x44,0x41,0xE3,0x30,0x80,0x28,0x36,0xEE, + 0x44,0x41,0x03,0x39,0xA8,0xE2,0x7A,0xAA,0x44,0x41,0xE2,0x30,0xFE,0xFF,0x6B,0x62, + 0xE3,0x38,0x03,0x31,0xFF,0x2A,0xAA,0x9E,0x03,0x39,0xE3,0x30,0xFF,0x23,0xAF,0x7E, + 0x03,0x39,0xC2,0x30,0x0A,0x0E,0x03,0x2B,0x44,0x41,0xE2,0x30,0xAB,0x2F,0xFD,0xE5, + 0x24,0x39,0xE3,0x38,0x8F,0x8B,0x0F,0xFD,0x44,0x41,0x04,0x39,0xFF,0xE6,0x5A,0x58, + 0x44,0x41,0xE3,0x30,0xFF,0x7F,0xFA,0xAB,0x24,0x41,0xE3,0x38,0xBF,0xB6,0xF8,0xF8, + 0x03,0x39,0xC2,0x30,0xE0,0xCA,0xAA,0xA0,0x23,0x39,0xC2,0x30,0x2B,0x2F,0xFF,0x7F, + 0x23,0x39,0xC2,0x28,0xBA,0x3E,0xF7,0x95,0x03,0x31,0xE3,0x30,0x80,0x78,0xDF,0x75, + 0x24,0x39,0xE3,0x30,0x7A,0x7B,0xFD,0x65,0x03,0x31,0xC3,0x28,0xBA,0xAF,0xBE,0xB2, + 0x24,0x39,0xC2,0x28,0x7F,0xFF,0xEF,0xAE,0x03,0x31,0xC2,0x28,0xFF,0xE9,0xCD,0xCA, + 0x04,0x31,0xC2,0x28,0x2A,0xEF,0xE5,0xEE,0x04,0x31,0xC3,0x28,0x68,0x63,0x69,0xFD, + 0xE3,0x30,0xC3,0x28,0xDA,0x7D,0x59,0x57,0x03,0x31,0xC3,0x28,0x75,0xDD,0xFD,0xAD, + 0xE3,0x30,0xA2,0x28,0xF6,0xF7,0x0A,0x0A,0xE3,0x30,0xA2,0x28,0xEF,0xFF,0xFA,0xB8, + 0xE3,0x30,0xA2,0x28,0x67,0xFD,0xDC,0x38,0xC3,0x28,0xA2,0x28,0x51,0x6B,0x7A,0xC3, + 0xC3,0x28,0x82,0x20,0x7E,0xFF,0xBF,0xAF,0xA2,0x28,0x82,0x20,0x26,0x26,0x38,0xA8, + 0xA2,0x20,0x61,0x20,0xFE,0xFA,0xDA,0xAA,0xA2,0x28,0x61,0x18,0x38,0xBF,0x9F,0xFA, + 0xC2,0x28,0x81,0x20,0xB8,0x37,0xDF,0xDE,0x03,0x31,0xC2,0x28,0xAD,0xE9,0xAD,0x7D, + 0x23,0x39,0xC2,0x28,0xBF,0xBD,0xAF,0xAF,0x44,0x41,0xA2,0x30,0xFC,0x7E,0x7F,0xFE, + 0xE2,0x30,0x82,0x30,0x22,0x0A,0xAB,0x22,0xC2,0x30,0xC2,0x28,0x08,0x00,0xA0,0x2A, + 0x03,0x39,0xA2,0x30,0xEF,0xFD,0xBB,0x2B,0xE2,0x30,0xA1,0x30,0x7F,0xAB,0x00,0xA0, + 0xE2,0x30,0xC2,0x30,0x1B,0x2F,0x1B,0xD7,0x03,0x39,0xC2,0x30,0x7F,0xF3,0xAB,0x2D, + 0x02,0x39,0xA2,0x30,0xFF,0xDA,0xE0,0xA0,0x03,0x39,0xC2,0x30,0x7F,0x6E,0xEB,0xDD, + 0x03,0x39,0xA2,0x28,0xBF,0x1F,0x3F,0xAF,0x03,0x39,0xC2,0x28,0xFE,0xFB,0xF4,0x5F, + 0xE3,0x30,0xA2,0x28,0xBA,0xF2,0xD7,0xB5,0x03,0x31,0xA1,0x28,0xFE,0x7C,0xEB,0xEA, + 0x03,0x31,0xA1,0x28,0xA9,0xBF,0x2F,0xAA,0x44,0x41,0xE2,0x30,0xAB,0x0D,0x2D,0xAD, + 0x44,0x41,0x03,0x39,0x5E,0x5C,0x78,0x3E,0x85,0x49,0x03,0x39,0x5D,0xED,0xA7,0x8E, + 0x44,0x41,0xE2,0x30,0x55,0x5F,0x78,0xE8,0x44,0x41,0xE3,0x30,0x57,0xFF,0xEB,0x0B, + 0x23,0x39,0xE3,0x30,0xD5,0xE7,0xA3,0x88,0x43,0x41,0x03,0x39,0xFE,0xAB,0xAF,0xE7, + 0x43,0x41,0x03,0x39,0xA2,0x02,0x0B,0x0D,0x64,0x49,0x02,0x39,0xD7,0x97,0xA3,0xEF, + 0xC5,0x51,0x23,0x41,0xD5,0xAF,0x2F,0x2B,0x06,0x5A,0x64,0x51,0xB5,0x8F,0xAE,0x03, + 0x67,0x6A,0x06,0x5A,0xB5,0xBF,0xFB,0xBD,0x67,0x6A,0x27,0x62,0x28,0x08,0x88,0x2F, + 0xA9,0x6A,0x47,0x6A,0xFA,0xB6,0x3F,0xAF,0xC9,0x72,0x67,0x6A,0x8D,0xB7,0xEE,0x8B, + 0xC9,0x7A,0x68,0x6A,0x1F,0xEB,0x8A,0x2E,0xC9,0x72,0x68,0x72,0xEA,0xAF,0x4A,0xAA, + 0xEA,0x7A,0x68,0x72,0x2A,0x02,0x2B,0xD7,0xE9,0x7A,0xA9,0x7A,0xB7,0xFD,0xED,0x29, + 0x0A,0x7B,0x88,0x72,0xDF,0x5F,0xFE,0xA8,0x2A,0x83,0xA8,0x72,0xFF,0x35,0xDD,0xFF, + 0x0A,0x83,0xA9,0x72,0x2A,0x2A,0xAB,0xDE,0x0A,0x83,0xC9,0x7A,0xB7,0xB0,0x80,0x8D, + 0x2B,0x83,0xC9,0x7A,0x7E,0x6D,0x5C,0xFB,0x0A,0x83,0xA9,0x72,0xAB,0xDB,0xDE,0x2A, + 0x0A,0x83,0xA8,0x7A,0x4A,0xF9,0xBF,0xF8,0x09,0x7B,0xA9,0x7A,0x82,0xAA,0x2A,0x9E, + 0x2A,0x83,0xC9,0x7A,0x5F,0xA8,0xA2,0xAB,0x2A,0x83,0xC9,0x7A,0x75,0xD7,0xAA,0xAC, + 0x2B,0x83,0xE9,0x7A,0x9B,0xA6,0xFF,0x22,0x2A,0x83,0xC9,0x7A,0xE8,0xEE,0x7A,0x62, + 0x0A,0x83,0xC9,0x7A,0x08,0xE2,0x0D,0xAF,0x4B,0x8B,0xC9,0x7A,0x02,0xDD,0x7E,0x76, + 0xAC,0x9B,0x0A,0x7B,0x2A,0xBD,0x75,0xD5,0x2D,0xA4,0x0A,0x83,0x02,0xAF,0xFF,0x5D, + 0x6E,0xAC,0x4B,0x8B,0x02,0x0A,0xBD,0xF5,0x8E,0xAC,0xAC,0x93,0x20,0x00,0xAA,0xFD, + 0x8F,0xB4,0x2D,0xA4,0xA8,0x2A,0x2B,0x09,0xAF,0xB4,0x6E,0xAC,0xF7,0xBA,0xB8,0xAB, + 0xF0,0xB4,0x8F,0xB4,0xDB,0xF7,0xD7,0xFD,0xAF,0xB4,0x8F,0xB4,0x20,0x88,0x0E,0x02, + 0x44,0x41,0xE2,0x40,0xFD,0xBD,0xF7,0xDF,0x23,0x49,0xC2,0x38,0xAB,0xA7,0xEA,0x8A, + 0x43,0x49,0xC2,0x38,0xFB,0xF7,0x9E,0xE3,0x03,0x41,0xC2,0x38,0x78,0x6A,0xCA,0xCC, + 0x22,0x39,0xC2,0x38,0xDF,0x79,0xFF,0xD7,0xE2,0x38,0xC2,0x38,0x1F,0xAF,0x36,0xB0, + 0x03,0x41,0xC2,0x38,0xCB,0x96,0x52,0x7F,0x03,0x41,0xC2,0x38,0x0F,0x2E,0xEA,0xEE, + 0x03,0x41,0xA1,0x30,0x36,0xBE,0xAB,0xA2,0x02,0x41,0xC2,0x38,0x38,0xF8,0xEB,0xEA, + 0x22,0x39,0xC2,0x38,0xF7,0xF6,0xFC,0xFA,0x02,0x39,0xC2,0x38,0x96,0xDE,0xD4,0xBE, + 0x02,0x41,0xC2,0x38,0xA6,0x25,0x8A,0xAA,0x03,0x41,0xC2,0x38,0xA7,0xB7,0xF7,0xBF, + 0x03,0x41,0xC2,0x38,0xA2,0x60,0x6E,0xFA,0x03,0x41,0xA1,0x30,0x9E,0xFB,0xE2,0xEA, + 0x03,0x39,0xC2,0x38,0xDB,0x27,0x03,0xBF,0x23,0x39,0xC2,0x38,0xFE,0x5F,0xF7,0xFD, + 0x03,0x41,0xE2,0x38,0x9A,0xB5,0xA9,0x47,0x03,0x41,0xC2,0x38,0xCF,0xEF,0x8A,0x8F, + 0xE2,0x38,0xC2,0x30,0x88,0x2E,0x1A,0x2E,0x03,0x41,0xC2,0x38,0x2F,0xB5,0xDE,0xEF, + 0xE2,0x40,0xA2,0x38,0x00,0xB8,0xFA,0xBE,0x66,0x72,0x23,0x49,0x2D,0x2D,0x2D,0x2D, + 0x66,0x72,0x05,0x62,0xF0,0x42,0x4A,0xE8,0x26,0x6A,0x06,0x62,0x54,0x5E,0xFE,0x80, + 0x46,0x6A,0x84,0x51,0xFE,0x58,0xFA,0xFA,0x64,0x49,0xE2,0x38,0xDE,0x5A,0x7E,0x58, + 0x03,0x39,0xC2,0x30,0x03,0x02,0xB8,0xD8,0x23,0x39,0xC2,0x30,0xBF,0xF8,0x7C,0x5A, + 0x03,0x39,0xC2,0x30,0x5A,0x5F,0x55,0xD5,0x03,0x39,0xC2,0x30,0xED,0xAF,0xEB,0xEB, + 0x24,0x39,0xC2,0x30,0x36,0xBF,0xFB,0xBF,0x03,0x39,0xE2,0x30,0xEF,0xF0,0xBD,0x97, + 0x03,0x39,0xA1,0x28,0xA2,0xAA,0xBC,0x78,0x23,0x39,0xC2,0x30,0xE2,0xA2,0xFF,0x6D, + 0x03,0x39,0xC2,0x30,0xAA,0x22,0x2A,0xFD,0x23,0x39,0xC2,0x30,0x8A,0x00,0x2A,0x2B, + 0x44,0x41,0x03,0x39,0xA2,0xED,0x7E,0xB3,0x24,0x39,0xE2,0x38,0xF2,0x22,0xB0,0x88, + 0x44,0x41,0xE3,0x38,0xA0,0xA0,0xBB,0xF6,0x44,0x41,0xE3,0x38,0x6A,0x6A,0x2A,0xBB, + 0x23,0x39,0xE3,0x38,0xF5,0xE5,0x7F,0xA2,0x03,0x39,0xC2,0x30,0x0E,0x2A,0x80,0x6A, + 0x24,0x39,0xC2,0x30,0x2D,0x2E,0xAF,0x3F,0x44,0x41,0xE3,0x30,0xE7,0xFF,0xFD,0xA5, + 0x24,0x39,0xC2,0x30,0xFF,0x7F,0xFF,0xAA,0x03,0x39,0xE3,0x30,0x03,0x09,0x81,0x0B, + 0x44,0x41,0xC2,0x30,0x0A,0xAF,0xFE,0x7F,0x44,0x41,0x04,0x39,0x5A,0x32,0xCF,0xAF, + 0x44,0x41,0xE3,0x38,0x56,0x7E,0xE8,0xEE,0x23,0x39,0xE3,0x30,0x7F,0xD7,0xFD,0xAA, + 0x03,0x39,0xC2,0x28,0x2B,0x08,0x70,0xA0,0x23,0x39,0xE3,0x30,0x5F,0x7E,0x6C,0xAD, + 0x03,0x31,0xC3,0x30,0xBB,0x3E,0x22,0xA0,0x23,0x39,0xE3,0x30,0xBF,0x3F,0xDF,0xAF, + 0x24,0x39,0x03,0x31,0x55,0x5C,0xFE,0x8B,0x23,0x31,0xE3,0x30,0x67,0xCD,0xEB,0xE0, + 0x04,0x31,0xE3,0x30,0x7D,0xB7,0x28,0xD6,0x03,0x31,0xC2,0x28,0x5A,0xF8,0xEC,0xAE, + 0xE3,0x30,0xC2,0x28,0x57,0x56,0x5A,0x0A,0xE3,0x30,0xC2,0x28,0xAF,0x0D,0xED,0x28, + 0x03,0x31,0xC2,0x28,0x97,0xDC,0xEF,0xFA,0xE3,0x30,0xC2,0x30,0xF0,0x72,0xAA,0xE3, + 0xE3,0x30,0xC2,0x28,0xB4,0x67,0xFF,0x2B,0xE3,0x30,0xA2,0x28,0xFF,0xFB,0xEB,0xE8, + 0xE2,0x28,0xA2,0x20,0xF7,0xEB,0xEA,0xAA,0x82,0x28,0xA2,0x20,0xDF,0xFD,0xFD,0x5F, + 0xC2,0x28,0xA2,0x20,0x5D,0xA5,0xD5,0x5C,0xC2,0x28,0x81,0x20,0x6E,0xF2,0x68,0xA7, + 0xC2,0x28,0x81,0x20,0xDF,0xD7,0x7E,0x80,0xC2,0x28,0x81,0x20,0x23,0xBF,0x5F,0x7F, + 0x03,0x39,0x81,0x20,0x0A,0x22,0xAD,0xB5,0x24,0x39,0xC2,0x30,0xEC,0xAA,0x2F,0xBD, + 0x24,0x39,0xC2,0x30,0x5D,0x75,0xEE,0x68,0xE2,0x30,0x82,0x28,0x7F,0xFE,0xAA,0x00, + 0xE3,0x38,0xC2,0x28,0x2B,0xA9,0x0B,0xAB,0x03,0x39,0xE2,0x30,0x9E,0xAE,0xBF,0x5D, + 0xE2,0x30,0xC2,0x30,0x57,0xFD,0xAF,0x9A,0x02,0x39,0xC2,0x30,0x3D,0xAD,0xA3,0xBF, + 0x03,0x39,0xC2,0x30,0xFA,0x5E,0xEF,0xAE,0xE3,0x30,0xC2,0x30,0x57,0x9F,0xD5,0x57, + 0x23,0x39,0xC2,0x30,0xFF,0x77,0x5D,0xB5,0x03,0x31,0xA2,0x28,0xF2,0x7A,0xF2,0xF8, + 0xE3,0x30,0xA2,0x28,0x9F,0xB5,0x0F,0x8A,0x03,0x31,0xC2,0x30,0x83,0xAA,0x82,0x0B, + 0x03,0x39,0xE2,0x30,0x5C,0x99,0xB6,0xD7,0x23,0x39,0xE2,0x30,0xB5,0xF7,0x87,0xAB, + 0x43,0x39,0xE2,0x30,0x2A,0xBE,0xBE,0xFA,0x64,0x41,0x03,0x39,0x80,0xFB,0x7F,0x7B, + 0x44,0x41,0xE2,0x30,0xE8,0xAE,0xFE,0xFF,0x44,0x39,0xE2,0x30,0x8F,0xFE,0x29,0xB7, + 0x23,0x39,0xC2,0x30,0x00,0x88,0x70,0xAA,0x23,0x39,0xE2,0x30,0xE7,0xD4,0xA6,0x0E, + 0x64,0x41,0x03,0x39,0xF1,0x7B,0x75,0x55,0x64,0x49,0xE2,0x38,0x2D,0xAF,0xA9,0x2F, + 0xE6,0x59,0x64,0x49,0xA9,0xAD,0xCF,0x29,0x26,0x62,0xC5,0x51,0xD9,0xF9,0xE2,0xFA, + 0x47,0x62,0xE6,0x59,0x3F,0xB7,0x97,0xB5,0x68,0x6A,0xE6,0x59,0x22,0x03,0xB7,0xAE, + 0xA9,0x72,0x47,0x6A,0xB5,0x9F,0xBF,0x2D,0xC9,0x72,0x68,0x6A,0xAA,0xFA,0xEA,0x6B, + 0xC9,0x72,0x88,0x6A,0xB5,0xDA,0xBA,0x4E,0xC9,0x7A,0x88,0x6A,0xEE,0xEB,0x0F,0x35, + 0xC9,0x7A,0x88,0x72,0xD7,0xED,0xE2,0x30,0xEA,0x82,0x88,0x72,0x2D,0xA7,0xB7,0xF7, + 0x0A,0x83,0xA9,0x72,0x0A,0xAF,0xB7,0xFD,0xE9,0x7A,0xA9,0x72,0xF2,0x40,0x6A,0xFD, + 0xC9,0x7A,0x88,0x72,0x38,0x3A,0x8B,0xC3,0x0A,0x83,0xC9,0x7A,0xA7,0xE7,0x66,0xD5, + 0xEA,0x82,0x88,0x72,0x08,0xAA,0x5E,0xAB,0x2B,0x8B,0xC9,0x7A,0xBF,0xAF,0x35,0x2D, + 0x2A,0x83,0xEA,0x7A,0x58,0x5E,0x58,0x57,0x0A,0x83,0xC9,0x7A,0x55,0x5B,0x90,0xF0, + 0x0A,0x83,0xA9,0x72,0x02,0xBE,0x37,0xB5,0x2B,0x83,0xC9,0x7A,0xA2,0xA8,0xE2,0x5E, + 0x0A,0x83,0xEA,0x7A,0xC3,0x57,0x57,0x7E,0x2B,0x83,0xEA,0x82,0x83,0x3D,0x09,0xEB, + 0x2A,0x83,0xC9,0x7A,0x7B,0xFA,0xFC,0x6A,0x0A,0x83,0xC9,0x7A,0xFC,0xCA,0xAA,0xE8, + 0x2A,0x83,0xEA,0x7A,0x9D,0xB5,0x5F,0x5F,0x2A,0x83,0xEA,0x7A,0xAA,0xB7,0x69,0x7F, + 0x6B,0x8B,0xE9,0x7A,0x0B,0x2F,0xF5,0x5F,0xAC,0x93,0xE9,0x7A,0x00,0x2A,0xAD,0x55, + 0x4E,0xAC,0x4B,0x8B,0x0A,0xAB,0xFD,0x55,0x6E,0xAC,0x8C,0x93,0x00,0x0A,0x2F,0xD5, + 0x8F,0xB4,0xED,0x9B,0x00,0x00,0x02,0xBD,0xF0,0xBC,0x6F,0xAC,0xAA,0x8B,0xEB,0xFD, + 0x23,0x41,0xE2,0x40,0xFD,0xDB,0x0B,0x80,0x23,0x49,0xE2,0x40,0xA2,0x5E,0x58,0x50, + 0x03,0x41,0xC2,0x38,0x00,0xA2,0xEE,0x0A,0x03,0x41,0xA1,0x30,0xF8,0x62,0xA0,0xB0, + 0x03,0x41,0xC2,0x38,0x95,0x2D,0xEB,0xFE,0x23,0x41,0xE2,0x38,0xD7,0xF5,0x65,0xBB, + 0x03,0x41,0xE2,0x38,0xD7,0x35,0x1B,0xC1,0x23,0x41,0xE2,0x38,0x77,0x6A,0xEF,0x6F, + 0x03,0x41,0xC2,0x38,0xA3,0xBF,0xFB,0x7A,0x02,0x39,0xC2,0x38,0xAA,0xBA,0x20,0xBD, + 0x03,0x41,0xC2,0x38,0x78,0xD4,0x7E,0xFE,0xE2,0x38,0xC2,0x38,0x3E,0xBD,0x33,0x6E, + 0x03,0x41,0xC2,0x38,0xAA,0xA2,0x82,0xBD,0xE2,0x38,0xC2,0x38,0xCA,0xC0,0x00,0x02, + 0x23,0x41,0xC2,0x38,0xFF,0xFB,0x5F,0x75,0x02,0x39,0xC2,0x38,0x55,0xF7,0xBF,0x8F, + 0x03,0x41,0xC2,0x38,0xF4,0x7C,0x7B,0xA2,0x23,0x39,0xC2,0x38,0xB5,0xF5,0xFF,0xFF, + 0xE2,0x38,0xA1,0x30,0x20,0x04,0x8A,0x28,0x03,0x39,0xC2,0x38,0xFF,0x2F,0x0F,0xCD, + 0x02,0x41,0xE3,0x38,0xD7,0x55,0x5B,0x5D,0x03,0x41,0xA2,0x30,0x8D,0xAF,0x7E,0xEB, + 0xE3,0x40,0xA2,0x38,0xBF,0xA8,0x22,0x0D,0x67,0x72,0x23,0x49,0x2D,0x2D,0x2D,0x09, + 0x66,0x72,0x26,0x6A,0x55,0xE8,0x80,0x12,0x66,0x72,0x06,0x62,0xFA,0xDA,0xB8,0xFA, + 0x46,0x6A,0x64,0x49,0xF8,0x7A,0x7E,0xDA,0x64,0x49,0xE2,0x38,0x5C,0x76,0x7E,0x5F, + 0x23,0x39,0xE2,0x30,0xD5,0x97,0xFA,0x7F,0x23,0x39,0xA2,0x30,0xBA,0xA8,0xAE,0x7F, + 0x03,0x39,0xE3,0x30,0x57,0x62,0xA2,0x0B,0x03,0x31,0xA2,0x30,0xAB,0x2A,0x02,0x2A, + 0x03,0x31,0xC2,0x30,0xFE,0xE7,0x96,0xFE,0x24,0x39,0xE3,0x30,0xFB,0xBF,0xBD,0xFD, + 0x03,0x39,0xC2,0x30,0x78,0x66,0xD4,0xFE,0x03,0x39,0xC2,0x30,0x27,0x2B,0x0F,0x8A, + 0x03,0x39,0xC2,0x30,0xCA,0x6B,0xAA,0x80,0x03,0x39,0xC2,0x30,0x29,0xAF,0xBA,0x2A, + 0x44,0x41,0xE2,0x30,0x8B,0xC7,0xD5,0x55,0x23,0x39,0xE3,0x38,0xCB,0xFE,0xBC,0xFC, + 0x23,0x39,0xE3,0x38,0xFE,0xA7,0xEB,0xBA,0x03,0x39,0xE3,0x30,0x00,0xA2,0x22,0x20, + 0x24,0x39,0xE3,0x38,0x3A,0x8A,0xDA,0x58,0x44,0x41,0xE3,0x30,0x74,0x7F,0x5F,0xFB, + 0x23,0x39,0xC2,0x30,0x2F,0xFF,0xFF,0xFE,0x24,0x41,0xE2,0x30,0x27,0xE1,0xFF,0xBF, + 0x44,0x41,0x03,0x39,0x53,0x7F,0xD5,0xF7,0x44,0x41,0x04,0x39,0x55,0x5F,0xE8,0xAA, + 0x24,0x39,0xE3,0x38,0x6B,0x82,0xF8,0xBC,0x23,0x39,0xE3,0x38,0xAB,0xF7,0xBF,0x8F, + 0x23,0x39,0xC2,0x30,0x8A,0x3E,0x26,0xAA,0x23,0x39,0xE3,0x38,0xAA,0xAA,0xFE,0x56, + 0x24,0x39,0x03,0x39,0x55,0xBE,0x3B,0x95,0x24,0x39,0xE2,0x30,0xAA,0x20,0x2C,0x9E, + 0x24,0x39,0xE3,0x30,0x5A,0xD8,0xFE,0xBF,0x24,0x39,0xE3,0x30,0xDF,0x7F,0xDF,0x60, + 0x03,0x31,0xC2,0x30,0x02,0x2A,0xAA,0xF7,0x24,0x31,0xC2,0x30,0xB8,0xBA,0xBD,0xBF, + 0x23,0x39,0xC2,0x28,0xFB,0xBF,0xAA,0xA3,0x23,0x31,0xE3,0x30,0xD5,0x75,0xDE,0xBE, + 0x03,0x31,0xC2,0x28,0xBF,0xBF,0xAB,0xAA,0x03,0x31,0xC2,0x28,0x9E,0xDF,0xE8,0xA8, + 0x03,0x31,0xC2,0x30,0xAA,0x2D,0xEB,0xFA,0x04,0x31,0xA2,0x28,0xE2,0xEC,0x6F,0xEF, + 0xE3,0x30,0xC2,0x28,0xAF,0xBA,0x2D,0x95,0xE3,0x30,0xC2,0x28,0x6E,0xD7,0x76,0xFC, + 0xE2,0x30,0xC2,0x28,0x7F,0x67,0x77,0x7D,0xE3,0x30,0xA2,0x28,0x8F,0x82,0xFB,0x9F, + 0xE2,0x28,0x82,0x20,0xFC,0x7F,0xBF,0xEE,0xC2,0x28,0x82,0x20,0xEF,0xBF,0xAA,0xA2, + 0x03,0x29,0xA2,0x28,0xF9,0xEF,0xFD,0xDF,0xC2,0x28,0x81,0x20,0x7E,0xFC,0xFF,0xEE, + 0xA2,0x28,0x81,0x20,0x27,0x95,0xDF,0x7A,0xE3,0x30,0x81,0x20,0x02,0xAF,0xFF,0x5D, + 0x24,0x39,0x81,0x20,0x8A,0xEB,0xB9,0xF5,0x03,0x31,0xA2,0x28,0xAB,0x2A,0xAA,0xDB, + 0x23,0x39,0xE2,0x30,0xF5,0x0E,0xB2,0xFB,0x23,0x39,0xC2,0x28,0x5A,0x68,0xEA,0xBA, + 0x03,0x31,0xA1,0x30,0xBA,0x82,0x82,0xAA,0x02,0x31,0xC2,0x28,0xBD,0xBD,0x7D,0xFE, + 0x02,0x39,0xA1,0x28,0xAA,0xA8,0xFA,0xE9,0x03,0x39,0xC2,0x30,0xEF,0x7A,0x52,0x5F, + 0x03,0x31,0xC2,0x30,0x2D,0x07,0x0A,0x02,0x24,0x39,0xC2,0x30,0x7C,0xBA,0xAA,0xF2, + 0xE3,0x30,0xA2,0x28,0xEA,0x80,0xFA,0x96,0x24,0x39,0xC2,0x28,0xAF,0xA7,0xA7,0x0F, + 0x03,0x39,0xE3,0x30,0x9F,0xBE,0xB8,0x70,0x03,0x39,0xE3,0x30,0x00,0x0A,0x03,0xBF, + 0x44,0x41,0x03,0x39,0x5F,0xBF,0x08,0x38,0x65,0x41,0xE3,0x30,0x6F,0xF6,0x5E,0x54, + 0x03,0x31,0xC2,0x28,0xB0,0xEA,0xF8,0x57,0x03,0x31,0xC2,0x30,0xBF,0xBF,0xDF,0xF9, + 0x23,0x39,0xC2,0x28,0x2E,0xAE,0x4B,0x5F,0x03,0x31,0xA2,0x28,0x00,0x8A,0xAB,0xA7, + 0x64,0x41,0xC2,0x30,0xBF,0xBF,0xBD,0x3F,0x85,0x49,0xE2,0x38,0xB9,0x2F,0xA2,0x02, + 0x07,0x62,0x85,0x49,0xBD,0xAF,0xAB,0xBB,0x47,0x6A,0xE5,0x59,0x5F,0xFF,0xB7,0xBF, + 0x48,0x6A,0xC6,0x59,0xBF,0x2F,0x25,0x2F,0x68,0x6A,0x27,0x62,0x29,0x0E,0x22,0x02, + 0xA9,0x72,0x47,0x62,0xA7,0xEE,0xAA,0xAB,0xA8,0x72,0x68,0x6A,0xFF,0x0F,0xE7,0x9B, + 0xA9,0x72,0x67,0x6A,0x8E,0xBB,0x9A,0x08,0xA9,0x72,0x88,0x6A,0x16,0x0E,0x2E,0x4A, + 0xC9,0x7A,0x88,0x6A,0xA8,0xBE,0xEF,0xFD,0xA9,0x72,0x68,0x6A,0x8A,0xA0,0x9E,0x2A, + 0xEA,0x82,0x68,0x6A,0xAE,0xEB,0xEF,0x73,0xE9,0x7A,0x88,0x72,0xFA,0xCA,0xDA,0xFD, + 0xC9,0x7A,0x88,0x72,0x0A,0x3F,0x2F,0xA3,0x0A,0x83,0x88,0x72,0x30,0xA2,0x6A,0xDF, + 0xEA,0x7A,0x88,0x72,0xA8,0xBB,0xFB,0x9E,0x0A,0x83,0xA8,0x72,0x2F,0xAF,0xAF,0xD5, + 0x0A,0x83,0xA9,0x72,0xA2,0xBA,0xDF,0x5F,0x2B,0x83,0xC9,0x7A,0xEA,0xBF,0x15,0x5D, + 0x0B,0x83,0xCA,0x7A,0xDD,0xFF,0x7E,0xAF,0x0A,0x83,0xC9,0x7A,0x6C,0xFF,0xFF,0x8A, + 0x2B,0x83,0xC9,0x7A,0x3F,0xED,0xBB,0x71,0x0A,0x83,0xA9,0x7A,0x28,0xBE,0x2B,0x6D, + 0x4B,0x8B,0xCA,0x7A,0x2A,0x2A,0xEB,0xF5,0x2B,0x8B,0xC9,0x7A,0x60,0x76,0xF2,0xFE, + 0x0A,0x83,0xC9,0x7A,0x88,0xEE,0xAF,0x9A,0x4B,0x8B,0xE9,0x7A,0x7D,0xFD,0xB3,0x2A, + 0x2A,0x83,0xC9,0x7A,0xBE,0x77,0xFC,0xD8,0x0A,0x83,0xA8,0x72,0x3F,0x2D,0x8B,0xAE, + 0x4B,0x8B,0xEA,0x7A,0x0B,0xA7,0xE7,0xBF,0x8C,0x93,0xE9,0x7A,0x2A,0xBB,0xAF,0x7E, + 0xCD,0x9B,0x0A,0x83,0x02,0xAA,0xBF,0x7D,0x8F,0xB4,0x4B,0x8B,0x2A,0xAB,0xFD,0x55, + 0x03,0x41,0x23,0x39,0x82,0x00,0x08,0x23,0x23,0x41,0xA2,0x38,0xE8,0x7A,0xF8,0xFE, + 0x02,0x41,0xC2,0x38,0xBA,0xB9,0x69,0xEA,0xE2,0x38,0xC2,0x38,0xF8,0xBB,0x0B,0x0F, + 0x02,0x41,0xA2,0x30,0xCA,0xAB,0x83,0x82,0x23,0x41,0xE2,0x38,0xEB,0x6D,0xFC,0xFB, + 0x23,0x41,0xE2,0x38,0x65,0xD5,0x57,0x95,0x23,0x41,0xC2,0x38,0xFB,0x3B,0xDF,0x5B, + 0x03,0x41,0xC2,0x38,0xFC,0x58,0x6E,0xFF,0x02,0x39,0xC2,0x30,0xAE,0x3B,0xFB,0xDE, + 0x03,0x41,0xC2,0x38,0xDE,0xB8,0x20,0x3B,0x23,0x41,0xC2,0x38,0x56,0xDF,0xFE,0xFC, + 0x03,0x41,0xA2,0x30,0xAB,0xEB,0xE7,0xB0,0x03,0x41,0xE2,0x38,0xE1,0x09,0x9D,0x55, + 0x03,0x41,0xC2,0x38,0x77,0xC4,0x8A,0x8A,0x03,0x41,0xC2,0x38,0x4D,0x59,0x5B,0xE2, + 0x03,0x41,0xE2,0x38,0xFC,0xDF,0x57,0x56,0x03,0x39,0xC2,0x38,0xAE,0xF0,0x5A,0x5D, + 0x03,0x39,0xC1,0x30,0xEF,0xBD,0xBE,0x8B,0x03,0x41,0xC2,0x38,0xB5,0xBF,0x5F,0xCE, + 0x03,0x39,0xC2,0x38,0xFA,0x8A,0x7F,0xF7,0xE3,0x38,0xC2,0x38,0x6C,0x7E,0x7F,0xF7, + 0x03,0x41,0xA1,0x30,0x25,0xAF,0xAB,0xFE,0x88,0x72,0x64,0x49,0x0D,0x2D,0x2D,0x2D, + 0x87,0x72,0x47,0x6A,0xB8,0x3A,0xB6,0xF3,0x66,0x72,0xC4,0x59,0xE2,0x7A,0x78,0x7E, + 0xE5,0x59,0x44,0x49,0xF8,0x7E,0x5E,0x7A,0x43,0x41,0xE2,0x38,0x5C,0x7E,0xEF,0x78, + 0x03,0x39,0xC2,0x30,0x6A,0xA0,0xA2,0xBA,0x03,0x39,0xA2,0x30,0x7A,0xBA,0xAA,0x80, + 0x03,0x39,0xC2,0x30,0x88,0xE2,0x62,0x5A,0x03,0x31,0xC2,0x30,0x23,0x8A,0x2F,0x2A, + 0x03,0x39,0xA2,0x28,0xAA,0xBA,0x60,0xE0,0x03,0x31,0xC2,0x28,0x2E,0xBD,0x95,0x9D, + 0x03,0x31,0xC2,0x28,0xAA,0x2C,0x9C,0xF6,0x03,0x31,0xC2,0x30,0xEE,0xAA,0xFA,0x68, + 0x03,0x31,0xE2,0x30,0xBF,0x5F,0x97,0xE9,0x23,0x31,0xC2,0x28,0xEA,0xCA,0xFF,0xF8, + 0x03,0x39,0xE2,0x30,0xBE,0x6B,0xDE,0x52,0x03,0x39,0xE3,0x30,0x00,0xDE,0x3E,0xAA, + 0x03,0x39,0xE3,0x30,0x42,0x82,0x3D,0xF7,0x24,0x39,0xC2,0x30,0x82,0xAA,0xAB,0xF7, + 0x03,0x39,0xE3,0x30,0xA0,0xF0,0x42,0xF0,0x24,0x39,0xC2,0x30,0x8A,0xAB,0xFF,0xDE, + 0x03,0x39,0xE3,0x30,0xB8,0x28,0xF2,0x92,0x23,0x39,0xE3,0x30,0xBE,0xAE,0xAE,0xBF, + 0x44,0x41,0x03,0x39,0xDB,0x9F,0x07,0xAF,0x44,0x41,0x03,0x39,0xE7,0xD6,0xBE,0x1E, + 0x44,0x41,0x04,0x39,0x77,0x1D,0xFB,0xA0,0x44,0x41,0x03,0x39,0xB5,0x6F,0xFE,0xDA, + 0x24,0x41,0x03,0x39,0x55,0x95,0xBF,0xBC,0x24,0x39,0xC2,0x30,0xBB,0xA2,0x80,0x22, + 0x24,0x39,0xC2,0x30,0xFF,0x5F,0x5A,0xF8,0x03,0x39,0xC2,0x30,0x2A,0x8F,0xF7,0xBA, + 0x24,0x39,0xE3,0x30,0x8F,0xA9,0xFF,0xBF,0x24,0x39,0xE3,0x30,0x62,0xC0,0xDE,0xFE, + 0x24,0x39,0xC2,0x30,0xFD,0xAA,0xAA,0xEB,0x03,0x31,0xC2,0x30,0xAF,0x0F,0x28,0xA0, + 0x03,0x31,0xA2,0x30,0xA2,0xE8,0x22,0x2A,0x24,0x39,0xE3,0x30,0x2E,0x0F,0x9F,0xDE, + 0x24,0x39,0xE3,0x30,0x6F,0xEA,0xF2,0xEB,0x03,0x31,0xE3,0x30,0x62,0x7F,0x5F,0xB2, + 0x23,0x39,0xE3,0x30,0xD5,0x55,0xC5,0xF3,0x24,0x39,0xC2,0x30,0x77,0x7F,0x7B,0xEA, + 0x03,0x31,0xC3,0x30,0xF5,0xED,0x8F,0x8D,0xE3,0x30,0xC2,0x28,0x7E,0x78,0x74,0x70, + 0xE3,0x30,0xC2,0x28,0x55,0xFB,0xBB,0xFF,0xE2,0x28,0x82,0x28,0x2E,0xAA,0x28,0x02, + 0xE3,0x30,0xA2,0x20,0xBF,0xEE,0xBC,0xF4,0x03,0x31,0xC2,0x28,0x7D,0x7F,0x53,0xDD, + 0xC2,0x28,0xA2,0x20,0x3A,0xAF,0x2A,0x0E,0xE2,0x28,0xA2,0x20,0x57,0x5E,0x5F,0x7C, + 0x81,0x28,0xA2,0x20,0xFF,0x9F,0xFF,0xFD,0xC2,0x28,0x81,0x20,0xFB,0xEF,0xAA,0x2D, + 0xA2,0x28,0x81,0x20,0xB7,0xAE,0xA0,0xC8,0xC2,0x28,0x61,0x20,0x2A,0xBA,0xFF,0xFF, + 0x03,0x31,0x81,0x20,0x0A,0xB9,0xFF,0x75,0x03,0x31,0xA2,0x28,0x28,0xBA,0x7F,0x55, + 0x03,0x31,0xC2,0x30,0x22,0xAA,0x2F,0xA5,0x03,0x39,0xE2,0x30,0xDE,0x2A,0x02,0x9F, + 0x23,0x39,0xC2,0x28,0x75,0xB7,0xAA,0x3A,0x24,0x31,0xC2,0x30,0x7D,0xAB,0xBA,0xF8, + 0x24,0x39,0xE3,0x30,0xEB,0xEE,0xA5,0xE1,0x24,0x39,0xC2,0x28,0xFA,0x7A,0x68,0x7B, + 0xE3,0x30,0xA2,0x28,0x17,0xBF,0xB6,0xA8,0x03,0x39,0xA1,0x28,0x0E,0x2E,0x9F,0xBF, + 0x23,0x39,0xC2,0x30,0x62,0xAA,0x8E,0x83,0x24,0x39,0xE3,0x38,0xAD,0xBD,0x37,0xAD, + 0x44,0x41,0xE2,0x30,0xAA,0xAF,0xEA,0x62,0x24,0x39,0xC3,0x28,0xF8,0x7E,0xFB,0xFE, + 0xE3,0x30,0xA2,0x28,0xD6,0x5C,0xEE,0xB8,0x03,0x31,0xA2,0x28,0xAD,0xAF,0xAA,0x2E, + 0x03,0x31,0xA1,0x28,0xFE,0xFF,0xDC,0x0E,0x03,0x31,0xC2,0x28,0xA5,0xA5,0xA3,0x08, + 0x64,0x41,0xE2,0x30,0xBD,0xBD,0xAB,0x2B,0xA5,0x49,0x64,0x49,0x21,0x2F,0xAD,0x33, + 0xE6,0x59,0xA5,0x51,0xB1,0xA5,0xAD,0x0B,0x48,0x62,0x06,0x5A,0xE7,0x55,0x9F,0x49, + 0x68,0x6A,0x06,0x5A,0x3D,0xB5,0xDE,0xF7,0x68,0x6A,0xE6,0x59,0x08,0x0A,0x2A,0xA7, + 0xA9,0x72,0x48,0x6A,0x5C,0xFE,0xE0,0x3D,0xA9,0x72,0x48,0x6A,0x22,0xBA,0xF7,0xFE, + 0xC9,0x72,0x68,0x6A,0xB8,0xBB,0xBA,0x9F,0xCA,0x7A,0x27,0x62,0xBA,0x82,0x86,0x08, + 0xA9,0x72,0x68,0x6A,0x0E,0x03,0xBF,0x98,0xA9,0x72,0x88,0x6A,0xF4,0xA7,0x94,0x24, + 0xC9,0x7A,0x88,0x72,0x70,0x6F,0xDA,0xB2,0xE9,0x7A,0x88,0x72,0xD9,0xF5,0xA2,0xB3, + 0xE9,0x7A,0xA9,0x72,0xCD,0xF6,0xDC,0x5F,0xE9,0x7A,0xA9,0x72,0xFD,0x80,0xE2,0x6E, + 0xE9,0x7A,0x89,0x72,0xBA,0x92,0x2B,0xBA,0xE9,0x7A,0xA8,0x72,0xDF,0x72,0x73,0xDA, + 0x0A,0x7B,0x88,0x6A,0xEE,0xBF,0xB5,0x2F,0x2A,0x83,0xC9,0x72,0xD7,0x3F,0xF5,0xFE, + 0x2A,0x83,0xC9,0x7A,0xFD,0xB4,0xAA,0xDD,0x2A,0x8B,0xA8,0x7A,0x2F,0xEE,0x7A,0x76, + 0x0A,0x83,0xA9,0x7A,0xE2,0xAB,0x89,0xEB,0xEA,0x7A,0xA9,0x7A,0xED,0x5D,0xA8,0xA8, + 0x0A,0x83,0xA9,0x72,0xA5,0xAD,0xAE,0xAE,0x0B,0x83,0xCA,0x7A,0xBF,0x95,0xAF,0x6B, + 0x0B,0x83,0xCA,0x7A,0xDE,0xD7,0xDE,0x79,0x4B,0x8B,0xC9,0x7A,0x2B,0xAF,0xF5,0xFD, + 0x2A,0x83,0xC9,0x7A,0xF0,0xA2,0xA6,0x0E,0x2A,0x83,0xC9,0x7A,0xD7,0xE8,0xC0,0xA8, + 0x0A,0x83,0xC9,0x7A,0x28,0x09,0xED,0x83,0x4B,0x8B,0xE9,0x7A,0xA8,0x8B,0xBD,0x8D, + 0x4A,0x83,0x09,0x7B,0x8E,0x6F,0xCB,0xAF,0x4B,0x8B,0xE9,0x7A,0x0A,0x3B,0x9E,0x7F, + 0x03,0x41,0xC2,0x38,0x06,0xAA,0xC3,0xE0,0x03,0x41,0xA2,0x30,0x78,0xEA,0xBE,0xEF, + 0x03,0x41,0xA2,0x38,0xAB,0xBB,0xEB,0xCD,0xE2,0x38,0xA1,0x30,0x08,0x0A,0x08,0xC8, + 0x03,0x41,0xC2,0x38,0xBA,0xA5,0x97,0x17,0x23,0x41,0xE2,0x38,0x6F,0x75,0xFE,0xFE, + 0x23,0x41,0xC2,0x38,0xB7,0xEF,0xE0,0x53,0x03,0x41,0xC2,0x38,0xE0,0xFA,0x57,0x73, + 0x03,0x41,0xE2,0x38,0x55,0x56,0xFF,0x6F,0x23,0x41,0xC1,0x30,0xDF,0xD7,0xBF,0xBB, + 0x03,0x41,0xC2,0x38,0xAF,0xA7,0x2A,0x3C,0x03,0x41,0xC2,0x38,0xEB,0xAF,0x27,0xB7, + 0x03,0x41,0xC2,0x38,0xA0,0xDA,0xF0,0xA0,0x03,0x39,0xC2,0x38,0xEF,0xEA,0x6A,0xFB, + 0x03,0x39,0xC2,0x38,0x37,0xD7,0xAF,0xEB,0x03,0x41,0xC2,0x38,0xE8,0xC0,0xC2,0xDE, + 0x03,0x41,0xC2,0x38,0xEB,0xD3,0x7B,0xDA,0x03,0x41,0xA1,0x30,0x7F,0xFA,0xFD,0xCA, + 0xE2,0x38,0xC2,0x38,0x8D,0x0D,0xC5,0x2E,0xE2,0x38,0xC2,0x38,0x84,0x74,0x95,0xA4, + 0xE2,0x38,0xC2,0x38,0xC1,0xF2,0x00,0x08,0x03,0x41,0xA2,0x38,0xB7,0xBF,0xBB,0xA2, + 0x03,0x41,0xC2,0x38,0x57,0x7F,0xEB,0x4B,0x67,0x72,0x03,0x41,0x29,0x0D,0x0D,0x0D, + 0x87,0x72,0x26,0x6A,0xA0,0xAA,0x7A,0x78,0x47,0x6A,0x64,0x51,0xE8,0x68,0xF8,0xFA, + 0xA4,0x51,0x03,0x41,0xFC,0xDE,0x7E,0xFA,0x44,0x49,0xC2,0x30,0xE8,0xBE,0xFF,0xFE, + 0x03,0x39,0xC2,0x30,0x28,0xF8,0xF8,0xE0,0x03,0x39,0xC2,0x30,0xAA,0xA7,0xE5,0xF5, + 0x23,0x39,0xC2,0x30,0xDF,0xBE,0xAB,0x2F,0x03,0x31,0xA2,0x30,0x0A,0xAA,0x88,0xE2, + 0x03,0x31,0xC2,0x30,0xC2,0xBA,0xBA,0x6E,0x03,0x31,0xC2,0x28,0xAA,0xBA,0x7F,0x5F, + 0x03,0x31,0xC2,0x28,0x7E,0x2A,0x88,0x02,0x03,0x31,0xC2,0x30,0x6A,0xE2,0x7C,0xB8, + 0x03,0x31,0xC2,0x28,0x8B,0xCB,0xF9,0x8E,0x23,0x39,0xC3,0x30,0xBC,0xFF,0x7F,0x5F, + 0x03,0x31,0xC2,0x30,0xE2,0x3F,0x8B,0xAB,0x03,0x31,0xC2,0x28,0x02,0x02,0x23,0x7B, + 0x03,0x39,0xE3,0x30,0xFA,0xEF,0x1E,0xDB,0x24,0x39,0xC2,0x30,0xB9,0xF7,0xFC,0xE0, + 0x03,0x39,0xC2,0x30,0xA2,0xEB,0xAB,0xAA,0xE3,0x30,0xA2,0x30,0x08,0x28,0x2A,0x8F, + 0x24,0x41,0xE3,0x30,0xD7,0xAC,0xAA,0x80,0x24,0x39,0xE3,0x30,0x7B,0xBB,0xAE,0xAF, + 0x24,0x39,0xE3,0x30,0x03,0x2A,0x5F,0x9F,0x44,0x41,0xE3,0x30,0x2A,0x2A,0xA7,0x95, + 0x64,0x41,0x03,0x39,0xFA,0xD8,0x5F,0xF7,0x24,0x39,0x03,0x39,0x74,0xF4,0x54,0x57, + 0x23,0x39,0xC3,0x30,0xE2,0x9A,0xEE,0xBB,0x24,0x39,0xE3,0x38,0x27,0xAF,0xAA,0xAA, + 0x24,0x39,0xE3,0x38,0xFA,0xA2,0xEB,0xFF,0x44,0x39,0xE3,0x38,0x5F,0xFF,0x7E,0xFD, + 0x24,0x39,0x03,0x39,0x54,0x6D,0xF9,0xDD,0x23,0x39,0xE3,0x30,0xFE,0xD8,0xA8,0xB6, + 0x03,0x39,0xE3,0x30,0xA9,0xE5,0x17,0x74,0x24,0x39,0xE3,0x30,0x5E,0x15,0x0F,0xB5, + 0x44,0x39,0xE3,0x30,0xF5,0xE9,0xFF,0xE3,0x24,0x39,0xC2,0x28,0x3A,0xB8,0xAE,0x9A, + 0x23,0x39,0xC3,0x28,0xDF,0xFF,0x2A,0x0A,0x23,0x39,0xE3,0x30,0xFF,0xFB,0xFC,0x68, + 0xE4,0x38,0x23,0x31,0xEF,0xEA,0xFB,0xAB,0x23,0x39,0xE3,0x30,0xD7,0xFF,0xEC,0xBB, + 0x23,0x39,0xC2,0x30,0x8D,0xAE,0xEE,0xFE,0x03,0x31,0xC3,0x30,0xF8,0xF8,0xBB,0x87, + 0x03,0x31,0xC2,0x28,0xF7,0xA7,0x09,0x03,0x03,0x31,0xC2,0x28,0xF7,0xFE,0x0A,0xF8, + 0xE2,0x30,0xC2,0x28,0x56,0xD7,0xD7,0x57,0xE2,0x28,0xA2,0x28,0xAB,0x80,0xEA,0x8A, + 0x03,0x31,0xC2,0x28,0xD9,0xFB,0x6F,0x75,0x03,0x31,0x81,0x20,0x72,0xE2,0xEA,0xAB, + 0xC2,0x28,0x81,0x20,0x78,0x3E,0x2A,0x00,0xE3,0x30,0x81,0x20,0xA9,0x63,0xCA,0xBB, + 0xA2,0x28,0x81,0x20,0xEB,0x2B,0xEA,0xA0,0xA2,0x28,0x82,0x20,0x3F,0xAF,0xBA,0xFA, + 0xA2,0x28,0x61,0x20,0xAF,0xD7,0xFF,0xF2,0xC2,0x28,0x61,0x20,0x8A,0xBB,0xF7,0x7F, + 0xE3,0x30,0x81,0x20,0x2B,0xB7,0xBD,0xD5,0xE3,0x30,0xA2,0x28,0x20,0x02,0xDB,0x5F, + 0x03,0x31,0xA2,0x28,0x2A,0xAA,0x9F,0xF5,0x24,0x39,0xC2,0x28,0x3A,0xBA,0xED,0xD5, + 0x24,0x39,0xE3,0x30,0x67,0xF7,0x35,0xFF,0x04,0x31,0xE3,0x30,0x7D,0x67,0x1D,0x57, + 0x03,0x31,0xC2,0x28,0x7E,0xA8,0xAE,0xB5,0x03,0x31,0xC2,0x28,0xF5,0xAF,0x2A,0x88, + 0x44,0x39,0xE2,0x30,0xCF,0xBD,0x8F,0x2D,0x23,0x39,0xE2,0x30,0xAF,0xAE,0xCA,0x28, + 0x24,0x39,0xC2,0x28,0x80,0xE2,0xEA,0x60,0x03,0x39,0x82,0x28,0x02,0x80,0xAB,0xB5, + 0x03,0x31,0xC2,0x28,0x5E,0x27,0xA5,0x95,0x03,0x31,0xC2,0x28,0x2F,0x9F,0xF7,0xFE, + 0x03,0x31,0xC2,0x28,0x88,0x2E,0x3E,0x3F,0x44,0x39,0xE3,0x30,0xBF,0xFD,0xAF,0x2F, + 0xA5,0x49,0x23,0x39,0xBD,0x2D,0x2F,0x2B,0xC5,0x51,0x85,0x49,0xB1,0x0B,0xA8,0x02, + 0x06,0x5A,0xC6,0x51,0x9D,0xB5,0x23,0x32,0x27,0x62,0xC6,0x59,0x0B,0xFB,0x6A,0xBA, + 0x27,0x62,0xC6,0x51,0x80,0xB8,0xEA,0x2A,0x47,0x62,0x07,0x62,0xAA,0xAE,0x2F,0x39, + 0x68,0x6A,0x27,0x62,0x0E,0xBE,0xDF,0xAA,0x88,0x6A,0x48,0x6A,0xDC,0xEE,0x97,0xBD, + 0xC9,0x72,0x48,0x6A,0xBF,0x2F,0xBF,0xDF,0xEA,0x7A,0xA9,0x72,0xBB,0xEB,0x7F,0xD6, + 0xEA,0x7A,0x88,0x6A,0x5E,0x7B,0x7F,0x2B,0xE9,0x7A,0x88,0x6A,0xE5,0x89,0xE0,0xAE, + 0xE9,0x7A,0x88,0x72,0xF2,0xE5,0xB5,0xAC,0xEA,0x7A,0x89,0x72,0x5B,0xFF,0xBE,0x8E, + 0xC9,0x7A,0x88,0x72,0xB0,0xFA,0xD2,0xA0,0xE9,0x7A,0x88,0x72,0xAE,0xAD,0xBF,0xFF, + 0xEA,0x7A,0x88,0x72,0xAB,0xEA,0x72,0x62,0xE9,0x7A,0xA8,0x72,0xFA,0xEE,0xF9,0x29, + 0x0A,0x83,0xA9,0x72,0x29,0xCB,0xA2,0xEB,0x2A,0x83,0xC9,0x7A,0xEB,0xAA,0x2F,0xBD, + 0x0A,0x83,0xC9,0x7A,0x54,0x3A,0xAA,0xFA,0x0A,0x83,0xC9,0x7A,0x57,0xA8,0xA8,0xF7, + 0x2A,0x83,0xA9,0x7A,0xB7,0xA3,0xAA,0xB2,0x2A,0x83,0xC9,0x7A,0x75,0xFF,0xA2,0xA2, + 0x0A,0x83,0xA9,0x72,0xBE,0xBA,0x5E,0x7C,0x0A,0x83,0xA9,0x72,0xFF,0xA2,0xFA,0x5B, + 0x0B,0x83,0xCA,0x7A,0xEA,0xFF,0xFD,0xFD,0xEA,0x7A,0xA9,0x72,0x20,0x22,0xDA,0xA0, + 0x2A,0x83,0xA9,0x72,0x8A,0xEF,0x7F,0x7E,0x2B,0x83,0xA9,0x72,0xAA,0x2D,0xBF,0xF7, + 0x2A,0x83,0xC9,0x7A,0xB2,0xB8,0xFE,0xDF,0x4B,0x8B,0xEA,0x7A,0xCB,0x21,0x8E,0x5D, + 0x4B,0x83,0xE9,0x7A,0xFE,0xDE,0xAB,0x7B,0x0A,0x83,0xC9,0x7A,0xB0,0xFF,0xBA,0xF6, + 0x03,0x41,0xA1,0x30,0xB0,0xF2,0xBA,0x8B,0xE2,0x38,0xA1,0x30,0xBC,0xFB,0x28,0xBC, + 0x03,0x41,0xC2,0x38,0x55,0x5E,0xEA,0xAF,0x23,0x41,0xC2,0x38,0x75,0x3D,0xBD,0x9E, + 0x23,0x41,0xC2,0x38,0xAD,0xE7,0x26,0xAF,0x23,0x41,0xE2,0x38,0xD7,0xD7,0x5E,0xB8, + 0x02,0x39,0xC2,0x38,0x6A,0xEA,0x68,0xA8,0x02,0x39,0xC2,0x38,0xFF,0x6F,0x5A,0x7C, + 0x22,0x41,0xC2,0x38,0x5B,0x5D,0x7D,0x7F,0x03,0x41,0xA1,0x30,0x8B,0xAB,0xFD,0xE5, + 0x03,0x41,0xC2,0x38,0xF4,0x5A,0x5B,0x7A,0x23,0x39,0xC2,0x38,0xBD,0xD7,0xFD,0x5F, + 0x03,0x39,0xA1,0x30,0x2A,0xAF,0xE6,0xEA,0xE2,0x38,0xC2,0x38,0x08,0x2A,0xCA,0x7B, + 0x02,0x39,0xC2,0x38,0xFB,0xF7,0x7F,0xEB,0xE2,0x38,0xC2,0x30,0xAC,0x0E,0xC9,0x4F, + 0xE2,0x38,0xC2,0x38,0x08,0x02,0xA2,0x20,0x03,0x41,0xC2,0x38,0xAA,0xDE,0xF9,0x4F, + 0x03,0x41,0xC2,0x38,0xFC,0xF8,0xFA,0xFD,0x03,0x39,0xC2,0x38,0xFA,0xBB,0xDF,0xD5, + 0x03,0x41,0xA2,0x38,0xFA,0x7A,0xFE,0xB8,0xE2,0x38,0xA2,0x30,0xA2,0x9B,0xBC,0x3C, + 0x03,0x41,0xC2,0x38,0xAB,0xAA,0xBA,0xE7,0x67,0x72,0x02,0x41,0x0D,0x2D,0xAD,0x35, + 0x87,0x72,0x06,0x62,0x78,0x68,0x6A,0xEA,0x06,0x6A,0x63,0x49,0xE0,0xE8,0xFC,0x7E, + 0x84,0x51,0x23,0x41,0x7C,0xFE,0x7E,0xCB,0x23,0x41,0xE2,0x30,0xFE,0xFC,0x7C,0x5C, + 0x03,0x39,0xC2,0x30,0xA0,0xFE,0xAF,0xE7,0x03,0x39,0xC2,0x30,0xF5,0xD5,0xAB,0xBD, + 0x03,0x39,0xC2,0x30,0xCB,0x6F,0xEA,0xCB,0xE3,0x30,0xC2,0x28,0xE0,0xFC,0xB0,0xE0, + 0x03,0x31,0xA2,0x28,0xBB,0xAE,0xFE,0x58,0xE3,0x30,0xC2,0x28,0xBC,0xF6,0x3D,0x09, + 0x24,0x39,0xC2,0x30,0x2A,0x8B,0xE7,0xFF,0x23,0x39,0xA2,0x28,0xA2,0xFB,0xF7,0xF7, + 0x03,0x31,0xC2,0x30,0xA6,0xAE,0x8B,0xAB,0x03,0x31,0xC2,0x30,0xDA,0x50,0xF2,0xAA, + 0xE3,0x30,0xC2,0x28,0x2A,0x2F,0xBC,0x28,0x23,0x39,0xC2,0x28,0xFF,0xFF,0xFB,0xA2, + 0x03,0x31,0xC2,0x30,0x0B,0x2B,0x2F,0x0A,0x23,0x39,0xE3,0x30,0x7A,0x7A,0xDF,0xD7, + 0x03,0x39,0xE3,0x30,0x8B,0xEB,0xF2,0xD2,0x03,0x39,0xC2,0x30,0xA8,0x38,0xFF,0x6F, + 0x24,0x39,0xC2,0x30,0xA0,0xFA,0x7F,0xED,0x24,0x39,0xE3,0x30,0xCF,0xE5,0xFF,0xF7, + 0x24,0x39,0xE3,0x30,0x8B,0x8B,0x8E,0x9C,0x24,0x39,0xE3,0x30,0x3F,0x2F,0xB3,0xFA, + 0x44,0x41,0xE2,0x30,0xB2,0xF8,0xEE,0x7D,0x43,0x39,0xE2,0x38,0xFA,0xAA,0xAA,0xBF, + 0x44,0x41,0x03,0x39,0xBD,0xAB,0xAD,0xF7,0x44,0x41,0x03,0x39,0x77,0x7E,0xB7,0x68, + 0x44,0x41,0xE3,0x38,0x7F,0x4A,0xEA,0xFF,0xE3,0x38,0x23,0x31,0xEF,0xAA,0xAE,0xAF, + 0x03,0x39,0xC3,0x30,0x00,0xE2,0xDA,0xA3,0x24,0x41,0xE3,0x30,0xAF,0xBF,0xA9,0x8A, + 0x24,0x39,0xC2,0x30,0xFA,0xFE,0xBE,0x7C,0x24,0x39,0xC2,0x30,0xAD,0xEB,0xAA,0xE2, + 0x24,0x39,0xE3,0x30,0x63,0x7B,0x7F,0xED,0x03,0x31,0xC2,0x30,0x00,0xAB,0xAD,0xEA, + 0x43,0x39,0xE2,0x30,0xBD,0xEA,0xAC,0xEB,0x23,0x39,0x03,0x31,0x4C,0x50,0x70,0x5A, + 0x24,0x39,0xE3,0x30,0x5F,0xFF,0xEB,0xA8,0x03,0x31,0xE2,0x30,0xC1,0xFA,0xF7,0x5E, + 0x24,0x39,0xE3,0x30,0xBF,0xFF,0xEB,0xCB,0x03,0x39,0xA2,0x28,0x22,0x28,0x2A,0x2B, + 0x44,0x39,0xE3,0x30,0x75,0x77,0x7C,0xFA,0x03,0x31,0xC2,0x30,0xC2,0xEE,0xDE,0x8A, + 0x03,0x31,0xC2,0x28,0x5D,0xFD,0xFF,0xA0,0x03,0x31,0xC2,0x28,0x55,0x57,0xB7,0x1F, + 0x03,0x31,0xC2,0x28,0xD5,0xF5,0xBA,0x20,0x24,0x31,0xC2,0x28,0x5F,0x5B,0x73,0x6F, + 0xE3,0x30,0xC2,0x28,0xDD,0xF7,0x55,0x7F,0xE3,0x28,0xA2,0x28,0x7A,0xD8,0xAA,0xAB, + 0xC2,0x28,0xA2,0x20,0x5A,0xEB,0x0B,0x8F,0xC2,0x28,0xA2,0x20,0x7F,0xEC,0xEB,0xB7, + 0xC2,0x28,0x82,0x20,0x5A,0x5A,0xDC,0xFA,0xC3,0x28,0x82,0x20,0x5D,0x57,0xFC,0xAA, + 0xC2,0x20,0x61,0x18,0xF7,0xFF,0xBA,0xA2,0xA2,0x28,0x81,0x20,0x0F,0x15,0xF7,0x78, + 0xA2,0x28,0x61,0x20,0x2A,0xBA,0xBB,0xBF,0xE2,0x30,0x82,0x20,0xBA,0x2F,0xFB,0xF5, + 0x03,0x31,0xA2,0x28,0x3A,0xBE,0x5F,0xD5,0x03,0x31,0xA2,0x28,0x22,0x2C,0x2E,0xBD, + 0xE3,0x30,0xA2,0x28,0xA8,0x80,0xF8,0x5F,0x03,0x31,0xA2,0x28,0x8C,0x8E,0x57,0x55, + 0x44,0x39,0xA2,0x28,0x2B,0xAF,0xAF,0xFD,0x65,0x41,0x03,0x31,0xBE,0xE8,0xE3,0x7D, + 0x24,0x39,0xC2,0x28,0xE8,0x78,0x5E,0x5E,0xE3,0x30,0xA2,0x28,0xE3,0xC2,0xBF,0x8B, + 0x03,0x31,0xC2,0x28,0xEF,0x8A,0xAB,0x3F,0x23,0x39,0xC2,0x28,0xDF,0xF7,0xE2,0xAB, + 0x23,0x39,0xE3,0x30,0xF7,0xAF,0xAF,0x0D,0xA5,0x49,0x03,0x39,0xA5,0x25,0xAF,0x2B, + 0x06,0x5A,0x65,0x41,0xAD,0x8B,0xAB,0xEA,0x06,0x5A,0xA5,0x51,0xAB,0x2E,0x09,0xA2, + 0xC6,0x59,0x05,0x52,0xAB,0xEE,0xFB,0xEA,0x27,0x62,0xC5,0x59,0xA7,0xAD,0x8B,0xA2, + 0x48,0x6A,0xE6,0x59,0xBA,0xFD,0xDB,0x82,0x88,0x6A,0x06,0x5A,0xD7,0xD7,0xDF,0xAA, + 0xA9,0x72,0x47,0x62,0xEF,0x2D,0xAD,0x3B,0x89,0x6A,0x48,0x6A,0xFA,0xA0,0x82,0x8B, + 0x88,0x6A,0x48,0x6A,0xAF,0xAA,0xAA,0xDF,0xCA,0x7A,0x68,0x6A,0x8B,0x03,0x2B,0xBD, + 0xE9,0x7A,0x68,0x6A,0x22,0xFB,0xFA,0xF7,0xE9,0x7A,0xA9,0x72,0xFD,0xBB,0xAF,0xD5, + 0xE9,0x7A,0x68,0x6A,0xBA,0x9F,0xFE,0xA8,0xC9,0x7A,0x68,0x6A,0x80,0x28,0xEA,0xFC, + 0xE9,0x7A,0x88,0x72,0x63,0xB2,0x03,0xAF,0xE9,0x7A,0x88,0x72,0xFF,0xBD,0x2B,0x00, + 0xEA,0x7A,0x88,0x72,0x8A,0xBA,0x6A,0x7C,0xE9,0x7A,0xA9,0x72,0x82,0x0B,0xAF,0x6D, + 0xE9,0x7A,0xA8,0x72,0x79,0x7A,0xA2,0xEA,0xE9,0x7A,0xA9,0x72,0xB8,0xE4,0xC0,0xB0, + 0xC9,0x7A,0x88,0x72,0xBC,0xDB,0xBB,0x7E,0xC9,0x7A,0x88,0x72,0x2B,0x2B,0xAF,0x15, + 0x0A,0x83,0xA9,0x72,0x22,0xBF,0xF9,0xFF,0x2B,0x83,0x88,0x72,0xA8,0xA3,0xBD,0xDF, + 0xEA,0x7A,0xA8,0x72,0xB8,0xFE,0xBC,0xAA,0xEA,0x7A,0x88,0x72,0xD2,0xBA,0xAA,0xA8, + 0x2B,0x83,0xC9,0x7A,0xFD,0x5D,0xB7,0xD5,0x0A,0x83,0xA9,0x72,0x20,0xB6,0x9E,0xA2, + 0x2B,0x83,0xC9,0x7A,0x5E,0xBF,0x3F,0xAD,0x2B,0x83,0xA8,0x7A,0x7B,0x2A,0x22,0x8A, + 0x0A,0x83,0xA8,0x72,0x89,0x2F,0xAB,0x8E,0x0A,0x83,0xC9,0x7A,0xC0,0xAA,0x00,0xBE, + 0xEA,0x82,0x0A,0x7B,0xEF,0xF5,0x6A,0xEF,0x2A,0x83,0xEA,0x7A,0x9E,0xB6,0x76,0x73, + 0x03,0x41,0xA1,0x30,0xA8,0xBC,0x76,0xD6,0x23,0x41,0xC2,0x38,0xE5,0x5D,0xEF,0xEF, + 0x03,0x41,0xA1,0x30,0xAF,0x39,0x0E,0x2A,0x03,0x39,0xC2,0x38,0xAA,0x2B,0x3D,0x96, + 0x03,0x41,0xC2,0x38,0x03,0xAB,0xA8,0x78,0x03,0x41,0xC2,0x38,0x28,0xBA,0x16,0xD5, + 0x02,0x41,0xE2,0x38,0xB2,0x38,0x5E,0x5E,0x03,0x41,0xA1,0x30,0xFE,0xF8,0xAA,0x2A, + 0xE2,0x38,0xA1,0x30,0xFF,0xDF,0xBE,0xE8,0x03,0x41,0xA1,0x30,0x29,0xAB,0xEB,0xFB, + 0xE2,0x38,0xA1,0x30,0xA0,0x2A,0xBE,0x0A,0x02,0x41,0xE2,0x38,0x5F,0x57,0x85,0xDD, + 0x03,0x41,0xA1,0x30,0xEA,0x7E,0x7A,0x82,0x23,0x41,0xC2,0x38,0x7B,0x5F,0x5D,0x7F, + 0x22,0x41,0xC2,0x38,0xD5,0xD7,0x77,0x7F,0xE2,0x38,0xA1,0x30,0xFC,0xFE,0xBC,0xA2, + 0x02,0x41,0xC2,0x38,0x55,0xED,0x83,0x68,0x03,0x39,0xC2,0x38,0xEB,0xEB,0x2B,0x4F, + 0x03,0x39,0xC2,0x38,0xD7,0xFB,0xAA,0xD6,0x02,0x41,0xA1,0x30,0xFE,0xFA,0xF8,0xB9, + 0xE2,0x38,0xA2,0x30,0x3A,0xAB,0xEA,0xAC,0xE2,0x38,0xA2,0x30,0x78,0xB9,0xA8,0x8A, + 0xE2,0x38,0xA1,0x30,0x8A,0x88,0xFF,0x5A,0x26,0x6A,0xC1,0x30,0x3D,0x35,0xB5,0xB5, + 0x66,0x6A,0xC5,0x59,0xA0,0xE2,0x7A,0x7A,0xE5,0x59,0x84,0x51,0x5C,0x7C,0xF7,0xEB, + 0xA4,0x51,0x64,0x49,0x6F,0x5E,0x5E,0xE2,0x64,0x49,0xE2,0x30,0x54,0x5E,0xD6,0xDF, + 0x23,0x39,0xC2,0x30,0xE5,0xC9,0xA8,0xE0,0x03,0x39,0xC2,0x30,0xAE,0xA7,0xCF,0xAF, + 0x24,0x31,0xC2,0x30,0xE7,0xDD,0xF7,0xDF,0x03,0x31,0xC2,0x30,0xAC,0xF0,0x56,0xD7, + 0x03,0x31,0xA2,0x28,0xD8,0xBE,0xFF,0xFF,0xE3,0x30,0xC2,0x28,0x2A,0x28,0xAE,0xFD, + 0xE3,0x30,0xC2,0x28,0x2C,0x2F,0x3A,0xAB,0x02,0x31,0xC2,0x28,0xD7,0xCF,0xEA,0xAB, + 0x03,0x31,0xE3,0x30,0x55,0xE7,0xBD,0x8D,0x03,0x39,0xA2,0x28,0xAA,0xE3,0xAA,0x82, + 0x03,0x31,0xE3,0x30,0x15,0x55,0x7D,0x7F,0x23,0x39,0xE3,0x30,0x62,0xF7,0x57,0x55, + 0x03,0x31,0xC2,0x28,0x08,0xFA,0xF6,0x7D,0x03,0x31,0xE2,0x30,0xD5,0xDE,0xF5,0xE5, + 0x03,0x31,0xC2,0x30,0xA3,0xA2,0x2A,0x2B,0x03,0x31,0xE2,0x30,0xCF,0xAA,0x0F,0x28, + 0x03,0x39,0xC3,0x30,0x89,0xC8,0x88,0xE8,0x03,0x39,0xA2,0x28,0x2F,0xBA,0xEE,0x2E, + 0x03,0x31,0xC2,0x30,0xA8,0x30,0x5F,0xFF,0x03,0x39,0xE3,0x30,0xE2,0xAA,0xED,0x73, + 0x24,0x39,0xE3,0x30,0xF3,0x79,0xFF,0xBD,0x23,0x39,0xE3,0x30,0xAA,0xF3,0xD7,0xD8, + 0x23,0x39,0xE3,0x30,0x22,0x2E,0x3F,0x2E,0x24,0x39,0xE2,0x30,0xA0,0x7A,0x7E,0x8A, + 0x23,0x39,0xE3,0x30,0xE8,0xE3,0x6A,0x6A,0x24,0x39,0xC2,0x38,0xAA,0xA8,0x8A,0xA9, + 0x23,0x39,0xE3,0x38,0xDF,0x58,0xF8,0xF6,0x24,0x39,0xC3,0x38,0x02,0x8B,0xAA,0x8A, + 0x44,0x41,0xC3,0x30,0xFE,0xDA,0xFA,0x22,0x24,0x39,0xC2,0x30,0xB3,0xDF,0xBE,0xCC, + 0x44,0x39,0xE3,0x30,0xED,0xED,0xF5,0x87,0x44,0x39,0x03,0x31,0x7E,0xFA,0xEE,0xAB, + 0x03,0x31,0xC2,0x30,0xE2,0xA2,0x00,0xA0,0x03,0x31,0xC2,0x30,0x08,0x2A,0x3E,0x3E, + 0x44,0x39,0xE2,0x30,0xA7,0x2B,0xAB,0xFB,0x24,0x39,0xE2,0x30,0xDC,0xB8,0x28,0xAA, + 0x24,0x39,0xE3,0x30,0xEA,0xF8,0xA8,0x00,0x24,0x39,0xC2,0x30,0xBD,0x23,0x00,0xA0, + 0x24,0x39,0xE3,0x30,0x27,0x3C,0xA0,0xAE,0x24,0x39,0xE3,0x30,0xFE,0x5E,0x7A,0xB2, + 0x23,0x39,0xE3,0x30,0x5E,0xEE,0xF8,0xC8,0x23,0x39,0xC2,0x28,0xFF,0xEF,0xFE,0xD2, + 0x03,0x31,0xC2,0x28,0xBB,0x3F,0xB6,0x2A,0x24,0x39,0xC2,0x30,0xFE,0xFA,0xF2,0x7A, + 0xE3,0x30,0xC2,0x28,0x5A,0x2A,0x0D,0x3D,0x03,0x31,0xC2,0x28,0x57,0x7E,0xFE,0x34, + 0x03,0x31,0xA2,0x20,0x6F,0xFF,0xAB,0xA8,0x03,0x31,0xC2,0x28,0x55,0xDD,0xF7,0x4B, + 0xE3,0x28,0xA2,0x20,0x57,0x9E,0xEA,0x00,0xE3,0x28,0xA2,0x28,0xFD,0xFF,0xF3,0xF3, + 0xC2,0x28,0xA2,0x20,0x97,0xA5,0x05,0x0E,0xC3,0x28,0x81,0x20,0xFE,0xE0,0x00,0x80, + 0xC2,0x28,0x82,0x20,0x55,0xD5,0xDB,0xA8,0xC3,0x28,0x82,0x20,0xFD,0xF5,0xB7,0x2B, + 0xC2,0x28,0x82,0x20,0xF7,0xD5,0xF7,0xAE,0xC3,0x28,0x81,0x20,0xAA,0x6F,0xBA,0xFC, + 0xA2,0x28,0x82,0x20,0xDF,0xFF,0xBF,0xBC,0xC2,0x28,0x82,0x20,0xFF,0x2F,0x2F,0x3E, + 0xE2,0x28,0xA2,0x28,0xAB,0xA7,0xF5,0xD5,0x03,0x31,0xC2,0x28,0x03,0x3B,0xA7,0xBD, + 0x03,0x31,0xA2,0x28,0x72,0xEA,0xBA,0xFA,0x03,0x31,0xA2,0x28,0xEF,0x35,0x3F,0x3E, + 0x24,0x39,0xC2,0x28,0xFF,0x9F,0x9F,0x3F,0x24,0x39,0x03,0x31,0x55,0xB5,0x3F,0x2A, + 0x85,0x41,0xE2,0x30,0xAD,0xA9,0x2F,0x2A,0xC6,0x51,0x63,0x41,0xBF,0xEA,0x09,0x02, + 0x06,0x5A,0xC6,0x51,0xA9,0xEB,0xB2,0x3E,0x06,0x5A,0xC5,0x51,0xF8,0xAA,0x92,0xE2, + 0x06,0x5A,0xA5,0x51,0xEB,0xB7,0xBF,0xA8,0x48,0x6A,0xE6,0x59,0xEF,0xB5,0x3B,0xAD, + 0x68,0x6A,0x06,0x5A,0xE9,0xA5,0xAF,0x2F,0x88,0x72,0x27,0x62,0xAF,0x29,0x25,0xF3, + 0xA9,0x72,0x68,0x6A,0x2E,0xAA,0xAA,0xF6,0xEA,0x7A,0x68,0x6A,0xFD,0xFF,0xF5,0xE3, + 0xCA,0x72,0x48,0x6A,0x5E,0x7F,0xEA,0x8A,0xC9,0x72,0x68,0x6A,0x2D,0xAE,0x23,0xC2, + 0xC9,0x7A,0x68,0x6A,0xEB,0xCA,0xB8,0x9A,0xC9,0x72,0x67,0x6A,0x8B,0xAF,0x57,0xFE, + 0xEA,0x7A,0x68,0x6A,0x83,0xA5,0xFD,0x7F,0xC9,0x7A,0x67,0x6A,0xB8,0xAF,0x37,0xAD, + 0xC9,0x7A,0x67,0x6A,0xAC,0x2F,0x6A,0x7E,0x0A,0x83,0xA9,0x72,0x8B,0xEF,0x7F,0xF5, + 0x0A,0x83,0xA8,0x72,0x78,0xFB,0xB5,0xFD,0x0B,0x83,0x88,0x72,0xFD,0x7F,0x68,0xBB, + 0xE9,0x7A,0x88,0x72,0xA8,0xF5,0xDD,0x63,0xE9,0x7A,0x88,0x72,0xB0,0xAA,0xAB,0xDF, + 0xE9,0x7A,0x88,0x72,0x7E,0xFE,0xAF,0x29,0xE9,0x7A,0x88,0x72,0x95,0xF7,0x7C,0x6E, + 0xEA,0x7A,0xA9,0x72,0xEB,0xCA,0x8D,0x6D,0xC9,0x7A,0x68,0x72,0x9A,0xF2,0xE8,0xAA, + 0xE9,0x7A,0x88,0x72,0xAB,0xFD,0x2D,0x0D,0xEA,0x7A,0x89,0x72,0xA2,0x82,0xF0,0xD0, + 0xEA,0x7A,0xA9,0x72,0xBF,0xBE,0xB7,0xF5,0xEA,0x7A,0x88,0x72,0x82,0x5A,0xB6,0xAA, + 0x0B,0x7B,0xA9,0x72,0xBD,0xDD,0xBE,0xF8,0x2B,0x83,0xA9,0x72,0x2A,0xEE,0xFF,0xFF, + 0x0A,0x83,0xA9,0x72,0xA2,0xF2,0xFD,0xB5,0x4B,0x83,0xC9,0x7A,0xFD,0xFF,0x35,0xA7, + 0x2B,0x83,0xE9,0x7A,0xFF,0xF7,0xDC,0x7F,0x2B,0x83,0xE9,0x7A,0xFA,0xF5,0xCD,0x7D, + 0xE2,0x38,0xA1,0x30,0x98,0x08,0x02,0x8A,0x03,0x41,0xC2,0x38,0xA9,0xF8,0x0A,0xAB, + 0x03,0x41,0xC2,0x38,0xFF,0xFF,0x0F,0x8B,0x03,0x41,0xA1,0x30,0xE6,0xBA,0xAA,0xA2, + 0x03,0x41,0xC2,0x38,0x7E,0x7F,0xCF,0xCB,0x02,0x39,0xA2,0x30,0x27,0x3B,0xAF,0x2F, + 0x03,0x41,0xC2,0x38,0xFA,0xFE,0xFC,0xF6,0x03,0x41,0xC2,0x38,0xB7,0x95,0x2F,0xAB, + 0x23,0x41,0xC2,0x38,0x5A,0x78,0xA8,0xFA,0xE2,0x38,0xA1,0x30,0x21,0xA0,0x8A,0x82, + 0x03,0x41,0xA1,0x30,0x2C,0xA2,0xAE,0xFD,0x23,0x39,0xC2,0x38,0xDF,0xFF,0xF5,0x45, + 0xE2,0x38,0xC2,0x38,0x00,0x0A,0x9E,0x7F,0x03,0x41,0xC2,0x38,0xDB,0x7B,0xAB,0xFF, + 0x23,0x41,0xC1,0x30,0x7B,0xFF,0xFF,0xBD,0x03,0x39,0xC2,0x38,0x5A,0x7E,0x06,0x8F, + 0x02,0x39,0xA1,0x30,0x62,0xFA,0xD2,0x7A,0xE2,0x38,0xC1,0x38,0xA9,0x43,0xCD,0x27, + 0xA2,0x38,0xE3,0x30,0xBA,0xFB,0xEA,0xAA,0x03,0x41,0xA1,0x30,0xBD,0x97,0xAE,0x2E, + 0x03,0x41,0xC2,0x38,0x5F,0x7B,0x5E,0x58,0xE2,0x38,0xA2,0x30,0x2E,0xA9,0x43,0x7B, + 0xC2,0x30,0x81,0x30,0xB8,0xB8,0xFF,0xAB,0x83,0x49,0xC2,0x30,0x25,0x35,0xB5,0x95, + 0x27,0x62,0xA5,0x59,0xE8,0xE9,0xAE,0xBD,0xE5,0x59,0x84,0x51,0xAA,0x28,0xEA,0x68, + 0xC5,0x51,0x22,0x41,0xFA,0x78,0xFA,0x82,0x23,0x41,0xC2,0x30,0xAA,0xAF,0xBC,0x98, + 0x23,0x39,0xC2,0x30,0xEA,0xEA,0x2A,0xFE,0x23,0x39,0xE2,0x30,0x57,0xEE,0xFE,0xBB, + 0x03,0x31,0xC2,0x28,0xEA,0x5A,0xB8,0xA8,0x03,0x31,0xC2,0x28,0x7E,0xBB,0xBE,0x20, + 0xE3,0x30,0xC2,0x28,0xD5,0xEF,0xFC,0x5C,0x03,0x31,0xC2,0x28,0xF7,0xEF,0x86,0xAB, + 0x23,0x39,0xC2,0x28,0x5F,0xFF,0x9F,0x25,0x03,0x31,0xC2,0x28,0xBD,0xB7,0xF8,0xC8, + 0x03,0x31,0xA2,0x28,0x8A,0x8A,0xBE,0x9E,0x03,0x31,0xA3,0x28,0xA2,0x20,0x80,0xA8, + 0x03,0x31,0xE3,0x30,0x55,0x5E,0x56,0xD5,0x23,0x31,0xC3,0x30,0xEF,0xEF,0xA7,0x36, + 0x23,0x39,0xC2,0x28,0xF5,0xFF,0xAE,0xF8,0x03,0x31,0xE3,0x30,0xED,0x33,0x98,0x97, + 0x03,0x31,0xC2,0x28,0x9A,0xFE,0xEE,0xAE,0x03,0x31,0xC2,0x28,0x00,0xE6,0xEB,0xEE, + 0x03,0x31,0xC3,0x30,0xAA,0xAB,0xA5,0xAF,0x24,0x39,0xC2,0x30,0x2F,0xBE,0x7A,0x76, + 0x24,0x39,0xC2,0x28,0xFB,0xB2,0xFB,0xA1,0x24,0x39,0xE3,0x30,0xFA,0xEF,0xCB,0x20, + 0x44,0x39,0xE3,0x30,0x3D,0xBD,0xFD,0xF7,0x44,0x39,0x03,0x39,0xDF,0xDA,0xDF,0x55, + 0x23,0x39,0xE3,0x38,0xA8,0xEB,0xEF,0x7F,0x23,0x39,0xE3,0x38,0x8A,0x8F,0x27,0xEF, + 0x03,0x39,0xC2,0x30,0x8E,0x6C,0xFC,0xE0,0x23,0x41,0xE3,0x30,0x7D,0xFD,0xA8,0xA2, + 0x03,0x39,0xE2,0x30,0xA7,0x16,0x5C,0xDC,0x64,0x41,0x03,0x39,0x55,0xDC,0x5D,0xED, + 0x45,0x41,0xE3,0x30,0xAA,0xFA,0x70,0x6A,0x23,0x39,0xE3,0x38,0x7B,0x4B,0x2F,0xBF, + 0x23,0x39,0xE3,0x30,0x0B,0xE3,0xE8,0xAA,0x23,0x39,0xE2,0x30,0x82,0x02,0x23,0xB5, + 0x24,0x39,0xE3,0x30,0x8F,0xC0,0x80,0xAA,0x23,0x39,0xE2,0x30,0xB7,0xFF,0xD9,0x6D, + 0x03,0x39,0xE2,0x30,0xF8,0xC0,0x78,0x4F,0x03,0x39,0xE3,0x30,0x95,0xD5,0xF5,0xEF, + 0x45,0x41,0xC2,0x30,0x08,0x8A,0x9F,0x57,0x24,0x39,0xE3,0x38,0x80,0xAA,0xFE,0x6F, + 0x24,0x39,0xE3,0x30,0xAA,0x62,0x7A,0xBA,0x23,0x39,0xE3,0x30,0xAF,0xA2,0xBA,0x98, + 0x23,0x39,0xE2,0x30,0xBE,0xDA,0x78,0xFA,0x24,0x39,0xE2,0x30,0x7A,0x7E,0xF7,0xA6, + 0x23,0x39,0xE3,0x30,0xFB,0xCA,0xA7,0x6C,0x03,0x31,0xC2,0x28,0xE0,0xC2,0x1A,0x22, + 0x44,0x39,0xE2,0x28,0xD5,0xFA,0xEA,0xFE,0x03,0x31,0xC2,0x28,0x37,0xE6,0xAA,0x83, + 0x03,0x31,0xC2,0x28,0xF6,0x8A,0x3A,0xAA,0x03,0x31,0xC2,0x28,0xE3,0xFE,0xBA,0x22, + 0x03,0x31,0xC3,0x28,0x7A,0xFD,0xFF,0xEA,0xE3,0x30,0xA2,0x28,0xFB,0x3E,0xEF,0xF7, + 0xE3,0x30,0xA2,0x28,0xBA,0xB2,0x2B,0x83,0xE3,0x30,0xA2,0x28,0x7A,0xBC,0xEA,0x83, + 0xE3,0x28,0x82,0x28,0xBA,0xED,0xCD,0x8A,0xC2,0x28,0xA2,0x28,0x4E,0x20,0x03,0x8A, + 0xE3,0x30,0xA3,0x28,0xFB,0xF2,0xA8,0x2E,0x03,0x31,0xA2,0x28,0xDF,0xBA,0xFF,0x8B, + 0xE2,0x28,0xA2,0x28,0x57,0xBF,0x0A,0x82,0xE3,0x30,0xA2,0x28,0x59,0x8F,0x00,0x0A, + 0x03,0x31,0xA2,0x28,0xD5,0x9D,0xAE,0x0A,0x03,0x31,0xC2,0x28,0x9F,0x2F,0x85,0x2A, + 0x24,0x39,0xE3,0x30,0x57,0x7F,0x4F,0xFF,0x03,0x39,0xE3,0x30,0x09,0x69,0x5D,0xB5, + 0x44,0x39,0xE3,0x30,0xBF,0xAD,0xB3,0x3F,0x65,0x41,0x24,0x39,0xA9,0x03,0x0B,0xA5, + 0x07,0x5A,0x65,0x49,0x7F,0xAF,0xAF,0x0F,0x06,0x5A,0xA5,0x49,0xBD,0xE9,0xEC,0x00, + 0x06,0x5A,0xC6,0x51,0xBF,0x06,0x83,0x0E,0x27,0x62,0xC5,0x51,0x2F,0xF7,0xCE,0xA2, + 0x26,0x62,0xC5,0x51,0xBE,0x9E,0xAB,0xAB,0x47,0x62,0x07,0x62,0xF3,0xEA,0x6E,0xDD, + 0x68,0x6A,0x07,0x62,0xB5,0x25,0x07,0x22,0xA9,0x72,0x48,0x6A,0x6B,0xA2,0xFF,0xAB, + 0xA9,0x72,0x48,0x6A,0x3A,0x3D,0xFF,0xFB,0xEA,0x7A,0x68,0x6A,0xFC,0xFB,0x7B,0x7D, + 0xEA,0x7A,0x89,0x72,0x2B,0xAA,0xFD,0xF5,0xC9,0x7A,0x88,0x6A,0x0B,0xAF,0x7F,0x6E, + 0xC9,0x7A,0x47,0x62,0x6A,0xA8,0x02,0x2B,0xE9,0x7A,0x68,0x6A,0x57,0xBF,0xEE,0x0A, + 0xC9,0x72,0x88,0x72,0xE8,0xEE,0x1F,0xFA,0xEA,0x7A,0x87,0x6A,0x75,0x77,0xAA,0x2F, + 0xC8,0x7A,0x67,0x6A,0x0A,0x8D,0xA8,0xA8,0xE9,0x7A,0x68,0x72,0x23,0xAA,0xAE,0xDE, + 0xE9,0x7A,0xA9,0x72,0xF1,0x42,0x80,0xA9,0xEA,0x7A,0x88,0x72,0x3F,0xE6,0xFC,0xAF, + 0xEA,0x7A,0xA9,0x7A,0xC2,0xA3,0xA9,0x58,0x0A,0x83,0xA8,0x72,0x7F,0x7A,0x62,0xC9, + 0xE9,0x7A,0x88,0x72,0x0B,0x37,0x97,0xA3,0x09,0x7B,0xA9,0x72,0xA4,0xF2,0xEB,0xD4, + 0xC9,0x7A,0x88,0x72,0xF8,0xCE,0x6A,0x63,0xEA,0x7A,0x88,0x72,0xCB,0xBF,0xAD,0x82, + 0x0A,0x7B,0xA8,0x72,0xED,0xA7,0x8B,0xA3,0x0A,0x7B,0xC9,0x7A,0xFB,0xAA,0xEA,0xFC, + 0xEA,0x7A,0x88,0x6A,0xFA,0xF6,0x8A,0x08,0xEA,0x7A,0x68,0x6A,0x8F,0xA7,0xB7,0xEA, + 0xEA,0x7A,0xA9,0x72,0x20,0x10,0xBF,0x5E,0xEA,0x7A,0xA9,0x72,0x85,0x02,0xB2,0xFD, + 0x0A,0x83,0xA9,0x72,0x5D,0xFD,0x7F,0x8E,0x0A,0x83,0xA9,0x72,0x27,0xB7,0xDD,0xEF, + 0x2A,0x83,0xC9,0x7A,0x8E,0xCB,0xA5,0xD5,0x0A,0x83,0xC9,0x7A,0x38,0x7E,0x7E,0xBA, + 0xE2,0x38,0xC2,0x38,0x5B,0x5B,0x0A,0xC8,0x23,0x39,0xC2,0x38,0xE7,0x26,0xEF,0xAA, + 0x23,0x39,0xC2,0x38,0xFD,0xFF,0xF3,0xFB,0x02,0x39,0xC2,0x38,0xEF,0xF8,0xEA,0x9F, + 0x03,0x41,0xA1,0x30,0xA2,0xAA,0xBA,0xFE,0x03,0x41,0xC2,0x38,0xA7,0x78,0x5A,0xD7, + 0xE2,0x38,0xC2,0x38,0xD0,0xBF,0x0F,0x21,0x23,0x41,0xC2,0x38,0x6D,0xFD,0xCF,0xE3, + 0x02,0x39,0xC2,0x38,0xFA,0x4A,0xE3,0xFF,0xE2,0x38,0xA1,0x30,0x20,0xB2,0x2F,0x2E, + 0x03,0x41,0xA1,0x30,0xB7,0x8A,0xEA,0xBA,0x02,0x39,0xC2,0x38,0xAB,0x8B,0x4B,0x78, + 0xE2,0x38,0xA1,0x30,0x88,0x20,0x02,0x0B,0xE2,0x38,0xA1,0x30,0xA0,0xA0,0x60,0xE8, + 0x03,0x41,0xC2,0x38,0xEF,0xD9,0xFF,0x2F,0x02,0x39,0xC2,0x38,0xB7,0xFF,0xFF,0x68, + 0x02,0x39,0xC2,0x38,0xF6,0xDA,0xF7,0xDD,0xE2,0x38,0xA2,0x30,0x8E,0x00,0x28,0x0C, + 0x03,0x41,0xC2,0x38,0x49,0xE7,0xF5,0xD7,0x03,0x39,0xC2,0x38,0x1D,0x2F,0x29,0x08, + 0x03,0x41,0xC2,0x38,0x6E,0x7A,0x78,0x78,0xC2,0x38,0xA1,0x30,0xC0,0xFA,0xFE,0x50, + 0xE2,0x38,0xA1,0x30,0x5F,0xE5,0x25,0x35,0x85,0x51,0xA1,0x30,0xB5,0xB5,0xB7,0x37, + 0xA8,0x72,0x43,0x49,0xBD,0xEF,0xEA,0xA2,0xE5,0x59,0x84,0x51,0x68,0xCB,0x0A,0x08, + 0xC5,0x51,0x84,0x49,0x42,0x62,0xFE,0x7E,0x23,0x41,0xC2,0x30,0xF8,0x50,0xF8,0xF8, + 0x03,0x39,0xC2,0x30,0xAF,0x6F,0x5F,0x80,0x03,0x31,0xC2,0x28,0x02,0x23,0x22,0x1F, + 0x03,0x31,0xE3,0x30,0xBE,0x5C,0x57,0x5F,0x24,0x39,0xE3,0x30,0x5A,0x7F,0xFD,0x6B, + 0x23,0x31,0xC2,0x30,0x77,0xFE,0x5F,0xBF,0x03,0x39,0xC2,0x28,0xFF,0x7B,0xAB,0xF2, + 0x03,0x31,0xC2,0x30,0x87,0xFD,0xEA,0xEA,0x03,0x31,0xA2,0x28,0xCA,0xEE,0x6B,0xBF, + 0x03,0x31,0xC2,0x30,0xD7,0xF5,0xB9,0x8B,0x03,0x31,0xC2,0x30,0xEA,0x78,0x7A,0x62, + 0x03,0x31,0xC2,0x30,0x83,0xBB,0xFB,0xF5,0x03,0x31,0xA2,0x30,0x28,0xAA,0xAE,0x8A, + 0x03,0x31,0xC2,0x30,0xE8,0xBA,0xE2,0x6A,0x03,0x31,0xC2,0x28,0x8A,0x0B,0xA9,0x3D, + 0x24,0x39,0xC2,0x30,0xFF,0x8E,0x2B,0x9F,0xE3,0x30,0xC2,0x28,0xEA,0xAE,0xEC,0xFE, + 0x24,0x39,0xE3,0x30,0x79,0xEA,0x7F,0x55,0x03,0x31,0xA2,0x30,0xBA,0xAE,0x2A,0x22, + 0x24,0x39,0xE3,0x30,0x89,0x5D,0x55,0x57,0x24,0x39,0xC2,0x30,0x82,0xEA,0xB7,0xBF, + 0x24,0x39,0xE2,0x30,0xFE,0x7A,0x6B,0x5F,0x03,0x39,0xC2,0x30,0xA2,0xBB,0xEB,0xCF, + 0x03,0x39,0xE3,0x30,0xA8,0x2E,0x2B,0x95,0x24,0x39,0xE2,0x30,0xEB,0xAA,0xFA,0x7F, + 0x03,0x39,0xE3,0x30,0xC1,0x68,0x78,0xF3,0x03,0x39,0xE3,0x30,0xC3,0xC7,0xEE,0x8B, + 0x44,0x41,0xC2,0x30,0xDF,0x2E,0xFF,0x7D,0x24,0x39,0xE3,0x38,0xE0,0xFA,0xEB,0xEB, + 0x44,0x41,0xE3,0x30,0xA3,0xEB,0x7F,0x5F,0x03,0x39,0xE3,0x38,0x9C,0xB8,0x5B,0x1B, + 0x24,0x39,0xE3,0x38,0xEB,0x8B,0xFD,0xD7,0x03,0x39,0xE3,0x30,0x20,0x00,0x82,0x83, + 0x44,0x41,0x03,0x39,0x55,0xAF,0xAD,0x6D,0x23,0x39,0xE3,0x30,0x0B,0x89,0xAA,0xB7, + 0x23,0x39,0xE2,0x38,0xCB,0xC2,0xC2,0xFA,0x24,0x39,0xE3,0x30,0xBD,0x6D,0xBF,0x17, + 0x24,0x39,0xC2,0x30,0xF7,0xAE,0xEC,0xB8,0x03,0x39,0xE3,0x30,0xFE,0x7D,0x9E,0x23, + 0x24,0x39,0xC3,0x30,0xAA,0xB5,0xBA,0xF8,0x23,0x39,0xC4,0x30,0x0A,0x2A,0xB2,0xAA, + 0x23,0x39,0x03,0x31,0x7F,0x7E,0xB6,0x95,0x23,0x39,0xE2,0x30,0xE7,0x2F,0x2C,0x32, + 0x44,0x39,0xE2,0x30,0xFB,0x7E,0xFA,0x8A,0x23,0x39,0xC2,0x28,0xAA,0x9A,0xBE,0x2A, + 0x23,0x39,0xE3,0x30,0x5A,0xFF,0xBE,0xAA,0x03,0x31,0xE3,0x30,0x29,0xFD,0xD7,0x2C, + 0x24,0x39,0xE3,0x30,0xF8,0xFF,0xFA,0xE2,0x24,0x39,0xE3,0x28,0xDF,0xDF,0xBA,0xB3, + 0x24,0x39,0xE3,0x30,0x73,0xFA,0xA0,0xAA,0x04,0x31,0xC3,0x28,0xD7,0xD7,0xBC,0x30, + 0x04,0x31,0xE3,0x30,0x55,0xF5,0xEB,0x70,0x24,0x31,0xE3,0x30,0x7F,0x8F,0xEF,0x97, + 0x03,0x31,0xC2,0x28,0xEF,0xE0,0xE8,0xA0,0x03,0x31,0xA2,0x28,0xB7,0xEA,0xA2,0xA0, + 0x03,0x31,0xC2,0x28,0x36,0xA2,0x03,0xA2,0x23,0x31,0xE3,0x30,0xD5,0xF7,0xFD,0xFA, + 0xE3,0x30,0x03,0x29,0x2F,0x2B,0xB0,0x20,0x24,0x39,0xC2,0x28,0xDF,0xFA,0xE2,0x22, + 0x24,0x39,0xE3,0x30,0xBF,0x83,0x81,0xAA,0x24,0x39,0x03,0x31,0x57,0x57,0xFF,0x3F, + 0x44,0x41,0xE3,0x30,0x7D,0xF8,0xEE,0xFE,0x24,0x39,0xE3,0x30,0x37,0xAA,0x22,0x20, + 0x64,0x41,0x03,0x31,0x27,0x2D,0xAB,0x2A,0xC5,0x51,0x43,0x39,0xD5,0xBF,0xAF,0x2A, + 0x07,0x5A,0xA5,0x49,0xB5,0xBF,0xBF,0x3F,0x27,0x62,0xE6,0x59,0xC8,0xAE,0x05,0x27, + 0x27,0x62,0xE6,0x59,0x2F,0xBC,0xD6,0x78,0x47,0x62,0xE5,0x59,0x6A,0xA2,0xBD,0x2D, + 0x27,0x62,0xC5,0x59,0x6E,0xC0,0xC8,0xE0,0x68,0x6A,0xE6,0x59,0x3D,0xAD,0x35,0xA5, + 0x88,0x6A,0x27,0x62,0xBF,0xD7,0xDF,0x87,0xA9,0x6A,0x48,0x6A,0xEF,0xAE,0xCB,0xE7, + 0xA8,0x6A,0x48,0x6A,0x7B,0x7F,0x77,0xDF,0x68,0x6A,0x47,0x62,0x8B,0xE3,0xF2,0xE1, + 0xA9,0x72,0x27,0x62,0x2F,0xBB,0xB7,0xEB,0xA9,0x72,0x68,0x6A,0x2C,0x8F,0x3D,0xBD, + 0xA9,0x72,0x48,0x6A,0x0B,0x02,0x72,0xF0,0xC9,0x7A,0x67,0x6A,0x2A,0xBB,0xEB,0xFD, + 0xE9,0x7A,0x88,0x72,0x78,0x2E,0xD9,0x55,0xC9,0x7A,0x47,0x62,0x2F,0x94,0xBA,0xAA, + 0xC9,0x7A,0x88,0x72,0xBA,0xBA,0x2A,0xEF,0xC9,0x7A,0x67,0x6A,0xEA,0xA2,0x00,0x8A, + 0xC9,0x7A,0xA8,0x72,0x8A,0xE9,0x72,0xFC,0xE9,0x7A,0x88,0x72,0xE3,0xEE,0x77,0x5F, + 0xEA,0x7A,0xA9,0x72,0x62,0xEB,0x9D,0x5F,0x0A,0x7B,0xA8,0x72,0xEF,0xFD,0xFF,0x9F, + 0x0A,0x7B,0xA8,0x72,0xCB,0xF3,0x6B,0xAB,0xE9,0x7A,0xA8,0x72,0xEC,0xAD,0x8F,0x7F, + 0x0A,0x7B,0xA8,0x72,0xD7,0xA7,0x0E,0x3B,0x0A,0x83,0xA9,0x6A,0xEE,0xD7,0xF7,0xE2, + 0xEA,0x7A,0xA9,0x72,0xE8,0x47,0xBF,0x5F,0xEA,0x7A,0xA9,0x72,0xBF,0xFA,0xFB,0x7E, + 0xEA,0x7A,0xA9,0x72,0x3C,0xAA,0xBC,0x4F,0xEA,0x7A,0x89,0x72,0x9A,0xFE,0x0E,0x06, + 0xEA,0x7A,0xA9,0x72,0x7E,0xB3,0xAE,0xFF,0xEA,0x7A,0x88,0x6A,0xEF,0x58,0xA2,0x00, + 0x0B,0x83,0xA9,0x72,0x82,0xBD,0x97,0xBF,0x0A,0x7B,0xC9,0x7A,0xFC,0xAB,0x62,0xCE, + 0x0A,0x7B,0xA8,0x72,0xDF,0xBE,0x3B,0xA3,0x0A,0x83,0xC9,0x7A,0x83,0x01,0xC0,0xFE, + 0x23,0x41,0xC2,0x38,0xFE,0xBC,0xFF,0x7F,0x02,0x39,0xC2,0x38,0xA0,0xBE,0xBF,0x7D, + 0x23,0x41,0xC2,0x38,0x5E,0xFA,0xBB,0xCF,0xC2,0x40,0x03,0x39,0xFB,0xEF,0xAB,0x9F, + 0x03,0x41,0xC2,0x38,0x5E,0xAC,0xA9,0xBD,0x03,0x41,0xC2,0x38,0xD5,0xFF,0xEA,0xC0, + 0x23,0x41,0xC2,0x38,0xBD,0xD5,0xD7,0x7F,0x03,0x41,0xC2,0x38,0x98,0x9D,0xF7,0xD5, + 0x03,0x41,0xA1,0x30,0x9A,0xE2,0x88,0xAF,0x03,0x39,0xC2,0x38,0xFF,0xAF,0x0A,0x2B, + 0x03,0x41,0xC2,0x38,0xDB,0xF8,0x7A,0xF6,0xE2,0x38,0xC1,0x30,0x78,0x18,0x00,0x82, + 0xE2,0x38,0xC2,0x38,0x7F,0x70,0x60,0x0F,0x03,0x41,0xA1,0x30,0x7E,0xEF,0xAB,0xAA, + 0x03,0x41,0xC2,0x38,0x8B,0x79,0x7E,0xFE,0xE2,0x38,0xA2,0x30,0x00,0x8A,0xF0,0x20, + 0xE2,0x38,0xC2,0x38,0x73,0xEB,0x00,0xE0,0xE3,0x38,0xC2,0x38,0x2C,0xDE,0xD4,0xF0, + 0xE2,0x38,0xC2,0x38,0x0B,0xE2,0x6B,0xED,0x03,0x41,0xC2,0x38,0xDE,0x55,0xFB,0xE3, + 0x03,0x39,0xA2,0x30,0xE2,0x6A,0xFA,0xDE,0xC2,0x38,0x81,0x30,0xBE,0xAA,0x28,0x37, + 0xE2,0x38,0xA2,0x30,0x25,0x3F,0x0A,0x03,0x26,0x62,0xE2,0x38,0xBD,0x35,0x2D,0x2D, + 0xC8,0x7A,0x47,0x6A,0x7F,0xEA,0xE2,0xC0,0x47,0x6A,0xE5,0x59,0x7B,0x78,0x7A,0xEA, + 0xE6,0x59,0x64,0x49,0xFC,0x7E,0x72,0x7A,0x43,0x41,0xC2,0x30,0xDE,0xDE,0xFE,0xF2, + 0x23,0x39,0xE2,0x30,0xF3,0x59,0xDE,0xFF,0x03,0x39,0xC2,0x28,0x7B,0xEB,0xAE,0xF0, + 0x03,0x31,0xE3,0x30,0x40,0x7A,0xDF,0xD7,0x03,0x31,0xC3,0x30,0x82,0x8A,0x3E,0xDE, + 0x03,0x31,0xE3,0x30,0x35,0xD7,0x57,0x59,0x03,0x31,0xC3,0x30,0xE0,0xF2,0xB0,0xB0, + 0x03,0x31,0xE3,0x30,0xB5,0x65,0x65,0xBD,0x03,0x31,0xC2,0x28,0xFF,0xFE,0xFA,0xA2, + 0xE2,0x30,0xC2,0x28,0x02,0x09,0x0B,0x30,0x03,0x31,0xC2,0x30,0xAB,0xD7,0xFF,0xFB, + 0xE3,0x30,0xC3,0x28,0x3A,0xAC,0x08,0xAA,0x03,0x31,0xC3,0x30,0xA2,0x8B,0x0A,0xA9, + 0xE3,0x30,0xC2,0x30,0x00,0x0C,0x83,0xD8,0xE3,0x30,0xC2,0x28,0x08,0x8C,0xB8,0x60, + 0x03,0x31,0xC2,0x28,0xBE,0xFB,0xA9,0xEB,0x03,0x39,0xC3,0x28,0xB7,0xF7,0xAA,0xEB, + 0x03,0x31,0xC2,0x30,0x9F,0x0E,0xEA,0xEB,0x03,0x31,0xC3,0x30,0x0F,0x2B,0x2F,0xAF, + 0x03,0x31,0xE3,0x30,0x86,0xE7,0x77,0xBD,0xA2,0x38,0x03,0x31,0xDF,0x7F,0xFF,0xBD, + 0x03,0x39,0xC2,0x30,0xB8,0xD8,0xDE,0xC2,0x03,0x39,0xC2,0x30,0x2F,0x1D,0x9F,0xDF, + 0x03,0x31,0xC2,0x30,0x97,0x08,0x0C,0x2A,0x03,0x39,0xE2,0x30,0xC0,0xE3,0xB6,0xA8, + 0x03,0x39,0xE2,0x30,0x32,0xBF,0xFF,0xA3,0x24,0x39,0xC2,0x30,0xA8,0xF7,0x9D,0xFF, + 0xE3,0x38,0xA2,0x30,0xB8,0xBE,0xBE,0xEE,0x03,0x39,0xC2,0x30,0xA2,0xA3,0xB9,0x0D, + 0x03,0x39,0xC3,0x30,0xB0,0xC8,0xAA,0xEA,0x24,0x39,0xC2,0x30,0x2B,0xFF,0x67,0xFE, + 0x03,0x39,0xE3,0x30,0x1B,0x15,0x2D,0x01,0x03,0x39,0xC3,0x30,0x00,0x0A,0xAE,0x3E, + 0x23,0x39,0xE3,0x30,0x8E,0x27,0x97,0x35,0x23,0x39,0xE3,0x38,0x7F,0xB0,0xAF,0xB7, + 0x03,0x39,0xC3,0x30,0x3B,0x07,0xFF,0x20,0x24,0x39,0xE3,0x30,0x7F,0x6E,0xAB,0xB8, + 0x44,0x41,0xE3,0x30,0xEB,0xEA,0x6A,0xDB,0x24,0x39,0xC2,0x30,0xBA,0xB6,0xBB,0x2A, + 0x03,0x39,0xE3,0x38,0x28,0x20,0xA0,0x28,0x24,0x41,0xE3,0x30,0xFE,0xDE,0xAB,0x03, + 0x24,0x39,0xE3,0x30,0x9F,0xD5,0x2E,0xAC,0x23,0x39,0xE2,0x30,0x2B,0x20,0x20,0x7A, + 0x44,0x39,0xE2,0x30,0x2E,0xAA,0xFE,0xF5,0x44,0x39,0xE2,0x30,0xAA,0xA8,0xA7,0xBD, + 0x44,0x39,0x03,0x31,0x2D,0x2B,0x9F,0x2E,0x44,0x39,0x03,0x39,0x57,0xFE,0xEB,0xA2, + 0x44,0x39,0xE3,0x30,0xEF,0x76,0xA8,0xE0,0x24,0x39,0x03,0x31,0xF9,0xF5,0x8B,0x03, + 0x44,0x39,0x03,0x31,0xB5,0xAA,0xEA,0x08,0x24,0x39,0xE3,0x30,0xBE,0xBC,0xA8,0x8A, + 0x24,0x39,0xC2,0x30,0xBF,0xF6,0x2E,0xA8,0x24,0x39,0xE3,0x30,0xB8,0x5A,0xFE,0xCA, + 0x24,0x39,0xE3,0x30,0xDA,0xBF,0xBD,0x23,0x24,0x39,0xE3,0x30,0x56,0xBE,0xFD,0xCE, + 0x24,0x39,0xE3,0x30,0xBA,0xCE,0x6B,0xCB,0x24,0x39,0xE3,0x30,0xB0,0xAB,0x69,0x6A, + 0x45,0x41,0xC2,0x30,0xF7,0xF7,0xAF,0xA8,0x24,0x39,0x03,0x31,0x9D,0xF5,0x96,0xA6, + 0x24,0x39,0xE3,0x30,0xEB,0xEA,0xEA,0x8B,0x24,0x39,0xE3,0x30,0x20,0x02,0x07,0x89, + 0x65,0x41,0x03,0x39,0x5C,0xF5,0xF7,0xF5,0x65,0x49,0x03,0x39,0xF7,0xFA,0xA3,0x8A, + 0xA6,0x49,0x44,0x41,0x7D,0x75,0x7F,0x0B,0xE7,0x51,0x65,0x41,0x3D,0xAD,0x2B,0x8A, + 0x06,0x5A,0xA5,0x51,0x9A,0xAB,0x2A,0x8A,0x07,0x62,0xA5,0x51,0xFE,0x9B,0xC2,0xE0, + 0x27,0x62,0xC6,0x59,0xC0,0xFE,0x5F,0x95,0x47,0x62,0xE6,0x59,0x3F,0xBD,0xBB,0x8F, + 0x88,0x6A,0xE6,0x59,0xD7,0xFB,0xA2,0xEA,0x68,0x62,0x06,0x5A,0xB7,0x3E,0x8A,0xEA, + 0x89,0x6A,0x27,0x62,0x89,0x0D,0xE9,0xEF,0x88,0x72,0x47,0x62,0xCA,0x79,0xFB,0xFE, + 0xA9,0x72,0x48,0x62,0xFE,0x6A,0x7B,0x7C,0x88,0x6A,0x48,0x6A,0xFF,0xAF,0xF5,0xFF, + 0x88,0x72,0x48,0x6A,0xE8,0x7E,0xFF,0x2F,0xA9,0x72,0x68,0x6A,0xDD,0xD5,0xE9,0x8A, + 0xA9,0x72,0x68,0x6A,0x76,0x9C,0xFE,0xBB,0xA9,0x72,0x47,0x6A,0xEC,0x98,0x37,0xB7, + 0xC9,0x72,0x88,0x6A,0x55,0x53,0x2A,0x8D,0xC9,0x72,0x88,0x72,0xED,0xAE,0xB8,0xB6, + 0xE9,0x7A,0x88,0x72,0x6F,0xFF,0x5E,0xF8,0xC9,0x7A,0x88,0x72,0x6F,0xAF,0xDA,0x8B, + 0xA8,0x72,0x48,0x6A,0x08,0x0A,0xDC,0xF8,0xC9,0x7A,0x68,0x6A,0x2A,0xBC,0xF7,0xFA, + 0xE9,0x7A,0x88,0x72,0x7A,0xE6,0x0F,0xAB,0xC9,0x72,0x68,0x6A,0x32,0x76,0xFF,0xBC, + 0xE9,0x7A,0x88,0x72,0xA8,0x2B,0xF2,0xB5,0x0A,0x7B,0xA8,0x72,0x5F,0x77,0xC3,0x3A, + 0xEA,0x72,0x88,0x6A,0x3F,0xFE,0x6A,0xEC,0x0A,0x7B,0xA9,0x72,0x8A,0xAF,0xF7,0x7F, + 0xEA,0x7A,0x88,0x6A,0xBA,0x22,0x7A,0xEB,0xEA,0x7A,0xA9,0x72,0x5B,0xA0,0xA9,0x29, + 0xEA,0x7A,0x88,0x6A,0x0F,0xAB,0xA7,0x0F,0x0B,0x83,0x67,0x6A,0x0A,0xC2,0xFE,0x97, + 0xE9,0x7A,0xA9,0x72,0xDF,0xBE,0xA3,0x4F,0x2A,0x7B,0xCA,0x7A,0xED,0x7D,0xFF,0x6F, + 0x0A,0x7B,0xC9,0x7A,0x72,0xBF,0x2F,0x2F,0x2A,0x83,0xC9,0x72,0xF5,0xCF,0xC3,0xEB, + 0xE9,0x7A,0x87,0x6A,0xC0,0x40,0xAA,0xA8,0x0A,0x7B,0xA9,0x72,0xE5,0x25,0xAC,0xEF, + 0x03,0x41,0xC2,0x38,0xEE,0xC8,0xF6,0xE6,0x03,0x41,0xC2,0x38,0xA9,0xCB,0xCF,0xEF, + 0x03,0x41,0xE2,0x38,0xE7,0x55,0x85,0xA9,0x03,0x41,0xC2,0x38,0x8B,0xFB,0x7A,0x68, + 0x03,0x41,0xC2,0x38,0xBA,0xFB,0xA1,0xCB,0x23,0x41,0xC2,0x38,0xEA,0x3B,0xDE,0x9A, + 0xC3,0x40,0x02,0x39,0xFF,0xBF,0xF5,0xDF,0x03,0x41,0xC2,0x38,0xD7,0x2D,0xE2,0xFA, + 0x03,0x41,0xA2,0x30,0xBF,0xFF,0x62,0xCA,0xE3,0x38,0xA1,0x30,0xB0,0x9F,0xAD,0x3D, + 0xE2,0x38,0xC2,0x30,0x2F,0x7C,0x20,0x80,0x03,0x41,0xC2,0x38,0x3F,0x2D,0x8B,0xBF, + 0x03,0x41,0xA1,0x30,0xBE,0xB6,0xAE,0x82,0x03,0x41,0xC2,0x38,0xF6,0xFF,0x26,0xBA, + 0x03,0x41,0xC2,0x38,0xFF,0xDF,0x7A,0x8F,0xC2,0x38,0xE2,0x30,0x3A,0xA2,0x20,0x2B, + 0xC2,0x38,0xE2,0x30,0xAA,0x80,0x20,0xAB,0x03,0x41,0xA1,0x30,0xEB,0xEF,0xF9,0x8E, + 0x03,0x39,0xC2,0x38,0x7F,0x7F,0x7E,0xFE,0x03,0x39,0xA2,0x30,0xE3,0xE3,0xEB,0x7A, + 0xE2,0x38,0x81,0x30,0x62,0x5E,0xBA,0xAF,0xE3,0x38,0x81,0x28,0x97,0xA7,0x82,0x88, + 0x03,0x39,0xA2,0x30,0xE1,0xEB,0xFD,0xB5,0xC7,0x7A,0xE2,0x38,0x2D,0x2D,0x2D,0x25, + 0x08,0x83,0x67,0x6A,0xE2,0x6A,0xFA,0xEA,0x67,0x6A,0x64,0x49,0xA8,0xE8,0xE0,0x78, + 0xC5,0x59,0x03,0x39,0xF0,0xFE,0xD6,0x57,0x44,0x41,0xE2,0x30,0xEB,0xF2,0x72,0xEA, + 0x23,0x39,0xC2,0x28,0x2A,0xFA,0x6F,0xEE,0x03,0x31,0xC2,0x28,0xB0,0xA9,0xFD,0xE9, + 0x03,0x31,0xC2,0x28,0xAB,0xEE,0xAF,0xAF,0x03,0x31,0xC2,0x30,0xF2,0x82,0xB2,0xA1, + 0x03,0x31,0xC3,0x30,0xEB,0x01,0x2F,0xBA,0x03,0x31,0xC2,0x28,0xE2,0xE8,0x80,0x42, + 0x03,0x31,0xC2,0x28,0x3E,0x2B,0x2A,0xAD,0x03,0x31,0xC3,0x30,0x0E,0x0B,0xE8,0xF8, + 0xE3,0x30,0xC2,0x28,0xEC,0xCE,0xA7,0x02,0x03,0x31,0xC3,0x30,0xBD,0x9D,0xD7,0xBF, + 0xE3,0x30,0xC2,0x28,0xA2,0xEA,0xF0,0xE7,0xE3,0x30,0xC2,0x28,0x02,0x01,0x6A,0x86, + 0x03,0x31,0xC3,0x30,0xFA,0x2E,0x63,0x63,0x03,0x31,0xC2,0x28,0xFA,0x92,0xDB,0xBF, + 0x03,0x31,0xC2,0x30,0xFE,0xFE,0xAB,0x8E,0x03,0x31,0xC3,0x30,0x7B,0xFF,0x2A,0x0E, + 0x03,0x31,0xA2,0x28,0xFA,0xD6,0xFE,0xCC,0xE3,0x30,0xA2,0x28,0x22,0xFA,0xA1,0x0B, + 0x03,0x31,0xC2,0x28,0x2A,0xA9,0x5F,0x7E,0x03,0x31,0xC2,0x30,0x7C,0xF7,0x65,0x73, + 0xE3,0x30,0xC2,0x28,0x00,0x2B,0x95,0xDA,0x23,0x39,0xC2,0x28,0xF2,0xCB,0xF7,0xB7, + 0x03,0x31,0xE2,0x30,0xC3,0xC2,0xCF,0x57,0x23,0x31,0xC2,0x30,0xA7,0x6E,0xE3,0xE3, + 0x03,0x31,0xC2,0x30,0x02,0x20,0xEC,0x68,0x03,0x39,0xC2,0x30,0x88,0x00,0xF8,0x0B, + 0x03,0x39,0xC2,0x30,0x7E,0xEA,0xA2,0x0A,0x03,0x39,0xC3,0x30,0x2A,0x37,0xAB,0xDB, + 0x24,0x39,0xE3,0x30,0xEE,0xAA,0xAE,0xF5,0x24,0x39,0xC3,0x30,0xC2,0x7A,0xB8,0xB2, + 0x24,0x39,0xE3,0x30,0xA9,0xAF,0xAB,0xB7,0x24,0x39,0xE3,0x30,0x55,0xDE,0xF7,0x7A, + 0x24,0x41,0xE3,0x30,0x09,0xBE,0xBD,0x65,0x24,0x39,0xE3,0x38,0xB4,0x36,0xF4,0xD7, + 0x24,0x41,0xC3,0x30,0x8A,0x88,0xE3,0xDA,0x24,0x39,0xE3,0x38,0x57,0xFB,0xE2,0x2F, + 0x24,0x39,0xE3,0x38,0x6D,0x7A,0x72,0xEC,0x24,0x39,0xE3,0x38,0x33,0x3B,0x39,0xB7, + 0x24,0x39,0xE3,0x30,0xBF,0xB6,0xA2,0xA2,0x24,0x39,0x03,0x39,0xBE,0x55,0x5F,0x55, + 0x23,0x39,0xE4,0x30,0xFA,0xEA,0xEB,0xA2,0x03,0x39,0xC2,0x30,0x3F,0xBF,0xEE,0x02, + 0x24,0x39,0xE3,0x30,0xDF,0xD7,0xFC,0xAB,0x03,0x31,0xC2,0x30,0x22,0xBF,0x2E,0x00, + 0x24,0x39,0xE2,0x30,0x3A,0xBF,0x78,0xA8,0x65,0x41,0xE3,0x30,0xE3,0xBB,0xA5,0xA7, + 0x64,0x41,0x04,0x31,0x7B,0xEE,0xF0,0xAB,0x44,0x39,0x03,0x31,0xAA,0xE2,0xE8,0x70, + 0x44,0x41,0x24,0x39,0xCB,0x79,0x55,0x35,0x44,0x39,0x04,0x39,0x6A,0x6B,0x7A,0xBA, + 0x24,0x41,0x03,0x31,0xF7,0xBE,0xA7,0x0E,0x64,0x41,0x03,0x39,0xFD,0xF7,0xE5,0xFF, + 0x44,0x41,0xE3,0x30,0xF2,0xE2,0xC2,0xAA,0x44,0x39,0xE3,0x30,0x62,0x62,0xBB,0xAB, + 0x44,0x41,0xE3,0x30,0xEB,0x73,0xBA,0xB2,0x24,0x41,0x03,0x31,0x7F,0xAF,0xBB,0x08, + 0x44,0x41,0xE3,0x30,0xB7,0xFB,0xBA,0xA8,0x44,0x41,0x03,0x39,0x7E,0xFA,0x2F,0x01, + 0x65,0x41,0x03,0x39,0xDD,0xF7,0xCA,0x23,0x65,0x41,0x04,0x39,0x75,0xF7,0x2E,0x0C, + 0xC6,0x51,0xE3,0x38,0x5F,0x5F,0xAF,0x2B,0xC6,0x51,0x24,0x39,0xBD,0xFD,0x2B,0x00, + 0x27,0x62,0x85,0x49,0xF5,0xBD,0xA3,0xA2,0x27,0x62,0xA5,0x49,0xBD,0xFE,0xAE,0x0A, + 0x27,0x62,0xC6,0x51,0xED,0xEF,0xFA,0xA8,0x07,0x62,0xE6,0x59,0xBA,0x95,0xB5,0x2F, + 0x47,0x6A,0xE6,0x59,0xBD,0xAB,0x02,0x80,0x47,0x62,0x07,0x62,0x3D,0x62,0x02,0x00, + 0x88,0x6A,0x27,0x62,0xD2,0x42,0x7D,0x5F,0x68,0x6A,0x07,0x62,0xAE,0xAA,0x1F,0xBD, + 0xA8,0x72,0x47,0x6A,0x7D,0xAA,0xAF,0xDF,0xA9,0x72,0x47,0x62,0xA7,0xBF,0xB8,0xFA, + 0xA8,0x72,0x48,0x62,0xEF,0x5E,0xFE,0xA8,0xA9,0x72,0x27,0x62,0xAA,0x3E,0xA7,0x2A, + 0xA9,0x72,0x68,0x6A,0xD6,0x77,0xCF,0x9E,0xCA,0x72,0x48,0x6A,0xAD,0xAB,0xAB,0x78, + 0xA8,0x72,0x47,0x62,0xAA,0x2E,0xFF,0xB8,0xA9,0x72,0x67,0x6A,0xEE,0x46,0xA0,0x02, + 0xA8,0x72,0x47,0x62,0x0B,0x89,0x27,0x02,0xC9,0x7A,0x88,0x6A,0xAA,0x9B,0x6F,0xE1, + 0xEA,0x7A,0x67,0x6A,0xF8,0xB6,0xBF,0xFD,0xC9,0x72,0xA8,0x72,0xAD,0x15,0xBF,0x7A, + 0xC9,0x72,0x68,0x6A,0x7C,0xFB,0xC9,0xAB,0xC9,0x72,0x89,0x72,0x43,0x89,0xBF,0xAA, + 0xEB,0x7A,0xA9,0x72,0xD5,0xD5,0xF3,0xAF,0xC9,0x72,0x88,0x6A,0xF5,0xF5,0x96,0xE2, + 0xC8,0x72,0x68,0x6A,0xFE,0xFA,0x2B,0x1F,0xC9,0x72,0x67,0x6A,0x30,0xAE,0xEA,0xAA, + 0xC9,0x72,0x88,0x72,0x00,0x0B,0x3D,0x9A,0xE9,0x7A,0x68,0x6A,0x68,0xEA,0xBC,0xFA, + 0xEA,0x7A,0x88,0x6A,0xD5,0xBB,0xA3,0xAD,0xEA,0x7A,0xA9,0x72,0x81,0x02,0x7E,0xAD, + 0xEA,0x7A,0xA9,0x72,0x39,0x28,0x03,0x2A,0x0A,0x7B,0xA8,0x72,0x56,0x8E,0x2C,0xBE, + 0x0A,0x7B,0xA9,0x72,0x57,0xF5,0x70,0xA0,0x0B,0x83,0x89,0x72,0x8F,0x6F,0x6F,0x9F, + 0xE9,0x7A,0xA9,0x72,0x0C,0x23,0x6E,0xD6,0x0A,0x7B,0xC9,0x72,0xE3,0xBD,0xBF,0xAD, + 0x2B,0x83,0xC9,0x72,0x5F,0x77,0xD7,0x2A,0x2B,0x83,0xA8,0x72,0xAF,0xAB,0xA6,0xF0, + 0x23,0x41,0xC2,0x38,0x54,0x5E,0x5E,0x5E,0x03,0x41,0xC2,0x38,0xBF,0x81,0xF9,0xA3, + 0x02,0x41,0xC2,0x38,0x8A,0x2A,0xBA,0xB5,0x03,0x41,0xE2,0x38,0xF3,0xD5,0xF7,0x56, + 0x03,0x41,0xC2,0x38,0x7C,0xE8,0xAA,0xF7,0x23,0x41,0xE2,0x38,0x73,0xEB,0xF5,0x55, + 0x03,0x39,0xC2,0x38,0x76,0xDE,0x90,0xDA,0x03,0x41,0xC2,0x38,0x6E,0x6E,0xFA,0xAA, + 0xE2,0x38,0xC2,0x30,0x0B,0x8D,0x27,0xDE,0x02,0x41,0xA1,0x30,0xB7,0xBA,0xAE,0xA8, + 0xE2,0x38,0xC1,0x38,0x40,0xFA,0x4B,0x7C,0xE2,0x38,0xC1,0x30,0x6E,0x37,0x22,0x01, + 0x02,0x41,0xA2,0x30,0xAA,0x86,0x22,0xE2,0x03,0x41,0xC2,0x38,0x7F,0xFA,0xF8,0xDF, + 0xE2,0x38,0xC2,0x38,0x29,0xB5,0xD8,0x3B,0xE2,0x38,0xC2,0x38,0xAF,0xBA,0x58,0xDF, + 0x03,0x39,0xC2,0x38,0xFB,0xD7,0x95,0xBA,0x03,0x39,0xC2,0x38,0xFE,0xBB,0x6A,0x58, + 0xE2,0x38,0xA2,0x30,0xAA,0xB8,0xFA,0xEE,0xC2,0x30,0x82,0x30,0xB0,0xF8,0xBA,0xB2, + 0x03,0x39,0xA2,0x30,0xF5,0xA5,0x2F,0xAF,0xE2,0x38,0xC2,0x30,0x0B,0x2C,0xF6,0x74, + 0xE2,0x38,0xA2,0x30,0xDF,0x5E,0x7A,0xFB,0x87,0x72,0xE2,0x38,0x0D,0x2D,0xBD,0xD5, + 0xA7,0x72,0x64,0x49,0x00,0xA8,0x7F,0x55,0x26,0x62,0x23,0x41,0x78,0x5E,0x7F,0x75, + 0x24,0x41,0xE3,0x38,0x1F,0xFB,0xE8,0xA0,0x23,0x39,0xE2,0x30,0xF8,0xD7,0xDF,0xEE, + 0x24,0x39,0xE2,0x30,0xFF,0x89,0x66,0x7E,0x03,0x31,0xC2,0x30,0xA8,0x33,0xBB,0xEA, + 0x23,0x39,0xE3,0x30,0xD5,0x75,0x75,0xDE,0x03,0x31,0xC3,0x30,0x0B,0xB7,0xF3,0xB0, + 0x03,0x31,0xC2,0x28,0xAF,0x7E,0xAB,0xC8,0x03,0x31,0xC3,0x30,0xF6,0xEE,0xAE,0xA7, + 0x23,0x39,0xC2,0x30,0x3D,0xFF,0xD7,0xDB,0x03,0x31,0xC2,0x30,0xFE,0xEE,0xAE,0xEA, + 0xE3,0x30,0xC2,0x28,0x2D,0x35,0x28,0x08,0x03,0x31,0xC2,0x30,0xE5,0x5E,0xAC,0xEB, + 0xE2,0x30,0xA2,0x28,0xA9,0xA7,0x2A,0x00,0xE2,0x30,0xC2,0x28,0x2F,0x0B,0xA8,0xA0, + 0x23,0x31,0xC2,0x30,0x6B,0xFF,0x7D,0x5F,0x03,0x31,0xC2,0x30,0xEF,0x2F,0x2F,0x3A, + 0x03,0x39,0xE3,0x30,0x55,0x55,0xB7,0x5E,0x24,0x39,0xE3,0x30,0xBF,0xDF,0xEF,0xED, + 0x03,0x39,0xC2,0x30,0xFE,0xFE,0xF8,0xF8,0x03,0x31,0xC2,0x28,0x97,0xD5,0xE6,0x0F, + 0x24,0x39,0xC2,0x28,0xF7,0xBF,0xB5,0xAF,0x03,0x31,0xC2,0x30,0xF2,0xC8,0xAA,0xCA, + 0xE3,0x30,0xC2,0x28,0xA2,0x7F,0xE6,0x20,0x03,0x31,0xC2,0x28,0xB6,0xAF,0xF7,0x7E, + 0x03,0x31,0xC2,0x30,0xFF,0xB6,0xBF,0xAD,0x04,0x31,0xE2,0x30,0xFD,0xF3,0x1E,0x25, + 0x03,0x31,0xC2,0x28,0xDF,0x7F,0x70,0x80,0x03,0x31,0xC2,0x30,0xAB,0xEB,0xFD,0xEA, + 0x03,0x31,0xE3,0x30,0x09,0x7B,0x7A,0x55,0x03,0x39,0xC3,0x30,0xB2,0xBE,0xA8,0xF7, + 0x03,0x39,0xE3,0x30,0xF5,0xBE,0x1B,0xBE,0x24,0x39,0xE3,0x30,0x7F,0xBF,0xFB,0xB2, + 0x24,0x39,0xE3,0x30,0xD6,0x7E,0xDA,0x7A,0x24,0x41,0x03,0x31,0xFF,0xEB,0xE3,0x8D, + 0x03,0x39,0xE3,0x30,0x55,0x77,0xE0,0xF8,0x24,0x41,0xE3,0x38,0xF5,0xBD,0xBD,0xD2, + 0x24,0x39,0xE3,0x30,0x57,0xAE,0x3A,0xAA,0x24,0x39,0xC3,0x38,0x0B,0xAA,0xBE,0xAA, + 0xE3,0x38,0x24,0x31,0xEA,0xAA,0xAE,0xA6,0x24,0x41,0xE3,0x30,0xEF,0x8A,0x88,0xAD, + 0x44,0x39,0xE3,0x38,0x7D,0xFD,0xF9,0xBF,0x24,0x39,0xC3,0x38,0xBA,0xAA,0x82,0x20, + 0x24,0x39,0x03,0x39,0x3E,0x6E,0xA0,0x5C,0x23,0x39,0xE3,0x30,0x09,0x2A,0xBA,0xDB, + 0x24,0x39,0x03,0x31,0x5A,0xB2,0x8B,0x7D,0x23,0x39,0xE3,0x30,0x00,0xF0,0x6A,0xAF, + 0x44,0x39,0x03,0x31,0xFD,0x8F,0xCF,0x67,0x65,0x41,0xE3,0x30,0xCF,0xEF,0x79,0xBF, + 0x44,0x39,0xE3,0x30,0x2B,0xAF,0xFF,0xF7,0x23,0x39,0xE3,0x30,0x00,0xB8,0xEE,0x7E, + 0x64,0x41,0xC2,0x30,0x2A,0xAF,0xFF,0x77,0x44,0x41,0x04,0x39,0x2C,0x20,0xAA,0x15, + 0x65,0x49,0x24,0x41,0x7E,0xEE,0xFB,0x0A,0x64,0x41,0x03,0x39,0x5A,0xFA,0xEA,0x28, + 0x64,0x41,0x03,0x39,0xFF,0xA5,0xAE,0x3C,0x86,0x49,0x03,0x39,0xF7,0xAD,0x8A,0x88, + 0x65,0x41,0x04,0x39,0xDF,0xEB,0x38,0x00,0x85,0x49,0x24,0x39,0xD5,0xBF,0xBB,0x02, + 0x85,0x49,0x24,0x39,0x7D,0xFF,0xB8,0xE0,0xA6,0x51,0x23,0x39,0xF9,0xEB,0x8A,0xAA, + 0x85,0x49,0x24,0x41,0xF7,0x0A,0x02,0x8E,0xA5,0x51,0x44,0x41,0xD5,0xAE,0xFE,0x0B, + 0xE6,0x59,0x85,0x49,0x95,0x3D,0x3F,0xDF,0x06,0x5A,0xC6,0x51,0xBF,0x3F,0xE3,0x9B, + 0x27,0x62,0xC5,0x51,0x20,0x08,0xA9,0x29,0x47,0x62,0x06,0x5A,0xD5,0xF5,0x7D,0xBD, + 0x48,0x6A,0x07,0x5A,0xFF,0xAF,0xA5,0x27,0x48,0x62,0xE6,0x59,0xF7,0xBA,0x2F,0x87, + 0x68,0x6A,0x06,0x5A,0xFA,0xEA,0x8B,0x87,0x67,0x6A,0x27,0x62,0x4A,0xB0,0x3E,0xBF, + 0x68,0x6A,0x06,0x5A,0x2A,0xBE,0x7C,0x7B,0x88,0x6A,0x27,0x62,0x97,0xD9,0xBD,0x0F, + 0xA8,0x72,0x47,0x62,0xDF,0xBF,0xCA,0x82,0xC9,0x72,0x67,0x6A,0x2B,0x35,0xD5,0x57, + 0xA8,0x72,0x68,0x6A,0xBB,0xE8,0xA8,0xFF,0xA9,0x72,0x47,0x62,0xDF,0x55,0x6B,0x2A, + 0xA9,0x72,0x47,0x62,0x9E,0xB5,0x27,0xBE,0xC9,0x72,0x88,0x6A,0x7A,0xEA,0x6A,0xCF, + 0xA9,0x72,0x47,0x62,0xEA,0x22,0x09,0x02,0xC9,0x72,0x88,0x6A,0x39,0x96,0x5F,0x57, + 0xC9,0x72,0x88,0x72,0x80,0xEA,0xBE,0xFD,0xC9,0x7A,0x68,0x6A,0xC9,0xAB,0xAA,0xB7, + 0xC9,0x72,0x67,0x6A,0xC9,0xE0,0xA8,0xDA,0xA8,0x72,0x68,0x6A,0x70,0x9F,0xDF,0xEA, + 0xC9,0x7A,0x68,0x6A,0xFA,0xBF,0xB3,0xA5,0xA9,0x72,0x68,0x6A,0x2E,0xAA,0x98,0xDB, + 0xCA,0x7A,0x68,0x6A,0x28,0xBF,0xFE,0xEF,0xC9,0x72,0x68,0x6A,0xE0,0xAE,0x89,0xB9, + 0xC9,0x7A,0x68,0x6A,0xB7,0x05,0x8E,0xEA,0xE9,0x7A,0x88,0x6A,0xBB,0xBA,0xA2,0xD5, + 0xEA,0x7A,0x88,0x6A,0x7A,0xE8,0x5A,0x79,0xCA,0x7A,0x67,0x6A,0x8A,0xC1,0x2B,0x0A, + 0xC9,0x72,0x89,0x72,0x99,0xB7,0x26,0xB2,0xC9,0x72,0x68,0x6A,0x28,0xAB,0xF7,0xFC, + 0xC9,0x72,0x26,0x62,0x00,0x00,0x02,0xA6,0xE9,0x7A,0x87,0x6A,0xBA,0xEE,0xA3,0xA7, + 0xEA,0x7A,0x88,0x6A,0x02,0xAB,0xFB,0xFA,0xCA,0x7A,0x68,0x6A,0x39,0xFA,0x2A,0x0F, + 0xCA,0x7A,0x68,0x6A,0x0A,0x8D,0x2A,0xAB,0x0A,0x83,0xA9,0x72,0x2B,0xAF,0xF5,0x56, + 0x0A,0x7B,0xC9,0x72,0xEA,0xF8,0xFB,0x95,0x0A,0x7B,0xA8,0x72,0xA0,0x7E,0xDA,0x7F, + 0x03,0x41,0xC2,0x38,0xFF,0x9B,0x73,0xDB,0x03,0x41,0xC2,0x38,0x6A,0x50,0xF2,0xE2, + 0x03,0x41,0xA2,0x38,0xEF,0xF2,0x7A,0x6B,0x02,0x39,0xA1,0x30,0xAB,0xA3,0xF9,0xFB, + 0x02,0x41,0xA2,0x30,0xBE,0xAA,0x26,0x8F,0x03,0x39,0xC2,0x38,0xFF,0xE8,0xBC,0xF6, + 0xE2,0x38,0xA1,0x30,0xA0,0xFA,0xD7,0xD7,0xE3,0x38,0xA1,0x30,0x02,0x83,0xBE,0x16, + 0xE2,0x38,0xA2,0x30,0xAA,0xA3,0x8A,0x00,0x02,0x39,0xC2,0x38,0xAE,0xD6,0xAF,0x99, + 0xE2,0x38,0xA1,0x30,0xA0,0xF0,0xDE,0xAA,0x03,0x41,0xC2,0x38,0xDF,0xAF,0x2F,0x79, + 0x03,0x39,0xC2,0x38,0x9A,0xEC,0xFE,0xEF,0x02,0x39,0xA1,0x38,0xEA,0xA8,0x6A,0xBA, + 0xE2,0x38,0xA2,0x30,0xFA,0xAB,0xA3,0xA0,0xE2,0x38,0xC2,0x38,0x05,0xA3,0xC2,0x60, + 0xE2,0x38,0xC2,0x30,0x02,0x8F,0xBF,0xEF,0xE2,0x38,0x81,0x30,0xB0,0xDB,0xD3,0x7A, + 0xE3,0x38,0xA2,0x30,0x4A,0x7A,0xDD,0xFD,0x03,0x39,0xA2,0x30,0x5D,0x9D,0x35,0xDD, + 0x03,0x39,0xC2,0x30,0x9A,0xEA,0xEA,0xDF,0x03,0x39,0xA2,0x28,0xBC,0x18,0xEE,0xEB, + 0x03,0x39,0x81,0x30,0xBE,0xEC,0xBF,0x7D,0xE3,0x38,0xA1,0x30,0x0B,0xAB,0xFF,0x75, + 0x23,0x41,0xA2,0x30,0x0B,0xEF,0x7D,0xDF,0x24,0x41,0x81,0x30,0x82,0xAE,0xFF,0xD7, + 0x24,0x41,0xA1,0x30,0xA0,0xBA,0xFF,0xD5,0x23,0x39,0xE3,0x30,0xAE,0xAA,0x7B,0x69, + 0x03,0x39,0xC2,0x30,0xFA,0xF2,0xFF,0xFF,0x03,0x31,0xC2,0x30,0x29,0x35,0xBF,0xFF, + 0x03,0x31,0xC2,0x28,0x80,0xBE,0xFB,0xFD,0x24,0x39,0xC3,0x28,0xDA,0x7B,0xCF,0xFA, + 0x24,0x39,0xC2,0x30,0x73,0x6D,0xDD,0x97,0xE3,0x30,0xC3,0x28,0x0B,0xE3,0xA2,0xE8, + 0x03,0x31,0xC3,0x30,0xBA,0x3E,0xAA,0xAB,0x03,0x31,0xC2,0x28,0xA8,0xE0,0x6A,0xFA, + 0xE3,0x30,0xC2,0x28,0x18,0x1F,0x8F,0xBF,0x03,0x31,0xC2,0x30,0xE7,0xFE,0xBF,0xFD, + 0x03,0x31,0xC2,0x28,0xEB,0xE7,0xDE,0x73,0x03,0x31,0xC2,0x28,0xEA,0xAB,0xEC,0xDD, + 0xE3,0x30,0xC2,0x28,0xB2,0xD7,0x80,0x3A,0x24,0x39,0xC2,0x30,0x2B,0xEB,0xB9,0x5B, + 0x23,0x39,0xC3,0x30,0xFE,0xF9,0xEA,0xE2,0x24,0x39,0xC2,0x30,0x82,0x7B,0xFD,0xD7, + 0x03,0x39,0xE3,0x30,0xE7,0x75,0x55,0x54,0x04,0x39,0xE3,0x30,0x09,0x55,0x55,0x55, + 0xE3,0x30,0xC2,0x30,0x08,0xA0,0xB0,0x00,0x03,0x31,0xC2,0x28,0x8F,0x8A,0x2A,0xA7, + 0x03,0x31,0xC2,0x30,0x80,0xAA,0xB5,0x36,0x03,0x31,0xC3,0x30,0xFE,0xF0,0xFE,0xEE, + 0x03,0x39,0xA2,0x30,0xAB,0xFA,0xED,0xBE,0x24,0x39,0xC2,0x30,0x0F,0x0F,0xBB,0xF7, + 0x24,0x39,0xC2,0x30,0xA7,0x3E,0xBF,0xEF,0x03,0x39,0xC3,0x30,0x76,0xEE,0xCA,0x80, + 0x03,0x31,0xA2,0x30,0xAA,0x22,0xAA,0xB2,0x03,0x31,0xC2,0x30,0xDE,0xBA,0x2B,0x3A, + 0x03,0x31,0xC2,0x30,0xAA,0xB8,0x70,0x70,0x03,0x31,0xC2,0x28,0x00,0x20,0xBF,0x2D, + 0x03,0x39,0xE3,0x30,0xE8,0xA6,0x5E,0x5F,0x24,0x39,0xE3,0x30,0x2F,0x2F,0x77,0x75, + 0x03,0x39,0xE3,0x30,0x8B,0x20,0x20,0x3A,0x24,0x39,0x03,0x39,0x7F,0x6F,0x25,0xF5, + 0x24,0x41,0x03,0x39,0x63,0x5B,0x5E,0x56,0x44,0x39,0xE3,0x38,0xFD,0xFF,0x7F,0xA5, + 0x24,0x39,0xE3,0x38,0x7F,0x7F,0xFA,0xA3,0x24,0x39,0xE3,0x38,0xA5,0x37,0xBE,0xFF, + 0x03,0x39,0xC3,0x30,0x00,0x00,0xE2,0xE2,0x24,0x39,0xC3,0x38,0xA0,0x2A,0xB2,0xA2, + 0x44,0x41,0xE3,0x38,0xDE,0xAE,0x3E,0x37,0x44,0x41,0xE3,0x30,0xDF,0xBB,0xEE,0x2E, + 0x44,0x41,0xE3,0x30,0xEA,0x53,0x6E,0xE8,0x44,0x41,0xE3,0x30,0xBA,0x0A,0xAD,0xEF, + 0x24,0x39,0x03,0x39,0x80,0x98,0x95,0x15,0x44,0x39,0x03,0x39,0xFF,0x97,0xAF,0xA8, + 0x65,0x41,0xE3,0x30,0xD7,0x7E,0x2A,0x2E,0x24,0x41,0x03,0x39,0x5D,0x79,0x6F,0x48, + 0x44,0x41,0xC3,0x30,0x7F,0x7B,0xAB,0x02,0x45,0x41,0x03,0x39,0x15,0xD5,0x7D,0xAF, + 0x65,0x41,0xE2,0x30,0x28,0x2F,0xBD,0xF7,0x85,0x49,0x23,0x39,0x0A,0x80,0xAA,0x6D, + 0x85,0x49,0x44,0x41,0xBE,0x32,0x82,0x09,0xA5,0x49,0x44,0x41,0xFE,0xFA,0xAA,0x3E, + 0xA6,0x49,0x45,0x41,0xB6,0xB6,0x9E,0xFE,0xC6,0x51,0x65,0x49,0xEA,0x8A,0xE7,0x97, + 0xA5,0x51,0x65,0x49,0xAB,0x22,0xAA,0x3F,0xC6,0x51,0x85,0x49,0x7D,0xE6,0x1E,0xAB, + 0xC6,0x51,0x65,0x49,0x77,0x9F,0xB6,0x0E,0x06,0x5A,0x44,0x41,0xAD,0xAB,0xAA,0x2A, + 0x27,0x62,0x85,0x49,0xAD,0x3F,0x2F,0x2E,0x47,0x62,0xC6,0x59,0xF6,0x8A,0xAA,0xAE, + 0x27,0x62,0xE6,0x59,0x25,0x3B,0xF2,0xC8,0x47,0x62,0x06,0x5A,0xE2,0xBF,0xA9,0x57, + 0x47,0x62,0x07,0x62,0xBF,0xF2,0x22,0x8E,0x88,0x6A,0x06,0x5A,0xAD,0xFF,0xFF,0x3B, + 0x67,0x6A,0x06,0x62,0xAE,0xFD,0xFB,0x60,0x67,0x6A,0xE6,0x59,0x3A,0xAF,0xCD,0x27, + 0x67,0x6A,0x26,0x62,0x7A,0xB2,0xFB,0xB8,0x88,0x6A,0x27,0x62,0xBF,0xA2,0x9A,0xD5, + 0xA8,0x72,0x68,0x6A,0x3B,0xBF,0xFF,0xF5,0x88,0x6A,0x27,0x62,0x80,0x2E,0xA7,0xBE, + 0x88,0x6A,0x27,0x62,0xD2,0x7A,0xBA,0xBA,0xA8,0x72,0x07,0x62,0x2B,0xF7,0xD7,0xFE, + 0xA8,0x72,0x47,0x62,0xEA,0xC8,0xAB,0x2D,0xC9,0x72,0x68,0x6A,0x2A,0x23,0xFF,0x55, + 0xC9,0x72,0x68,0x6A,0x2A,0xAA,0x2B,0x25,0x0A,0x83,0x88,0x6A,0xFF,0x7F,0x7A,0xA2, + 0xC9,0x72,0x68,0x6A,0x78,0xEA,0xEA,0xA0,0xEA,0x7A,0x68,0x6A,0xF5,0x9E,0x2F,0xFF, + 0xC9,0x72,0x88,0x6A,0xD6,0x9F,0xF8,0x9B,0xA9,0x72,0x68,0x6A,0xE2,0x66,0xFE,0xFA, + 0xA9,0x6A,0x48,0x6A,0xBF,0xDF,0xFF,0x3B,0x89,0x6A,0x48,0x6A,0x68,0x4A,0xBE,0x28, + 0xC9,0x72,0x48,0x62,0x8A,0xAF,0xE7,0xFF,0xC9,0x72,0x68,0x6A,0xA8,0xE8,0x7F,0x5F, + 0xCA,0x7A,0x68,0x6A,0xCA,0x8A,0x3B,0x29,0xE9,0x7A,0x88,0x6A,0xEF,0xF9,0x2A,0x83, + 0xC9,0x7A,0x67,0x6A,0x81,0xC3,0xCA,0xA6,0xEA,0x7A,0xA9,0x72,0xA1,0x85,0xAD,0x56, + 0xEA,0x7A,0x88,0x6A,0x7E,0x7A,0x68,0xE0,0xA9,0x72,0x47,0x62,0x02,0xE9,0xBF,0xAE, + 0xA8,0x72,0x47,0x62,0x8E,0x80,0x80,0xE8,0xE9,0x7A,0x88,0x6A,0x1D,0xFD,0x7D,0x1B, + 0xE9,0x7A,0x89,0x6A,0xFB,0x7E,0xEA,0xE2,0xEA,0x7A,0x88,0x6A,0xAB,0x8B,0xEF,0x37, + 0x0A,0x7B,0x89,0x6A,0x7B,0x7E,0xB0,0x22,0xC9,0x72,0x68,0x6A,0x0E,0x0A,0x2C,0x26, + 0x0A,0x7B,0xA9,0x72,0x8B,0xA2,0xD5,0xDD,0x09,0x7B,0xA9,0x72,0xAE,0x8F,0xAD,0xBF, +}; + +static const size_t pixel_1_width = 256; +static const size_t pixel_1_height = 256; +static const size_t pixel_1_size = 32768; +static const unsigned char pixel_1_data[32768] = +{ + 0xA8,0x6A,0x84,0x49,0x5B,0x55,0xAD,0x0D,0x46,0x62,0x23,0x39,0xD6,0xDF,0xFE,0xF8, + 0x06,0x5A,0x02,0x39,0xA2,0x57,0x7E,0xAE,0x67,0x62,0xE2,0x30,0xDF,0xFF,0x0B,0xFF, + 0xC5,0x49,0xE2,0x30,0xA2,0x5A,0xE8,0xBE,0x88,0x62,0x02,0x31,0x5F,0xAF,0x2F,0xD5, + 0xC5,0x49,0x03,0x39,0x5F,0x78,0x68,0xEF,0x67,0x5A,0xE2,0x30,0xFF,0x8B,0xBD,0x57, + 0xA5,0x49,0xE2,0x30,0xDE,0x70,0xBA,0x0A,0x47,0x62,0x23,0x39,0xEF,0x0F,0x55,0x57, + 0xE5,0x51,0xC2,0x30,0xDE,0x7A,0xFF,0x8A,0x26,0x5A,0x03,0x39,0x8B,0xAD,0x55,0x5F, + 0x06,0x5A,0x23,0x39,0x97,0xFF,0xF5,0x8F,0x47,0x62,0x64,0x49,0x82,0x7B,0x55,0xDF, + 0x47,0x62,0x43,0x41,0x5E,0x5F,0xEB,0x8F,0x27,0x5A,0x03,0x39,0x82,0x55,0xD7,0x7E, + 0x07,0x5A,0x23,0x41,0xDF,0x7D,0xCA,0xEF,0xC5,0x51,0x03,0x39,0xA2,0xF5,0x9E,0x5F, + 0x89,0x6A,0x44,0x41,0x55,0x5D,0xE3,0x5D,0xC5,0x51,0x02,0x31,0xEF,0xB5,0x1C,0x7B, + 0x27,0x5A,0x03,0x39,0x5F,0xFA,0xE2,0x57,0xC5,0x51,0x24,0x39,0xF5,0x25,0x97,0xFD, + 0xE5,0x51,0x03,0x39,0x7E,0xA8,0xEA,0xDF,0x26,0x5A,0x23,0x39,0xAD,0x0D,0xD7,0x8A, + 0xE5,0x51,0x03,0x39,0x7E,0xE8,0xFE,0xDF,0x67,0x62,0x44,0x41,0x2D,0xAD,0xD5,0x03, + 0x27,0x62,0x64,0x49,0xF0,0xF0,0x55,0xE8,0xE6,0x59,0x64,0x41,0xAB,0x7F,0x95,0x02, + 0x46,0x5A,0x84,0x49,0xF7,0x05,0x2D,0xFF,0x68,0x6A,0xE5,0x51,0xB5,0xAE,0xA8,0x2B, + 0x87,0x6A,0x06,0x5A,0xA7,0x2B,0xCB,0x8A,0x87,0x6A,0x23,0x41,0x20,0xA2,0xBF,0xF7, + 0x47,0x62,0xA5,0x51,0x00,0x02,0x8C,0xD7,0x87,0x6A,0x26,0x5A,0x6E,0x2E,0x88,0xFF, + 0xA7,0x6A,0x43,0x41,0x55,0x5E,0x7A,0x6A,0x27,0x5A,0x03,0x39,0xFF,0x83,0x8B,0xF5, + 0xA5,0x49,0x23,0x39,0xBD,0xB4,0x5E,0xF0,0x47,0x5A,0x02,0x31,0x7E,0xE0,0xFB,0xFF, + 0x26,0x52,0x03,0x39,0x2D,0x2D,0xD7,0x7F,0x26,0x52,0x23,0x39,0xDE,0x78,0x77,0xBD, + 0x26,0x5A,0x23,0x39,0x02,0xAB,0xF5,0xD7,0x54,0xE6,0xA5,0x51,0x0D,0xB5,0x55,0x55, + 0x96,0xEE,0x26,0x5A,0x00,0x00,0x03,0x2D,0xB6,0xF6,0x96,0xEE,0xBF,0xAF,0x8B,0xAD, + 0xD6,0xF6,0x96,0xEE,0xDF,0xFD,0xBD,0x2F,0xD7,0xF6,0x96,0xEE,0x0B,0x82,0x70,0x5E, + 0xD7,0xF6,0x96,0xEE,0x2E,0xAE,0x3D,0xB7,0xD7,0xF6,0x75,0xE6,0x78,0xBC,0xAA,0xFA, + 0xF7,0xF6,0xB6,0xEE,0xD5,0xED,0x8A,0xE5,0xF8,0xFE,0xB6,0xEE,0xF6,0xBF,0x02,0xDF, + 0xF7,0xF6,0xD7,0xF6,0x29,0x02,0x02,0x09,0x18,0xFF,0xF7,0xF6,0xBA,0x3E,0xF7,0x55, + 0x18,0xFF,0xF8,0xF6,0xEA,0xA0,0xAB,0x55,0x18,0xFF,0xF8,0xF6,0x55,0xD7,0xFE,0xB9, + 0x18,0xF7,0xD7,0xF6,0xAA,0xFA,0xDA,0xA0,0x18,0xF7,0xD7,0xF6,0x5F,0x7F,0xFF,0x6A, + 0xD7,0xF6,0x97,0xEE,0x20,0x0E,0xF8,0xC0,0xF7,0xF6,0x96,0xEE,0x22,0xAB,0xFA,0xAD, + 0xF7,0xF6,0x96,0xEE,0x5E,0x72,0xEB,0xBF,0x96,0xEE,0x51,0xC5,0x70,0x68,0xE0,0xE8, + 0x34,0xE6,0x10,0xC5,0x80,0x03,0x89,0x0D,0x14,0xDE,0xF3,0xDD,0x76,0x7C,0x5F,0x76, + 0x14,0xDE,0xF3,0xDD,0x7E,0xBF,0x8D,0x8B,0x14,0xDE,0xD3,0xDD,0xA9,0xAF,0xEB,0xFE, + 0x47,0x5A,0x23,0x41,0xF5,0x3D,0xA7,0xDE,0x88,0x6A,0x43,0x41,0x5D,0x80,0xA2,0x5D, + 0x86,0x62,0x22,0x39,0xFD,0xF8,0xFE,0xD7,0xC5,0x49,0xC2,0x30,0x5E,0xFA,0xAA,0x2E, + 0x27,0x5A,0x02,0x31,0xAF,0x0B,0xFD,0xFE,0xA5,0x49,0xE2,0x30,0xF8,0xE0,0xBD,0xAD, + 0x67,0x62,0x23,0x39,0x2F,0xB5,0x55,0xF2,0xA5,0x49,0x02,0x31,0x68,0x7E,0xB5,0x37, + 0x68,0x62,0xE2,0x30,0x0B,0xF5,0xFF,0xA0,0xC5,0x49,0xE2,0x30,0x70,0x7E,0xB5,0xBE, + 0x06,0x52,0xC2,0x30,0x0B,0xFD,0xB0,0xA2,0x85,0x49,0xE2,0x30,0xE0,0xAD,0x2E,0x98, + 0x07,0x62,0x03,0x41,0xAD,0xFD,0xE0,0xEB,0xC5,0x61,0x64,0x49,0x67,0xAD,0xAB,0x0F, + 0xE6,0x61,0x44,0x41,0xDF,0xF8,0xF0,0x6A,0xA5,0x49,0xE2,0x30,0xFD,0x27,0x36,0xFA, + 0x48,0x62,0x24,0x39,0x75,0xF0,0xFA,0xFF,0x27,0x5A,0xE2,0x30,0xBD,0x27,0xFF,0xFE, + 0xC8,0x6A,0x03,0x39,0x5F,0xF0,0x7F,0xFF,0x27,0x52,0xE2,0x30,0x2D,0xAF,0xFF,0xAA, + 0x06,0x52,0x24,0x41,0x7C,0xF8,0xFF,0xAA,0x68,0x62,0x23,0x39,0x2D,0xF5,0x57,0x5F, + 0x06,0x52,0x23,0x39,0x7A,0xFB,0x0A,0x0B,0x27,0x5A,0x02,0x31,0x0B,0xFD,0xDE,0xFE, + 0x06,0x52,0x42,0x39,0x7E,0xFF,0x02,0xBF,0x67,0x62,0x84,0x41,0xAD,0x55,0xE0,0x55, + 0xE6,0x51,0x03,0x31,0x80,0x5E,0x68,0xFE,0x46,0x62,0x43,0x39,0xFF,0x0F,0xAD,0x55, + 0x05,0x52,0x43,0x39,0xFE,0xA8,0xFC,0x55,0x27,0x62,0x23,0x31,0x03,0x0A,0xBF,0xD5, + 0x27,0x62,0xE2,0x38,0x00,0x2B,0xBF,0x5E,0x26,0x5A,0x02,0x39,0xDC,0x68,0xFA,0xD5, + 0x26,0x5A,0x23,0x41,0xFF,0x0B,0xF5,0x56,0x06,0x5A,0x44,0x41,0xB0,0x58,0xD5,0x25, + 0xC5,0x51,0x02,0x39,0x02,0x02,0xED,0xF0,0xC5,0x51,0x23,0x39,0xDE,0x5C,0x55,0xEB, + 0x68,0x62,0x02,0x39,0xA2,0xFF,0x55,0xAF,0xC6,0x51,0x23,0x39,0xA2,0x57,0x55,0x00, + 0x26,0x5A,0x03,0x39,0xFF,0x55,0xF7,0x82,0x26,0x5A,0x03,0x39,0xBD,0x55,0xFF,0x02, + 0x26,0x62,0x02,0x39,0x7E,0x55,0xAF,0x00,0x27,0x62,0x02,0x39,0xDD,0xDD,0xAE,0x00, + 0xF0,0xBC,0x44,0x49,0x35,0xF5,0xBF,0x2F,0xD7,0xF6,0xD2,0xD5,0x22,0x89,0x29,0x0B, + 0xD7,0xF6,0x96,0xEE,0x8B,0x43,0x68,0x78,0xB6,0xEE,0x76,0xEE,0xB6,0x9F,0x95,0x56, + 0xB6,0xF6,0x34,0xE6,0x02,0x22,0xAA,0xF5,0x96,0xEE,0xF3,0xDD,0xF0,0x9C,0xD6,0x97, + 0xF7,0xF6,0xD3,0xD5,0x2A,0xAA,0xBF,0x5F,0xF7,0xF6,0xD3,0xD5,0x88,0x0A,0x2A,0xB5, + 0x18,0xFF,0x75,0xE6,0xF7,0x5E,0xE8,0xBB,0xF7,0xF6,0x55,0xE6,0x02,0xB5,0x5F,0xFA, + 0xF7,0xF6,0x55,0xE6,0x20,0x00,0x2D,0x97,0x18,0xF7,0xD7,0xF6,0xF7,0xFF,0x8A,0xE9, + 0x18,0xFF,0xD7,0xEE,0xAA,0xFD,0xEA,0xEB,0x18,0xF7,0xD7,0xF6,0xE2,0xAA,0x57,0x5C, + 0xF7,0xF6,0xB7,0xEE,0xF8,0xA8,0xFF,0xFE,0xD7,0xF6,0x75,0xEE,0x2E,0xF0,0x40,0x82, + 0xD7,0xF6,0x55,0xE6,0xA0,0xE2,0xE2,0xC1,0x96,0xEE,0xD3,0xD5,0x60,0xE0,0xC0,0xC2, + 0x14,0xDE,0x51,0xCD,0x25,0x35,0xBF,0xFF,0x14,0xDE,0xF3,0xDD,0xD4,0xBE,0xBC,0xBA, + 0x34,0xE6,0xF3,0xDD,0xEB,0xEA,0xE2,0xFA,0x14,0xDE,0xF3,0xDD,0xB7,0xED,0xDB,0xF5, + 0x05,0x5A,0x43,0x41,0xD8,0x50,0x72,0xC0,0x47,0x62,0x63,0x41,0x03,0xAB,0x55,0x25, + 0x67,0x62,0x84,0x41,0x57,0x77,0x55,0x78,0xA5,0x49,0x63,0x41,0x00,0x6A,0xEB,0xFE, + 0xA5,0x49,0x02,0x39,0xA0,0x7B,0xA0,0xAA,0xA5,0x49,0x02,0x31,0x3E,0xB3,0x8F,0x9A, + 0xCA,0x8B,0xA4,0x49,0x55,0x7D,0xC9,0x55,0x85,0x41,0xE2,0x28,0x9E,0xBE,0xF8,0x58, + 0x47,0x5A,0x02,0x31,0xFF,0x0F,0xAF,0x75,0xA5,0x49,0x02,0x31,0x5E,0xC8,0xCA,0xFF, + 0x84,0x49,0xE2,0x30,0xAA,0x02,0xA9,0x77,0x84,0x49,0xE2,0x30,0xAB,0x22,0xA8,0x55, + 0xA4,0x51,0x02,0x39,0xAF,0xAE,0xBA,0x95,0x26,0x72,0x84,0x51,0xED,0xBD,0xAB,0x8B, + 0x06,0x6A,0x84,0x51,0x7E,0x7A,0x78,0x40,0x85,0x51,0xE3,0x38,0x80,0xAA,0x7E,0x5C, + 0x85,0x49,0xC2,0x30,0x00,0x2A,0x5D,0xFD,0x85,0x49,0xC3,0x30,0x00,0xAA,0x57,0xAF, + 0x85,0x49,0xE2,0x30,0x88,0xEE,0x55,0xAA,0xC5,0x51,0xE3,0x30,0xAA,0x7F,0x55,0x2A, + 0xC5,0x49,0x03,0x39,0xAA,0x55,0x55,0x28,0x06,0x52,0x03,0x39,0x5B,0xD5,0xB5,0x00, + 0x06,0x5A,0xE2,0x30,0xFF,0x55,0xAE,0x00,0x06,0x5A,0xE2,0x30,0xFF,0xB5,0x2B,0x00, + 0x27,0x5A,0x02,0x39,0x75,0x57,0xAA,0x00,0x06,0x5A,0x23,0x39,0x55,0x55,0x2A,0x00, + 0x05,0x5A,0xE2,0x30,0xD7,0xBF,0x00,0x20,0x07,0x5A,0xC2,0x30,0xD6,0xA8,0x80,0x22, + 0x07,0x62,0xE2,0x30,0x55,0xAA,0x00,0xAA,0x06,0x5A,0x03,0x31,0xD5,0x0A,0x20,0x00, + 0xC8,0x72,0x64,0x49,0x5B,0xFF,0xFA,0x0A,0xAC,0x93,0x84,0x49,0x55,0xFD,0x55,0x02, + 0xD0,0xB4,0xE6,0x59,0x55,0x55,0x55,0x0A,0x32,0xC5,0x06,0x5A,0x55,0x55,0x55,0x00, + 0xB4,0xD5,0x06,0x5A,0x55,0x55,0xF5,0x00,0x36,0xE6,0x06,0x5A,0x55,0x55,0xFF,0x00, + 0x55,0xE6,0x06,0x5A,0x55,0x55,0xAB,0x00,0x97,0xEE,0x27,0x62,0x55,0x55,0xAA,0x00, + 0x35,0xDE,0x26,0x62,0x55,0xD5,0x00,0x00,0x75,0xE6,0xE5,0x59,0x55,0xFF,0x00,0x00, + 0x75,0xE6,0x06,0x5A,0x55,0xAF,0x00,0x00,0x96,0xEE,0x27,0x62,0x55,0xAA,0x00,0x00, + 0xB6,0xEE,0xE8,0x7A,0xBD,0x0A,0x00,0x00,0xD7,0xF6,0x75,0xEE,0x0D,0x89,0xA2,0xA0, + 0xB6,0xF6,0x76,0xEE,0xE0,0x68,0x78,0xEA,0x96,0xEE,0xF4,0xDD,0xE8,0xE0,0x7A,0x7A, + 0xB6,0xF6,0xD3,0xD5,0xBF,0xBD,0xB5,0x2F,0xD7,0xF6,0x14,0xDE,0xF5,0xAB,0x82,0x00, + 0xB7,0xF6,0x55,0xE6,0x5D,0xBF,0xFE,0xE0,0xB6,0xEE,0x51,0xCD,0x5F,0x80,0x08,0x22, + 0x96,0xEE,0x92,0xCD,0x0B,0xB5,0xF8,0x80,0xF7,0xF6,0x34,0xDE,0xAA,0xAB,0xB5,0xF5, + 0xD7,0xF6,0x14,0xDE,0x6A,0xC0,0x02,0x0A,0xD7,0xF6,0x92,0xCD,0x02,0x2D,0xBE,0x80, + 0x18,0xFF,0x96,0xE6,0xAA,0x20,0x29,0x95,0x18,0xF7,0xD7,0xF6,0xEA,0xBA,0xAA,0xEA, + 0xF7,0xF6,0xB7,0xEE,0xEE,0xEC,0xF0,0xC0,0xD7,0xF6,0x96,0xEE,0xAA,0xBC,0xFA,0x6A, + 0xB6,0xEE,0x34,0xDE,0x8B,0x27,0xB4,0xBE,0x96,0xEE,0x34,0xE6,0xCB,0xEB,0xFD,0xB7, + 0xF3,0xDD,0x71,0xCD,0xDF,0xD6,0x5C,0x5C,0x34,0xE6,0xD3,0xDD,0xAF,0xA9,0x39,0xA9, + 0x34,0xE6,0x14,0xDE,0x78,0x53,0x5F,0x5E,0x34,0xE6,0xF3,0xDD,0xD5,0xB5,0xDF,0xFF, + 0x2A,0x83,0xC5,0x51,0x57,0x5E,0x5E,0x7C,0x84,0x49,0xE1,0x30,0x2B,0xD6,0x5C,0x00, + 0x67,0x62,0x22,0x39,0xFF,0x77,0x55,0x2B,0xA8,0x6A,0x23,0x39,0xFF,0x55,0xFF,0x00, + 0x27,0x62,0x02,0x31,0xFF,0x55,0xAA,0x00,0x27,0x5A,0x02,0x31,0x5F,0x7D,0x8A,0x80, + 0x06,0x5A,0x02,0x31,0x55,0x55,0xAA,0x00,0xE6,0x51,0xC2,0x28,0x5D,0xFF,0x00,0x20, + 0x07,0x5A,0xC1,0x30,0x55,0xFF,0x00,0xA2,0x06,0x5A,0xE2,0x30,0xD5,0xFF,0x00,0xAA, + 0x07,0x5A,0xC1,0x30,0x56,0xA2,0x00,0xAA,0x06,0x5A,0xE2,0x30,0x55,0x22,0x80,0xAE, + 0xC5,0x59,0x02,0x39,0xB5,0x00,0x00,0x00,0x26,0x72,0xC5,0x61,0x09,0xA9,0xEF,0xED, + 0x26,0x72,0xE5,0x69,0x4A,0xBF,0xFB,0x8B,0xAB,0xA3,0xC5,0x59,0x55,0x57,0x5D,0x2F, + 0x11,0xC5,0xC6,0x59,0x55,0x55,0x55,0x02,0x72,0xCD,0xE5,0x51,0x55,0x55,0x75,0x00, + 0xF3,0xD5,0xC5,0x51,0x55,0x55,0xFF,0x00,0x35,0xE6,0xE6,0x59,0x55,0x55,0xBF,0x00, + 0x55,0xE6,0xE6,0x59,0x55,0x55,0xAA,0x00,0xB6,0xEE,0x26,0x62,0x55,0x55,0xAA,0x00, + 0x34,0xDE,0xC6,0x51,0x55,0xFD,0x00,0x00,0x76,0xEE,0xE6,0x59,0x55,0xFF,0x00,0x00, + 0x76,0xE6,0xC5,0x59,0x55,0xAA,0x00,0x00,0x96,0xEE,0x26,0x62,0x55,0xAA,0x00,0x00, + 0xB7,0xF6,0xA8,0x7A,0x55,0x2A,0x00,0x00,0x76,0xEE,0xE9,0x7A,0xF5,0x20,0x00,0x00, + 0x76,0xEE,0x2E,0xA4,0xD5,0x00,0x00,0x00,0xD3,0xDD,0x26,0x6A,0xAA,0xC0,0xE0,0x78, + 0x4E,0xAC,0x06,0x62,0x3E,0xB7,0x55,0x55,0xB7,0xF6,0x8F,0xB4,0xAA,0x03,0x09,0x09, + 0xF8,0xFE,0x55,0xE6,0xD5,0xAE,0xAA,0x00,0x18,0xFF,0x76,0xEE,0x75,0xBF,0xA2,0x08, + 0xF7,0xF6,0x96,0xEE,0x5D,0xAE,0xA8,0xAC,0xD7,0xF6,0x96,0xEE,0xBD,0xAA,0x08,0x00, + 0xD7,0xF6,0xB7,0xEE,0x5D,0xEF,0xEC,0x8A,0xD7,0xF6,0x96,0xEE,0xEF,0xAA,0x82,0x82, + 0xD7,0xF6,0xB7,0xEE,0xF7,0xE7,0xEA,0xA8,0xD7,0xF6,0xB6,0xEE,0xEB,0xEB,0xFF,0xAA, + 0xB6,0xF6,0xD7,0xEE,0x8A,0x22,0xFA,0xEB,0xF7,0xF6,0xB6,0xEE,0x77,0x5F,0xFD,0xBB, + 0xF7,0xF6,0x96,0xEE,0x2A,0x8B,0x62,0x58,0xD7,0xF6,0x76,0xEE,0xE8,0xBB,0xFD,0x5D, + 0x96,0xEE,0x14,0xE6,0x00,0xE8,0xF8,0x7E,0xB6,0xF6,0x14,0xDE,0x5F,0xFD,0x2F,0x2D, + 0xF7,0xF6,0x55,0xE6,0xAD,0x0A,0xAA,0xAA,0xF7,0xF6,0xB7,0xF6,0x8A,0xA2,0xAA,0xAD, + 0xF7,0xF6,0xB6,0xEE,0x5E,0xFA,0xA8,0xAB,0xD7,0xF6,0x75,0xE6,0xDF,0xFA,0xAA,0x80, + 0xB6,0xEE,0x76,0xEE,0x37,0xBF,0xAA,0x00,0xD7,0xF6,0x55,0xE6,0xD6,0xA8,0x0A,0x2A, + 0xF7,0xF6,0x76,0xEE,0xBD,0xBF,0xAE,0xA8,0x38,0xFF,0xD7,0xF6,0xFF,0xED,0xBD,0x2F, + 0x18,0xFF,0xB7,0xEE,0x7E,0xAE,0xEA,0xA0,0x18,0xF7,0xB7,0xEE,0xA3,0xAD,0xDE,0xFA, + 0x18,0xF7,0xD7,0xF6,0x6A,0xEA,0xEB,0xFF,0xB7,0xEE,0x75,0xE6,0xA0,0x60,0x60,0x60, + 0x96,0xEE,0x92,0xD5,0xA8,0xB8,0xFA,0x5A,0x75,0xEE,0x14,0xDE,0xB6,0xF4,0xDE,0x56, + 0x55,0xE6,0x71,0xCD,0x5E,0x5C,0x5C,0x58,0x34,0xE6,0xB3,0xD5,0x8B,0x89,0x0B,0x01, + 0x34,0xE6,0xF3,0xDD,0xDA,0x5A,0x5E,0x5F,0x14,0xDE,0xD3,0xDD,0x0B,0xA2,0xEA,0x6F, + 0x35,0xE6,0xE5,0x59,0x56,0x7A,0xA0,0x00,0xF4,0xD5,0xA4,0x51,0x55,0x55,0xBA,0x00, + 0xF4,0xD5,0xC5,0x51,0x55,0x55,0xAA,0x00,0x35,0xE6,0x06,0x5A,0x55,0x55,0xAA,0x00, + 0x35,0xE6,0x26,0x62,0x55,0x55,0x8A,0x00,0x35,0xE6,0xA5,0x51,0x55,0xFF,0x00,0x00, + 0x35,0xE6,0xC5,0x51,0x55,0xBB,0x00,0x00,0x55,0xE6,0xC5,0x51,0x55,0xAA,0x00,0x00, + 0x75,0xEE,0x67,0x6A,0x55,0xAA,0x00,0x00,0x55,0xE6,0xE9,0x7A,0x55,0x22,0x00,0x00, + 0x55,0xE6,0xCC,0x93,0x55,0x02,0x00,0x00,0x76,0xEE,0x2E,0xA4,0xF5,0x20,0x00,0x00, + 0x55,0xEE,0xAC,0x9B,0x7B,0xC0,0xC0,0xC0,0x67,0x72,0xA4,0x61,0xF7,0xD6,0x54,0x5C, + 0x26,0x72,0xA4,0x61,0xAB,0x8B,0xA9,0x0F,0x2D,0xAC,0x26,0x72,0x35,0xB5,0x55,0x55, + 0x55,0xEE,0xE9,0x8A,0x02,0x03,0x0B,0x2D,0xB6,0xF6,0x75,0xEE,0xD5,0xAB,0xAA,0x8B, + 0xB6,0xF6,0x75,0xEE,0xFD,0xAB,0xA2,0x82,0xB6,0xF6,0x96,0xEE,0x55,0xEA,0xEA,0xEA, + 0xB6,0xF6,0x96,0xEE,0xA5,0x2B,0xBE,0x8F,0xB6,0xF6,0x96,0xEE,0xF3,0x88,0x32,0x0F, + 0xB6,0xF6,0x96,0xEE,0x2E,0x82,0x2A,0x08,0xB6,0xF6,0xD7,0xEE,0x22,0xC8,0x88,0xFC, + 0xF7,0xF6,0xB6,0xF6,0xE7,0xAA,0x0A,0x02,0xF8,0xFE,0xD7,0xEE,0xF5,0xEA,0x8A,0xAA, + 0xF7,0xF6,0xD7,0xF6,0xD5,0x0A,0x02,0x00,0xF7,0xFE,0xD7,0xF6,0xD7,0xFC,0xEA,0x7E, + 0xB6,0xF6,0xCB,0xA3,0x80,0xA0,0xE0,0x78,0xCF,0xBC,0x67,0x72,0x58,0x56,0x57,0x55, + 0x67,0x7A,0xC5,0x61,0xDE,0xFA,0xB8,0x30,0xD7,0xF6,0x2D,0xAC,0x09,0x09,0x09,0x09, + 0x18,0xFF,0xF7,0xF6,0xDF,0xBF,0xBD,0xFF,0x17,0xFF,0xF7,0xF6,0xEB,0xBB,0x82,0xAB, + 0xF7,0xF6,0xD7,0xF6,0x6C,0x5A,0xD0,0x30,0xF7,0xF6,0xD7,0xF6,0x55,0xFE,0xFF,0xEF, + 0xD7,0xF6,0xB6,0xEE,0x0B,0x2B,0x00,0x00,0xB7,0xF6,0xF7,0xEE,0xAA,0xEA,0xAE,0xEF, + 0xD7,0xF6,0xB7,0xEE,0x88,0x0A,0x02,0x80,0xF7,0xF6,0xB6,0xEE,0xFF,0xBE,0xAE,0xAE, + 0xB6,0xF6,0xF7,0xEE,0xAA,0xBA,0xBB,0xEE,0xF7,0xF6,0xB6,0xEE,0x0E,0x82,0xC2,0x78, + 0xD7,0xF6,0x96,0xEE,0x78,0x54,0x76,0x57,0x96,0xEE,0xF4,0xDD,0xA0,0xE8,0x6A,0x78, + 0x35,0xE6,0x91,0xCD,0xE0,0x70,0x5F,0x16,0x96,0xF6,0xF3,0xDD,0xAD,0xFD,0x03,0x00, + 0xB6,0xF6,0xB3,0xD5,0x0A,0xF7,0xFE,0xA8,0xD7,0xF6,0xF4,0xDD,0x02,0xAF,0xFD,0xFF, + 0xD7,0xF6,0x55,0xE6,0x00,0x0A,0x3D,0xD5,0xF7,0xF6,0xB6,0xEE,0xAA,0xAA,0x83,0xB5, + 0xD7,0xF6,0x96,0xEE,0xFE,0xF8,0x28,0x00,0xD7,0xF6,0x96,0xEE,0x0A,0xAE,0x9E,0xF8, + 0x18,0xF7,0xD7,0xF6,0xFF,0xFD,0xB5,0xA5,0x38,0xFF,0xF8,0xF6,0xA5,0xB5,0xDD,0xD7, + 0x38,0xFF,0xF8,0xF6,0xFA,0xE8,0x82,0x0B,0x18,0xFF,0xB7,0xF6,0xEA,0xFA,0xFA,0xDC, + 0xF7,0xF6,0x76,0xEE,0x82,0xAB,0xAF,0xB7,0xD7,0xF6,0x75,0xE6,0x7A,0x78,0x78,0xDA, + 0x55,0xE6,0x10,0xC5,0xF8,0xF8,0x58,0x58,0x55,0xEE,0xD3,0xDD,0xFA,0xF3,0xF2,0xE1, + 0x14,0xE6,0x10,0xC5,0xF0,0x60,0x60,0x40,0xD7,0xF6,0x92,0xD5,0xFD,0xBD,0xA9,0x2D, + 0x75,0xEE,0xF3,0xDD,0x7F,0x77,0x7E,0x80,0x34,0xE6,0x92,0xCD,0x6A,0x7A,0x6A,0x88, + 0xD6,0xF6,0x96,0xEE,0x5F,0x5E,0xEA,0xAE,0xB6,0xEE,0x75,0xE6,0x55,0xBB,0x02,0x00, + 0xB6,0xEE,0x75,0xE6,0xD5,0xAA,0x02,0x00,0xD7,0xF6,0x75,0xE6,0x55,0xEF,0xAA,0xA2, + 0xB6,0xEE,0x75,0xE6,0xFD,0xAA,0x20,0x00,0xB6,0xEE,0x75,0xEE,0xFF,0x22,0x00,0x00, + 0xD5,0xEE,0x76,0xEE,0xF7,0xFF,0xFF,0xFE,0x96,0xEE,0x75,0xEE,0x8B,0xC8,0x0A,0x08, + 0xB7,0xF6,0x75,0xEE,0xFF,0xFF,0xBE,0xAA,0xD6,0xF6,0x96,0xEE,0xF7,0xBF,0xAB,0xAA, + 0xD7,0xF6,0x96,0xEE,0xFF,0x2F,0x8A,0xA2,0xD7,0xF6,0x96,0xF6,0xDB,0xAA,0xAA,0xA8, + 0xB6,0xF6,0x6D,0xB4,0x60,0x40,0x60,0xC0,0x66,0x7A,0x84,0x61,0x7E,0xFE,0xFA,0xEC, + 0x27,0x7A,0x84,0x61,0x2D,0xBF,0xFF,0xDE,0x26,0x72,0xE6,0x71,0x25,0x2E,0xBF,0x6D, + 0xD3,0xDD,0x67,0x7A,0x25,0xB5,0xD5,0xD5,0x96,0xF6,0x8F,0xBC,0x00,0x02,0x02,0x09, + 0xB6,0xF6,0x96,0xEE,0x28,0x02,0x8A,0x0A,0xD6,0xF6,0x96,0xEE,0xFE,0xEA,0xAA,0xEA, + 0xB6,0xF6,0x96,0xEE,0x2A,0x02,0x22,0x00,0xB6,0xF6,0x96,0xEE,0xAA,0x82,0x20,0x08, + 0xD6,0xF6,0xB6,0xF6,0x5D,0xD5,0x6D,0xA5,0xD7,0xF6,0xB6,0xEE,0x2B,0x2B,0x2E,0x3A, + 0xD7,0xFE,0xF7,0xF6,0x75,0x57,0xD7,0x55,0x17,0xFF,0xF7,0xF6,0x5D,0xDF,0x7F,0x5B, + 0xD6,0xFE,0xF7,0xF6,0xD7,0xD7,0x55,0xA7,0xD6,0xF6,0xAF,0xBC,0x00,0x80,0xE0,0x78, + 0x35,0xEE,0x87,0x7A,0x78,0x5E,0x57,0x57,0xC7,0x8A,0x47,0x7A,0xFF,0xFF,0xAD,0x2F, + 0xAB,0xA3,0x46,0x72,0xD5,0x97,0x97,0x1F,0xF7,0xFE,0x8F,0xBC,0x09,0x0B,0x03,0x02, + 0x17,0xFF,0xF8,0xF6,0xEA,0x2E,0x2A,0xAA,0x18,0xFF,0xF7,0xF6,0x0A,0xA8,0xA2,0xCA, + 0xF7,0xF6,0xD7,0xF6,0xA8,0xA8,0xA8,0x82,0xF7,0xF6,0xD7,0xF6,0xFF,0x9F,0xFA,0x5A, + 0xD7,0xF6,0xD6,0xEE,0x82,0xA8,0x22,0x8A,0xF7,0xF6,0xD7,0xF6,0xDF,0x7B,0xD5,0x9D, + 0xF7,0xF6,0xB7,0xEE,0xAF,0xBA,0xEA,0xAA,0xF7,0xF6,0xD7,0xF6,0x5D,0xDD,0xF7,0x2B, + 0x17,0xFF,0xB7,0xEE,0xAF,0xAB,0xEA,0x78,0xF8,0xF6,0x96,0xEE,0xFC,0x7E,0x5F,0x5F, + 0x96,0xEE,0x34,0xE6,0x80,0xC8,0x68,0x5C,0x55,0xE6,0xB2,0xD5,0xE8,0xFA,0xFE,0x97, + 0xB7,0xF6,0xF3,0xDD,0x35,0x2D,0x0B,0x02,0xD7,0xF6,0xB6,0xF6,0xAD,0xA0,0x82,0xA2, + 0xD7,0xF6,0x96,0xEE,0x7E,0xAE,0xBA,0xA8,0xD7,0xF6,0x55,0xE6,0xD7,0x8A,0x22,0x2A, + 0xD7,0xF6,0x75,0xE6,0x5F,0xAF,0x28,0xA8,0xF7,0xF6,0x75,0xE6,0xBD,0xFF,0xFE,0x82, + 0xF7,0xF6,0x96,0xEE,0xA2,0x83,0x89,0x2F,0xF7,0xF6,0xB7,0xEE,0x5E,0xFA,0xB0,0xA0, + 0xF8,0xF6,0xB7,0xEE,0x0B,0x0B,0x8A,0xA2,0x18,0xF7,0xD7,0xEE,0x20,0x8A,0xAF,0xB7, + 0x38,0xFF,0xF8,0xF6,0x8F,0xB5,0xDF,0x57,0x38,0xFF,0x96,0xEE,0xF8,0x78,0x72,0x6A, + 0xD7,0xF6,0x35,0xE6,0x2E,0x3F,0xBE,0xDF,0xB6,0xF6,0x14,0xDE,0xB8,0xFC,0xDC,0x7C, + 0x34,0xE6,0x10,0xBD,0x58,0x5C,0x5C,0x5C,0x34,0xE6,0x92,0xCD,0x83,0xC1,0xC9,0xC9, + 0xF4,0xDD,0x51,0xC5,0x40,0x42,0x42,0x8B,0x76,0xEE,0xCF,0xB4,0x0B,0x2D,0xB5,0x25, + 0x95,0xEE,0x55,0xE6,0xEC,0x5E,0x5F,0xDC,0x96,0xEE,0x55,0xE6,0xD7,0xFB,0xAD,0xA9, + 0xD6,0xF6,0xB6,0xEE,0xB5,0xFD,0xFD,0xDD,0xD6,0xF6,0xB6,0xEE,0xF5,0xDF,0xF6,0xF9, + 0xD6,0xF6,0xB6,0xEE,0xAD,0xFF,0xBB,0xBB,0xD6,0xF6,0xB6,0xEE,0xFF,0xDF,0xBF,0xFF, + 0xD7,0xF6,0xB6,0xEE,0x77,0xFF,0xBA,0xFA,0xB6,0xF6,0xD6,0xEE,0x28,0xBA,0xAF,0xBA, + 0xB7,0xEE,0x95,0xEE,0x56,0xDF,0x57,0x76,0xB7,0xFE,0x95,0xEE,0xD5,0xD5,0x7F,0xF5, + 0xB5,0xF6,0x96,0xEE,0xAF,0xEE,0xFB,0xBF,0xD7,0xF6,0xB6,0xEE,0xAB,0x2B,0x8B,0x29, + 0xD7,0xF6,0xB6,0xEE,0xAE,0x28,0x02,0x80,0xD7,0xF6,0xB6,0xEE,0xBA,0xAA,0xA0,0x00, + 0xB6,0xF6,0x86,0x7A,0x80,0xE0,0x60,0x70,0x47,0x72,0x63,0x61,0xA8,0xAE,0xBA,0xDC, + 0x26,0x72,0x84,0x61,0x7A,0x70,0xF8,0xEA,0x07,0x72,0x64,0x61,0x0A,0xAB,0xBF,0xF7, + 0xA7,0x7A,0xA5,0x61,0x2F,0xBF,0xBD,0xF5,0x75,0xEE,0xA7,0x82,0x0B,0x2D,0x35,0xB5, + 0xD7,0xF6,0x75,0xF6,0xAA,0x2A,0xAA,0x81,0xD6,0xF6,0xB6,0xF6,0xDB,0xEE,0xB9,0xA3, + 0xD6,0xF6,0xB6,0xF6,0x5D,0x76,0x78,0xFF,0xB6,0xF6,0xB7,0xEE,0x88,0x22,0x88,0x20, + 0xD6,0xF6,0xB6,0xF6,0x37,0xBD,0xB7,0x9D,0xF7,0xF6,0xB6,0xEE,0xBB,0xBE,0xAF,0xAF, + 0xD6,0xFE,0xF7,0xF6,0xD5,0xDF,0x77,0x55,0xD7,0xFE,0xF7,0xF6,0x7D,0x55,0xF5,0xED, + 0xF7,0xFE,0x51,0xD5,0x00,0xA0,0xE0,0x78,0xF3,0xE5,0x46,0x72,0xE0,0x78,0x5E,0x57, + 0x67,0x7A,0x26,0x7A,0x89,0xFA,0x7A,0xFE,0xA7,0x8A,0x47,0x82,0x3B,0x0A,0xAF,0x8D, + 0xB2,0xDD,0x87,0x82,0x95,0x95,0xB5,0x35,0xF7,0xFE,0x55,0xEE,0x01,0x01,0x03,0x02, + 0x18,0xFF,0xF7,0xF6,0x3A,0x2A,0x2A,0x2A,0x37,0xFF,0xF8,0xF6,0xFE,0xFA,0xEE,0xAE, + 0xF7,0xF6,0xD7,0xF6,0xA0,0xE0,0xA8,0xBC,0xF7,0xF6,0xD7,0xF6,0x7A,0x6F,0xFE,0xDB, + 0xD7,0xF6,0xF7,0xEE,0x08,0x88,0x0A,0x22,0xF7,0xF6,0xD7,0xF6,0xD7,0xB5,0xB5,0xD5, + 0xF7,0xF6,0xD7,0xF6,0xDD,0xFD,0x3D,0x2B,0x18,0xFF,0xD7,0xF6,0x2D,0x8F,0x63,0x58, + 0xF7,0xF6,0x96,0xEE,0xF8,0xF8,0x7F,0x5F,0xB7,0xF6,0x35,0xE6,0xA8,0xEA,0x7A,0x7A, + 0x55,0xEE,0x92,0xCD,0xE0,0xE8,0x5A,0xDE,0xD7,0xF6,0x71,0xCD,0xB7,0x2D,0x0B,0x02, + 0xD7,0xF6,0xB6,0xF6,0x8D,0x0B,0x00,0x00,0xD7,0xF6,0xB7,0xEE,0xA8,0xAA,0x00,0x80, + 0xD7,0xF6,0xB7,0xEE,0xE8,0x8A,0xF8,0xFC,0xD7,0xF6,0xB6,0xEE,0x55,0x7F,0x8F,0x23, + 0xD7,0xF6,0xB6,0xEE,0x5D,0x55,0x77,0x6E,0xF7,0xF6,0x96,0xEE,0x2B,0x2F,0xBD,0xFF, + 0x18,0xFF,0xD7,0xF6,0xFF,0xAA,0x2B,0x2D,0x39,0xFF,0xF7,0xF6,0x5F,0x7F,0xEA,0xAA, + 0xF7,0xF6,0xD7,0xEE,0x2C,0x2E,0x02,0x00,0xF8,0xF6,0xD7,0xF6,0xA4,0xEC,0xDA,0xB8, + 0xF7,0xF6,0xB7,0xEE,0xA0,0xA2,0xC2,0xE0,0xD7,0xF6,0xB7,0xEE,0x40,0x6A,0xA2,0x22, + 0xB7,0xEE,0x14,0xDE,0x9E,0xDE,0xD8,0x58,0xD7,0xF6,0x34,0xE6,0x58,0x7A,0x72,0x62, + 0x14,0xDE,0x10,0xC5,0x5C,0xF8,0xF8,0xF8,0x34,0xE6,0x71,0xCD,0x89,0xA9,0xAD,0xAD, + 0xD3,0xDD,0x51,0xC5,0x8B,0x0B,0x0F,0xA5,0xB6,0xF6,0x10,0xC5,0x25,0x2D,0x2F,0x2F, + 0xB6,0xF6,0x34,0xE6,0xDA,0x58,0xF8,0x70,0x96,0xEE,0x35,0xE6,0x3F,0xB5,0xBD,0xBD, + 0xD6,0xF6,0xB6,0xEE,0x5B,0xF7,0xFD,0xBD,0xD6,0xF6,0xB6,0xEE,0x6F,0xBE,0xBA,0xB6, + 0xD6,0xF6,0xB6,0xEE,0xBF,0xE3,0xAD,0xA7,0xD6,0xF6,0xB6,0xEE,0xAF,0x6E,0xFF,0xEC, + 0xD6,0xF6,0xB6,0xEE,0xAD,0xBF,0xE3,0xEF,0xD6,0xF6,0xB6,0xEE,0x3F,0xEE,0xEE,0xFD, + 0xB6,0xF6,0x95,0xEE,0xFA,0xF6,0xFC,0xBE,0xB6,0xF6,0x96,0xEE,0xA5,0xED,0x7E,0xFE, + 0x96,0xF6,0xB6,0xEE,0x9F,0x6E,0x7F,0x7A,0xF6,0xF6,0xB6,0xEE,0xFD,0xBF,0xFF,0xAB, + 0xD7,0xF6,0xB6,0xEE,0xE0,0xE0,0x0A,0x08,0xB6,0xF6,0xF7,0xEE,0xAF,0xAF,0xAB,0xAB, + 0x55,0xEE,0xC4,0x61,0x70,0x70,0x70,0x70,0xE6,0x69,0x23,0x51,0x58,0x5E,0x5E,0x7F, + 0xE6,0x71,0x03,0x51,0x02,0x03,0x09,0xAD,0xA5,0x61,0x44,0x59,0xFA,0xBE,0x5C,0x58, + 0xC5,0x69,0x44,0x51,0x2F,0xAD,0xB5,0xF5,0xAB,0x9B,0xE6,0x69,0x2D,0xBD,0xB5,0xD5, + 0xB6,0xF6,0x6A,0x93,0x02,0x0B,0x09,0x25,0xD6,0xFE,0xD7,0xF6,0xFF,0xFF,0xDF,0xBE, + 0xD7,0xF6,0xB6,0xF6,0xBC,0xFE,0xEC,0xB8,0xD7,0xF6,0xB6,0xF6,0xD5,0xB7,0xBF,0xAB, + 0xD6,0xF6,0xB6,0xF6,0xFE,0xBE,0xAC,0xA0,0xF7,0xFE,0xB6,0xF6,0xBD,0xEF,0xBF,0xBE, + 0xD7,0xFE,0xF7,0xF6,0x55,0x57,0xFF,0xEF,0xD7,0xF6,0xB2,0xDD,0x00,0x00,0x80,0x60, + 0x76,0xEE,0x66,0x7A,0xE0,0x78,0x5E,0x5F,0x67,0x82,0x05,0x72,0xE8,0xFD,0xBF,0x2B, + 0x87,0x8A,0x05,0x7A,0xA7,0xAD,0x2F,0xEA,0x87,0x8A,0x25,0x7A,0x02,0xEA,0xFE,0xDF, + 0x76,0xEE,0x66,0x82,0x35,0x25,0x25,0x2D,0x18,0xFF,0xF7,0xFE,0x2D,0x09,0x29,0x01, + 0x38,0xFF,0x17,0xF7,0x57,0xDD,0x7F,0xFE,0x18,0xFF,0xF7,0xEE,0x88,0xE2,0xA0,0xC0, + 0xF7,0xF6,0xD7,0xF6,0xAC,0x2E,0xB8,0xAA,0xF7,0xF6,0xD7,0xF6,0xFF,0xFA,0x7A,0xBA, + 0xF7,0xF6,0xD7,0xF6,0x5A,0xF7,0x95,0xAA,0xF7,0xF6,0xD7,0xF6,0xD7,0x5E,0x5F,0x23, + 0x18,0xFF,0xB6,0xF6,0x2B,0x2B,0xA2,0x72,0x17,0xFF,0xB6,0xF6,0x5C,0x5F,0x57,0x55, + 0xB6,0xF6,0x54,0xE6,0xE0,0xA8,0xE8,0x78,0x75,0xEE,0x92,0xD5,0xA0,0xE8,0x78,0xFA, + 0xB7,0xF6,0x92,0xCD,0xB7,0x25,0x0B,0x02,0xF7,0xF6,0xB6,0xF6,0xAD,0xBB,0xAA,0xAB, + 0xF7,0xF6,0xD7,0xF6,0x5F,0xD5,0xFD,0x75,0xD7,0xF6,0xB7,0xEE,0xA8,0x00,0x00,0x00, + 0xD7,0xF6,0xB7,0xEE,0x3A,0xAA,0x0A,0xA8,0xD7,0xF6,0xB6,0xEE,0x28,0xFA,0xB8,0xFB, + 0xD7,0xF6,0xB7,0xEE,0xFE,0xBE,0x2F,0xB8,0xD7,0xF6,0xB7,0xEE,0x5F,0xFC,0xA2,0xA0, + 0xF7,0xF6,0xB7,0xEE,0x2D,0x3D,0xFF,0xFF,0x38,0xFF,0xF7,0xF6,0x2A,0xAB,0xAD,0xB5, + 0x39,0xFF,0xF7,0xF6,0x5E,0x58,0x60,0xC0,0xF7,0xF6,0xD8,0xF6,0xAA,0xAA,0x8B,0x78, + 0xF7,0xF6,0x96,0xEE,0x8A,0xE8,0x68,0x5F,0xD7,0xF6,0x96,0xEE,0x2A,0x2A,0x2F,0x2D, + 0xB7,0xF6,0x91,0xCD,0xB8,0xB8,0xE8,0xD8,0xD6,0xF6,0x54,0xE6,0x62,0xE2,0xA3,0xA9, + 0x14,0xDE,0x71,0xCD,0x74,0xFC,0x74,0xFC,0x34,0xE6,0x92,0xCD,0xAD,0xA5,0xB5,0xB5, + 0x71,0xCD,0xAF,0xB4,0xA8,0xAC,0xBE,0xD4,0xB6,0xF6,0x71,0xCD,0x0D,0x09,0x0B,0x2D, + 0xD7,0xF6,0x34,0xE6,0xF8,0xF8,0x78,0x7A,0x75,0xEE,0x34,0xE6,0x27,0xA7,0xBF,0xEF, + 0xD6,0xF6,0xB6,0xEE,0xFF,0xEA,0xBA,0xAB,0xD6,0xF6,0xB6,0xEE,0x29,0xAB,0xEC,0xEA, + 0xD6,0xF6,0xB6,0xEE,0xAA,0xAA,0x0A,0x0E,0xD6,0xF6,0xB6,0xEE,0xAA,0xAA,0xAA,0xA2, + 0xD6,0xF6,0xB6,0xEE,0xAA,0x86,0x7F,0x4A,0xD6,0xF6,0xB6,0xEE,0xFE,0xEA,0xBB,0xBA, + 0x96,0xF6,0xB6,0xEE,0xF9,0xFD,0xBD,0xED,0xB6,0xF6,0x96,0xEE,0xEE,0xAA,0xEE,0xCA, + 0x95,0xF6,0xB6,0xEE,0xDF,0x7F,0xDD,0x55,0xD6,0xF6,0xB6,0xEE,0x82,0x03,0x23,0x03, + 0xD6,0xF6,0xF7,0xEE,0x00,0x20,0x22,0xA0,0xD6,0xF6,0xB7,0xEE,0xA2,0x82,0x00,0x00, + 0xB6,0xF6,0xC4,0x59,0x70,0x70,0x70,0x60,0x85,0x59,0x23,0x49,0xE3,0xAE,0x5E,0xF7, + 0x85,0x59,0x23,0x51,0x2D,0xAE,0x7F,0x7F,0x85,0x61,0xE3,0x40,0xE0,0xF8,0xFB,0x5F, + 0x64,0x51,0xE3,0x40,0x2A,0x2F,0x2F,0x3D,0x87,0x72,0x84,0x59,0x3D,0xBD,0xBD,0x2D, + 0xCF,0xBC,0xA8,0x7A,0x2D,0xBD,0xF5,0xF5,0x96,0xF6,0x8B,0x93,0x00,0x0B,0xF5,0x55, + 0xB6,0xF6,0x8B,0x93,0x00,0x28,0xFF,0x55,0xB6,0xF6,0xAB,0x93,0x00,0x00,0x2A,0xD5, + 0xB6,0xF6,0xCF,0xBC,0x00,0x00,0x00,0xF5,0xD7,0xF6,0x31,0xCD,0x00,0x00,0x0A,0xB5, + 0xD7,0xFE,0x92,0xD5,0x00,0x00,0x00,0x7A,0x35,0xE6,0xE5,0x69,0x80,0xE0,0x78,0x5E, + 0xE8,0x8A,0xE5,0x71,0xDC,0xF7,0xFD,0xF5,0x87,0x8A,0x26,0x7A,0x29,0xA9,0xCA,0xEB, + 0x67,0x8A,0x06,0x7A,0x60,0xFC,0x9A,0x97,0xC8,0x92,0x06,0x7A,0xF5,0xBD,0x2F,0x0A, + 0xB6,0xF6,0x88,0x8A,0x0D,0x09,0x0B,0x0B,0x38,0xFF,0xF8,0xFE,0xBF,0xBD,0xBF,0xF7, + 0x18,0xFF,0x38,0xF7,0xAE,0xBA,0xAA,0xA8,0x38,0xFF,0xF7,0xF6,0xFA,0x7A,0xFA,0xF8, + 0xF7,0xF6,0xD7,0xF6,0xCE,0x32,0xA0,0x20,0xF7,0xF6,0xD7,0xF6,0xAC,0xBA,0xC2,0x00, + 0xF7,0xF6,0xD7,0xF6,0xA0,0xAA,0x8A,0x23,0x18,0xFF,0xD6,0xF6,0xBF,0x2F,0x8A,0x72, + 0x17,0xFF,0x96,0xEE,0xF8,0x7E,0xD7,0x57,0xB6,0xF6,0x55,0xE6,0x82,0xAA,0xE2,0x62, + 0x96,0xEE,0xB3,0xD5,0xA0,0xA8,0xFA,0xDF,0xD7,0xF6,0x14,0xDE,0xB5,0x0B,0x2B,0x02, + 0xF7,0xF6,0xD7,0xF6,0xD5,0x96,0xAF,0xFF,0xD7,0xF6,0xF6,0xEE,0x02,0x82,0x0A,0x00, + 0xF7,0xF6,0xB6,0xEE,0xEA,0xEA,0x7A,0xEA,0xD7,0xF6,0xB7,0xEE,0x80,0xC2,0xFB,0xAC, + 0xD7,0xF6,0xB7,0xEE,0xAA,0xEA,0x00,0x00,0xB7,0xF6,0xD7,0xEE,0xEA,0xFF,0xFF,0xAE, + 0xD7,0xF6,0xB7,0xEE,0x88,0x0A,0x2B,0xFF,0xD7,0xF6,0xB7,0xEE,0x88,0xA0,0x80,0xA0, + 0xD7,0xF6,0xF7,0xEE,0x88,0xA0,0x88,0xA0,0x18,0xFF,0xD7,0xF6,0x3D,0xBF,0xBD,0xF5, + 0x38,0xFF,0xF7,0xF6,0x82,0x8A,0xAB,0xBD,0x39,0xFF,0x97,0xEE,0xFE,0xFE,0x7C,0x78, + 0xB7,0xF6,0x76,0xE6,0xE8,0xE8,0xFF,0xFE,0xD7,0xF6,0x76,0xEE,0xAF,0xBF,0xBF,0xB5, + 0xB7,0xF6,0x30,0xC5,0xD8,0xD8,0xD8,0xF8,0xB7,0xF6,0x34,0xE6,0x83,0x8B,0x23,0x89, + 0x55,0xEE,0x92,0xCD,0x56,0x7C,0x5C,0xFC,0xF4,0xDD,0x71,0xCD,0x2D,0x2D,0x2F,0x2F, + 0x92,0xCD,0x4D,0xAC,0xFE,0xDC,0xD4,0x5C,0x35,0xE6,0x10,0xC5,0x2B,0x2D,0xBD,0xAD, + 0x96,0xEE,0x34,0xE6,0xE0,0xE2,0xA9,0xE9,0x55,0xE6,0x34,0xE6,0x92,0x1C,0x28,0x80, + 0xD6,0xF6,0xB6,0xEE,0xAB,0xEE,0xAE,0x2A,0xD6,0xF6,0xB6,0xEE,0x8A,0xAB,0xBA,0xA0, + 0xD6,0xF6,0xB7,0xEE,0xAA,0x03,0x28,0xAC,0xF7,0xF6,0xB6,0xEE,0xAB,0xEA,0xBB,0xEF, + 0xD6,0xF6,0xD7,0xEE,0x8A,0x8A,0xA2,0xAA,0xD6,0xF6,0xB6,0xEE,0x72,0xE0,0x80,0x80, + 0xD6,0xF6,0x96,0xEE,0xFF,0xFE,0xFE,0xEA,0x95,0xF6,0xD6,0xEE,0xBA,0xEA,0xF6,0xFF, + 0xD6,0xF6,0xB6,0xEE,0xF5,0xF7,0xFD,0xFF,0xD6,0xF6,0xF7,0xEE,0x28,0xA8,0x80,0x20, + 0xD6,0xF6,0xF7,0xEE,0x80,0x08,0x28,0x82,0xF6,0xF6,0xD7,0xF6,0x77,0x5F,0xFF,0xFE, + 0xD6,0xF6,0x4A,0x8B,0x60,0xC0,0x80,0x80,0x47,0x6A,0x03,0x41,0x77,0xD7,0x56,0xD4, + 0x44,0x49,0xE3,0x40,0xAB,0xA8,0xA0,0x60,0x23,0x49,0xE3,0x40,0x7A,0x68,0x5E,0x56, + 0x64,0x51,0xE3,0x40,0x3D,0xB5,0x35,0x3D,0xC8,0x7A,0xA5,0x59,0x2D,0x2D,0x2D,0xBD, + 0x4A,0x93,0xA8,0x7A,0x2F,0x2D,0x8B,0xCD,0x4B,0x93,0xA8,0x7A,0x80,0xE8,0x5E,0x57, + 0x09,0x83,0x47,0x72,0x00,0xAA,0xFF,0xD7,0x4A,0x8B,0x87,0x72,0x02,0xAF,0xF5,0xD5, + 0x0C,0xA4,0xE8,0x82,0x2A,0xAF,0xBD,0xBD,0x6E,0xB4,0x09,0x8B,0x2A,0xFA,0x7B,0x5F, + 0x6E,0xB4,0x05,0x6A,0x80,0x7A,0x5F,0x57,0xA8,0x82,0xC4,0x61,0xFC,0xBE,0xAF,0xAD, + 0x46,0x7A,0xC5,0x69,0xBC,0xFE,0xFE,0xD6,0x47,0x82,0xE5,0x79,0xE2,0xAF,0xB5,0x35, + 0xA8,0x92,0x06,0x7A,0xA7,0x89,0x8B,0x8B,0x2A,0x9B,0x67,0x8A,0x25,0x3D,0x2B,0x0B, + 0xF7,0xFE,0x0D,0xB4,0x09,0x03,0x01,0x09,0x38,0xFF,0xF7,0xF6,0xBF,0xFF,0xBF,0xFF, + 0x38,0xFF,0x17,0xF7,0xFF,0xBF,0xFD,0xFB,0x38,0xFF,0x17,0xF7,0x5E,0x5F,0xF7,0x7F, + 0x38,0xFF,0xF7,0xF6,0x57,0x5F,0x7F,0xFA,0x18,0xFF,0xF7,0xF6,0x77,0x5D,0xB5,0xAE, + 0x17,0xFF,0xB6,0xEE,0x2A,0x0A,0xC0,0x60,0xF7,0xFE,0x55,0xE6,0xA0,0xFC,0xFF,0xFF, + 0xB6,0xF6,0x75,0xEE,0x82,0x02,0xAB,0x57,0xB6,0xF6,0x55,0xE6,0x70,0x7A,0xBA,0xDF, + 0xF7,0xFE,0xB3,0xD5,0x97,0x0F,0x02,0xAA,0xF7,0xFE,0xD7,0xF6,0xD5,0x7A,0xEA,0xAB, + 0xF7,0xF6,0xD7,0xF6,0xE3,0xEF,0xE3,0xF9,0xF7,0xF6,0xD7,0xF6,0x55,0x5F,0x76,0xEA, + 0xF7,0xF6,0xB6,0xEE,0xAB,0xBF,0xBB,0xB2,0xD7,0xF6,0xB7,0xEE,0x08,0x80,0xE8,0x80, + 0xD7,0xF6,0xB7,0xEE,0xA0,0xA8,0xE8,0xA6,0xB6,0xF6,0xD7,0xEE,0xAB,0xAB,0xAF,0xFA, + 0xD7,0xF6,0xB7,0xEE,0xFF,0xBB,0xAA,0xEA,0xB7,0xF6,0xF7,0xEE,0xAA,0xAA,0xAA,0x6E, + 0xF8,0xF6,0xD7,0xF6,0xD5,0x55,0xFD,0x2B,0xF8,0xF6,0xD7,0xF6,0x0F,0x0B,0x0A,0x0A, + 0x18,0xFF,0xD7,0xF6,0x2A,0x2B,0xBB,0xFF,0x39,0xFF,0x97,0xEE,0x78,0x7A,0x72,0x6A, + 0x96,0xEE,0x76,0xE6,0xB8,0x80,0xA8,0xBD,0xB7,0xF6,0x56,0xEE,0x3F,0xBF,0xAF,0xAE, + 0xB7,0xF6,0x30,0xC5,0xD8,0xD8,0xF8,0x58,0xB7,0xF6,0x34,0xE6,0x09,0x89,0x29,0x89, + 0x76,0xEE,0x72,0xCD,0xF8,0xF8,0x78,0x58,0xD3,0xD5,0x71,0xCD,0x2B,0xAE,0xFE,0xD5, + 0x92,0xD5,0x6D,0xAC,0xD4,0x96,0x16,0x36,0x34,0xE6,0x92,0xD5,0xBD,0xAF,0x2B,0x0F, + 0x96,0xEE,0x34,0xE6,0xE1,0xEB,0xCB,0x8B,0x55,0xE6,0x35,0xE6,0xA2,0xBE,0xFA,0xAC, + 0xD6,0xF6,0xB6,0xEE,0xAA,0xAA,0xAA,0x02,0xD7,0xF6,0xB6,0xEE,0xAA,0xA8,0xBA,0x28, + 0xD6,0xF6,0xB7,0xE6,0x20,0x02,0xC0,0xA2,0xD6,0xF6,0xB6,0xEE,0x8A,0x2A,0x0B,0x02, + 0xD7,0xF6,0xD6,0xEE,0xAA,0x2A,0xB2,0x22,0xF8,0xF6,0xD6,0xF6,0x7D,0x5F,0x77,0xDD, + 0xD6,0xF6,0xB6,0xEE,0x56,0xF7,0x5E,0x9E,0xD6,0xF6,0xB6,0xEE,0x75,0xF5,0xD5,0xB6, + 0xD6,0xF6,0xB6,0xEE,0x9D,0xD7,0xFD,0xBB,0xF8,0xF6,0xD7,0xF6,0x5D,0xF5,0xFF,0xBD, + 0xF6,0xF6,0xD7,0xF6,0x55,0xDD,0xFC,0xFE,0xF6,0xF6,0xD7,0xF6,0xFD,0x75,0x5F,0x6E, + 0xF8,0xFE,0x76,0xE6,0x6A,0xE8,0xCA,0xAA,0x51,0xC5,0x02,0x41,0x56,0x56,0x54,0x5C, + 0x84,0x51,0x23,0x41,0xF7,0xFD,0x8D,0x9D,0x44,0x49,0x03,0x41,0x56,0x94,0xF4,0x36, + 0x06,0x62,0x03,0x41,0xB5,0xBF,0x2B,0x23,0x67,0x72,0xC5,0x59,0x29,0x0B,0x2A,0xD7, + 0x09,0x83,0x46,0x6A,0x2A,0xAB,0xFF,0xFD,0xA8,0x7A,0x27,0x6A,0xA8,0xE8,0xFE,0xFB, + 0x88,0x72,0x26,0x6A,0xA8,0x2E,0xEB,0x6F,0xA7,0x7A,0x26,0x6A,0x2F,0xBF,0xB7,0xD5, + 0x6A,0x93,0xA7,0x7A,0x29,0xBD,0xD5,0x55,0x6A,0x93,0x47,0x72,0xA0,0xA2,0xEA,0x7F, + 0x88,0x7A,0xA4,0x61,0x78,0x78,0x5E,0xDF,0x68,0x7A,0xE5,0x69,0x0D,0x2D,0xED,0xED, + 0x47,0x7A,0x23,0x59,0xB8,0xF8,0xDE,0xDE,0x26,0x82,0x84,0x69,0x2B,0x0B,0x0B,0x2D, + 0x67,0x8A,0x26,0x82,0x02,0xDA,0x7A,0xDD,0x49,0x9B,0x67,0x8A,0x2D,0x35,0xBD,0xE9, + 0xF7,0xFE,0x0C,0xB4,0x09,0x09,0x09,0x09,0x18,0xFF,0xF7,0xF6,0x2A,0x2A,0xBA,0xAA, + 0x38,0xFF,0xF7,0xF6,0x3B,0xAE,0xFB,0xEF,0x18,0xFF,0x38,0xF7,0xEB,0xAA,0xAA,0xA8, + 0x38,0xFF,0x18,0xFF,0xBA,0xAA,0x8A,0xFA,0x38,0xFF,0xD7,0xF6,0xAA,0xAA,0xCA,0x6A, + 0x18,0xFF,0xB6,0xEE,0x58,0x5E,0xF7,0xFF,0xD6,0xF6,0x96,0xEE,0xFF,0xFF,0x68,0x7A, + 0x95,0xEE,0x91,0xD5,0xA0,0xE0,0x70,0x88,0x76,0xEE,0xF0,0xC4,0xA2,0xB7,0x2D,0x02, + 0x55,0xEE,0x51,0xCD,0x2F,0xD7,0xF8,0xF0,0xD7,0xF6,0xD4,0xDD,0x02,0x03,0x0F,0x2D, + 0xF7,0xF6,0xD7,0xF6,0xA9,0x2B,0xBA,0xAD,0xD8,0xFE,0xF7,0xF6,0xD5,0x75,0x77,0xDD, + 0xF7,0xF6,0xD7,0xF6,0x5E,0xA7,0x88,0x56,0xF7,0xF6,0xB7,0xEE,0xAA,0xE8,0xEA,0xFF, + 0xF7,0xF6,0xB7,0xEE,0xFF,0xDE,0xF5,0xAB,0xF7,0xF6,0xB7,0xF6,0xFF,0xAB,0xAA,0x08, + 0xF7,0xF6,0xB7,0xEE,0xBF,0xAB,0x00,0x00,0xF8,0xF6,0xD7,0xF6,0x8A,0xEA,0xA0,0xAA, + 0xF8,0xF6,0xD7,0xF6,0x2A,0x0A,0xA2,0x6E,0xF7,0xF6,0xD8,0xF6,0x02,0x00,0xF8,0xFB, + 0xD7,0xF6,0xF8,0xEE,0xAA,0x82,0x22,0x0A,0x18,0xFF,0xB7,0xEE,0x4A,0xEA,0xEB,0xEF, + 0xB6,0xEE,0x76,0xEE,0x77,0x5F,0x5E,0x74,0x96,0xEE,0x55,0xEE,0x22,0x2A,0x2A,0x37, + 0xB6,0xF6,0x31,0xC5,0xD8,0xD8,0xD8,0xD8,0x96,0xEE,0x14,0xE6,0x01,0x09,0x0B,0x09, + 0x96,0xEE,0x72,0xCD,0x58,0x78,0x78,0x68,0x72,0xCD,0x51,0xC5,0x2A,0x9B,0xC2,0x7B, + 0xD3,0xD5,0xCF,0xBC,0x37,0x2F,0x2A,0x0B,0x34,0xE6,0xD3,0xD5,0x3D,0x39,0x3B,0xAF, + 0x96,0xEE,0x55,0xE6,0xCF,0xAB,0xA1,0xAB,0x76,0xEE,0x55,0xE6,0x57,0x57,0x9C,0x1E, + 0xD6,0xF6,0xB7,0xEE,0x80,0xA8,0xE8,0xA2,0xD7,0xF6,0xF6,0xEE,0x88,0xA0,0x00,0x00, + 0xD7,0xF6,0xD6,0xEE,0xAA,0xA8,0xAA,0xAA,0xD7,0xF6,0xF6,0xEE,0x20,0x2A,0xA8,0x80, + 0xF7,0xF6,0xD7,0xF6,0x59,0xD5,0xFD,0xBD,0xF7,0xF6,0xD7,0xF6,0xFF,0xDF,0xAF,0xA3, + 0xD6,0xF6,0xB7,0xEE,0xA8,0xEA,0xA0,0xB0,0xD6,0xF6,0xB6,0xEE,0xDB,0xFE,0xB2,0x82, + 0xD7,0xF6,0xB6,0xEE,0xBF,0xBE,0x6E,0xAE,0xF8,0xF6,0xD7,0xF6,0xBF,0x55,0xDD,0xD9, + 0xF7,0xF6,0xD7,0xF6,0x5F,0xFF,0xBF,0xEF,0xF7,0xF6,0xD7,0xF6,0xAA,0xAA,0xAE,0xE2, + 0xF7,0xF6,0xD7,0xF6,0x76,0x76,0x76,0xDD,0x54,0xE6,0x23,0x41,0x5C,0x5C,0x5C,0x58, + 0xC5,0x59,0xA2,0x38,0xBF,0xBD,0xBD,0x2B,0x06,0x62,0x23,0x49,0xF5,0xBF,0x0B,0x00, + 0x26,0x6A,0xA5,0x59,0xFD,0xFB,0xA0,0x80,0xE5,0x61,0xA5,0x59,0xBF,0x65,0xE6,0x38, + 0x47,0x6A,0xE6,0x61,0x2F,0xA5,0xFF,0x0B,0x47,0x72,0xE5,0x61,0x2A,0x3E,0xD7,0x5E, + 0x68,0x72,0xE5,0x61,0xE8,0xFE,0x55,0x55,0x46,0x6A,0xE5,0x61,0x8E,0xBF,0xBD,0x55, + 0xA8,0x7A,0xC5,0x61,0x02,0xAA,0xFF,0x5D,0x68,0x72,0xC4,0x61,0xE0,0x7A,0x57,0x55, + 0x88,0x82,0xA4,0x61,0xD5,0xAD,0x8F,0x0B,0xA8,0x82,0xA5,0x69,0xFE,0xFA,0x6A,0x70, + 0x85,0x61,0xE3,0x58,0xB8,0xFE,0xBF,0xAF,0x67,0x82,0x64,0x61,0xBD,0xB5,0xA5,0x25, + 0xA8,0x8A,0x26,0x82,0x7D,0xFD,0xAB,0x02,0x6A,0x9B,0x46,0x82,0xFD,0xBD,0xBF,0x17, + 0xF7,0xFE,0x8F,0xBC,0x09,0x09,0x03,0x03,0xF7,0xFE,0x17,0xF7,0xFA,0xEE,0xAE,0xEF, + 0x18,0xFF,0xF7,0xF6,0x2F,0xAB,0x82,0xAA,0x17,0xFF,0xF7,0xF6,0xAA,0xFA,0x5E,0x76, + 0x17,0xFF,0xD7,0xF6,0x20,0x0A,0x0B,0x42,0x17,0xFF,0xB6,0xEE,0xE0,0x7C,0xDF,0x75, + 0x18,0xFF,0xB6,0xEE,0x7D,0xF7,0xFD,0x2B,0xF8,0xFE,0xF3,0xDD,0xEA,0x7A,0x7A,0xC0, + 0xF8,0xFE,0xD3,0xD5,0x0B,0x09,0x0B,0x02,0xF7,0xFE,0x76,0xEE,0x7E,0x70,0x60,0xC0, + 0x76,0xEE,0xF4,0xDD,0x70,0x48,0x88,0x88,0x76,0xEE,0xD3,0xD5,0x2D,0x2D,0x2F,0xBE, + 0xF7,0xFE,0x96,0xEE,0xAA,0x8B,0x29,0x29,0xF7,0xF6,0xD7,0xF6,0xEB,0xEC,0xFA,0xA0, + 0xF7,0xF6,0xD7,0xF6,0xF5,0xF3,0xB9,0xD1,0xF7,0xF6,0xD7,0xF6,0xB5,0x2B,0xEF,0x75, + 0xF7,0xF6,0xD7,0xF6,0xD6,0xF6,0xF7,0xFF,0xF7,0xF6,0xD7,0xF6,0xAA,0xBE,0xBF,0xF9, + 0xF7,0xF6,0xD7,0xF6,0xA6,0xAF,0xBA,0xCA,0xF7,0xF6,0xD7,0xF6,0x80,0xA2,0x0A,0xAA, + 0xF7,0xF6,0xD7,0xF6,0x8E,0x82,0x88,0xB5,0xF7,0xF6,0xD7,0xF6,0x08,0x00,0xC8,0x72, + 0xF8,0xF6,0xB7,0xEE,0xFA,0x78,0xFE,0x5F,0xF8,0xF6,0xB7,0xEE,0x8B,0x8B,0xAB,0xB5, + 0xB6,0xEE,0x76,0xE6,0x76,0xF6,0xBE,0xAC,0x96,0xEE,0x76,0xEE,0x35,0x88,0xD8,0xD6, + 0x96,0xF6,0x51,0xCD,0xD8,0xD8,0xF8,0xD8,0x96,0xEE,0x14,0xDE,0x89,0x8B,0x8B,0xAB, + 0x55,0xEE,0x72,0xCD,0x60,0x60,0x40,0x60,0x51,0xCD,0xAF,0xB4,0xA0,0xE8,0xF8,0x7E, + 0x34,0xE6,0xF0,0xBC,0xA9,0x2D,0x29,0x09,0x54,0xE6,0x14,0xE6,0xD7,0xDF,0xBA,0x9A, + 0x96,0xEE,0x55,0xE6,0xA9,0x2B,0x03,0x0F,0xB6,0xEE,0x55,0xE6,0xF7,0xFF,0xF7,0x27, + 0xD7,0xF6,0xB6,0xEE,0xAA,0xA8,0x0A,0x02,0xD7,0xF6,0xB6,0xEE,0xAA,0xAA,0xAA,0xA8, + 0xD6,0xF6,0xB7,0xEE,0xA2,0x22,0x22,0x02,0xF7,0xF6,0xB6,0xEE,0xAA,0xBA,0xEB,0xBB, + 0xD7,0xF6,0xF7,0xEE,0xA0,0x80,0x28,0x8A,0xF7,0xF6,0xD7,0xF6,0xEB,0x6D,0x56,0x5E, + 0xF7,0xF6,0xB6,0xEE,0xEA,0xAA,0xAF,0xFF,0xD7,0xF6,0xF6,0xEE,0x88,0x80,0xA2,0x80, + 0xF7,0xF6,0xB6,0xEE,0xF6,0xFA,0xFA,0xAA,0xF7,0xF6,0xD7,0xF6,0xE9,0xFD,0xE0,0x8A, + 0xF7,0xF6,0xD7,0xF6,0xAA,0xAA,0xBE,0xAE,0xF7,0xF6,0xD7,0xF6,0xA9,0xAF,0xEB,0xAA, + 0xF7,0xF6,0x97,0xF6,0x22,0xA8,0xC8,0x6A,0x75,0xEE,0xA4,0x59,0x78,0x78,0x7C,0xFE, + 0xA7,0x7A,0x83,0x51,0xF5,0xBF,0x2A,0x08,0x09,0x8B,0x06,0x6A,0x55,0xFF,0xEB,0x02, + 0xE9,0x82,0x26,0x6A,0x55,0x7F,0xFA,0x88,0x87,0x72,0xC4,0x59,0x7F,0x57,0x7E,0x70, + 0xC8,0x7A,0xA4,0x59,0xAF,0x2B,0x25,0xAD,0x88,0x72,0xE5,0x61,0x58,0x58,0x78,0x5C, + 0x05,0x62,0xA4,0x59,0xBF,0x2F,0x27,0xFF,0x27,0x6A,0xE5,0x61,0x55,0xD5,0x70,0x55, + 0x06,0x62,0x84,0x59,0x62,0x78,0xAA,0x08,0xC8,0x82,0xA4,0x59,0x95,0x25,0x2F,0x0A, + 0xAC,0xA3,0x87,0x7A,0xF5,0xAB,0x2A,0x02,0x6B,0xA3,0xE6,0x71,0x7A,0xEA,0xAC,0x28, + 0x2A,0x9B,0xC5,0x69,0x55,0x7B,0xE0,0x00,0x8B,0xA3,0xE5,0x71,0xB5,0xB5,0xBF,0xF0, + 0xC9,0x92,0xC5,0x69,0xA0,0xE8,0xFA,0x7E,0x76,0xF6,0x46,0x72,0x95,0xB5,0x25,0x0D, + 0xF7,0xFE,0x35,0xEE,0x01,0x02,0x00,0x00,0xF8,0xFE,0x17,0xF7,0xF9,0xFB,0xCE,0xBE, + 0x17,0xFF,0xF7,0xF6,0xCA,0xEA,0xEA,0xDA,0x17,0xFF,0xD7,0xF6,0xEA,0xAE,0x8A,0x6A, + 0x18,0xFF,0x96,0xE6,0xE2,0xB8,0xFE,0x7F,0xD7,0xF6,0x14,0xDE,0x00,0x20,0xEA,0x7E, + 0x38,0xFF,0x34,0xDE,0x02,0x0A,0x29,0x09,0x38,0xFF,0x55,0xE6,0x70,0xE8,0xA8,0xA0, + 0x18,0xFF,0xB7,0xEE,0x2D,0x29,0xAA,0x0F,0x18,0xFF,0xD7,0xF6,0x6A,0xEA,0xAA,0x88, + 0xD7,0xF6,0x55,0xE6,0xD7,0x5E,0x7C,0x78,0x76,0xEE,0x14,0xE6,0xDE,0x5A,0xEA,0xEA, + 0xF8,0xFE,0x55,0xE6,0x89,0x2D,0x2D,0xA5,0x18,0xFF,0xD7,0xF6,0xA9,0xBD,0xBF,0xFF, + 0x18,0xFF,0xD7,0xF6,0x5F,0x7E,0xFA,0xAB,0xF7,0xF6,0xD7,0xF6,0x75,0x55,0x57,0xF8, + 0xF7,0xF6,0xD7,0xF6,0xA7,0x6D,0x6D,0xAB,0x17,0xF7,0xD7,0xF6,0x7D,0xD5,0xFD,0xAA, + 0xF8,0xFE,0xD7,0xEE,0x7F,0xBF,0xAA,0x28,0x18,0xFF,0xD7,0xF6,0xFD,0xFA,0xAB,0xFA, + 0xD8,0xFE,0xF7,0xF6,0x55,0x55,0xF5,0xDD,0xF7,0xF6,0xB7,0xEE,0xE8,0xE8,0xFA,0x7A, + 0xB6,0xEE,0x56,0xE6,0xA0,0xA8,0x28,0x2C,0xD7,0xF6,0x96,0xEE,0x07,0x03,0x02,0x00, + 0xB6,0xF6,0x56,0xEE,0xBA,0x7E,0xEA,0xEE,0x96,0xEE,0x35,0xE6,0x88,0x2B,0x2A,0x2A, + 0x76,0xEE,0x72,0xCD,0xD8,0xD0,0xD8,0xF8,0x96,0xEE,0x15,0xE6,0x8B,0x89,0xAF,0xE9, + 0x56,0xEE,0xB3,0xD5,0x60,0x60,0x6A,0x6A,0xF1,0xC4,0x6E,0xAC,0xE8,0xF8,0x7E,0xDC, + 0x34,0xE6,0xEF,0xC4,0x29,0x09,0x0B,0x0B,0x55,0xE6,0x14,0xDE,0xBE,0x97,0xFE,0x3E, + 0x96,0xEE,0x35,0xE6,0x0B,0x3B,0x57,0x5F,0xD7,0xF6,0x35,0xE6,0x2F,0x2F,0x8D,0x2B, + 0xD6,0xF6,0xB6,0xEE,0x02,0x00,0xE2,0x02,0xD6,0xF6,0xB6,0xEE,0x22,0xCA,0x88,0xA8, + 0xD6,0xF6,0xB6,0xEE,0x02,0x2B,0xAA,0x88,0xD7,0xF6,0xD6,0xEE,0xAA,0xA2,0xAA,0x2A, + 0xD7,0xF6,0xF6,0xEE,0x82,0x0A,0x80,0x0A,0xD6,0xF6,0xF7,0xEE,0x08,0x82,0x82,0x08, + 0xD6,0xF6,0xB6,0xEE,0xBA,0xBE,0xFE,0xFC,0xD6,0xF6,0xB6,0xEE,0x02,0x23,0xAB,0xAA, + 0xD6,0xF6,0xF7,0xEE,0xA8,0xA2,0xA0,0x08,0xF7,0xF6,0xD6,0xF6,0x08,0x02,0x8F,0xFD, + 0xF7,0xF6,0xD6,0xF6,0xB8,0x02,0x00,0xAB,0xD7,0xFE,0xF7,0xF6,0xBD,0xF7,0xD5,0xF5, + 0xD7,0xF6,0x13,0xE6,0xC0,0xC0,0x40,0x40,0x8D,0xB4,0x86,0x72,0x5C,0x5C,0x56,0x56, + 0xA8,0x7A,0x06,0x6A,0x2A,0xEF,0xFF,0x5C,0xE8,0x8A,0xE5,0x61,0x02,0xAA,0x5F,0x75, + 0xC8,0x82,0x05,0x62,0xA8,0xFE,0xF5,0xDD,0x87,0x72,0x84,0x51,0xE8,0x7A,0x7E,0x7E, + 0xE5,0x61,0x43,0x49,0x02,0xAB,0xD7,0xDF,0xE6,0x61,0x84,0x51,0xAA,0xAB,0xE5,0x29, + 0x26,0x6A,0xA5,0x59,0x5F,0xBF,0xAF,0x3F,0x67,0x72,0xC5,0x59,0xF5,0xFD,0xA7,0x2B, + 0x29,0x93,0xE5,0x61,0xD5,0xFF,0x2B,0x0B,0x4A,0x9B,0x66,0x7A,0xAD,0x2B,0x8A,0x02, + 0x2E,0xBC,0x4A,0x9B,0x2D,0x2D,0x2D,0x3D,0x8F,0xC4,0x2A,0x9B,0x5F,0xE8,0x80,0x00, + 0xEC,0xAB,0xC9,0x8A,0x9D,0xD7,0xFE,0xF8,0xAC,0xAB,0x05,0x6A,0xE0,0xE8,0xFA,0x5F, + 0x30,0xCD,0x26,0x72,0x55,0xD5,0xB5,0x2D,0xD7,0xFE,0x2A,0x93,0x09,0x0B,0x02,0x00, + 0x18,0xFF,0xF7,0xF6,0xEE,0xEB,0x83,0xAB,0x17,0xFF,0xF7,0xF6,0xAB,0xBF,0xAE,0xEA, + 0x17,0xFF,0xD7,0xF6,0xBA,0xBE,0xAE,0xFA,0x18,0xF7,0x95,0xEE,0x60,0x7C,0x5E,0xB5, + 0x17,0xFF,0x75,0xE6,0x77,0xF7,0xAB,0x00,0x17,0xFF,0xB3,0xD5,0x7E,0xFA,0xA8,0xA0, + 0x18,0xFF,0x75,0xE6,0x01,0x02,0x00,0x00,0x39,0xFF,0xD7,0xF6,0x70,0xF0,0xE8,0xE0, + 0x18,0xFF,0xD7,0xF6,0xAD,0x2F,0xAF,0xEF,0x18,0xFF,0xF8,0xF6,0xEE,0xDD,0xAB,0xBB, + 0xF8,0xFE,0x55,0xE6,0x78,0x60,0xC0,0x80,0x75,0xEE,0x34,0xE6,0x6A,0xEA,0xEA,0xF8, + 0xD7,0xF6,0x34,0xE6,0x2F,0x35,0xBD,0xBF,0xF7,0xF6,0xB7,0xF6,0x20,0xAA,0xAB,0xAB, + 0x18,0xFF,0xF8,0xF6,0xF5,0xD5,0xBF,0x55,0xF8,0xF6,0xD7,0xF6,0x3A,0xBC,0xE0,0x00, + 0x18,0xFF,0xF8,0xF6,0x57,0x6B,0xD5,0x55,0xF8,0xFE,0xF7,0xF6,0xD5,0xD5,0x5F,0x5F, + 0x18,0xFF,0xF7,0xF6,0x75,0xF7,0xFD,0xD5,0xF7,0xF6,0xD8,0xF6,0x00,0x00,0xA8,0xE8, + 0xF7,0xF6,0xD7,0xF6,0xE8,0x7A,0xFA,0x7A,0xD7,0xF6,0x96,0xEE,0xB0,0xE8,0xF2,0x7A, + 0xD7,0xEE,0x75,0xEE,0x2F,0xBF,0x37,0xB7,0xD7,0xF6,0xB6,0xEE,0x00,0x00,0xBE,0xEA, + 0x96,0xEE,0x35,0xE6,0x2A,0xAC,0xA6,0x96,0x76,0xEE,0x55,0xE6,0x08,0x2E,0x38,0x0A, + 0x76,0xEE,0x92,0xCD,0xD8,0xD8,0xD8,0xD8,0x76,0xEE,0x14,0xDE,0xC9,0xC1,0xA9,0xEB, + 0x35,0xE6,0xB3,0xD5,0x68,0x6A,0x6E,0x7E,0x51,0xCD,0xEC,0xA3,0xBE,0x96,0x97,0x36, + 0x95,0xEE,0x72,0xD5,0xAD,0xA9,0x8F,0x0B,0xB7,0xF6,0x14,0xDE,0xB7,0x37,0x2F,0xA8, + 0xB7,0xF6,0x35,0xE6,0xFF,0xF8,0xBE,0x57,0xB6,0xEE,0x55,0xEE,0x03,0x8A,0xAA,0x7B, + 0xF7,0xF6,0xB6,0xEE,0x8F,0xEF,0xEF,0xAB,0xD7,0xF6,0xD6,0xEE,0xAA,0xAA,0xAA,0xAA, + 0xD6,0xF6,0xF6,0xEE,0x00,0xA0,0xA0,0x82,0xD7,0xF6,0xD6,0xEE,0xAA,0xAA,0x2A,0x2A, + 0xD6,0xF6,0xD7,0xEE,0x2A,0xA2,0xAA,0x8A,0xD6,0xF6,0xD6,0xEE,0x8A,0xAA,0x2A,0xA2, + 0xD6,0xF6,0xB6,0xEE,0xAE,0xDC,0xFB,0xBA,0xD6,0xF6,0xB6,0xEE,0xEF,0xBA,0xEE,0xBB, + 0xD6,0xF6,0xB6,0xEE,0x0A,0x83,0xBA,0xAE,0xD6,0xF6,0xB6,0xEE,0x00,0x82,0x80,0xAA, + 0xD6,0xF6,0xF7,0xEE,0xA8,0xAA,0x80,0x00,0xD7,0xFE,0xF6,0xEE,0xAB,0xAB,0x3E,0x2A, + 0xB6,0xF6,0x49,0x8B,0x80,0xE0,0x60,0x60,0x49,0x8B,0x43,0x49,0xA8,0xFE,0x5F,0x5F, + 0x87,0x72,0xE2,0x38,0xA8,0xAE,0xDF,0x55,0x06,0x62,0x23,0x41,0x00,0x2A,0xFF,0x55, + 0x05,0x62,0xE2,0x38,0xA0,0xEE,0xDF,0x55,0xA4,0x59,0x02,0x39,0x80,0xAA,0xBD,0xB5, + 0xA8,0x7A,0x44,0x51,0xF5,0xAD,0x0B,0x0B,0x87,0x7A,0xE5,0x61,0x55,0x7E,0xF8,0x78, + 0x27,0x6A,0xE5,0x61,0xDC,0x70,0xD7,0xB7,0xCC,0xA3,0x26,0x6A,0xF5,0xAD,0x2D,0xAD, + 0x2D,0xB4,0x29,0x93,0x55,0xFF,0x82,0x0A,0x4D,0xBC,0x29,0x9B,0xD5,0xD5,0x7E,0xF8, + 0x0D,0xB4,0x29,0x93,0x2B,0x3F,0xF5,0x5F,0xAF,0xCC,0x8B,0xA3,0x82,0xAB,0xDD,0x55, + 0xEC,0xAB,0x67,0x7A,0xF8,0x78,0x58,0x5E,0xEC,0xAB,0x06,0x72,0x57,0x55,0xD5,0x3F, + 0xD7,0xFE,0xE8,0x82,0x2D,0x29,0x0B,0x02,0x18,0xFF,0xF7,0xFE,0xBD,0xAF,0x09,0x01, + 0x17,0xFF,0xF8,0xF6,0xA2,0x08,0xA2,0xA8,0x17,0xFF,0xF7,0xF6,0x7A,0xFA,0xAE,0x6A, + 0x18,0xFF,0xB7,0xEE,0x78,0xDA,0xBE,0xAF,0x39,0xFF,0xD6,0xF6,0xF5,0xAF,0xAB,0x0A, + 0x59,0xFF,0xD7,0xFE,0xAA,0xAA,0x8A,0x60,0xF8,0xFE,0xF4,0xDD,0xB8,0x1C,0x36,0x2F, + 0x38,0xFF,0x18,0xFF,0xBD,0xBD,0xBD,0xFD,0x39,0xFF,0xF8,0xF6,0xE8,0x78,0x7A,0x5A, + 0x18,0xFF,0xF8,0xF6,0xA5,0xA5,0xED,0xED,0x18,0xFF,0xF8,0xF6,0xFF,0xAB,0x0B,0xAD, + 0x18,0xFF,0xD7,0xF6,0xE2,0xA2,0xA2,0xA0,0xF7,0xF6,0x55,0xE6,0x57,0x7E,0xF8,0xE8, + 0xB6,0xF6,0x55,0xE6,0x35,0xB7,0xBB,0xAE,0xF7,0xF6,0xB7,0xF6,0x8B,0x89,0x0D,0x2B, + 0xF7,0xF6,0xD7,0xF6,0x00,0x0B,0x2B,0x0A,0xD7,0xFE,0xF8,0xF6,0x7D,0xDF,0x5D,0x55, + 0xF7,0xF6,0xD7,0xF6,0x88,0x02,0x00,0x82,0xF7,0xF6,0xD7,0xF6,0x08,0x2B,0x5F,0x78, + 0xF7,0xF6,0xD7,0xF6,0x38,0xAA,0xFA,0xEA,0xF7,0xF6,0xD7,0xF6,0xF8,0x7A,0x7B,0x7F, + 0xF7,0xF6,0xB6,0xEE,0xB2,0xFA,0xFB,0x7F,0xD7,0xF6,0x55,0xE6,0xE8,0x7A,0x7A,0x5F, + 0xD7,0xF6,0x55,0xEE,0x2D,0x2D,0x2D,0x2B,0xD7,0xF6,0x96,0xF6,0xAA,0xE8,0xA8,0x6A, + 0x75,0xEE,0xD3,0xD5,0x2C,0xBC,0xB6,0xF6,0x96,0xEE,0x55,0xE6,0xAB,0xBF,0xAB,0xAD, + 0x55,0xE6,0x92,0xD5,0xD8,0xF8,0xD8,0xD8,0x76,0xEE,0xF3,0xDD,0x8B,0xAB,0xAB,0xA9, + 0x34,0xEE,0xB3,0xDD,0xFE,0x6A,0x7E,0x7C,0x72,0xD5,0x6E,0xAC,0x37,0x3F,0x2E,0x2A, + 0x96,0xF6,0x31,0xCD,0x0B,0xAF,0xFF,0x77,0x55,0xEE,0x31,0xCD,0xA0,0xFA,0xFF,0x55, + 0xF3,0xDD,0x51,0xCD,0xA8,0x2F,0xAD,0x2B,0x75,0xEE,0xF4,0xDD,0x81,0xBB,0xF9,0xAF, + 0xD6,0xF6,0xF2,0xDD,0x00,0x00,0x08,0xAD,0xF7,0xF6,0xB6,0xEE,0xAB,0xAB,0xAF,0xFF, + 0xD6,0xF6,0xB7,0xEE,0x08,0x02,0x0A,0x08,0xD6,0xF6,0xF7,0xEE,0xA0,0x02,0x82,0x2C, + 0xD6,0xF6,0xF6,0xEE,0x00,0x0A,0x88,0x00,0xD6,0xF6,0xF7,0xEE,0x28,0x00,0x88,0x28, + 0xF6,0xF6,0xB6,0xEE,0x7F,0xBB,0xAA,0xBA,0xD6,0xF6,0xB6,0xEE,0xEF,0x88,0x00,0x00, + 0xD6,0xF6,0xB6,0xEE,0xFF,0x3B,0x20,0x80,0xD6,0xF6,0xB6,0xEE,0xAB,0xFB,0xA2,0xA0, + 0xD6,0xF6,0xB6,0xEE,0x02,0x02,0x00,0x2A,0xD6,0xF6,0xB6,0xF6,0xA0,0xE0,0xC8,0xE8, + 0x75,0xEE,0x86,0x72,0xE0,0x60,0x60,0x70,0x05,0x62,0xC2,0x30,0xE8,0xEC,0xFA,0x7E, + 0x02,0x39,0xA1,0x28,0x7C,0xFF,0x7E,0x56,0x03,0x39,0xA1,0x28,0xAB,0xFF,0x3F,0xF5, + 0x23,0x41,0xC2,0x30,0xEF,0x29,0x29,0xAF,0xE5,0x69,0x23,0x41,0xF5,0xB5,0x35,0x3D, + 0x09,0x93,0x06,0x6A,0xAD,0xAB,0x82,0x02,0x87,0x7A,0x23,0x41,0xE8,0xFA,0x5E,0x5C, + 0xC5,0x61,0x03,0x41,0x00,0x0F,0xB5,0xD5,0x29,0x93,0x84,0x51,0x2B,0xAB,0xBF,0xFD, + 0xCC,0xAB,0x47,0x72,0x0A,0xAB,0xB7,0xF5,0x0D,0xB4,0x2A,0x93,0x80,0x82,0xAB,0xAD, + 0xAB,0xAB,0x09,0x8B,0x78,0xE0,0xE2,0x60,0x29,0x93,0x67,0x7A,0x80,0xEE,0x5E,0x57, + 0xEC,0xAB,0x67,0x7A,0x57,0xFF,0xAD,0x2D,0x8E,0xBC,0xA8,0x82,0x35,0x3D,0xBF,0xBF, + 0xD7,0xFE,0xEF,0xC4,0x02,0x03,0x03,0x2D,0x18,0xFF,0xF7,0xFE,0x2E,0xA6,0xAE,0xBD, + 0x18,0xFF,0xF7,0xF6,0xA2,0x82,0x02,0xCA,0x18,0xFF,0xB6,0xEE,0xE0,0xB8,0xFE,0x7E, + 0x38,0xFF,0xB6,0xEE,0xBF,0xEF,0xBF,0x35,0x59,0xFF,0x18,0xFF,0xA5,0xA9,0xAA,0x8A, + 0x39,0xFF,0x96,0xEE,0xE0,0x60,0x78,0x58,0x18,0xFF,0x55,0xE6,0x37,0xA7,0x27,0x2D, + 0x39,0xFF,0x18,0xFF,0xF5,0xBD,0xD5,0xD5,0x39,0xFF,0xF8,0xF6,0xFA,0xFA,0xFC,0xFA, + 0x18,0xFF,0xF8,0xF6,0x7E,0x7F,0x57,0x96,0x18,0xFF,0xF8,0xF6,0x2B,0xEB,0xEE,0xAB, + 0x18,0xFF,0xF8,0xF6,0x62,0xEA,0xCA,0xEA,0xF7,0xF6,0x96,0xEE,0x5A,0xFA,0xF8,0xB8, + 0xD7,0xF6,0x75,0xEE,0xDF,0xFE,0xB8,0xA0,0xF8,0xF6,0xB6,0xF6,0x09,0x0D,0x25,0x37, + 0x18,0xFF,0xD7,0xF6,0xAF,0xBF,0x3E,0xBF,0x18,0xFF,0xF7,0xF6,0x57,0x7E,0x80,0xAA, + 0x18,0xFF,0xD7,0xF6,0xDF,0xAB,0xBA,0xAA,0xF8,0xFE,0xF7,0xF6,0x7F,0xFF,0xFD,0xFF, + 0xF7,0xF6,0xB6,0xF6,0xA2,0x68,0x7A,0x5A,0xD7,0xF6,0x76,0xEE,0x80,0xEB,0x7E,0x7A, + 0xB6,0xF6,0x55,0xE6,0x88,0x7E,0x7F,0xFB,0x96,0xEE,0x55,0xE6,0xD6,0xA5,0x2D,0x02, + 0xD7,0xF6,0x76,0xEE,0x8D,0x8F,0x2F,0xAF,0xB6,0xF6,0x96,0xEE,0x5E,0xEF,0x2B,0xE5, + 0x55,0xE6,0xB3,0xD5,0xB4,0xBE,0xF4,0xBE,0x75,0xEE,0x35,0xE6,0x83,0x8D,0xF9,0xAD, + 0x55,0xEE,0x92,0xD5,0xFC,0xDC,0xDC,0xDE,0x55,0xEE,0x51,0xCD,0x02,0xA2,0xFA,0x5A, + 0x14,0xE6,0x72,0xCD,0xA0,0x80,0x82,0xA9,0x51,0xCD,0x6E,0xB4,0x28,0x2E,0x2E,0x36, + 0x72,0xCD,0x31,0xC5,0x80,0xE0,0x5C,0x5C,0x92,0xD5,0x30,0xC5,0x37,0x2D,0x0F,0x2D, + 0xF4,0xDD,0x92,0xD5,0xBD,0xA5,0xA5,0x2D,0x55,0xE6,0xD3,0xDD,0x2B,0xA7,0xB7,0x75, + 0x92,0xD5,0xE8,0x82,0x2F,0xD5,0x55,0x55,0x95,0xEE,0x08,0x83,0x00,0xAD,0xD5,0x55, + 0xB5,0xF6,0x28,0x83,0x00,0x00,0x2F,0xD5,0xB6,0xF6,0x6D,0xB4,0x00,0x00,0x00,0x2D, + 0xF7,0xF6,0x95,0xF6,0xAA,0x2B,0xAA,0xBD,0xF7,0xF6,0xD6,0xF6,0xDD,0x9F,0x5D,0x75, + 0xF7,0xF6,0xB6,0xF6,0xAA,0x38,0xBB,0x7F,0xF6,0xF6,0xD6,0xF6,0xF5,0x7E,0xF7,0x5D, + 0xF6,0xF6,0xD6,0xF6,0x7B,0x57,0x56,0x57,0xF7,0xFE,0xD6,0xF6,0x5F,0xFB,0x55,0x57, + 0xD6,0xF6,0xB6,0xF6,0x3A,0xA2,0x00,0x00,0xF7,0xF6,0xB6,0xF6,0xFF,0xFF,0xEA,0xAA, + 0x75,0xEE,0x26,0x62,0x70,0x70,0x70,0x60,0x84,0x49,0xE2,0x30,0xF8,0x7C,0x7E,0xFE, + 0x03,0x39,0x61,0x20,0xFE,0x5E,0xDA,0x80,0x02,0x39,0x81,0x20,0xAD,0xBD,0x2B,0x2A, + 0x02,0x39,0xC2,0x30,0xBE,0x2F,0xBB,0xF0,0x46,0x7A,0x03,0x41,0xBD,0x35,0x3D,0x2D, + 0x09,0x93,0x67,0x7A,0x83,0x83,0xCB,0x7F,0x47,0x72,0xE2,0x38,0x78,0x5C,0x7C,0x5E, + 0x44,0x49,0xC2,0x30,0x3F,0x35,0xBD,0xBD,0xE5,0x61,0xA1,0x30,0x02,0x0A,0xAA,0x55, + 0xE8,0x82,0xE3,0x40,0x2A,0x0A,0xAF,0xD5,0x8A,0xA3,0xE5,0x61,0x0A,0xAA,0xAB,0xBD, + 0xAB,0xA3,0xC8,0x82,0xE0,0xFA,0x7B,0x55,0xE9,0x8A,0x46,0x7A,0x9F,0xB7,0xAF,0x2F, + 0xEB,0xA3,0xE9,0x8A,0x2D,0x2D,0xF7,0xD7,0xEC,0xAB,0x88,0x7A,0xF8,0x70,0x6A,0xFE, + 0xEF,0xC4,0x06,0x6A,0x2F,0xF5,0x55,0x57,0xB6,0xF6,0x25,0x6A,0x00,0x2D,0x35,0xB5, + 0x18,0xFF,0x75,0xEE,0xA0,0xE2,0xFF,0xFD,0xD6,0xF6,0x96,0xEE,0xAA,0xAE,0xCF,0x38, + 0x59,0xFF,0xB7,0xEE,0xAD,0x0D,0x8B,0x22,0x59,0xFF,0x18,0xFF,0xEA,0xE8,0xFE,0x7A, + 0xF7,0xFE,0x55,0xE6,0xF0,0x7C,0x5C,0x5F,0xF8,0xFE,0x55,0xE6,0x0D,0x2D,0x0D,0x0D, + 0x39,0xFF,0xF8,0xF6,0xAB,0xAB,0x29,0xAF,0x39,0xFF,0xF8,0xF6,0xEA,0xFA,0x6A,0xEA, + 0x18,0xFF,0xF8,0xF6,0x7D,0xB7,0x5E,0xDB,0x18,0xFF,0xF8,0xF6,0xAF,0xFB,0xFD,0xF7, + 0x18,0xFF,0xF8,0xF6,0xFA,0x6A,0xEF,0x5F,0xF7,0xF6,0x97,0xEE,0xA8,0xA8,0xAA,0xA2, + 0xF7,0xF6,0xD7,0xF6,0x55,0x5F,0xAB,0xAA,0xF8,0xF6,0xB7,0xF6,0x37,0x3B,0x2A,0x22, + 0x18,0xFF,0xF7,0xF6,0x5F,0xDF,0x5A,0x7B,0x18,0xFF,0xF8,0xF6,0xBB,0xAA,0xBF,0xEF, + 0xF7,0xFE,0x18,0xF7,0xAF,0xBD,0xAF,0xFF,0xF7,0xF6,0xD7,0xF6,0xA0,0x00,0xE0,0x58, + 0xD7,0xF6,0x96,0xEE,0xE0,0xEC,0x7A,0x76,0xB7,0xF6,0x76,0xEE,0xF8,0xFA,0x5E,0x55, + 0x96,0xEE,0x55,0xE6,0xEA,0x7A,0xFA,0x5B,0x76,0xEE,0x55,0xE6,0x8B,0x2D,0xB9,0x2F, + 0xB6,0xF6,0x76,0xEE,0xA3,0xEB,0xEA,0xAA,0xB6,0xF6,0x76,0xEE,0xAB,0x8F,0xEB,0xCB, + 0x14,0xE6,0x72,0xCD,0xAC,0xBC,0xB4,0xD6,0x75,0xEE,0xF4,0xE5,0x2B,0x8B,0xAB,0xA9, + 0x34,0xE6,0xB3,0xD5,0xDC,0xDC,0xD4,0xDE,0x14,0xE6,0x30,0xC5,0x58,0x58,0x68,0xE0, + 0xB3,0xD5,0x10,0xC5,0x09,0x2D,0x35,0x9F,0x31,0xC5,0x4D,0xAC,0x26,0x26,0xA6,0x36, + 0x31,0xCD,0xF0,0xBC,0x3C,0x3F,0x37,0xEA,0x92,0xD5,0x31,0xC5,0x2F,0xAF,0xA7,0xA5, + 0xF3,0xDD,0x72,0xD5,0x2F,0xAF,0xAD,0xAD,0xD3,0xDD,0x51,0xCD,0x82,0xEA,0x72,0x58, + 0xE8,0x82,0xC7,0x7A,0x00,0x8E,0xFE,0x98,0x08,0x83,0xC7,0x7A,0xFE,0xA2,0xFB,0xDB, + 0x08,0x83,0xC7,0x82,0x2B,0x2E,0xFE,0xFD,0xEB,0x9B,0xE8,0x82,0x3F,0x75,0x55,0x55, + 0x55,0xEE,0xE8,0x82,0x0A,0xF5,0x55,0x55,0xB5,0xF6,0xE7,0x82,0x00,0x0A,0xBD,0x55, + 0xB6,0xF6,0x8A,0x9B,0x00,0x00,0x02,0xF5,0xD6,0xF6,0xF4,0xE5,0x00,0x08,0x02,0x2D, + 0xF6,0xFE,0xB6,0xF6,0xAE,0xAF,0xFF,0xD5,0xF8,0xFE,0xD6,0xF6,0xDF,0x5F,0xD5,0x55, + 0xD7,0xFE,0xD6,0xF6,0xD5,0x7F,0x7F,0xFF,0xF6,0xFE,0xD7,0xF6,0x7E,0x5D,0x7B,0x7A, + 0xB6,0xF6,0x86,0x72,0x60,0x60,0xC0,0xC0,0xE6,0x59,0x23,0x41,0x55,0x57,0x5E,0xE8, + 0x84,0x49,0x23,0x41,0x7F,0xFB,0x55,0x3A,0x64,0x49,0xE2,0x30,0xD7,0xEC,0xBA,0xF8, + 0x23,0x41,0xE2,0x38,0x7F,0xF6,0xBB,0x29,0x46,0x7A,0x44,0x49,0x2D,0x2D,0x0D,0x2F, + 0x66,0x7A,0x84,0x59,0xA0,0xE8,0x7A,0x5A,0x64,0x51,0xE3,0x38,0x5C,0x78,0x6E,0xE8, + 0xE2,0x38,0xA2,0x30,0x62,0xE2,0x80,0x08,0xC2,0x30,0x81,0x28,0x97,0xBE,0xEA,0xF8, + 0x23,0x41,0x82,0x28,0x2F,0x2F,0xAF,0x35,0x88,0x82,0x43,0x49,0x2D,0xB5,0x35,0x35, + 0xE9,0x8A,0x67,0x7A,0xAB,0x3D,0x3F,0x7A,0x09,0x8B,0x88,0x7A,0xFB,0xDE,0xD8,0xDF, + 0x29,0x93,0x87,0x7A,0x2B,0xB7,0xFF,0x6F,0x09,0x8B,0xA5,0x59,0xA8,0xF8,0x7A,0x5F, + 0xE8,0x82,0xC5,0x61,0xEE,0xAF,0x2D,0x09,0xCC,0xA3,0xC5,0x61,0x35,0xF7,0xFB,0xFE, + 0xB6,0xF6,0xE9,0x8A,0x02,0x0B,0x2D,0xD5,0x38,0xFF,0x75,0xEE,0xBE,0x2F,0x0A,0x01, + 0x39,0xFF,0x19,0xFF,0x00,0x80,0x20,0xE0,0x39,0xFF,0x96,0xF6,0xC0,0xC8,0x60,0x78, + 0x76,0xEE,0x35,0xE6,0xC8,0x68,0x6E,0x7A,0xF8,0xFE,0x55,0xE6,0x09,0x09,0x09,0x0B, + 0x39,0xFF,0xF8,0xFE,0xAF,0xAF,0xAD,0xAD,0x18,0xFF,0xF8,0xF6,0xE0,0xC0,0xA0,0xA0, + 0x18,0xFF,0xF8,0xF6,0xF7,0xFF,0xDD,0xFE,0x19,0xFF,0xF7,0xF6,0xDF,0xFF,0xFD,0x57, + 0xF8,0xFE,0x17,0xF7,0x2A,0xA2,0x2A,0x2A,0xF7,0xF6,0xD7,0xF6,0x9C,0xFA,0xAA,0xA2, + 0xF8,0xF6,0xD7,0xF6,0xBA,0x3F,0x27,0x2D,0x17,0xFF,0xF8,0xF6,0xDD,0xF7,0x7F,0xFD, + 0x18,0xFF,0xF7,0xF6,0x7F,0xEB,0xE9,0xEB,0x18,0xFF,0xD7,0xF6,0x2A,0xAA,0x2F,0x8F, + 0x18,0xFF,0xF8,0xF6,0xEA,0x6A,0x6F,0x7D,0xF7,0xF6,0xB7,0xEE,0x78,0x78,0x7A,0x5A, + 0xB7,0xF6,0x76,0xEE,0xF8,0x76,0x5E,0x75,0x96,0xEE,0x55,0xE6,0x5F,0x7E,0x8A,0x97, + 0x96,0xEE,0x35,0xE6,0x77,0xF7,0xFA,0x28,0x96,0xEE,0x35,0xE6,0xBF,0xAF,0xB7,0x3F, + 0xB7,0xF6,0x76,0xEE,0xCA,0xFA,0x7E,0x5E,0xB6,0xF6,0x55,0xE6,0xE2,0xEA,0xEA,0x6A, + 0xD3,0xDD,0x31,0xCD,0x3C,0xAC,0xBC,0xB6,0x35,0xE6,0xB3,0xD5,0x02,0x0B,0x0B,0x09, + 0x14,0xE6,0xB3,0xD5,0x9E,0xFC,0x9C,0xBC,0x14,0xE6,0xD3,0xDD,0x7A,0x6C,0xDC,0xF4, + 0xD3,0xDD,0x31,0xC5,0x5E,0x78,0x40,0x40,0x31,0xCD,0x4E,0xAC,0x37,0x37,0x37,0x17, + 0x31,0xCD,0xCF,0xBC,0xA8,0x28,0xBC,0x5E,0x71,0xCD,0x11,0xC5,0x2F,0xAF,0xAF,0xA7, + 0x14,0xE6,0x31,0xC5,0x2B,0x0F,0xBF,0x5F,0xD3,0xDD,0xF0,0xBC,0xF8,0x7C,0xF7,0xB5, + 0xE8,0x82,0xA7,0x7A,0xEF,0x3F,0xAB,0xEA,0xE8,0x82,0xA7,0x7A,0x2C,0xBF,0xDD,0xFF, + 0xE8,0x82,0xC7,0x82,0x2B,0xCA,0x5E,0x7B,0xE8,0x82,0xA7,0x7A,0x8A,0xAA,0xFE,0x2D, + 0xE8,0x82,0xC7,0x82,0xEF,0x2A,0xCB,0xC4,0x08,0x8B,0xC8,0x82,0xAD,0xAD,0x9F,0x56, + 0x49,0x8B,0xC7,0x82,0x3F,0xFF,0x7D,0x55,0xB3,0xDD,0x08,0x83,0x2F,0x55,0x55,0x55, + 0x75,0xEE,0x28,0x8B,0x00,0x2F,0x55,0x55,0x96,0xF6,0x08,0x83,0x00,0x00,0x2B,0xD5, + 0xB6,0xF6,0x8E,0xB4,0x00,0x00,0x00,0x2D,0x95,0xFE,0xD6,0xF6,0x55,0x75,0xFF,0xBA, + 0xB6,0xF6,0x51,0xC5,0x40,0xC0,0x00,0x00,0x13,0xE6,0x84,0x51,0x57,0x57,0x5E,0x58, + 0xC5,0x59,0x64,0x49,0xAA,0x8F,0xAA,0xF5,0x85,0x51,0x23,0x41,0x58,0x5C,0xF8,0xAA, + 0x66,0x7A,0x23,0x49,0x55,0xD5,0xBD,0x2F,0x29,0x93,0x06,0x6A,0xF5,0xED,0xAB,0x8A, + 0x88,0x82,0x84,0x59,0x78,0x68,0xF0,0xE8,0xA5,0x61,0x03,0x41,0x7F,0x7F,0xBA,0xA0, + 0xC6,0x59,0xA2,0x30,0xF5,0xD7,0xFE,0xA2,0x24,0x41,0x81,0x28,0x5E,0x5E,0xFA,0x2A, + 0x64,0x49,0xA1,0x28,0xB5,0xB5,0xAD,0x02,0x67,0x7A,0x43,0x49,0x25,0x2D,0xAD,0xFF, + 0xA8,0x7A,0xA4,0x59,0xC0,0xFA,0x5F,0xF5,0x88,0x7A,0xE5,0x61,0x0B,0xB5,0x55,0xD5, + 0xA8,0x7A,0x23,0x49,0x00,0xE0,0xEA,0x72,0x26,0x6A,0x02,0x49,0xBA,0xB7,0xB5,0x25, + 0xA7,0x7A,0xC5,0x61,0x29,0x2F,0xAE,0xFA,0x09,0x93,0x06,0x72,0xEA,0xEA,0xEB,0x89, + 0x4A,0x93,0x26,0x72,0x2F,0x3F,0xBD,0xB5,0x18,0xFF,0x6A,0x93,0x03,0x09,0x25,0x25, + 0x38,0xFF,0x18,0xFF,0xE2,0xA2,0x79,0x5D,0x18,0xFF,0x75,0xEE,0x70,0x70,0x58,0x5C, + 0x75,0xEE,0x35,0xE6,0x7E,0xEB,0xFA,0xBA,0x18,0xFF,0x96,0xEE,0xA9,0x89,0x89,0x8B, + 0x39,0xFF,0xF8,0xF6,0xAF,0xA9,0xAF,0xEF,0x18,0xFF,0xF8,0xF6,0xA8,0xAE,0xAA,0xEA, + 0x18,0xFF,0xF8,0xF6,0xFF,0xDA,0xF6,0x7F,0x17,0xFF,0xF8,0xF6,0x5F,0x56,0x57,0xD5, + 0xD8,0xFE,0xF7,0xF6,0xDF,0x5D,0x7D,0xDD,0xD7,0xFE,0xF7,0xF6,0xD7,0x7D,0x5E,0xDF, + 0xF7,0xF6,0xD7,0xF6,0x3F,0x98,0xE0,0x2A,0x18,0xFF,0xF8,0xF6,0xF7,0xDD,0xB5,0xBF, + 0x18,0xFF,0xF8,0xF6,0xE3,0xAB,0xFE,0xFE,0xD8,0xFE,0xF7,0xF6,0x55,0x6F,0x7D,0xFF, + 0xF7,0xF6,0xB7,0xF6,0x88,0xE8,0xE8,0xEA,0xD7,0xF6,0x76,0xEE,0xE0,0xF8,0x5E,0xDE, + 0x96,0xEE,0x76,0xEE,0x67,0x77,0x55,0x57,0x76,0xEE,0x35,0xE6,0xEA,0xFB,0xFE,0xEA, + 0x75,0xEE,0x34,0xE6,0xA2,0xFE,0xFA,0x82,0xB6,0xF6,0x55,0xE6,0xA5,0x2F,0xAD,0xBD, + 0xB6,0xF6,0x55,0xEE,0xBC,0xAE,0xBE,0xBF,0xB6,0xF6,0x35,0xE6,0xC2,0xF0,0x62,0xEA, + 0xD3,0xDD,0x31,0xCD,0xBC,0xF6,0xFE,0x7C,0x34,0xE6,0x72,0xCD,0x0B,0xAB,0xAD,0xA9, + 0x14,0xE6,0xB3,0xD5,0xBC,0x3E,0x3F,0xB6,0x14,0xE6,0x10,0xC5,0x88,0x88,0x68,0x56, + 0xD3,0xDD,0xF0,0xC4,0xE0,0x7E,0x55,0x55,0x31,0xC5,0x2D,0xAC,0xB7,0x96,0xDE,0x98, + 0x11,0xC5,0x6E,0xB4,0xB8,0xF8,0xD8,0x50,0x72,0xCD,0xF0,0xC4,0x2F,0xA9,0xA9,0xBB, + 0x51,0xCD,0xF0,0xBC,0x60,0x78,0xDC,0x97,0x71,0xD5,0xF0,0xBC,0x2D,0x0F,0x2B,0x2A, + 0xC8,0x82,0x45,0x72,0x0A,0xAD,0xD7,0xD7,0xE8,0x82,0x45,0x6A,0x0A,0x0A,0xAF,0x5D, + 0xE8,0x82,0x66,0x72,0xA2,0x02,0x8A,0xAD,0xE8,0x82,0xA7,0x7A,0xF2,0xAE,0xB4,0xAA, + 0xE8,0x82,0xA7,0x82,0xAE,0xC2,0x42,0xFE,0xE8,0x82,0xC8,0x82,0x5E,0x7F,0xF5,0xD5, + 0xE8,0x82,0xA7,0x82,0x0B,0x02,0x8B,0x2F,0xC8,0x8A,0xE8,0x82,0xED,0x7D,0x5D,0xEF, + 0x08,0x8B,0xC8,0x82,0xAF,0xEB,0xF6,0xBB,0x08,0x8B,0xC8,0x82,0x2F,0xBF,0x9D,0xBB, + 0x2D,0xAC,0xE8,0x8A,0x2D,0x55,0x55,0x55,0x75,0xF6,0x09,0x8B,0x0A,0xF5,0x55,0x55, + 0xB6,0xF6,0x29,0x8B,0x00,0x0A,0xFD,0x55,0x35,0xEE,0xE5,0x59,0x70,0x70,0x60,0x7F, + 0x64,0x49,0x02,0x41,0xAE,0x3F,0xB5,0xAF,0xA5,0x59,0x43,0x49,0xBA,0xBF,0xAB,0x3D, + 0xC8,0x8A,0xA5,0x59,0x2D,0x2D,0x2F,0xBD,0x29,0x9B,0xC8,0x8A,0x40,0x40,0xAA,0x29, + 0xC9,0x92,0xE5,0x69,0xFA,0x7A,0xD8,0xF8,0x67,0x7A,0xC5,0x61,0xD7,0xBF,0xFF,0xF8, + 0x67,0x7A,0xA5,0x59,0x7F,0xEA,0x80,0xA2,0x06,0x62,0xE2,0x38,0xFF,0xFA,0x7E,0xF8, + 0x85,0x51,0x03,0x41,0x02,0xEA,0xB5,0xFF,0x85,0x59,0x23,0x41,0xA8,0x2F,0x25,0x2B, + 0x47,0x72,0xA4,0x59,0xED,0x0F,0x0B,0x0F,0x88,0x72,0xC5,0x61,0xB5,0xB7,0xAA,0xA0, + 0x46,0x6A,0xE2,0x38,0x70,0x78,0x7C,0x7E,0x67,0x72,0x02,0x41,0x2D,0x2D,0x29,0xAF, + 0x67,0x7A,0xC5,0x61,0x80,0xE8,0x5F,0xDF,0x09,0x8B,0x26,0x72,0x09,0x29,0x0B,0x8B, + 0xC9,0x82,0x67,0x7A,0x2E,0xE0,0xBE,0xF9,0x93,0xDD,0xC8,0x82,0x35,0xB5,0x55,0x55, + 0xF7,0xFE,0x8B,0x9B,0x00,0x02,0x03,0x2D,0xF7,0xFE,0x55,0xEE,0x5C,0xDC,0x5E,0x56, + 0x96,0xEE,0x55,0xEE,0xD7,0xDD,0xB7,0x17,0x18,0xFF,0xB7,0xF6,0xA9,0x89,0xAF,0x89, + 0x39,0xFF,0xF8,0xF6,0xAF,0xE9,0xAF,0xAB,0x18,0xFF,0xF8,0xF6,0xFA,0xFE,0xEA,0x68, + 0x18,0xFF,0xF8,0xF6,0x77,0xDB,0x57,0x5F,0xD7,0xFE,0xF8,0xF6,0x57,0x5D,0xFF,0xFF, + 0xF7,0xF6,0xD6,0xF6,0x2E,0xAE,0x22,0x0A,0x18,0xFF,0xF7,0xF6,0x57,0xFB,0xDA,0xFB, + 0x18,0xFF,0xF7,0xF6,0xEF,0xFF,0x5F,0x55,0x18,0xFF,0xF8,0xF6,0xE7,0xE5,0xDF,0xFF, + 0x18,0xFF,0xF8,0xF6,0x5F,0x7F,0x5E,0xDF,0xF7,0xF6,0xD7,0xF6,0xAA,0xEA,0xE2,0xF8, + 0xF8,0xF6,0x96,0xEE,0xE8,0xFA,0x5E,0x7E,0x96,0xEE,0x76,0xEE,0xD8,0x5C,0x5C,0x57, + 0x76,0xEE,0x56,0xEE,0x72,0x4D,0xF0,0xFA,0x76,0xEE,0x14,0xE6,0xAA,0xA8,0xFA,0x6C, + 0x76,0xEE,0x14,0xE6,0x0E,0xAB,0x0B,0xA9,0x96,0xEE,0x76,0xEE,0x65,0xF5,0xBF,0xBD, + 0x96,0xEE,0x76,0xEE,0x5D,0xF7,0xEF,0xFE,0x96,0xEE,0x35,0xE6,0xCA,0xEA,0x60,0xE0, + 0x14,0xE6,0x72,0xCD,0x76,0xFA,0x88,0x00,0xF4,0xDD,0x72,0xD5,0x09,0x2B,0x0A,0x20, + 0xF4,0xE5,0x31,0xC5,0xA8,0xA8,0xE8,0x60,0x50,0xCD,0xAF,0xB4,0xF8,0xEE,0x7F,0xD7, + 0xF0,0xC4,0x6D,0xAC,0x02,0xA8,0xEA,0x5E,0x71,0xCD,0x8E,0xB4,0x7A,0x62,0xE3,0x8B, + 0x10,0xC5,0x2D,0xA4,0xF0,0x72,0x72,0x62,0x51,0xCD,0xD0,0xBC,0x0B,0x01,0xA9,0x89, + 0x72,0xCD,0xF0,0xBC,0xB7,0xAF,0x2B,0x0B,0x71,0xCD,0x51,0xCD,0xF7,0xEE,0xBF,0xF8, + 0xA7,0x7A,0x66,0x72,0xFD,0xF7,0xEE,0xBA,0xA6,0x7A,0x66,0x72,0x75,0x76,0x79,0xEA, + 0x86,0x72,0x46,0x72,0xA5,0xAE,0x80,0x20,0xC8,0x82,0x25,0x6A,0x0A,0xD7,0xFF,0xFF, + 0xC8,0x82,0x46,0x72,0x00,0x0A,0x95,0x55,0xE8,0x8A,0x46,0x72,0x0A,0x88,0x8A,0xB5, + 0xE8,0x82,0xA7,0x7A,0xEA,0x8A,0xEB,0x2D,0xE8,0x82,0xC8,0x82,0xBF,0xFD,0x51,0x55, + 0xE8,0x82,0xC8,0x82,0xAB,0x62,0x9C,0xCF,0x09,0x8B,0xA7,0x82,0xEA,0xB8,0xFE,0xF6, + 0xE8,0x8A,0xC8,0x82,0xC0,0xC8,0xEE,0xFB,0x08,0x8B,0xC8,0x82,0xF2,0x0B,0xFF,0x6E, + 0xC8,0x8A,0x09,0x83,0xDF,0xBB,0xA2,0xA8,0x08,0x8B,0xC5,0x59,0x60,0x68,0x72,0x78, + 0x84,0x51,0x43,0x49,0xB5,0xF7,0x94,0x55,0xA5,0x59,0x44,0x49,0x3D,0x2F,0x08,0x02, + 0xA8,0x8A,0xC5,0x61,0xB5,0x35,0x2D,0x2F,0xE9,0x92,0x67,0x82,0x0A,0xA2,0x62,0x78, + 0xA8,0x8A,0x26,0x72,0xF0,0x78,0x56,0x57,0x67,0x7A,0xE5,0x69,0xF0,0xEA,0xFF,0x77, + 0x67,0x72,0xA4,0x59,0xEA,0xE0,0xFF,0x57,0x05,0x62,0x44,0x51,0x78,0x7A,0x57,0x57, + 0x64,0x51,0x03,0x41,0xF7,0xB7,0xEB,0xE8,0xA5,0x59,0x23,0x49,0xFD,0xAF,0x35,0x37, + 0x67,0x72,0xC5,0x59,0x3D,0xB5,0xA5,0xED,0x88,0x72,0xE5,0x61,0x68,0x70,0x7E,0xF7, + 0xA4,0x59,0x02,0x41,0x78,0xFA,0xFC,0x3C,0x47,0x72,0x43,0x49,0xF5,0x3D,0x2F,0xAF, + 0xE9,0x8A,0xE6,0x69,0xD5,0xBD,0x3F,0x2B,0x29,0x93,0x47,0x7A,0x6F,0x7A,0xF8,0x78, + 0xE9,0x8A,0x47,0x7A,0x2D,0x35,0xF9,0xC1,0x4A,0x93,0x26,0x6A,0xF8,0xFA,0xFF,0x57, + 0xD3,0xDD,0xC8,0x82,0x2D,0xD5,0xD5,0x55,0x55,0xEE,0x6B,0x9B,0x00,0x02,0x0B,0x0D, + 0xB6,0xF6,0x55,0xEE,0xB7,0x37,0x15,0xB5,0x18,0xFF,0xD7,0xF6,0xE9,0xEB,0xF9,0xE9, + 0x38,0xFF,0xF8,0xF6,0xAB,0xAB,0xEB,0xB9,0x18,0xFF,0xF8,0xF6,0xEA,0xF8,0xF8,0xFA, + 0x18,0xFF,0xD8,0xF6,0xEA,0xFA,0xBE,0xFA,0xF7,0xF6,0xD8,0xF6,0xAA,0xBA,0x2A,0xA2, + 0xD8,0xFE,0xF7,0xF6,0x5F,0xF7,0x57,0x5F,0x18,0xFF,0xF7,0xF6,0x6D,0xBD,0xAD,0xEB, + 0x18,0xFF,0xF8,0xF6,0x75,0xFF,0xFB,0xEA,0x17,0xFF,0xF8,0xF6,0xFA,0xAF,0xFF,0x7F, + 0x18,0xFF,0xB7,0xF6,0xA8,0xEA,0xEE,0x7B,0xD7,0xF6,0x96,0xEE,0x20,0xFE,0x5E,0x5E, + 0xB7,0xF6,0x55,0xE6,0xE0,0xE8,0xFF,0xFF,0x96,0xEE,0x55,0xE6,0xAF,0xBB,0xEA,0xFA, + 0x76,0xEE,0x56,0xEE,0xDE,0xBE,0xBA,0x8C,0x76,0xEE,0x35,0xE6,0x7E,0xE8,0xA0,0x82, + 0x76,0xEE,0x14,0xE6,0x2F,0x3F,0xFE,0xFA,0x96,0xEE,0x35,0xE6,0x02,0x08,0x0A,0x7F, + 0x96,0xEE,0x55,0xEE,0xBE,0x2A,0x82,0xD5,0x96,0xEE,0x34,0xE6,0xC8,0x48,0x62,0x42, + 0x34,0xE6,0xF4,0xDD,0xBC,0x5D,0x55,0x5D,0x14,0xE6,0xD3,0xDD,0xBA,0x7F,0xA5,0xAB, + 0xF4,0xE5,0xAF,0xBC,0xE0,0x60,0x78,0x58,0xCF,0xBC,0x6E,0xB4,0xE8,0x7B,0x7A,0x80, + 0xAF,0xBC,0x0D,0xA4,0xBA,0xDF,0xDF,0xE8,0x51,0xCD,0xAF,0xBC,0x09,0x2D,0x95,0x55, + 0x51,0xCD,0x0D,0xAC,0x68,0x60,0xE0,0xDE,0x31,0xCD,0xAF,0xBC,0x81,0x09,0x0B,0xA3, + 0x92,0xD5,0x31,0xCD,0xA9,0xA9,0xAB,0xA9,0x91,0xD5,0x52,0xCD,0xFA,0xFE,0xEB,0xEA, + 0xA7,0x7A,0x45,0x6A,0x02,0x8A,0x0A,0x8D,0xA7,0x7A,0x86,0x72,0xD4,0x56,0xFE,0xAD, + 0x86,0x7A,0xA7,0x72,0xEA,0xEF,0xEB,0xA7,0xC8,0x82,0x66,0x7A,0xFF,0xDF,0x9E,0xAB, + 0xA7,0x7A,0x66,0x72,0x55,0xFB,0x8B,0xA8,0x87,0x7A,0x66,0x72,0xBD,0xF0,0xC2,0x2C, + 0xA6,0x7A,0x46,0x72,0x2F,0xF7,0xFE,0xEE,0xE8,0x82,0x45,0x72,0x08,0xAF,0x5D,0xD5, + 0xE9,0x8A,0x46,0x72,0x02,0x88,0x2B,0xFD,0xE8,0x8A,0x87,0x7A,0xA8,0x82,0xA8,0xAD, + 0xE8,0x82,0xA7,0x82,0x02,0x8A,0x9D,0xAA,0xE8,0x8A,0xC8,0x82,0xF6,0x2C,0x2F,0x9E, + 0xE8,0x8A,0xA7,0x7A,0xA2,0x82,0x6A,0xAE,0xE8,0x82,0xA4,0x59,0x78,0x78,0x72,0x68, + 0x23,0x49,0xE2,0x38,0x08,0xF8,0xFC,0x5C,0x84,0x59,0xC2,0x30,0x02,0x3F,0xB5,0xD5, + 0xC7,0x8A,0x63,0x51,0x2B,0xAB,0xBF,0xF5,0x09,0x93,0x47,0x7A,0xE2,0x82,0xEA,0x75, + 0x68,0x7A,0x06,0x72,0xA8,0xBC,0xFF,0x68,0x47,0x72,0x64,0x59,0xFE,0x78,0xFA,0xAB, + 0xC5,0x61,0x24,0x51,0xF0,0x7B,0xEB,0xE8,0x64,0x51,0x23,0x49,0x2A,0xD5,0xD7,0xF5, + 0x84,0x51,0x23,0x49,0x5E,0xDE,0x2F,0x7B,0xC5,0x59,0x03,0x41,0x2F,0x0A,0xFA,0xDF, + 0xE6,0x61,0x43,0x41,0x00,0xBA,0xF5,0x55,0xC5,0x59,0x23,0x41,0x00,0x00,0xCA,0x55, + 0x47,0x72,0x64,0x51,0xD5,0xF5,0x2D,0x0D,0x88,0x82,0xC5,0x61,0x75,0xB5,0x2E,0x0A, + 0xC9,0x8A,0x06,0x72,0x0B,0xBE,0xFC,0x78,0xC9,0x8A,0x06,0x6A,0xE0,0xE8,0xBA,0xD5, + 0x87,0x7A,0x64,0x51,0x02,0x8A,0xE8,0x7E,0xC5,0x61,0x03,0x49,0x20,0x9E,0xB7,0xB7, + 0x87,0x7A,0x64,0x51,0x0A,0x3F,0xAD,0xAF,0x15,0xEE,0x67,0x72,0x2F,0xBD,0xD5,0x55, + 0x76,0xEE,0x09,0x8B,0x00,0x02,0xAF,0x55,0xD8,0xFE,0x0D,0xAC,0x00,0x00,0x22,0xF5, + 0x18,0xFF,0x34,0xE6,0x00,0x02,0x02,0x29,0x18,0xFF,0xF8,0xF6,0xFA,0xFA,0xFA,0xAF, + 0xF7,0xFE,0xF8,0xF6,0xFF,0xFF,0xEF,0xFF,0xF7,0xF6,0xD8,0xF6,0x2A,0xA8,0xAE,0x2A, + 0x18,0xFF,0xF7,0xF6,0x57,0xFD,0xF5,0xBF,0xF8,0xFE,0x17,0xF7,0xAA,0xEA,0xBB,0x8E, + 0x18,0xFF,0xF8,0xF6,0xFE,0xFF,0xEE,0xFE,0x18,0xFF,0xD7,0xF6,0xEA,0xEE,0xFB,0x7A, + 0x17,0xF7,0xB7,0xF6,0x7F,0xFE,0x5F,0x5D,0xB7,0xF6,0x76,0xEE,0xF8,0x58,0xF8,0xFE, + 0x75,0xEE,0x35,0xE6,0xAE,0xFE,0xFA,0xF0,0x76,0xEE,0x55,0xEE,0xFE,0xDD,0x1E,0x02, + 0x76,0xEE,0x55,0xEE,0xF9,0xDC,0x58,0xF8,0x76,0xEE,0x55,0xEE,0xE9,0xAE,0xEE,0xAB, + 0x75,0xEE,0x35,0xE6,0x6E,0x68,0xE8,0xAA,0x56,0xEE,0x14,0xE6,0x7F,0xFF,0xBE,0xAE, + 0x96,0xF6,0x35,0xE6,0xB5,0x05,0x3D,0xBF,0x96,0xF6,0xD3,0xDD,0xE0,0x60,0x68,0x7A, + 0x14,0xE6,0xD3,0xDD,0x0B,0x0D,0x09,0x25,0x14,0xE6,0xD3,0xDD,0x80,0x20,0x5C,0xD8, + 0xD4,0xDD,0xF0,0xC4,0x58,0x78,0x78,0x7C,0xF0,0xC4,0xAF,0xBC,0xB0,0xFA,0xDA,0xAA, + 0xF0,0xC4,0x4D,0xAC,0x6A,0x62,0xE0,0x00,0xD0,0xBC,0x6A,0x93,0xA2,0xAA,0xFB,0x5C, + 0x8E,0xB4,0x4B,0x93,0x28,0x2A,0x3F,0x35,0x31,0xC5,0xF0,0xC4,0xA9,0x8B,0xF9,0x75, + 0x72,0xD5,0x10,0xC5,0x23,0xAF,0xAD,0xFD,0x72,0xD5,0x31,0xCD,0x00,0xBA,0xAA,0x57, + 0x45,0x6A,0x05,0x62,0x3A,0xEA,0x7D,0xE6,0x86,0x72,0xE5,0x61,0x02,0xAF,0x6F,0xFE, + 0xA7,0x7A,0x05,0x62,0x80,0x0A,0xAF,0xD5,0xA7,0x7A,0x46,0x72,0x80,0xA8,0x0A,0x95, + 0xA7,0x7A,0x86,0x7A,0xF9,0xB9,0xBB,0xAB,0xA7,0x7A,0x66,0x7A,0xBD,0xB8,0xAA,0xB8, + 0xA7,0x7A,0x46,0x72,0xE8,0xA2,0xA2,0x02,0xA7,0x7A,0x66,0x7A,0x7E,0x3B,0x2A,0x22, + 0xA7,0x7A,0x66,0x7A,0x77,0x5E,0xB8,0x20,0xA7,0x7A,0x66,0x7A,0xE5,0x5D,0xFF,0xE8, + 0xE8,0x82,0x45,0x72,0x02,0xBD,0xD7,0xFE,0xE8,0x82,0x66,0x72,0xA2,0x2A,0xB5,0x55, + 0x08,0x8B,0x87,0x7A,0x2A,0xC8,0xA2,0xBD,0xC7,0x82,0x05,0x62,0x60,0x80,0x00,0x00, + 0xC7,0x82,0xE2,0x40,0x57,0x57,0x5E,0x78,0xE2,0x38,0xA1,0x38,0xFC,0x5E,0x7A,0xE8, + 0x64,0x59,0xA2,0x38,0x0B,0xFD,0xBD,0x3D,0x26,0x72,0x23,0x51,0x2F,0x3D,0x2D,0x2F, + 0x88,0x82,0xE6,0x69,0x6A,0x02,0x00,0x2A,0x88,0x82,0x05,0x6A,0x55,0xFB,0x02,0x96, + 0xE9,0x8A,0x84,0x51,0x7F,0xEA,0xF0,0xEA,0x27,0x6A,0x02,0x41,0xFF,0x7F,0x58,0x5F, + 0x44,0x49,0xC2,0x38,0xE0,0x68,0xFE,0xD7,0x44,0x41,0xE2,0x38,0x2B,0xA9,0xED,0x7F, + 0x44,0x41,0xA2,0x30,0xE0,0x7A,0x5F,0x5F,0xA5,0x59,0x81,0x30,0xFF,0xBD,0xAD,0x2B, + 0x47,0x72,0x43,0x51,0x0D,0x0D,0xAF,0xBF,0x88,0x7A,0x06,0x6A,0xCA,0xEF,0x8B,0xAD, + 0x27,0x72,0x84,0x59,0xE0,0xF8,0x68,0x5A,0xE6,0x61,0x84,0x59,0x09,0x6F,0xAD,0xEB, + 0xC6,0x61,0x23,0x41,0x70,0x72,0x7A,0x7E,0xA5,0x59,0x03,0x41,0xB5,0xB5,0x35,0x35, + 0x47,0x72,0xC5,0x61,0xE9,0x63,0xFB,0x3A,0xE9,0x8A,0x06,0x72,0x29,0x0D,0xAB,0xEA, + 0xC8,0x82,0x26,0x72,0xBC,0x5C,0xFE,0x2F,0x8B,0x9B,0x67,0x7A,0x2B,0xBD,0xBD,0xEF, + 0xF8,0xFE,0xC8,0x82,0x02,0xAB,0xFD,0x55,0xD7,0xFE,0x6A,0x93,0x00,0x02,0xAF,0xD5, + 0xF7,0xFE,0x72,0xD5,0x00,0x00,0x22,0xFD,0xF8,0xFE,0x56,0xEE,0x08,0x08,0x22,0xBD, + 0xF8,0xFE,0xD7,0xF6,0x00,0xAA,0xA8,0xFE,0x18,0xFF,0xD7,0xF6,0xAA,0xAA,0xAB,0xFF, + 0x18,0xFF,0xD8,0xF6,0xAA,0xAF,0xFF,0xEF,0xF8,0xFE,0xB7,0xF6,0x60,0xF2,0xF8,0x5E, + 0xD7,0xF6,0x76,0xEE,0xA0,0xEC,0xFA,0x7E,0xB6,0xF6,0x55,0xEE,0xAA,0xFA,0xFA,0xF5, + 0x96,0xF6,0x55,0xEE,0x7A,0x8A,0xAB,0xEF,0x76,0xEE,0x55,0xEE,0xFB,0x7C,0x98,0x0B, + 0x97,0xF6,0x56,0xEE,0xDE,0x9F,0xE6,0xFA,0x97,0xF6,0x56,0xEE,0x7D,0xFF,0xFA,0xEA, + 0x76,0xEE,0x55,0xEE,0x36,0xEA,0xBA,0xAE,0x75,0xEE,0x35,0xEE,0xB7,0xAE,0x88,0x0A, + 0x76,0xEE,0x34,0xE6,0x5A,0x70,0x7A,0x5F,0x55,0xEE,0xB3,0xD5,0xF0,0x68,0x70,0x78, + 0x14,0xE6,0xB3,0xD5,0x2D,0x2F,0x2B,0xAD,0x75,0xEE,0x14,0xE6,0x7D,0xFF,0xBF,0x2D, + 0x55,0xEE,0x31,0xCD,0x56,0x7C,0xE0,0x80,0xD3,0xDD,0xD0,0xBC,0x55,0xF7,0xDE,0xE8, + 0x72,0xCD,0xF0,0xC4,0xFD,0xAF,0x2B,0xAA,0x31,0xCD,0x09,0x83,0x70,0x70,0xC0,0x80, + 0xAF,0xB4,0xA8,0x7A,0x2D,0x2D,0x35,0xF7,0xF0,0xC4,0x0C,0xA4,0x00,0x0A,0xAA,0xB5, + 0x31,0xCD,0xAF,0xBC,0x0A,0xAB,0x37,0xF5,0x31,0xCD,0xCF,0xBC,0x00,0xEA,0xEB,0xDF, + 0x46,0x72,0x26,0x6A,0xED,0xDE,0x18,0x88,0x46,0x72,0x26,0x6A,0xE5,0x6B,0x08,0x22, + 0x46,0x72,0x05,0x6A,0xBF,0xAA,0xFE,0xDA,0x46,0x72,0x05,0x6A,0xFF,0x6E,0xD7,0xBA, + 0xA7,0x7A,0x05,0x6A,0x2F,0x7D,0xDF,0xFF,0xA7,0x7A,0x26,0x6A,0x00,0x2B,0xD7,0x55, + 0xA7,0x82,0x25,0x6A,0x08,0xA0,0x2A,0x95,0xA7,0x7A,0x87,0x7A,0xAF,0xFA,0xFF,0xA5, + 0xA7,0x7A,0x87,0x7A,0x8B,0x0F,0x2D,0xFC,0xC7,0x82,0x66,0x72,0x7F,0xFF,0x3A,0xF8, + 0xA7,0x82,0x87,0x7A,0xFF,0xBD,0xFF,0x0C,0xA7,0x82,0x66,0x7A,0xE6,0xFA,0xAA,0x08, + 0xC7,0x82,0x66,0x72,0xD5,0xBB,0xFE,0x8B,0xC8,0x82,0x66,0x72,0x0B,0xF7,0xFF,0xAA, + 0xC7,0x82,0x84,0x59,0x70,0xC2,0xA2,0x28,0x46,0x72,0xE3,0x40,0x55,0x57,0xFC,0xE8, + 0x64,0x59,0xE2,0x40,0xAD,0x2D,0x8E,0x88,0xA5,0x61,0x03,0x49,0x2F,0x57,0x5F,0x5F, + 0x27,0x72,0xE3,0x48,0x0A,0xAF,0xF5,0xF5,0x67,0x7A,0x44,0x51,0x00,0xAA,0xFD,0x5D, + 0x47,0x7A,0xE3,0x40,0xA0,0xFA,0xFF,0x7F,0x44,0x51,0xA2,0x30,0xE0,0xBA,0xFE,0xD7, + 0x44,0x41,0xC2,0x38,0xF7,0xEF,0xBB,0x2A,0x44,0x41,0xE3,0x38,0x7F,0xEF,0xEA,0x83, + 0x23,0x41,0xA2,0x30,0xDE,0xDE,0xBE,0x2A,0xA5,0x59,0x03,0x41,0x2D,0x0D,0x2D,0x03, + 0x06,0x72,0x84,0x59,0x35,0xFD,0xCA,0xA2,0x06,0x6A,0xA4,0x61,0x2A,0xFD,0xD5,0xDE, + 0xE5,0x69,0x24,0x49,0xB8,0xFA,0xFE,0x5E,0xE5,0x61,0x23,0x49,0x8B,0x2A,0xAF,0xB5, + 0x84,0x51,0x03,0x41,0xF8,0xF8,0xD6,0xF6,0xC6,0x59,0x02,0x41,0x2D,0x2D,0xAA,0xE3, + 0x88,0x7A,0x44,0x51,0x2A,0x0B,0x2F,0xB5,0x88,0x82,0xE5,0x69,0x4A,0xF8,0x58,0xA0, + 0xC9,0x8A,0x05,0x6A,0x2D,0x2F,0xBF,0xEF,0x0A,0x93,0x67,0x7A,0xA0,0xE2,0x7F,0x5D, + 0x88,0x7A,0x26,0x72,0x26,0x3D,0xBD,0x01,0x2A,0x93,0x26,0x72,0x3E,0xB7,0xD7,0xFF, + 0xEC,0xA3,0x88,0x7A,0xF8,0x57,0x55,0x55,0xD3,0xDD,0x68,0x7A,0x0B,0xFD,0xD5,0x55, + 0x34,0xE6,0x88,0x7A,0x00,0xBF,0xD5,0x55,0x96,0xF6,0xA8,0x7A,0x00,0x02,0xFF,0x55, + 0xB7,0xF6,0x6A,0x93,0x00,0x00,0x03,0xBD,0xD7,0xF6,0x35,0xE6,0x88,0xA8,0xAA,0xFD, + 0x96,0xEE,0x55,0xEE,0xC0,0xE8,0xAE,0xFF,0x96,0xF6,0x35,0xE6,0xAE,0x8A,0x7E,0xD7, + 0x76,0xEE,0x34,0xE6,0x28,0xAE,0xBF,0x55,0x76,0xEE,0x35,0xEE,0x00,0x00,0xA0,0xFB, + 0x97,0xF6,0x35,0xE6,0xAA,0xA2,0xAA,0xD5,0x96,0xF6,0x35,0xE6,0x22,0x02,0xF8,0xDF, + 0x76,0xEE,0x55,0xEE,0xD4,0x57,0xE5,0x25,0x96,0xF6,0x55,0xEE,0xD5,0xFD,0xEB,0x2A, + 0x76,0xEE,0x35,0xE6,0xFB,0xF8,0x70,0x70,0x35,0xEE,0x92,0xD5,0x70,0x78,0x78,0x70, + 0x15,0xE6,0x92,0xD5,0x25,0x3D,0xAD,0xA9,0x35,0xE6,0xF4,0xE5,0x0A,0xDF,0x85,0x0D, + 0x96,0xEE,0x35,0xE6,0xED,0x89,0x29,0x2B,0x76,0xEE,0x92,0xD5,0x6A,0x00,0x00,0x00, + 0x75,0xEE,0x51,0xCD,0x55,0x57,0xFC,0xF0,0xB2,0xD5,0x10,0xC5,0x7B,0xEF,0xAE,0xA8, + 0x72,0xCD,0x47,0x6A,0x57,0x5C,0x78,0xF0,0x0D,0xA4,0x06,0x62,0x0B,0xB5,0xD5,0x5F, + 0xAF,0xBC,0x88,0x72,0x00,0x22,0xAD,0x55,0xCF,0xBC,0x2B,0x8B,0x00,0x02,0x0B,0x0D, + 0x66,0x72,0x26,0x6A,0xBA,0x7E,0x8C,0x0C,0x46,0x72,0x25,0x6A,0x20,0x08,0x00,0x30, + 0x66,0x72,0x26,0x6A,0x7F,0xB1,0xBB,0x2A,0x66,0x72,0x25,0x6A,0xFD,0xEE,0xFE,0x3C, + 0x66,0x72,0x25,0x6A,0x6F,0xAE,0xAF,0x1F,0x46,0x72,0x26,0x6A,0xB9,0x29,0x3B,0x00, + 0x46,0x72,0x26,0x6A,0x95,0xCC,0xAB,0x80,0x87,0x7A,0x25,0x6A,0x29,0xDF,0x7D,0x7D, + 0xA7,0x7A,0x25,0x6A,0x20,0x2D,0xD5,0x57,0xC7,0x82,0x25,0x6A,0xAA,0xA8,0x2F,0xFD, + 0xA7,0x82,0x67,0x7A,0xA8,0x80,0xA8,0xBD,0xA7,0x82,0x87,0x7A,0x28,0xE0,0x8A,0xC8, + 0xC7,0x8A,0xA7,0x7A,0x55,0x7D,0xFD,0xEF,0xC7,0x82,0x86,0x7A,0xAE,0xA9,0x82,0xA2, + 0xC8,0x82,0x86,0x7A,0x7F,0xBB,0xBB,0x3E,0xC8,0x82,0x64,0x59,0x7A,0x68,0xA8,0x20, + 0xC8,0x8A,0x64,0x59,0x55,0xDD,0xFA,0xA0,0x67,0x72,0x44,0x59,0x55,0xFF,0xFA,0xE0, + 0xA5,0x59,0x24,0x49,0xBF,0xE8,0xF8,0x5E,0x85,0x51,0xE2,0x38,0xA0,0xAA,0xFE,0x5E, + 0x64,0x51,0xC2,0x30,0x68,0x5A,0x5F,0x7D,0x03,0x39,0xA2,0x30,0xB5,0xEF,0xAF,0x03, + 0x44,0x41,0xC2,0x30,0x83,0xAA,0x7E,0x7A,0x44,0x49,0xC2,0x38,0xAE,0xBF,0xBD,0x3D, + 0x64,0x51,0x03,0x41,0x35,0x8F,0xC8,0xA0,0xA5,0x59,0x23,0x49,0x0F,0x3D,0xBD,0xAF, + 0x47,0x7A,0xA5,0x59,0xB2,0x2B,0x29,0xA5,0x67,0x7A,0x44,0x51,0xFA,0x68,0x70,0x7A, + 0xA5,0x59,0xC2,0x38,0xB8,0xFA,0xF7,0xD7,0xA5,0x59,0x23,0x41,0xFB,0x6B,0xE9,0x09, + 0xA5,0x51,0x03,0x41,0xDE,0xFF,0xB5,0xFC,0xA5,0x51,0x23,0x49,0xEB,0xBB,0xE8,0x5F, + 0x68,0x7A,0x03,0x41,0x2F,0xAD,0x2D,0x25,0x4B,0x93,0xA7,0x82,0xA9,0x8D,0xAE,0x5D, + 0xE9,0x8A,0xA5,0x59,0xFA,0xF8,0x7E,0x5E,0x67,0x7A,0xE6,0x61,0x2B,0x2B,0xAF,0xBD, + 0xC9,0x8A,0x27,0x72,0x2F,0xAA,0xBF,0x35,0x09,0x93,0xA8,0x82,0x5F,0x7A,0x2E,0xBF, + 0xE9,0x8A,0x47,0x7A,0x55,0x5F,0xF8,0xE8,0x67,0x7A,0xE5,0x69,0x7F,0xAA,0x8A,0xF8, + 0x87,0x7A,0xE5,0x69,0xAD,0xAB,0x02,0xAB,0x87,0x72,0x26,0x6A,0x78,0xEA,0xDF,0x5A, + 0x4E,0xAC,0x47,0x6A,0x25,0xD5,0x55,0x55,0x55,0xEE,0x88,0x72,0x02,0x03,0xF5,0x55, + 0x35,0xE6,0x6A,0x93,0x00,0x00,0x0A,0xB5,0x55,0xEE,0xD3,0xDD,0xA8,0xA2,0xAA,0xA9, + 0x34,0xE6,0xF4,0xE5,0xA0,0xA8,0xFA,0xDE,0x35,0xE6,0xF4,0xE5,0x02,0x8E,0x2F,0xDD, + 0x34,0xE6,0xF4,0xDD,0xFE,0x57,0xFC,0xEF,0x35,0xE6,0xD3,0xDD,0x2F,0x29,0xBB,0xAF, + 0x96,0xF6,0x34,0xE6,0xAD,0xAF,0x37,0xB5,0x96,0xF6,0x35,0xE6,0x82,0xA8,0x72,0x5F, + 0x55,0xEE,0x35,0xE6,0xC0,0x2A,0xAD,0xF5,0x35,0xE6,0x72,0xD5,0x78,0xA0,0x00,0x00, + 0x35,0xEE,0x92,0xD5,0xB5,0xBD,0xA8,0x80,0x34,0xE6,0xF4,0xDD,0x0B,0xBA,0xDF,0xDB, + 0x96,0xEE,0x14,0xE6,0x8B,0x0B,0x0F,0x2D,0x96,0xEE,0x76,0xEE,0xE8,0xF8,0x8A,0xA8, + 0x76,0xEE,0xD3,0xDD,0x70,0xC0,0x00,0x00,0x55,0xEE,0x72,0xD5,0x7F,0x7F,0x7A,0xE0, + 0xF3,0xDD,0xF1,0xC4,0x62,0x0A,0x0A,0x0A,0xB3,0xDD,0xE9,0x82,0x57,0xE0,0x00,0x00, + 0x72,0xD5,0x67,0x72,0x55,0xFF,0xA8,0x80,0xCF,0xBC,0xE9,0x82,0x09,0x03,0x02,0x28, + 0x66,0x72,0x46,0x72,0x25,0xD6,0x9C,0xBE,0x66,0x72,0x25,0x72,0xAE,0x89,0xA8,0xA0, + 0x67,0x72,0x46,0x72,0xD9,0xA3,0x66,0xB6,0x66,0x7A,0x46,0x72,0xAF,0xCF,0x7C,0xB2, + 0x66,0x72,0x46,0x72,0xFE,0xF4,0xBD,0x5D,0x66,0x72,0x46,0x72,0x5E,0x16,0xF8,0xF3, + 0x67,0x7A,0x26,0x72,0x7F,0x8F,0x2D,0xA8,0x66,0x7A,0x26,0x6A,0xDF,0xEF,0xA8,0xC3, + 0x66,0x72,0x25,0x72,0xE2,0xAB,0xEA,0xEE,0x66,0x72,0x25,0x6A,0x6F,0xDF,0x9A,0xBA, + 0x66,0x72,0x25,0x6A,0x2F,0x7F,0x67,0xA8,0xC7,0x82,0x26,0x6A,0x8A,0xAD,0x7D,0xFF, + 0xC8,0x8A,0x46,0x72,0xAA,0x8A,0x9D,0xD5,0xC7,0x82,0x66,0x7A,0x22,0x0A,0xAA,0xB5, + 0xC7,0x82,0xA7,0x82,0x09,0x02,0x0A,0x07,0xE8,0x8A,0x87,0x7A,0x7A,0xEA,0x00,0x0A, + 0x09,0x93,0x46,0x72,0x7A,0xEB,0xE8,0x68,0x87,0x7A,0x23,0x49,0xE0,0xF8,0xFA,0x7E, + 0x65,0x51,0xC2,0x30,0x88,0xFA,0x5E,0x57,0x23,0x41,0x81,0x28,0xF8,0xDF,0xDF,0xD5, + 0xE3,0x30,0xA2,0x28,0x02,0xAA,0xAF,0xBF,0x03,0x39,0xA2,0x28,0xA2,0xA2,0xEA,0xDE, + 0xE3,0x30,0xA2,0x30,0x00,0xAA,0xFA,0xFF,0x84,0x51,0xC2,0x30,0xB7,0xBF,0x25,0x0D, + 0x84,0x51,0xE3,0x40,0xE0,0xAE,0xB6,0xD7,0xA5,0x59,0x44,0x51,0xF5,0x2F,0x2F,0xFB, + 0x27,0x72,0x85,0x59,0x35,0x35,0xA7,0xA5,0xE6,0x61,0x03,0x41,0xF8,0xF8,0x7A,0x7C, + 0x44,0x49,0xC3,0x38,0xEE,0x7A,0x7C,0xBA,0xC6,0x59,0xE3,0x38,0x2D,0x0D,0x0B,0xAB, + 0xC6,0x59,0x44,0x49,0xF0,0x5C,0x70,0x7A,0x44,0x49,0xE3,0x38,0xE8,0xFE,0x76,0xAE, + 0xA5,0x59,0xE3,0x38,0x25,0xB5,0xFD,0xFB,0x67,0x72,0x44,0x49,0x82,0xFA,0x7F,0x75, + 0xE5,0x61,0x44,0x49,0xE0,0xBF,0xF5,0x55,0xE6,0x61,0x43,0x51,0x2B,0xBF,0xBF,0xB5, + 0x67,0x7A,0x84,0x59,0x0B,0x2D,0x2F,0x3F,0xE9,0x8A,0x06,0x72,0x2A,0xBE,0xDA,0x5F, + 0xE9,0x92,0x67,0x7A,0x78,0xEF,0xAD,0xE9,0xC9,0x8A,0x27,0x72,0x5E,0xF0,0xC0,0x88, + 0x87,0x7A,0xC4,0x61,0xAB,0x7F,0xFA,0xA8,0x47,0x72,0x84,0x59,0x00,0x0B,0xFF,0x5E, + 0x26,0x6A,0x84,0x51,0x80,0xA0,0xFB,0x55,0x67,0x72,0xA5,0x59,0x2A,0xFD,0xF5,0xD5, + 0x0C,0xA4,0x26,0x6A,0x2F,0xBD,0xD5,0x55,0x34,0xEE,0x0A,0x8B,0x02,0x0A,0x2D,0xD5, + 0x35,0xEE,0x31,0xCD,0xA0,0xA8,0x22,0xAD,0x14,0xE6,0xB3,0xDD,0xEA,0x6B,0xA2,0x88, + 0x14,0xE6,0xB3,0xDD,0xCA,0xAF,0xFA,0x6A,0xF4,0xE5,0xD3,0xDD,0x2E,0x9F,0x97,0xD5, + 0x55,0xE6,0xF4,0xDD,0x0B,0xAB,0xAF,0xEF,0x34,0xE6,0xF4,0xDD,0x80,0x2A,0xAF,0xD5, + 0x55,0xEE,0x14,0xE6,0xAA,0xAF,0xAF,0xCD,0x34,0xE6,0xF4,0xDD,0xD6,0x5E,0x7A,0x67, + 0x34,0xE6,0xF4,0xDD,0xBF,0xAF,0xB5,0xFD,0x14,0xE6,0xF4,0xDD,0x20,0x28,0x82,0x02, + 0x96,0xEE,0x14,0xE6,0x2F,0x0D,0x2D,0x25,0x76,0xFE,0x96,0xEE,0x77,0xDD,0x75,0x5D, + 0x96,0xEE,0x76,0xEE,0xF8,0xC2,0x8A,0xA0,0x96,0xEE,0x35,0xE6,0x7A,0x88,0xA2,0xE2, + 0x76,0xEE,0x93,0xD5,0xD7,0xF8,0xE0,0xFA,0x15,0xE6,0xB3,0xD5,0xAA,0x8B,0xAF,0xD7, + 0xF4,0xDD,0x92,0xD5,0x7A,0x80,0x0A,0xAA,0xD3,0xDD,0xCC,0x9B,0x5A,0xE0,0x80,0x00, + 0x66,0x72,0x45,0x72,0xC3,0x2B,0x02,0x83,0x66,0x7A,0x46,0x72,0xBA,0xB4,0xFD,0x42, + 0x87,0x7A,0x46,0x72,0xEA,0xBA,0xDB,0x7F,0x87,0x7A,0x46,0x72,0xFD,0xED,0xBA,0xBB, + 0x66,0x72,0x25,0x72,0x1A,0xAA,0x88,0x82,0x87,0x7A,0x46,0x72,0xF5,0xFE,0xB3,0xEA, + 0x86,0x7A,0x46,0x72,0x7D,0xFD,0xEE,0xFC,0x87,0x7A,0x25,0x6A,0xEF,0xAF,0xAA,0x88, + 0x66,0x7A,0x46,0x72,0x79,0xB8,0x76,0xC2,0x66,0x7A,0x46,0x72,0xEC,0x4C,0x6C,0xC4, + 0x66,0x7A,0x46,0x72,0x17,0x72,0x8F,0xC6,0x87,0x7A,0x46,0x72,0x77,0x7D,0xBE,0xEA, + 0x87,0x7A,0x46,0x72,0x5F,0x7D,0xB5,0x8A,0x87,0x7A,0x25,0x72,0xFD,0xAF,0xEB,0x8A, + 0xA7,0x82,0x46,0x72,0x0A,0xBF,0x7D,0x6F,0xE8,0x8A,0x46,0x72,0x0A,0x0F,0xB7,0x1F, + 0x09,0x8B,0xE5,0x69,0x70,0x70,0x78,0x78,0xA4,0x59,0xC2,0x38,0xF8,0x5E,0x7C,0x78, + 0xC2,0x30,0x82,0x28,0x60,0xF0,0xC8,0xC0,0xE2,0x30,0x82,0x20,0xD5,0x7F,0xBF,0xAE, + 0xC2,0x28,0xA2,0x28,0xFF,0xFF,0x52,0x3A,0xC2,0x30,0xA2,0x28,0x0A,0xA3,0x7B,0x5C, + 0x03,0x39,0xA2,0x28,0x97,0xBD,0x25,0x2D,0x65,0x49,0xE2,0x38,0xCD,0xFB,0x62,0x62, + 0x24,0x41,0xC2,0x38,0x3F,0x27,0xB7,0x2F,0x64,0x51,0x03,0x41,0xA0,0x0F,0x01,0x83, + 0xC5,0x59,0x23,0x49,0x2D,0xFF,0x7A,0x6A,0x85,0x51,0xE3,0x38,0x78,0x5A,0xFB,0xFE, + 0x24,0x41,0xE2,0x38,0x32,0xF5,0xB5,0xAA,0x65,0x49,0xE3,0x38,0xA2,0xA3,0xFF,0x55, + 0x64,0x49,0x03,0x41,0xF3,0x5F,0xDD,0x39,0x64,0x49,0xE3,0x38,0xBE,0xFF,0x7A,0x60, + 0x24,0x49,0xA2,0x30,0x00,0xAB,0xB7,0xA7,0xC5,0x59,0x44,0x49,0xED,0xAD,0xAB,0x09, + 0x84,0x51,0x02,0x41,0xEA,0xE8,0x7A,0x7C,0x85,0x51,0xE2,0x38,0x2F,0x2F,0xBF,0xAD, + 0x26,0x72,0x85,0x59,0x95,0xD5,0xAB,0x03,0x06,0x6A,0xC5,0x69,0x2B,0x8D,0xE2,0x60, + 0xA8,0x82,0xC5,0x61,0x02,0x82,0xFD,0x55,0xA8,0x82,0xC5,0x69,0x08,0x8A,0xAF,0xAD, + 0x88,0x7A,0xA5,0x61,0xE8,0xFE,0xFA,0x7E,0x06,0x6A,0x43,0x51,0xFE,0xA8,0x80,0x82, + 0xC6,0x59,0x64,0x51,0xBD,0xAA,0x80,0x68,0xE6,0x61,0x85,0x51,0xAA,0xBA,0xF0,0xFD, + 0x06,0x6A,0x84,0x51,0x2A,0x2F,0x35,0xB5,0x4B,0x93,0xE5,0x61,0x2B,0xAF,0xBD,0xD5, + 0x72,0xD5,0xA8,0x82,0x2F,0xB5,0xD5,0x55,0xF4,0xE5,0xCC,0xA3,0x00,0x02,0x0B,0x29, + 0xF4,0xE5,0xB3,0xDD,0xF0,0xD0,0x78,0xBB,0xD3,0xDD,0x72,0xD5,0x20,0x28,0xA0,0x78, + 0x14,0xE6,0x93,0xD5,0x82,0x2A,0xAF,0xB5,0x35,0xE6,0xD3,0xDD,0xDF,0xB7,0x37,0x2F, + 0x55,0xEE,0xB3,0xDD,0x82,0x80,0xA8,0x7A,0x35,0xE6,0xD3,0xDD,0xF7,0xBE,0x00,0x03, + 0x35,0xE6,0xF4,0xDD,0xB5,0xFE,0xBE,0xC0,0x35,0xE6,0xD3,0xDD,0x7A,0xFA,0x8A,0x20, + 0x96,0xEE,0xF4,0xDD,0x2D,0x25,0x2F,0x2F,0xB7,0xF6,0x96,0xEE,0xF7,0xFF,0x5F,0xDF, + 0x96,0xEE,0x76,0xEE,0xF0,0xF0,0xE8,0xA0,0x75,0xEE,0xB3,0xD5,0xE8,0x7C,0x78,0x60, + 0xD3,0xDD,0x92,0xD5,0xA8,0x7E,0xEF,0x6A,0xB3,0xD5,0x52,0xD5,0x02,0xA2,0xEA,0xAA, + 0xB3,0xD5,0x72,0xD5,0x00,0x8A,0xFF,0x5F,0x92,0xD5,0x51,0xCD,0x00,0xAC,0x7E,0xB7, + 0x67,0x7A,0xE5,0x69,0x80,0x22,0x22,0x3D,0x67,0x7A,0x47,0x72,0xE8,0x22,0x3F,0x4D, + 0x87,0x7A,0x46,0x72,0xEF,0xA7,0xBF,0xDF,0x47,0x7A,0x66,0x72,0x7D,0xF7,0x56,0x77, + 0x87,0x82,0x66,0x72,0x5D,0x5D,0xD7,0xDA,0x87,0x7A,0x46,0x72,0xEA,0xAF,0x3E,0xFE, + 0x86,0x7A,0x66,0x72,0x7E,0xED,0xCB,0xA1,0x86,0x7A,0x46,0x72,0xBD,0xAA,0xAA,0x2A, + 0x86,0x7A,0x66,0x72,0x7D,0x79,0xF0,0xB4,0x87,0x7A,0x46,0x72,0xEA,0xF0,0xEA,0xF8, + 0x87,0x7A,0x46,0x72,0xFB,0xFE,0xB2,0x2B,0x87,0x7A,0x46,0x72,0xAE,0xCE,0xBE,0xBE, + 0xA7,0x82,0x46,0x72,0xFE,0xBF,0x9F,0x2A,0xA7,0x82,0x66,0x7A,0x75,0x57,0xBF,0xFF, + 0x87,0x7A,0x45,0x7A,0xAF,0x2B,0x20,0xA0,0xEC,0xAB,0x87,0x7A,0x95,0xB5,0x2D,0x0D, + 0xCB,0xA3,0xE5,0x69,0x7E,0x7C,0x78,0x78,0xA5,0x59,0xE2,0x38,0x5C,0x58,0x58,0xF8, + 0xE3,0x38,0xA2,0x28,0x7D,0x5B,0xFE,0xF8,0xE3,0x30,0xA2,0x28,0xBF,0x8B,0xAA,0xFD, + 0xE3,0x30,0xA2,0x28,0xBE,0xF8,0xF8,0xFE,0xE2,0x30,0x81,0x28,0xFA,0xFF,0x3E,0x2D, + 0x44,0x41,0xA2,0x28,0xBD,0x2F,0x2B,0x02,0x85,0x49,0xE3,0x38,0x63,0x7E,0x5F,0x57, + 0x85,0x51,0xE3,0x38,0x25,0x2D,0x0F,0xAD,0x85,0x51,0xE2,0x38,0xAA,0xB8,0xF8,0x7A, + 0x85,0x51,0xE2,0x38,0x80,0xFA,0x55,0x55,0x24,0x39,0xC2,0x38,0xBE,0xD4,0xBB,0x5F, + 0x44,0x41,0xE3,0x38,0x0B,0xCF,0xD5,0x5F,0x44,0x49,0xE2,0x38,0x5C,0xDA,0xE9,0x97, + 0x85,0x49,0x03,0x41,0x3D,0xB5,0xDF,0x5F,0x85,0x51,0xE3,0x38,0x58,0xFE,0xAA,0xAA, + 0x45,0x49,0xC3,0x38,0xF5,0xFF,0xEE,0x08,0xA5,0x51,0x03,0x39,0x29,0xBD,0xFD,0xBE, + 0x85,0x51,0x03,0x41,0x78,0xFA,0xFA,0xAA,0xE5,0x61,0x03,0x41,0xBD,0xAD,0x2F,0x2B, + 0x47,0x72,0xA4,0x59,0x0D,0xBF,0xFB,0x7F,0x26,0x6A,0x64,0x51,0xF8,0x7C,0x7F,0xF5, + 0xC6,0x61,0x43,0x51,0x8A,0xAD,0x85,0x2E,0x06,0x6A,0x85,0x59,0xAF,0xCD,0x8F,0x02, + 0xE6,0x69,0x64,0x51,0xC0,0xE2,0xF7,0xDD,0xA5,0x59,0x44,0x49,0x0B,0x77,0xDF,0xFB, + 0xA5,0x59,0x44,0x49,0xF2,0x7F,0xFD,0x55,0xC6,0x59,0x44,0x49,0xBD,0x35,0x35,0xBB, + 0xE6,0x59,0x85,0x59,0xF6,0xC0,0x80,0xB2,0xE6,0x61,0xA5,0x59,0xE2,0xF5,0xDF,0xF9, + 0xC9,0x82,0xA5,0x59,0x2B,0xAD,0xB7,0xAF,0x10,0xCD,0xA8,0x82,0x0B,0x2D,0xBD,0xF5, + 0xD3,0xDD,0x4E,0xB4,0x00,0x00,0x03,0x2D,0xB3,0xDD,0x72,0xD5,0xDC,0x57,0x96,0xFE, + 0xF4,0xDD,0x72,0xD5,0x2D,0xAB,0x2B,0x2B,0x35,0xE6,0xD3,0xDD,0x8B,0x7A,0x55,0xBF, + 0xF4,0xDD,0x10,0xC5,0xA0,0xE0,0xE0,0x70,0x14,0xE6,0x10,0xC5,0x02,0x02,0x0B,0x2D, + 0x76,0xEE,0x14,0xE6,0xE9,0x2A,0xAA,0xFA,0x55,0xEE,0x14,0xE6,0xEA,0xF8,0xFE,0x7F, + 0xB7,0xF6,0x14,0xE6,0xBD,0x25,0x25,0x2D,0xB7,0xF6,0x76,0xEE,0xF8,0xBA,0xFA,0x5E, + 0x96,0xEE,0x55,0xEE,0x20,0xCA,0xBA,0xFD,0x76,0xEE,0xF4,0xDD,0x60,0x80,0xA0,0xA2, + 0x55,0xEE,0xB3,0xD5,0x57,0x5F,0x78,0x78,0xB2,0xD5,0x73,0xCD,0xBA,0xFE,0xEA,0x32, + 0x92,0xD5,0x72,0xCD,0xF8,0xEC,0x68,0xFA,0x92,0xD5,0x31,0xC5,0xFF,0xFE,0x7A,0x72, + 0xC4,0x61,0x42,0x59,0x3F,0xFF,0xBF,0xFF,0x66,0x72,0x64,0x59,0x0A,0xBD,0xD5,0x55, + 0x86,0x7A,0x44,0x59,0x82,0x22,0xAF,0xF5,0x87,0x7A,0xC4,0x61,0x0A,0x80,0xAA,0xAD, + 0x86,0x7A,0x26,0x72,0x28,0xAA,0xAA,0xA9,0x87,0x7A,0x25,0x72,0xAA,0xA2,0xAA,0x8B, + 0x87,0x7A,0x66,0x72,0xA1,0x0D,0xBB,0x63,0x86,0x7A,0x66,0x72,0x27,0xC0,0xB8,0x2C, + 0x87,0x7A,0x66,0x72,0xBB,0x28,0x02,0xAC,0x86,0x7A,0x46,0x72,0xB8,0xC0,0x08,0xB8, + 0x87,0x7A,0x25,0x7A,0xA2,0xA2,0xC2,0x22,0xA7,0x7A,0x46,0x7A,0x7A,0xBF,0xBB,0x2E, + 0x87,0x7A,0x66,0x7A,0x32,0x08,0xB0,0xD3,0xA7,0x82,0x66,0x7A,0x67,0xBE,0xBF,0xAE, + 0x6A,0x9B,0x87,0x7A,0x55,0xD5,0xD5,0x15,0x2E,0xB4,0x08,0x8B,0x2D,0x89,0x83,0x22, + 0x8A,0x9B,0x05,0x6A,0x78,0x58,0x5C,0x7C,0xE6,0x61,0x02,0x41,0xFA,0x78,0x78,0x78, + 0x23,0x41,0xA2,0x28,0x78,0x7A,0xFA,0x6A,0xC2,0x30,0xA2,0x28,0x9B,0x3E,0x57,0x7D, + 0xC2,0x28,0x81,0x28,0xF8,0xEA,0xB6,0xBB,0xE3,0x38,0x82,0x28,0x37,0xAF,0xAF,0xAF, + 0x24,0x41,0xA2,0x30,0x80,0xAA,0xFF,0xD7,0x44,0x41,0xC2,0x30,0xF7,0xFD,0x8B,0xC9, + 0x24,0x41,0xC2,0x38,0x2B,0xA9,0xEF,0x2B,0x44,0x49,0xC2,0x38,0x68,0xFE,0xF7,0xBE, + 0x24,0x41,0xC2,0x30,0xE5,0xB7,0xA7,0x0C,0x04,0x41,0xA2,0x30,0xF8,0xC0,0x00,0xA8, + 0xE3,0x30,0x82,0x30,0xA3,0xEF,0xDF,0xBE,0x23,0x41,0xC2,0x38,0x2B,0x29,0xAB,0x2A, + 0x44,0x41,0x03,0x41,0xEB,0x72,0x82,0x0A,0x44,0x49,0xE3,0x38,0x0A,0x83,0xAE,0x7F, + 0x86,0x49,0x03,0x41,0xAF,0x27,0x2D,0xFD,0x85,0x51,0x03,0x41,0xE0,0xF8,0xDC,0x5F, + 0x85,0x51,0x24,0x41,0x8D,0xEF,0xEB,0x7F,0x06,0x62,0x04,0x41,0x2F,0x3F,0xB5,0xF5, + 0xE5,0x61,0x44,0x49,0xE8,0xEE,0xDF,0x57,0xA5,0x59,0x23,0x49,0x0A,0x28,0xBF,0x95, + 0xE6,0x61,0x85,0x59,0x3F,0xBA,0xAA,0x7F,0x27,0x72,0xA5,0x59,0xE0,0x8B,0xAF,0xDD, + 0xE6,0x61,0x03,0x41,0xFE,0x5E,0xF8,0xA2,0x85,0x51,0x23,0x49,0x88,0x83,0x35,0xFE, + 0x64,0x49,0x44,0x49,0xA8,0x81,0x83,0x3D,0xC6,0x59,0x64,0x49,0xF9,0xE2,0x01,0x5F, + 0xA5,0x59,0x44,0x49,0x88,0xFA,0x9A,0x5E,0xE5,0x61,0x43,0x49,0x83,0xAD,0xFF,0xED, + 0x67,0x72,0xC5,0x59,0x09,0x0B,0x2D,0x25,0x29,0x8B,0x87,0x7A,0x2B,0xAF,0xFD,0xFD, + 0x11,0xCD,0xC8,0x82,0x0B,0x25,0xBD,0xD5,0x14,0xE6,0xD0,0xC4,0xAA,0xA2,0x0A,0x09, + 0x56,0xEE,0xB3,0xD5,0xAD,0xAF,0xAA,0x0A,0x55,0xEE,0xF3,0xDD,0xDF,0xBF,0xCA,0xA0, + 0x14,0xE6,0xF0,0xC4,0x58,0x58,0xDC,0xFE,0x14,0xE6,0xF0,0xC4,0x2D,0x2F,0x3F,0x3F, + 0x76,0xEE,0x14,0xE6,0xF8,0x6A,0xFA,0xEA,0x96,0xEE,0x14,0xE6,0xD7,0xD5,0xBD,0x2F, + 0x96,0xEE,0x35,0xE6,0x09,0x0A,0x02,0xA0,0x96,0xEE,0x55,0xE6,0xF8,0x5E,0xDE,0x5F, + 0x75,0xEE,0x55,0xE6,0xEF,0xBF,0xBE,0x5E,0x75,0xEE,0x55,0xE6,0xCB,0xEB,0xFA,0xBD, + 0x76,0xEE,0xD3,0xDD,0x7A,0xAA,0xA0,0xA0,0x55,0xEE,0x92,0xD5,0x57,0x5E,0xE8,0x80, + 0x14,0xE6,0x92,0xD5,0x75,0x55,0x5F,0x7C,0xB2,0xD5,0x51,0xCD,0xDE,0xDE,0xF8,0xEA, + 0x84,0x61,0x43,0x59,0xBB,0xFA,0xBE,0x7A,0x84,0x61,0x43,0x59,0xCA,0x66,0x8F,0xED, + 0x43,0x61,0x84,0x59,0xDE,0xDD,0xFF,0xFA,0xC4,0x61,0x63,0x59,0x35,0xBD,0xF5,0x7D, + 0x46,0x72,0x43,0x51,0x02,0xFF,0xD5,0x55,0x66,0x72,0x43,0x51,0x00,0x0A,0xBF,0x55, + 0xC7,0x7A,0xA5,0x61,0xA8,0xAA,0xAA,0xF5,0x87,0x7A,0x46,0x72,0xA0,0xC2,0x80,0x89, + 0x87,0x7A,0x66,0x7A,0xBE,0xAE,0xA6,0xAD,0x87,0x7A,0x66,0x7A,0x9E,0xBE,0xAF,0x47, + 0x87,0x7A,0x66,0x7A,0xAE,0x68,0x8F,0xA0,0xA8,0x82,0x67,0x7A,0xFB,0xAF,0xAF,0xBB, + 0xA7,0x82,0x67,0x7A,0xFD,0xFB,0xEA,0xBF,0xA7,0x82,0x67,0x7A,0xAE,0xEF,0xEF,0xEE, + 0xCB,0xA3,0x87,0x82,0x35,0x2D,0x09,0x03,0x0D,0xAC,0xCC,0xAB,0xFA,0x5D,0xF6,0x55, + 0xAA,0xA3,0xA4,0x59,0x7C,0x78,0x78,0x70,0xA5,0x59,0x02,0x41,0x78,0xFA,0xFA,0x6A, + 0x02,0x41,0xC2,0x30,0x7A,0x5A,0x5A,0x78,0xC2,0x30,0x82,0x28,0xAB,0xAF,0x02,0x08, + 0xE2,0x30,0xA2,0x28,0xD5,0xB5,0xAA,0xA8,0x44,0x41,0xA2,0x28,0xDD,0xFD,0xAF,0x03, + 0x23,0x41,0xA1,0x30,0xD7,0xEF,0x2A,0x00,0x24,0x41,0xE3,0x38,0xAF,0x0A,0x00,0x22, + 0x24,0x41,0xE3,0x38,0x0B,0x0A,0x02,0x80,0x44,0x41,0xE3,0x38,0xBA,0x60,0x5F,0xD7, + 0x64,0x49,0x24,0x41,0x66,0xCB,0x41,0x4D,0x44,0x41,0xC3,0x38,0x77,0x77,0xBF,0xA0, + 0x23,0x41,0xA2,0x30,0xB5,0xBF,0xAA,0x00,0x65,0x49,0xE3,0x38,0xAF,0x0A,0x2D,0xB5, + 0x23,0x41,0xE3,0x38,0xA8,0xA8,0xCC,0x72,0x24,0x41,0xE3,0x38,0xFF,0x2F,0x2F,0x3D, + 0x24,0x41,0xE3,0x38,0x8B,0xF7,0xBA,0xE0,0x64,0x49,0x03,0x41,0x5D,0xFD,0xBD,0x03, + 0x65,0x51,0x03,0x41,0xDF,0xE9,0xEF,0xE8,0x44,0x49,0xE3,0x40,0x27,0xEF,0xAB,0x2E, + 0x23,0x49,0xE3,0x40,0x80,0xE2,0x50,0xF8,0x85,0x51,0xE2,0x40,0xA7,0xB7,0xBD,0xB5, + 0xA5,0x59,0x44,0x49,0x02,0xAA,0xEA,0x7A,0xA5,0x59,0x03,0x41,0xA2,0xEA,0x77,0xD5, + 0xA5,0x59,0x03,0x39,0x82,0xAE,0xFF,0xD5,0x64,0x49,0x03,0x41,0x2A,0x2C,0x36,0x9D, + 0x64,0x49,0x24,0x41,0x2E,0xB7,0xDB,0xE8,0x85,0x49,0x23,0x41,0x02,0xAE,0xBF,0x77, + 0x64,0x49,0x03,0x41,0xE8,0xE8,0xDF,0x7F,0x84,0x51,0x23,0x41,0x25,0x25,0xBD,0x29, + 0x47,0x72,0xA4,0x51,0xAD,0xA5,0xAF,0x2D,0x87,0x7A,0xC6,0x61,0x0B,0xB5,0xBF,0xBA, + 0xE8,0x82,0x67,0x7A,0x22,0x8A,0xA9,0xA9,0xD3,0xDD,0x09,0x8B,0x09,0x0D,0x2D,0x35, + 0x55,0xEE,0xF4,0xE5,0x2D,0x0D,0xA2,0xFF,0x35,0xEE,0x92,0xD5,0x00,0xE0,0x78,0x7F, + 0x92,0xD5,0xF0,0xC4,0xDC,0xFE,0xF7,0xFF,0xD3,0xDD,0x10,0xC5,0x35,0xBD,0xBF,0xBD, + 0x76,0xEE,0xD4,0xDD,0x22,0x23,0x0B,0x09,0xB7,0xF6,0x76,0xEE,0xB5,0xAF,0xBF,0xAB, + 0x96,0xEE,0x76,0xEE,0x7C,0x58,0x5C,0x7E,0x75,0xEE,0x55,0xE6,0xBE,0xF0,0xFB,0xFE, + 0x75,0xEE,0x55,0xE6,0xFC,0x5F,0xFD,0x57,0x75,0xEE,0x34,0xE6,0x0F,0xAE,0xAE,0xFA, + 0x76,0xEE,0x55,0xE6,0x7E,0x5A,0xFF,0xEB,0x76,0xEE,0x55,0xE6,0x77,0x7F,0x5D,0x08, + 0x76,0xEE,0x14,0xE6,0x57,0xBE,0xAE,0x00,0x56,0xEE,0xB3,0xD5,0x57,0xBA,0x80,0x00, + 0x63,0x59,0x23,0x51,0xE2,0x3B,0x3A,0x3C,0x84,0x61,0x43,0x59,0xBE,0xDB,0xE8,0x6A, + 0x84,0x59,0x43,0x59,0xFA,0xEA,0x0A,0x83,0x84,0x61,0x22,0x51,0xE0,0x7A,0xDE,0xBB, + 0x43,0x51,0x22,0x51,0x4B,0x8C,0x6C,0x1A,0x64,0x59,0x02,0x49,0xFF,0x97,0xAF,0xA2, + 0x84,0x61,0x23,0x51,0xAD,0xB7,0x27,0x2B,0x26,0x72,0x84,0x59,0x0A,0xD5,0x55,0x55, + 0x66,0x7A,0x84,0x61,0x00,0x0B,0xD5,0x55,0x67,0x7A,0x84,0x61,0x00,0x00,0x02,0xB5, + 0xA7,0x82,0x47,0x7A,0xAA,0x2A,0xBB,0xBD,0xA7,0x82,0x67,0x7A,0xEB,0xAF,0xB7,0xBB, + 0xA7,0x82,0x87,0x7A,0xFA,0xF3,0x1F,0xF5,0xAB,0xA3,0x87,0x82,0xD5,0x95,0x3D,0x2D, + 0xEC,0xAB,0x8A,0x9B,0xA9,0xE3,0xFA,0xFA,0xCB,0xA3,0xAB,0xA3,0x0D,0xFA,0xFD,0xFD, + 0xAB,0xA3,0x05,0x6A,0x70,0x78,0x70,0xE0,0xC5,0x59,0xE2,0x40,0xFE,0xDE,0x78,0x78, + 0x44,0x41,0xC2,0x38,0x5A,0x72,0xFB,0x5F,0xE3,0x38,0xA2,0x30,0xEF,0xCD,0xFD,0xAA, + 0x03,0x39,0xA2,0x30,0xAF,0xAF,0x25,0x0E,0x64,0x49,0x03,0x41,0xA7,0xAF,0x8B,0x0B, + 0x65,0x49,0x03,0x41,0xFE,0x7A,0xAA,0x2A,0x65,0x49,0x03,0x41,0xFF,0xFB,0xF8,0xDC, + 0x24,0x41,0xE3,0x38,0x40,0xF7,0x9C,0xA0,0x85,0x51,0xE3,0x38,0xDD,0xAD,0xC2,0x02, + 0x85,0x51,0x03,0x41,0xE7,0xB7,0xFF,0x2F,0x85,0x51,0x24,0x49,0xFB,0x7B,0xC2,0x00, + 0x84,0x51,0x24,0x49,0x7E,0xA9,0x2D,0x2E,0x65,0x49,0xE3,0x38,0xB5,0xB7,0xFE,0x5C, + 0x23,0x41,0xE3,0x38,0xE0,0xE0,0xFB,0xDD,0x24,0x41,0xE3,0x38,0x2F,0x26,0xEF,0xFE, + 0x24,0x41,0xE3,0x38,0xF8,0x9E,0xFA,0xFA,0xA5,0x51,0x03,0x41,0x29,0x09,0x0D,0x2D, + 0x85,0x51,0xE2,0x38,0x78,0xFA,0xF8,0xFA,0x65,0x51,0xE3,0x38,0xAF,0x0F,0xBF,0xFD, + 0x85,0x59,0x03,0x41,0x7E,0xFE,0xBF,0x2B,0x64,0x49,0x03,0x41,0x2D,0x2E,0x30,0x2C, + 0x85,0x51,0x23,0x41,0x58,0x7A,0xE2,0xF3,0x44,0x49,0x03,0x41,0xE2,0x00,0x37,0x1B, + 0x43,0x41,0xE3,0x38,0xFA,0xFB,0xEA,0xEE,0x23,0x41,0xC2,0x38,0x2A,0xBF,0x29,0x2B, + 0x64,0x49,0x23,0x41,0xA2,0xEB,0xD5,0x5D,0x44,0x49,0xE2,0x38,0x28,0xFA,0xDF,0xDF, + 0x44,0x41,0x03,0x41,0xAE,0x1F,0x2B,0xAF,0xA5,0x51,0x44,0x49,0x3D,0x0B,0x2F,0xED, + 0x47,0x6A,0xA5,0x59,0x2B,0x2D,0x95,0xFD,0xC8,0x82,0x06,0x62,0xFF,0xAA,0x03,0xA5, + 0xC8,0x82,0x67,0x7A,0x27,0x3F,0x96,0x5F,0x4D,0xAC,0xE8,0x82,0x35,0xB5,0xD5,0x55, + 0xF4,0xE5,0x8B,0x9B,0x00,0x03,0x0B,0x09,0x15,0xE6,0x10,0xC5,0xE8,0x60,0x70,0x78, + 0x31,0xCD,0xF0,0xC4,0xAA,0xBF,0x95,0x95,0x51,0xCD,0x10,0xC5,0x0A,0x2A,0x3F,0x3F, + 0x96,0xF6,0x72,0xCD,0x2B,0x0D,0x2D,0x25,0xB6,0xF6,0x76,0xEE,0xAB,0xEF,0x02,0xFA, + 0xB7,0xF6,0x55,0xE6,0xEB,0xBA,0x80,0x7F,0xB7,0xF6,0x35,0xE6,0xFB,0x8A,0xAA,0x55, + 0xB6,0xF6,0x14,0xDE,0xAE,0x08,0xAA,0x55,0x96,0xEE,0x92,0xCD,0x00,0x00,0xA0,0x5F, + 0x76,0xEE,0xF0,0xBC,0x00,0x00,0xAA,0x5F,0x96,0xF6,0xD0,0xBC,0x00,0x88,0xFE,0x55, + 0x76,0xEE,0x8F,0xAC,0x00,0xAA,0xFF,0xF5,0x36,0xE6,0x32,0xC5,0xE8,0xFF,0xFF,0x7F, + 0x84,0x59,0x23,0x59,0xB7,0xBF,0x2B,0x8B,0x84,0x59,0x44,0x59,0xF6,0xAA,0xA8,0xC2, + 0x84,0x59,0x23,0x51,0x6A,0xF8,0xAB,0xFF,0x84,0x59,0x23,0x51,0xF1,0xFD,0x7F,0xAF, + 0x63,0x59,0x23,0x51,0x6A,0x72,0xDF,0x77,0x84,0x61,0x23,0x51,0x7D,0xF5,0x2D,0xAF, + 0x84,0x61,0x43,0x59,0xA9,0x8A,0x88,0x08,0xA4,0x61,0x63,0x59,0xFE,0xBA,0x2F,0xAF, + 0xA4,0x61,0x43,0x59,0xEA,0x7C,0xFE,0xFF,0x64,0x59,0x43,0x59,0x1E,0x58,0x7E,0x57, + 0x47,0x7A,0x23,0x51,0x2B,0xF5,0xDD,0x55,0x67,0x7A,0x23,0x51,0x00,0x0A,0xF5,0x55, + 0x87,0x7A,0x23,0x51,0x00,0x00,0x0A,0x35,0xEB,0xAB,0xC8,0x82,0x2D,0x09,0x83,0xA2, + 0xCB,0xA3,0x6A,0x9B,0xA8,0xDF,0x5F,0xDD,0xAB,0xA3,0x6A,0x9B,0x2A,0xEB,0xED,0xA9, + 0xAB,0xA3,0x46,0x72,0x60,0x7A,0x6A,0xF0,0x66,0x7A,0x23,0x49,0x7E,0x7A,0x7A,0xF8, + 0x23,0x49,0xC2,0x38,0x57,0x57,0x7C,0xD8,0x04,0x41,0xC2,0x38,0xAD,0x2D,0xBD,0x9F, + 0x64,0x49,0xE3,0x38,0xF5,0xFF,0xEE,0xCA,0x84,0x49,0xE2,0x38,0x2D,0xAF,0xBF,0xF7, + 0x64,0x49,0x03,0x41,0xB0,0x58,0xDE,0x5E,0x44,0x49,0x03,0x39,0xD6,0x7F,0x7A,0xA2, + 0x44,0x41,0xE2,0x40,0xDE,0xBE,0x8A,0xF2,0xA6,0x51,0x43,0x49,0xAB,0xEA,0xE3,0x79, + 0xC6,0x59,0x44,0x49,0xF5,0xAD,0xED,0x8D,0xA5,0x59,0x44,0x51,0x3E,0x1F,0x15,0xF7, + 0x06,0x6A,0x85,0x51,0x57,0x7A,0xC0,0x83,0xA5,0x51,0xE2,0x38,0x5C,0x5A,0x7A,0x68, + 0x03,0x39,0xA2,0x30,0xBF,0xAD,0x2B,0x2B,0x23,0x41,0xE3,0x38,0xDE,0x7D,0xAA,0x82, + 0x23,0x41,0xE2,0x38,0xE7,0x3B,0xBB,0xA8,0x64,0x51,0x03,0x41,0x29,0x8F,0xD7,0xDD, + 0x64,0x51,0x03,0x41,0x70,0xBA,0xEA,0xAB,0x64,0x49,0x03,0x49,0xDD,0x2E,0x3E,0x32, + 0xA6,0x59,0x43,0x49,0xAF,0x8F,0xFB,0x57,0x84,0x49,0x23,0x41,0x97,0xFE,0xFB,0xAA, + 0x64,0x49,0xE3,0x38,0xEE,0xEC,0x7A,0x5A,0x23,0x41,0xC2,0x30,0x80,0x8A,0x26,0x2A, + 0x64,0x49,0xE2,0x38,0x77,0xFD,0x0E,0x2A,0x64,0x49,0xE3,0x38,0x25,0xBD,0xAE,0xE0, + 0x64,0x41,0x03,0x41,0xAA,0xA8,0xFE,0x67,0x64,0x49,0x03,0x39,0xD5,0xB7,0x2B,0x2E, + 0x64,0x49,0x23,0x41,0xFD,0x7F,0x57,0x58,0x64,0x49,0x03,0x41,0xBE,0xEA,0xC0,0x81, + 0xE6,0x61,0x44,0x49,0x2B,0xAD,0x25,0xF5,0x66,0x72,0xC5,0x59,0x0F,0xAD,0xAF,0xAB, + 0x67,0x72,0xE5,0x69,0xE8,0xEA,0xFA,0xE2,0xC8,0x82,0x26,0x6A,0x03,0x0D,0xED,0xB5, + 0x72,0xD5,0xC8,0x82,0x0D,0x2D,0x35,0xB5,0xD3,0xDD,0xF0,0xC4,0x70,0x58,0x78,0x5E, + 0x10,0xC5,0xD0,0xBC,0x2E,0x2F,0xBF,0x15,0x51,0xCD,0x10,0xC5,0xBB,0xBF,0xED,0xFD, + 0x14,0xE6,0x31,0xCD,0x3D,0x35,0xB5,0xD5,0xF4,0xDD,0xAF,0xBC,0x00,0xFE,0x5E,0x56, + 0xB3,0xD5,0x8F,0xB4,0x00,0xFF,0x75,0x55,0x72,0xCD,0x2D,0xAC,0x00,0xEA,0x77,0x57, + 0x52,0xCD,0x2D,0xA4,0x00,0xFF,0x5F,0x55,0x11,0xC5,0x2E,0xA4,0xA0,0xFE,0x55,0x3D, + 0x32,0xC5,0x4E,0xAC,0x7E,0x55,0xB5,0x00,0xB3,0xD5,0x8F,0xAC,0xB5,0x0D,0x0A,0x22, + 0xB4,0xD5,0x11,0xBD,0xBD,0xE8,0xF8,0x5A,0x72,0xC5,0x6F,0xAC,0xA8,0xEA,0x5A,0x7E, + 0x84,0x59,0x43,0x51,0x2E,0xCE,0x77,0x6F,0x64,0x59,0x23,0x51,0xA0,0x7A,0x77,0x5F, + 0x63,0x59,0x23,0x51,0xBE,0x8F,0xEF,0xF5,0x22,0x59,0x63,0x51,0xFF,0xEF,0xBB,0xAB, + 0x63,0x59,0x23,0x51,0xFB,0xAF,0x07,0x0F,0x84,0x61,0x43,0x59,0x39,0xDF,0xBE,0xFF, + 0x84,0x61,0x63,0x59,0x0A,0xAA,0x9F,0xC7,0xA4,0x61,0x43,0x59,0x6A,0x6C,0x5F,0xD7, + 0x63,0x59,0x23,0x51,0x08,0xAB,0xF8,0xFA,0x43,0x59,0x23,0x51,0x0A,0x8A,0x80,0x5C, + 0x23,0x59,0x02,0x49,0xD8,0xFA,0xBE,0xE7,0x23,0x51,0x03,0x49,0xC0,0xC8,0x88,0x8A, + 0xAB,0xA3,0x43,0x59,0x95,0x35,0x25,0x09,0xCB,0xA3,0x4A,0x9B,0xC2,0xF0,0x58,0x7E, + 0x8B,0x9B,0x49,0x93,0x28,0x02,0x0B,0xEF,0xAC,0xA3,0x6A,0x9B,0x0E,0xAF,0xFF,0xD5, + 0xCC,0xAB,0xC7,0x82,0x78,0x52,0x5A,0x5E,0xA7,0x7A,0x64,0x51,0x7E,0x58,0x78,0x60, + 0x44,0x49,0x03,0x41,0x58,0xA0,0x28,0xBE,0x23,0x41,0xE3,0x38,0x57,0xDC,0x9E,0xF8, + 0x84,0x51,0x23,0x41,0x89,0xAB,0x8B,0x8B,0x44,0x49,0xE2,0x38,0xFE,0x58,0xF8,0xBA, + 0x44,0x49,0x03,0x41,0x72,0xE3,0x7B,0x58,0x65,0x49,0xE3,0x38,0xE2,0xDA,0xFF,0x7A, + 0x23,0x41,0x02,0x41,0xE0,0xA0,0xDE,0x09,0xE3,0x40,0x23,0x39,0xB7,0x0B,0xAA,0xAD, + 0xC6,0x61,0x03,0x41,0x0D,0x8D,0x2D,0x09,0xA5,0x59,0x03,0x49,0xE8,0xFE,0xF6,0x56, + 0xC6,0x61,0x23,0x49,0x0B,0x3F,0xDF,0xDD,0x85,0x51,0xC2,0x38,0x78,0x70,0x60,0x60, + 0x03,0x39,0xA2,0x30,0x2F,0x2D,0xBF,0x97,0x23,0x41,0xE3,0x38,0x22,0x2B,0xFF,0x57, + 0x64,0x49,0x04,0x41,0xFA,0xAA,0x89,0xAB,0x85,0x51,0x23,0x49,0x57,0xE7,0x2B,0x0A, + 0xA5,0x59,0x44,0x49,0xED,0x82,0x88,0x8B,0x85,0x51,0x03,0x41,0xFA,0x58,0xFE,0xDC, + 0x43,0x49,0xE2,0x38,0xE0,0xEA,0xEA,0xF8,0x64,0x49,0x02,0x39,0x0B,0xAD,0xFD,0xF5, + 0x23,0x41,0x03,0x39,0x60,0xC0,0xF0,0xAA,0x24,0x41,0xE3,0x38,0x2B,0xF8,0x76,0x76, + 0x65,0x49,0xE2,0x38,0x0A,0x2B,0xAF,0xBD,0xA5,0x51,0x23,0x41,0x7A,0xE2,0xEF,0x7F, + 0x44,0x41,0x03,0x39,0xDF,0x57,0xA8,0xEA,0x85,0x49,0x03,0x39,0x2B,0x29,0xAD,0xF7, + 0x64,0x49,0x24,0x41,0x00,0x20,0x94,0xAF,0xA6,0x59,0x23,0x41,0xDD,0x7A,0xEA,0x2F, + 0x84,0x51,0x44,0x49,0xEF,0xF5,0xA7,0xF8,0x67,0x72,0x84,0x51,0x2D,0xB5,0x55,0x55, + 0xA8,0x7A,0xA5,0x59,0xA0,0xAA,0xAD,0xB5,0xC9,0x82,0x26,0x6A,0xAD,0xAB,0x0F,0xB5, + 0xEC,0xA3,0xC8,0x82,0x15,0xB5,0x95,0xD5,0xB3,0xDD,0x8F,0xB4,0xFA,0xF3,0xE2,0xE9, + 0xF0,0xC4,0xAF,0xBC,0x2E,0x2F,0xAF,0x95,0x31,0xCD,0xF0,0xC4,0xA9,0x0B,0x29,0xF5, + 0x51,0xCD,0xF0,0xBC,0x3A,0xAB,0x6A,0x7F,0x71,0xD5,0x2D,0xAC,0xF8,0x5E,0x5F,0x57, + 0xCF,0xBC,0x2D,0xA4,0xFF,0x5F,0xF5,0x25,0x93,0xCD,0x2D,0xA4,0x55,0x55,0xBF,0x02, + 0xB3,0xD5,0x0D,0xA4,0xD5,0x2F,0x02,0x00,0xB4,0xD5,0x11,0xBD,0xA9,0xEC,0xFC,0x5C, + 0x73,0xCD,0xF0,0xB4,0xA0,0x3E,0x3F,0x35,0x93,0xCD,0xF1,0xBC,0x60,0x60,0xE0,0x78, + 0x32,0xBD,0xB0,0xB4,0xB0,0xA5,0xA7,0x67,0xF1,0xBC,0x8F,0xAC,0x5A,0x5C,0xD7,0xF5, + 0x64,0x51,0x23,0x51,0xF0,0x96,0xFF,0xF5,0x43,0x51,0x23,0x51,0x3C,0x84,0x77,0xBB, + 0x64,0x59,0x23,0x51,0xB7,0xED,0xCE,0xAB,0x63,0x59,0x23,0x51,0xFF,0xAE,0x2E,0x8E, + 0x84,0x61,0x43,0x59,0xCB,0xEA,0x8E,0xFF,0x84,0x61,0x43,0x59,0x2B,0xAD,0xF6,0x7F, + 0x84,0x59,0x23,0x51,0xB8,0xFA,0xEE,0x7F,0x63,0x59,0x23,0x51,0xA8,0xBA,0xEA,0xE9, + 0x63,0x59,0x23,0x51,0xCF,0xE5,0xFF,0x77,0x23,0x51,0x03,0x49,0x6C,0xD8,0xCE,0x0F, + 0x23,0x51,0x03,0x49,0x4D,0x72,0xFF,0xEB,0xE8,0x8A,0x02,0x51,0x55,0xD5,0xB5,0x35, + 0xAB,0xA3,0x26,0x72,0x09,0x03,0x02,0x00,0x8B,0xA3,0x29,0x93,0xA0,0xE0,0xEA,0xDE, + 0x8A,0x9B,0x09,0x93,0xF8,0xFE,0xDB,0x7F,0x8B,0x9B,0x29,0x93,0xAB,0xAF,0xAD,0x2D, + 0x6A,0x9B,0x87,0x7A,0x78,0xD8,0x78,0x5C,0xE8,0x82,0x06,0x6A,0x62,0xE2,0xEA,0xAA, + 0x88,0x7A,0x23,0x49,0x55,0x57,0x5E,0x78,0x64,0x49,0xE3,0x40,0xFB,0x8B,0x2D,0xBF, + 0x64,0x49,0x03,0x41,0xAF,0x9E,0xD6,0x5C,0x23,0x41,0xE3,0x38,0xBC,0xDC,0x5F,0x57, + 0x44,0x49,0x03,0x41,0x82,0x09,0x0D,0x27,0x44,0x49,0xE3,0x38,0x7A,0x78,0x7B,0x7A, + 0x23,0x41,0xE3,0x38,0xA9,0xBD,0xFD,0xF5,0x24,0x41,0xE2,0x38,0x9A,0x2F,0x0E,0xAA, + 0xE7,0x61,0x44,0x49,0x2D,0xAD,0xF5,0x55,0xC6,0x61,0x24,0x49,0x5C,0xF8,0x2F,0xB7, + 0xA6,0x59,0x44,0x49,0xD5,0xB7,0x96,0xB0,0x85,0x51,0xE3,0x38,0x7A,0x78,0x58,0x58, + 0x04,0x39,0xA2,0x30,0xDF,0xD5,0xFD,0x35,0x24,0x41,0xC2,0x30,0xD7,0x9D,0xAA,0xB2, + 0x85,0x51,0x23,0x41,0xED,0xF9,0xEB,0x82,0x85,0x59,0x44,0x51,0x09,0xED,0xCB,0x0A, + 0x85,0x59,0x03,0x49,0xA2,0x8A,0x57,0xD6,0x64,0x51,0xE3,0x38,0xF8,0xEE,0x7E,0x7E, + 0x23,0x41,0xC3,0x38,0x88,0xBE,0xBF,0xED,0x65,0x49,0xE2,0x38,0xFD,0xFD,0xEF,0x8A, + 0x85,0x49,0x02,0x39,0xD5,0x7F,0xCB,0xEF,0x23,0x41,0xE2,0x38,0xEA,0x80,0xBE,0xFB, + 0x43,0x41,0x03,0x39,0x35,0x95,0xD5,0xDF,0x43,0x41,0xE2,0x38,0xC8,0xE0,0xF2,0x6E, + 0x23,0x39,0xE2,0x38,0xBF,0x6D,0xAF,0xAD,0x23,0x41,0xE2,0x30,0x08,0x0A,0xA3,0xAD, + 0x64,0x49,0x03,0x39,0x2F,0xD7,0xD5,0xFE,0x85,0x51,0x23,0x49,0xBE,0xEA,0x8F,0x2F, + 0x85,0x51,0x44,0x49,0x02,0x2E,0x1F,0x5E,0x47,0x6A,0x84,0x51,0x55,0xBF,0x3D,0xF5, + 0x67,0x72,0xC5,0x61,0x75,0x97,0x58,0xA3,0xA8,0x82,0x06,0x62,0x95,0xD5,0x37,0x3D, + 0xC9,0x82,0x46,0x72,0x22,0xBF,0xDE,0xE0,0x31,0xCD,0xC9,0x82,0x03,0x09,0x0D,0x25, + 0xF0,0xC4,0x6E,0xB4,0xAE,0xFC,0x58,0x70,0xF0,0xC4,0x8F,0xB4,0x2A,0xAB,0xED,0x55, + 0x10,0xC5,0x6E,0xB4,0xE8,0x7A,0xB7,0x25,0x31,0xCD,0x2E,0xAC,0x55,0xFD,0x2A,0x00, + 0xB3,0xD5,0x4E,0xAC,0xB5,0xAF,0x0A,0x0A,0xD4,0xD5,0x11,0xBD,0x2B,0xBF,0xDF,0x7E, + 0xD5,0xD5,0x32,0xC5,0xB0,0xEA,0x2F,0xF5,0x73,0xCD,0xD0,0xB4,0x58,0x5C,0x5C,0x40, + 0x73,0xC5,0x8F,0xAC,0x25,0x35,0xA5,0xE5,0x73,0xC5,0x0D,0x9C,0xE0,0xFA,0xFF,0x95, + 0xD0,0xB4,0xB0,0xAC,0xC3,0x43,0xE2,0x7B,0xF1,0xB4,0x8F,0xAC,0x95,0x2D,0x3F,0xA7, + 0x43,0x51,0x02,0x49,0xEF,0xF6,0x88,0xE0,0x64,0x59,0x23,0x51,0xED,0xAB,0xAB,0xFF, + 0x84,0x59,0x23,0x51,0x97,0xAF,0x8E,0xEF,0x64,0x59,0x43,0x59,0xC2,0x72,0x5D,0x30, + 0xA4,0x61,0x43,0x59,0xBF,0xF9,0xEB,0xCB,0x64,0x61,0x43,0x51,0xE0,0x5E,0xE7,0xF6, + 0x43,0x59,0x64,0x51,0x00,0x20,0xA8,0xC0,0x64,0x59,0x23,0x51,0xE9,0xE7,0xFC,0xFC, + 0x44,0x59,0x03,0x49,0xC2,0xFA,0x6E,0x7F,0x23,0x51,0x03,0x49,0xBF,0x5E,0x68,0xA8, + 0x44,0x59,0x03,0x49,0xFD,0xBF,0x3D,0x3F,0x8B,0xA3,0x43,0x59,0x25,0x2D,0x0B,0x03, + 0xCC,0xA3,0x4A,0x9B,0xF0,0x7C,0x7A,0x82,0x8A,0x9B,0x29,0x93,0x7F,0x5E,0xFF,0x70, + 0x4A,0x93,0x09,0x93,0x0F,0x0B,0xFE,0xA0,0x6B,0x9B,0x29,0x93,0x09,0x2F,0xD7,0xDD, + 0x4A,0x93,0x87,0x7A,0x7C,0x7C,0x58,0x58,0xA8,0x7A,0x27,0x72,0x88,0xAA,0xF8,0x6F, + 0x67,0x72,0x85,0x59,0x78,0xE0,0xA0,0xA0,0xE6,0x61,0x03,0x49,0xD5,0x77,0x78,0xE0, + 0x64,0x51,0xE2,0x38,0x70,0x7A,0xEF,0xD7,0x03,0x39,0xC2,0x38,0x8B,0xBA,0xFF,0x5E, + 0x85,0x51,0xE2,0x38,0xBF,0x2D,0x3D,0x95,0x85,0x51,0xE2,0x38,0x7A,0x78,0x78,0x5A, + 0x24,0x41,0xE3,0x38,0xA5,0xF6,0x76,0xF0,0x24,0x41,0xE3,0x38,0xAA,0xAE,0xED,0x27, + 0x65,0x51,0x03,0x41,0xBF,0xAD,0xCD,0x8F,0xA6,0x59,0x23,0x49,0xAF,0xAB,0x0B,0xA5, + 0xC6,0x59,0x65,0x51,0xB8,0xAE,0x6F,0xBF,0x65,0x51,0xC2,0x38,0x70,0x70,0x5A,0x56, + 0x03,0x39,0xA2,0x30,0x27,0xBF,0xD7,0xF5,0x03,0x39,0xA2,0x30,0x00,0x00,0xBF,0xF7, + 0xC6,0x61,0x23,0x41,0x89,0x09,0x0D,0xA5,0xE6,0x61,0x85,0x59,0xD7,0x78,0x70,0x49, + 0x85,0x51,0x03,0x41,0xDC,0x5C,0x5E,0xFE,0x24,0x41,0xE3,0x38,0x78,0x78,0x7B,0x76, + 0x24,0x41,0xE3,0x38,0xA9,0x3B,0xDD,0x57,0x64,0x49,0x23,0x41,0xBB,0x29,0xC3,0x81, + 0x64,0x49,0x03,0x41,0xEF,0xFA,0xF2,0xF7,0x23,0x41,0xE2,0x38,0x5F,0x5B,0x58,0xEC, + 0x44,0x41,0xE2,0x38,0xF3,0xF5,0xF5,0x95,0x24,0x41,0x03,0x39,0x76,0x8D,0xBE,0xB9, + 0x44,0x39,0xE2,0x38,0xFD,0xFF,0xD6,0x7E,0x23,0x39,0xE2,0x38,0xF7,0x9F,0x93,0xBB, + 0x64,0x49,0x03,0x39,0xE3,0xA9,0x2D,0xBF,0x64,0x49,0x23,0x41,0xAE,0x0B,0x0F,0xAB, + 0x64,0x49,0x23,0x49,0xBE,0xDF,0xDF,0xF8,0xC5,0x61,0x44,0x49,0x2D,0xBD,0xF5,0xAD, + 0x26,0x6A,0x64,0x51,0x0A,0x2D,0xB7,0x77,0x88,0x7A,0xC5,0x61,0x3F,0xAB,0xBF,0xD5, + 0x09,0x8B,0x68,0x7A,0xE0,0x8A,0x03,0x0D,0x11,0xC5,0xE9,0x82,0x35,0x35,0x15,0x95, + 0x35,0xEE,0x6F,0xB4,0x7F,0xFE,0xAA,0x02,0x35,0xE6,0x6E,0xB4,0x55,0xFF,0x02,0x00, + 0xF4,0xDD,0x6E,0xB4,0xB5,0xB7,0x00,0x00,0x14,0xE6,0x52,0xCD,0xF5,0xEB,0x5A,0x60, + 0xB3,0xD5,0x52,0xC5,0x27,0xCF,0xA9,0x2B,0xB4,0xCD,0x32,0xC5,0x78,0x7A,0x7B,0x6E, + 0x52,0xC5,0xF1,0xBC,0xAB,0xBA,0x7C,0x7A,0x93,0xCD,0xF1,0xBC,0x02,0x2A,0xAD,0xF5, + 0x73,0xCD,0x0E,0x9C,0xE8,0x60,0x78,0x7A,0xB0,0xB4,0xCC,0x93,0x25,0x0D,0x0B,0x03, + 0xD0,0xB4,0x90,0xAC,0xEC,0x7E,0x7E,0xDE,0xD0,0xB4,0x90,0xAC,0xA9,0x29,0xF7,0xD7, + 0x84,0x59,0x43,0x51,0x77,0xB5,0xEB,0xFA,0x64,0x59,0x23,0x51,0xF6,0xBC,0xFA,0xB8, + 0x64,0x59,0x43,0x59,0x55,0xDF,0x0A,0x11,0x84,0x61,0x43,0x59,0x2F,0x83,0xE8,0xF0, + 0x84,0x61,0x43,0x59,0xE2,0xF2,0xDC,0xD5,0x64,0x59,0x23,0x51,0xEA,0xFA,0xAB,0xAA, + 0x64,0x59,0x23,0x51,0xFA,0x7F,0x7F,0x6F,0x44,0x59,0xE2,0x48,0x88,0xE2,0xEE,0x8A, + 0x23,0x51,0xE2,0x48,0xEA,0xEA,0x7E,0xFC,0x23,0x51,0xE2,0x48,0xCE,0x2E,0xA8,0x9A, + 0xE9,0x8A,0x23,0x51,0xD5,0x95,0x35,0x25,0xCC,0xA3,0xC9,0x8A,0xA9,0x2A,0x2A,0x02, + 0xEC,0xAB,0x8B,0xA3,0xA3,0x0A,0xAA,0xFC,0xAB,0xA3,0x4A,0x93,0x78,0x68,0xE0,0xAA, + 0x8B,0x9B,0x29,0x93,0x5D,0x7F,0xFE,0x2A,0x6A,0x9B,0x2A,0x93,0x9F,0x2A,0xAA,0xF0, + 0x2A,0x93,0x47,0x72,0x78,0x78,0x78,0x78,0x67,0x72,0x26,0x72,0x60,0xF2,0xA2,0xFE, + 0x47,0x72,0x06,0x6A,0xBC,0xFE,0x8E,0x4C,0x26,0x6A,0xA5,0x59,0x70,0x88,0x20,0x20, + 0xE6,0x61,0xE3,0x40,0x57,0xDE,0x78,0xE0,0x23,0x41,0xC2,0x38,0x7F,0x5E,0x58,0xFA, + 0x24,0x41,0xE2,0x38,0xB5,0xB5,0x3D,0x2D,0x44,0x41,0xE3,0x38,0x7A,0xDE,0xF6,0x78, + 0x24,0x41,0xC2,0x38,0x8A,0xAB,0xBE,0xDF,0x24,0x41,0xE2,0x38,0xFF,0xAF,0xAB,0x09, + 0x44,0x49,0xE3,0x38,0xAE,0xBD,0xEA,0xAA,0xA6,0x59,0x03,0x41,0xB7,0xBD,0xA7,0x2D, + 0xA6,0x59,0x44,0x49,0xFA,0x72,0x7A,0x58,0x44,0x49,0xA2,0x30,0x5C,0xF8,0xFA,0xFB, + 0x03,0x39,0xA2,0x30,0xBF,0x0D,0x07,0x37,0x03,0x39,0xC3,0x30,0xD5,0xBE,0x2F,0x3A, + 0x85,0x51,0xE3,0x38,0x2D,0xB5,0xBF,0xAF,0xE6,0x61,0x44,0x49,0x0B,0x2F,0xD7,0x5D, + 0xA6,0x59,0x04,0x41,0x7A,0xF8,0x7E,0x5F,0x04,0x41,0xE3,0x38,0xE8,0x60,0x6B,0x49, + 0x23,0x39,0xC3,0x38,0xFF,0xBF,0xED,0xD3,0x64,0x49,0xE3,0x38,0xE2,0xAB,0xE9,0xAD, + 0x44,0x41,0x03,0x41,0x25,0x2E,0x2B,0x7E,0x64,0x49,0xC2,0x30,0xA8,0xF8,0xFA,0x7A, + 0x03,0x39,0xE2,0x30,0x96,0xE2,0x58,0x7D,0x23,0x39,0xE3,0x38,0xCB,0xED,0x75,0xD5, + 0x03,0x39,0xE3,0x30,0xC0,0xB7,0x75,0x3E,0x23,0x41,0xE3,0x38,0x89,0x09,0xAD,0xBE, + 0xA6,0x51,0x24,0x41,0xFD,0xAD,0x0F,0xA9,0xA5,0x51,0x44,0x49,0x75,0xEF,0xB0,0xE8, + 0xE6,0x61,0x44,0x49,0x5D,0xFF,0x2F,0xB5,0xE6,0x61,0x64,0x51,0xBD,0xBF,0xA8,0x00, + 0x07,0x6A,0xA5,0x59,0x7D,0x5D,0xA7,0xAC,0x88,0x7A,0x84,0x59,0xD5,0xFF,0xAB,0x2D, + 0xE8,0x82,0x26,0x6A,0x2D,0xBD,0x35,0xB5,0xAC,0x9B,0xE8,0x82,0x35,0x15,0x95,0x95, + 0x55,0xEE,0x6E,0xB4,0x02,0x03,0x01,0x09,0x76,0xEE,0x35,0xE6,0xEF,0xCA,0xEA,0x7B, + 0x55,0xEE,0xF4,0xDD,0xA8,0xA8,0xE2,0xFF,0x35,0xE6,0x32,0xC5,0x60,0x68,0x78,0xDA, + 0xB3,0xD5,0x52,0xC5,0xAB,0xE9,0xFB,0x68,0x93,0xCD,0x52,0xC5,0xE8,0xB8,0xAB,0x2D, + 0x73,0xCD,0x11,0xBD,0x7E,0xDE,0xFA,0xD8,0x11,0xBD,0x4F,0xA4,0x08,0x80,0xC0,0x60, + 0xB0,0xB4,0xEA,0x7A,0xA0,0xB7,0x37,0xAF,0xB0,0xB4,0x6F,0xAC,0x01,0x8B,0x21,0x29, + 0xD1,0xB4,0x6F,0xAC,0xAB,0x8A,0xCA,0x78,0xD1,0xB4,0x6F,0xAC,0x8A,0xEA,0xFA,0x55, + 0x63,0x59,0x23,0x51,0xBA,0x26,0x17,0x89,0x84,0x59,0x43,0x51,0xFF,0xED,0xFB,0xAE, + 0xA4,0x61,0x64,0x59,0xD7,0xDD,0x19,0xDF,0x84,0x61,0x43,0x59,0xEA,0xF8,0x7C,0x7E, + 0x63,0x59,0x22,0x51,0xAA,0x68,0xEA,0xB6,0x63,0x59,0x22,0x51,0x82,0xAB,0xFB,0xEE, + 0x43,0x59,0x23,0x49,0xA8,0xF8,0xDE,0xD7,0x44,0x59,0x03,0x49,0xE6,0xFE,0xFC,0xB6, + 0x23,0x51,0xE3,0x48,0xAB,0xAF,0xEA,0xAA,0x44,0x59,0xE2,0x48,0xFF,0x57,0x27,0x0E, + 0x6A,0x9B,0x23,0x51,0x25,0x0D,0x0D,0x09,0xCC,0xAB,0x8B,0x9B,0xFF,0x7B,0xAE,0x0B, + 0xCB,0xA3,0x49,0x93,0x5E,0x77,0xF6,0xE0,0x8A,0x9B,0x29,0x93,0x0A,0xAA,0x6A,0x6E, + 0x8B,0xA3,0x09,0x8B,0xA8,0xFE,0x55,0x57,0x6A,0x9B,0xC8,0x8A,0xA0,0xEA,0xFF,0x7F, + 0xE9,0x8A,0x46,0x72,0x78,0x58,0x7C,0x78,0x86,0x72,0x26,0x72,0x57,0xFF,0x7F,0x6F, + 0x26,0x72,0x06,0x6A,0xC0,0xE0,0x1C,0x90,0x47,0x72,0x06,0x6A,0xBD,0x25,0x1F,0x0E, + 0x87,0x7A,0x85,0x51,0x7A,0xC8,0xA2,0x08,0xE6,0x61,0xC3,0x38,0x77,0x7F,0x5E,0x78, + 0x23,0x41,0xC2,0x38,0x2A,0xBF,0xFD,0xA5,0x44,0x49,0xE3,0x38,0x70,0xFB,0xDF,0x7F, + 0x03,0x41,0xC2,0x38,0x9A,0xFA,0x7F,0xAF,0x64,0x49,0xE2,0x38,0xBD,0x3D,0xED,0xBD, + 0x44,0x49,0x03,0x41,0xB8,0xBC,0x5C,0x5C,0xA6,0x59,0x04,0x41,0x2F,0xBF,0xBD,0xF5, + 0xA6,0x59,0x44,0x49,0x70,0xF8,0xE8,0xFD,0x44,0x41,0xA2,0x38,0xFF,0xEE,0xBE,0xF8, + 0xE3,0x38,0xA2,0x30,0x37,0x2A,0x2A,0xAA,0x24,0x41,0xC2,0x30,0xB8,0xB0,0xAA,0xB5, + 0x44,0x49,0xE3,0x38,0x27,0x2F,0x2F,0x3A,0x65,0x51,0x24,0x41,0xFA,0x7A,0xFB,0x7B, + 0x24,0x41,0xE3,0x38,0xC2,0xE3,0xFA,0xD6,0x24,0x41,0xE3,0x38,0xF5,0x7F,0xA7,0x2F, + 0x24,0x41,0xE3,0x38,0xE2,0xEE,0xBE,0xDC,0x44,0x41,0xE3,0x38,0x8D,0x0F,0xAE,0x8D, + 0x44,0x41,0xE2,0x38,0x7A,0xC2,0x60,0xFE,0x03,0x39,0xC2,0x30,0x78,0xF4,0xB7,0xBE, + 0x23,0x39,0xC2,0x30,0xD9,0xBB,0xAB,0xA2,0x24,0x41,0xE3,0x30,0xF5,0xFB,0xEA,0x2B, + 0x23,0x39,0xC2,0x30,0x2F,0xBA,0xFE,0x7E,0x44,0x41,0xC2,0x30,0xFE,0xAA,0xAB,0x25, + 0x64,0x49,0xE3,0x38,0x09,0xA7,0xD5,0xFF,0x84,0x51,0x03,0x41,0x82,0xBD,0x55,0x5D, + 0x85,0x51,0x23,0x41,0x36,0x3F,0x37,0x95,0x47,0x72,0xA5,0x59,0xEF,0xBF,0xA9,0x0D, + 0x47,0x72,0xA5,0x59,0xAB,0x0F,0x37,0xFE,0x67,0x7A,0xE5,0x61,0x3D,0xB5,0x5E,0xD7, + 0x67,0x72,0xE5,0x61,0x2C,0x9E,0xF3,0xAB,0x29,0x8B,0x67,0x72,0x23,0xA9,0xBD,0xBD, + 0x35,0xE6,0x29,0x8B,0x0B,0x09,0x2D,0x2D,0x55,0xEE,0x14,0xE6,0xAA,0xEA,0x7F,0x55, + 0x35,0xE6,0xB3,0xD5,0xE8,0xF8,0x6A,0x7A,0xB3,0xD5,0xF1,0xBC,0xB0,0x3C,0xBE,0xB6, + 0xB4,0xD5,0x52,0xC5,0xE8,0xEA,0xEA,0x5A,0x73,0xCD,0x32,0xC5,0x2F,0xE7,0xEE,0xFF, + 0x52,0xC5,0xD1,0xB4,0xE0,0xA8,0xF8,0x78,0x11,0xBD,0xEE,0x9B,0xE8,0xEA,0x68,0x7A, + 0x6F,0xAC,0xCD,0x93,0x2D,0xAF,0x2F,0x25,0xB0,0xB4,0x4F,0xA4,0x2B,0x8B,0xEA,0x7E, + 0xB0,0xB4,0x2E,0xA4,0xFC,0xFE,0x97,0xBF,0xB0,0xB4,0x4F,0xA4,0x9F,0x3F,0xAA,0x4E, + 0x63,0x59,0x22,0x51,0x0B,0x8A,0xA0,0xC9,0x84,0x59,0x43,0x59,0x9E,0x17,0x6D,0xFD, + 0x83,0x61,0x23,0x51,0xEA,0x7A,0xFF,0x7D,0x63,0x59,0x23,0x51,0x8A,0x2B,0xAE,0xF6, + 0x63,0x59,0x23,0x51,0x3E,0x78,0xEE,0x77,0x43,0x51,0x02,0x49,0xAA,0xBC,0x9A,0x2E, + 0x43,0x51,0x02,0x49,0xAE,0x23,0xA0,0x5E,0x44,0x51,0x03,0x49,0xFA,0xDC,0xD7,0xFB, + 0x44,0x59,0x02,0x49,0xE7,0xB7,0x3F,0x0A,0x64,0x59,0x23,0x51,0xA9,0xAF,0xBE,0xDC, + 0x8B,0x9B,0xE6,0x69,0x0D,0x09,0x09,0x0B,0xEC,0xAB,0x8B,0x9B,0x0B,0x2F,0x89,0x2F, + 0x0D,0xAC,0x8B,0xA3,0x7A,0x7E,0xBA,0x82,0xCC,0xAB,0x49,0x93,0xDF,0x7B,0x58,0x78, + 0x6A,0x93,0xC8,0x82,0xA0,0xFA,0xFE,0x7F,0x29,0x93,0xC8,0x8A,0x78,0x56,0xDD,0xB7, + 0xE9,0x8A,0x66,0x72,0x5C,0x5C,0x58,0x58,0x66,0x72,0x26,0x72,0xEA,0xBA,0xBA,0xFA, + 0x46,0x72,0x06,0x6A,0xFC,0xB8,0x28,0xE2,0x67,0x7A,0x26,0x72,0xD5,0xBD,0xFD,0x2D, + 0xC8,0x82,0x46,0x72,0xA9,0x2B,0x2B,0x8A,0xA7,0x7A,0x03,0x49,0x5E,0x78,0x70,0xE0, + 0xE3,0x38,0xA2,0x30,0x38,0x3A,0xFE,0x60,0x03,0x41,0xA2,0x30,0x82,0xEA,0xFB,0x7D, + 0x24,0x41,0xC2,0x30,0xA5,0x25,0xBD,0xF5,0x24,0x41,0xC3,0x38,0x2E,0xEE,0xFE,0xFE, + 0x44,0x41,0xE3,0x38,0x7C,0xFB,0xAD,0xF5,0x44,0x49,0xE3,0x40,0xDF,0x57,0x7F,0x0A, + 0x65,0x49,0xE3,0x40,0x2F,0xBD,0xFF,0xFA,0x64,0x49,0xC2,0x30,0x78,0x6A,0xFA,0xF2, + 0x03,0x39,0xA2,0x30,0x7D,0x57,0x5C,0xDA,0xE3,0x38,0xA2,0x28,0x2D,0x2D,0x8D,0x0A, + 0xA5,0x51,0x03,0x39,0xF5,0xB5,0xB5,0x35,0x85,0x51,0x23,0x41,0xDF,0x5F,0x7E,0x70, + 0x44,0x49,0xE3,0x38,0x5E,0x7A,0x7A,0x5A,0x24,0x39,0xC2,0x30,0x8E,0xBB,0xFE,0xDF, + 0x03,0x39,0xC2,0x30,0xBA,0x56,0xD5,0xF5,0x23,0x39,0xC2,0x30,0x02,0xEA,0x77,0x77, + 0x03,0x39,0xC2,0x30,0xBC,0xAA,0x7E,0xAB,0x03,0x41,0xE2,0x30,0xFE,0xF5,0x7D,0x5F, + 0x24,0x39,0xC3,0x30,0x0B,0xBA,0xEB,0x7E,0x24,0x39,0xC2,0x30,0x2A,0xAA,0xE2,0xA9, + 0x03,0x39,0xE3,0x30,0xC0,0x08,0x88,0xEE,0x23,0x41,0xC2,0x30,0xB5,0xBF,0x3E,0xBE, + 0x23,0x41,0x03,0x39,0x50,0xB0,0xE3,0x2F,0x23,0x41,0xE3,0x38,0x76,0xE5,0xE7,0xA8, + 0x64,0x49,0x03,0x39,0x2B,0x2B,0x0D,0xB5,0x47,0x72,0x64,0x51,0x27,0xF5,0xF5,0x55, + 0x87,0x7A,0xA5,0x59,0xE8,0x82,0x09,0xB5,0x47,0x72,0xA5,0x59,0xBF,0x2F,0xD4,0x58, + 0x87,0x7A,0x05,0x62,0xAF,0x0A,0x2A,0xA9,0xA8,0x7A,0x67,0x72,0x3F,0xBA,0xE8,0x80, + 0x93,0xD5,0xC9,0x82,0x09,0x0D,0x2D,0x2D,0x14,0xE6,0x72,0xCD,0x88,0xAA,0xFF,0x5D, + 0xF4,0xDD,0x32,0xC5,0xA0,0xE8,0xEA,0x7A,0x93,0xCD,0xF1,0xBC,0x07,0x0F,0x09,0xA9, + 0x73,0xCD,0x11,0xBD,0xA0,0x60,0x40,0xA0,0x73,0xCD,0xD0,0xB4,0x0B,0x2F,0xB5,0xFF, + 0x52,0xC5,0xB0,0xB4,0xE8,0x78,0xDE,0x77,0x90,0xAC,0x2B,0x7B,0xE0,0xF0,0x78,0x58, + 0x70,0xAC,0x8C,0x8B,0x2F,0x2D,0x09,0xAB,0x90,0xAC,0x0E,0x9C,0xF8,0xDF,0xFF,0xA7, + 0x8F,0xAC,0x4F,0xA4,0x0D,0x6D,0xFD,0xD8,0xD0,0xB4,0x0E,0x9C,0xFF,0xBD,0xBD,0x2A, + 0x84,0x59,0x43,0x51,0xD5,0xED,0x2E,0x3A,0x63,0x59,0x22,0x51,0x83,0x42,0x62,0xFE, + 0x43,0x51,0x02,0x49,0xA8,0x2A,0x3A,0xB7,0x43,0x51,0x22,0x51,0x04,0x02,0xC2,0x4C, + 0x43,0x51,0x02,0x49,0xFE,0x7A,0xBA,0xB4,0x44,0x51,0x02,0x49,0xAB,0xEB,0xBA,0xBA, + 0x43,0x51,0x03,0x49,0xDC,0xBF,0x8B,0xA7,0x44,0x59,0x03,0x49,0x5E,0xFF,0xBF,0x27, + 0x64,0x59,0x03,0x51,0xAD,0xAF,0xA2,0xEA,0xA4,0x61,0x24,0x51,0x97,0x9F,0xBF,0x17, + 0xAB,0xA3,0x47,0x7A,0x09,0x0B,0x0B,0x0B,0x0D,0xAC,0xAB,0xA3,0xAD,0x3D,0xF5,0xFD, + 0x2D,0xB4,0xEC,0xAB,0x7A,0xF2,0x65,0x55,0xEC,0xAB,0x4A,0x93,0x7A,0x7C,0xA8,0x80, + 0x8B,0xA3,0xC8,0x82,0x7E,0x7E,0xE2,0xA0,0x29,0x8B,0xC8,0x82,0xBF,0x7D,0xDF,0x78, + 0xC8,0x82,0x26,0x6A,0xF8,0x68,0x78,0x78,0x46,0x72,0x26,0x6A,0x60,0xF0,0x8B,0xAE, + 0x46,0x72,0x25,0x6A,0xEB,0xAB,0xFB,0x3E,0xC8,0x82,0x26,0x72,0xBD,0xAF,0xAF,0x0B, + 0xC9,0x82,0x88,0x82,0xBB,0x6A,0x8A,0x0A,0xA8,0x82,0x26,0x6A,0x68,0x68,0xE8,0xE0, + 0xE5,0x61,0xC2,0x38,0x56,0x7E,0x7C,0x78,0xA2,0x30,0x61,0x28,0x08,0x2A,0x3C,0xAE, + 0xE3,0x38,0xA2,0x30,0x2E,0xED,0xD5,0x5D,0x03,0x39,0xA2,0x30,0xE2,0xEB,0x7D,0x5D, + 0x03,0x41,0xA1,0x30,0x0E,0xAA,0xE9,0xBD,0x44,0x49,0xE3,0x38,0x0E,0x25,0xBD,0xFD, + 0x65,0x49,0x03,0x41,0x70,0xE2,0xBF,0xDD,0x24,0x41,0xE3,0x38,0xE0,0xBE,0x76,0xDC, + 0x03,0x39,0x82,0x28,0xEA,0xFA,0xFC,0x58,0xE3,0x38,0xA2,0x30,0x22,0x03,0x0B,0xCD, + 0x65,0x49,0xC2,0x30,0x2B,0x09,0x29,0xED,0xA5,0x51,0x03,0x41,0xE8,0xEA,0x6F,0x55, + 0x24,0x41,0xC2,0x30,0xE0,0xE8,0xEA,0x7E,0xE3,0x38,0xC2,0x30,0x72,0xFC,0x37,0x29, + 0xE3,0x38,0xC3,0x28,0xAA,0x0B,0x08,0xA8,0x03,0x39,0xC2,0x30,0x7E,0x7A,0x2A,0xEA, + 0xE3,0x38,0xC2,0x30,0xAB,0x42,0xDB,0x95,0x03,0x39,0xC2,0x30,0xFA,0xF7,0xF7,0xD4, + 0x03,0x39,0xE3,0x30,0x7D,0xD7,0xD6,0x2D,0x03,0x39,0xC2,0x30,0x8F,0xEE,0xB6,0x8A, + 0x03,0x39,0xC2,0x30,0xFD,0x57,0x5E,0xA8,0x03,0x39,0xC2,0x30,0xBB,0xBF,0x2D,0x2A, + 0x44,0x41,0x03,0x39,0xBF,0xED,0x0D,0x09,0x44,0x41,0x03,0x39,0xFA,0x6B,0x78,0xFC, + 0x23,0x41,0xE2,0x38,0x70,0x60,0xEA,0xB2,0x64,0x49,0x03,0x41,0x23,0x29,0xD5,0x55, + 0xA5,0x59,0x44,0x49,0xAA,0xE9,0xFF,0xF9,0xE6,0x61,0x43,0x49,0xA0,0xA3,0xBF,0xB5, + 0x88,0x7A,0xA5,0x59,0x2D,0x2D,0x2D,0x27,0xE8,0x82,0x67,0x7A,0xEE,0xE7,0xB6,0xD8, + 0x31,0xC5,0xC8,0x82,0x2D,0xA5,0x35,0xB5,0x92,0xD5,0xD0,0xBC,0xA2,0x8B,0x2B,0xAD, + 0x72,0xCD,0xF1,0xBC,0x40,0x72,0xFA,0xF2,0x94,0xCD,0x11,0xBD,0xE9,0xE3,0xC2,0xC2, + 0x52,0xC5,0xD0,0xB4,0x0A,0xBF,0xFE,0x7E,0x32,0xC5,0x8F,0xAC,0xE0,0x70,0x7A,0x7F, + 0xB0,0xB4,0x4F,0xA4,0x0C,0x8F,0xEF,0xAB,0xB0,0xAC,0xEA,0x7A,0xDE,0x96,0x26,0x00, + 0xF1,0xBC,0x4E,0xA4,0x55,0x39,0x00,0x08,0x32,0xBD,0x8F,0xAC,0xD5,0xFA,0xE0,0x80, + 0xF1,0xBC,0x6F,0xAC,0xFB,0x7F,0xFE,0xA8,0xB0,0xAC,0x6F,0xAC,0xFE,0xDE,0xDF,0x78, + 0x63,0x59,0x23,0x51,0x42,0xFE,0xFE,0x75,0x44,0x59,0x23,0x49,0xFA,0xA2,0xBB,0xF7, + 0x43,0x51,0x23,0x51,0xB5,0x6F,0x8B,0x76,0x43,0x51,0x03,0x49,0xA2,0x7A,0x7A,0x76, + 0x44,0x51,0x02,0x49,0x35,0xD5,0xBF,0xAB,0x43,0x51,0x03,0x49,0x9A,0xF7,0xA7,0xAB, + 0x63,0x59,0x03,0x51,0xDF,0x5F,0xD7,0xFF,0x64,0x59,0x03,0x51,0x8D,0xAF,0xAA,0x2C, + 0x64,0x59,0x23,0x51,0x5C,0xF6,0xBE,0xAF,0x67,0x7A,0x43,0x59,0xD5,0x95,0x15,0x15, + 0xAB,0xA3,0x29,0x93,0x29,0x29,0x09,0x0B,0xEC,0xAB,0x8B,0x9B,0x2B,0xBE,0xFE,0x7F, + 0x0D,0xAC,0x6B,0x9B,0x02,0x0A,0xDF,0x55,0xEC,0xAB,0x2A,0x93,0x00,0x00,0xAA,0xDF, + 0xEC,0xAB,0xE8,0x8A,0xA8,0xA0,0xFA,0x5F,0x8B,0x9B,0x87,0x7A,0xF8,0x78,0x56,0x57, + 0xA8,0x7A,0x46,0x72,0x5C,0x5F,0x57,0x57,0x46,0x72,0x26,0x6A,0x98,0x88,0xF8,0xDF, + 0xC8,0x82,0x26,0x6A,0xF5,0xFD,0xB5,0x0D,0xC8,0x82,0x87,0x7A,0x89,0xE3,0xAA,0x7C, + 0xA8,0x82,0x05,0x6A,0x00,0xE8,0x7C,0x57,0x87,0x7A,0xC4,0x61,0xA8,0xEE,0xD5,0x55, + 0x26,0x6A,0x03,0x41,0x58,0x78,0x72,0xE2,0xE3,0x40,0x61,0x28,0xFF,0xFE,0xB6,0x9C, + 0xE3,0x38,0xA2,0x30,0x57,0x7F,0xFE,0x8B,0xE3,0x38,0xA2,0x30,0xD5,0xB7,0xBA,0xE2, + 0x03,0x41,0xA2,0x30,0x3D,0xAA,0x0B,0x02,0x24,0x41,0xC2,0x38,0xBF,0xD7,0x9E,0x0F, + 0x44,0x49,0xE3,0x38,0xA9,0x03,0x03,0x82,0x44,0x49,0xE3,0x38,0x57,0xEA,0xAA,0xAA, + 0x24,0x41,0xA2,0x28,0x7B,0x6F,0xE8,0xA0,0xC3,0x30,0x81,0x28,0x8F,0xEF,0x2F,0x2C, + 0x24,0x41,0xA2,0x30,0xBF,0xB5,0x3F,0x2F,0x45,0x41,0xC3,0x38,0xFE,0xE8,0xE2,0x72, + 0xE3,0x30,0xA2,0x30,0xFE,0x55,0x5F,0xEB,0xE3,0x30,0xA2,0x30,0xBF,0xFF,0xFF,0x2A, + 0xE3,0x38,0xA2,0x28,0x0A,0xBB,0xFE,0xBF,0x24,0x39,0xC2,0x30,0xFF,0xF5,0xFD,0x2F, + 0x03,0x39,0xC2,0x30,0xD7,0xBF,0xBE,0xE2,0xE3,0x38,0xC2,0x30,0x98,0xD8,0x72,0xFD, + 0x04,0x41,0xE2,0x30,0xFD,0xFF,0x2B,0x0B,0x44,0x41,0xE3,0x38,0x77,0xFF,0x7F,0xF2, + 0x24,0x41,0xE2,0x38,0xDF,0x7A,0x20,0x20,0x24,0x41,0xE2,0x38,0xDD,0xBB,0xAB,0x08, + 0x84,0x49,0x03,0x41,0xFF,0x69,0xE3,0xFF,0x23,0x41,0xE3,0x38,0xA2,0xF0,0xF8,0xB8, + 0x44,0x41,0x03,0x39,0xFF,0x5D,0xAF,0xA0,0x23,0x41,0xE2,0x38,0x02,0x89,0xAE,0x2A, + 0xA5,0x51,0x23,0x41,0xA9,0xAD,0xBD,0xF5,0xC5,0x59,0x64,0x51,0x9F,0xB0,0xBF,0xAD, + 0x67,0x72,0xE6,0x61,0x2D,0x27,0x2B,0xA9,0xC8,0x82,0x26,0x6A,0xE8,0x82,0x8A,0x9D, + 0x6E,0xAC,0x67,0x72,0x25,0xB5,0x35,0x95,0x93,0xCD,0xAF,0xBC,0xBD,0x2D,0x0B,0x0B, + 0x93,0xCD,0x6F,0xAC,0xB0,0xF8,0x9C,0xBE,0x94,0xCD,0xF1,0xBC,0xA2,0xA2,0xE2,0x58, + 0x53,0xC5,0xB0,0xB4,0x7A,0x78,0x62,0x7F,0x90,0xAC,0xEE,0x9B,0x28,0x0A,0xA0,0x7C, + 0xD0,0xB4,0xCD,0x93,0x02,0x80,0xEA,0xF5,0xB0,0xB4,0x0E,0x9C,0xA0,0xFF,0xD7,0x75, + 0x6F,0xAC,0xCC,0x93,0x00,0xAA,0x5F,0x77,0x11,0xBD,0xCD,0x9B,0x02,0xAF,0xFD,0xD5, + 0x11,0xBD,0x4F,0xA4,0x00,0x8A,0x2F,0xD5,0x32,0xC5,0xB0,0xB4,0x7F,0x2A,0x80,0x09, + 0x43,0x51,0x23,0x51,0xAE,0xB0,0x3C,0x94,0x43,0x51,0x03,0x49,0x2F,0x36,0xBC,0x5A, + 0x43,0x51,0xE2,0x40,0x00,0xA2,0xF0,0xFE,0x44,0x51,0x03,0x49,0x57,0xD5,0xA5,0xBD, + 0x43,0x51,0x23,0x49,0x65,0xBF,0x3A,0xE8,0x43,0x51,0x23,0x51,0xB5,0x7E,0x9B,0x9D, + 0x44,0x59,0x23,0x51,0x0F,0xA3,0x40,0x02,0x64,0x59,0x23,0x51,0xB4,0xE7,0x6F,0xF7, + 0x43,0x59,0x03,0x51,0xA2,0xA3,0xA2,0x68,0x29,0x93,0x43,0x51,0xB5,0x35,0x35,0x25, + 0xAB,0xA3,0x4A,0x93,0x09,0xAB,0x82,0xEB,0xCB,0xA3,0xA8,0x82,0xA0,0xA8,0xFA,0x7E, + 0x4B,0x9B,0x87,0x7A,0x00,0xAA,0x7E,0x55,0x09,0x8B,0x67,0x72,0x00,0xEE,0x77,0x55, + 0xE9,0x8A,0x67,0x72,0xF0,0x7E,0xD5,0x55,0x87,0x7A,0x46,0x72,0xE8,0x7F,0x5A,0x5F, + 0x86,0x72,0x26,0x72,0xDD,0x7B,0xF7,0xDF,0x87,0x72,0x25,0x6A,0xF7,0xBB,0xBB,0x2A, + 0xC8,0x82,0x46,0x72,0x8F,0x0B,0xA2,0x72,0x87,0x7A,0x05,0x6A,0xC0,0x68,0x7E,0x77, + 0x26,0x6A,0xC4,0x61,0x58,0xF6,0xAA,0xEA,0x06,0x6A,0xC4,0x61,0x55,0xBF,0xBA,0x20, + 0x06,0x6A,0xA5,0x59,0x6B,0xEF,0xC8,0x80,0xA5,0x59,0xC2,0x38,0x57,0x5E,0x58,0x78, + 0x04,0x41,0x81,0x28,0x0B,0xF5,0x75,0xFF,0x24,0x41,0xA2,0x30,0xEA,0x0B,0xAD,0xBD, + 0x03,0x39,0xA2,0x30,0xBA,0xFF,0x5C,0x5A,0x44,0x49,0xC2,0x30,0xAB,0x2B,0x29,0x89, + 0x65,0x49,0x24,0x41,0x6E,0x70,0x78,0xB7,0x44,0x49,0x03,0x41,0xDD,0xAE,0x7C,0xF8, + 0x44,0x41,0xE3,0x38,0x76,0xBF,0xAF,0x2F,0x04,0x39,0xA2,0x28,0xDE,0xF8,0x7C,0x5C, + 0x24,0x41,0x82,0x28,0x0B,0x2B,0xE7,0xD5,0x04,0x41,0xA2,0x28,0xE0,0xB8,0xBF,0xBD, + 0x04,0x39,0xC3,0x30,0xBF,0xEA,0x5A,0x57,0x03,0x39,0xA2,0x28,0xB3,0xFA,0xF7,0xFF, + 0x03,0x39,0xA2,0x28,0xBD,0xB7,0x3F,0xAF,0x24,0x41,0xC3,0x30,0x22,0x02,0xCA,0xFF, + 0x03,0x39,0xC2,0x30,0x70,0x50,0xEE,0xB7,0x03,0x39,0xC3,0x30,0xB5,0x3E,0xFE,0x9D, + 0x65,0x49,0x03,0x39,0xFD,0xAF,0x2D,0x29,0x64,0x49,0x03,0x39,0x5F,0xEE,0xE8,0x70, + 0x65,0x49,0x02,0x41,0xAA,0xAA,0x82,0xA9,0x64,0x49,0xE3,0x38,0xAC,0xEA,0xEE,0x5E, + 0x44,0x49,0xC2,0x30,0xA2,0xAE,0xD6,0x5F,0x23,0x41,0xC1,0x30,0x28,0xA0,0x7A,0xFD, + 0x44,0x41,0xC2,0x30,0xA0,0xEB,0xBF,0xB5,0x44,0x41,0x03,0x39,0x9B,0xD9,0x6B,0xED, + 0x64,0x49,0x03,0x41,0xA0,0xAB,0xB9,0xFB,0xA5,0x59,0x03,0x41,0x0B,0xAE,0x2B,0x05, + 0x26,0x6A,0xA5,0x59,0x2D,0x25,0x39,0x3B,0x67,0x72,0xE5,0x61,0x97,0x96,0xFC,0xF0, + 0x6B,0x93,0x26,0x6A,0x35,0x3D,0x15,0x1D,0x72,0xCD,0xD0,0xBC,0x03,0x01,0x01,0x81, + 0x53,0xC5,0x6F,0xAC,0x2E,0x2E,0x27,0xFD,0x93,0xCD,0x4E,0xA4,0xE0,0xE8,0x7E,0x57, + 0xD0,0xB4,0xAD,0x93,0xA0,0xEA,0x7F,0x5F,0x2E,0xA4,0x8C,0x8B,0xF8,0x5F,0x77,0x75, + 0xEE,0x9B,0x8C,0x8B,0x0B,0xAD,0xA5,0x9D,0x0E,0x9C,0xAD,0x93,0x2A,0xF5,0x2D,0xFF, + 0x2E,0x9C,0x8C,0x8B,0x8A,0xA2,0xFA,0x7A,0x2E,0xA4,0x6C,0x83,0x2F,0x37,0x37,0x95, + 0x8F,0xAC,0x2F,0xA4,0xBF,0x2B,0x27,0x2B,0x32,0xC5,0x8F,0xAC,0xDD,0xAB,0x2B,0x0B, + 0x43,0x51,0x23,0x51,0xF6,0x39,0x96,0xD5,0x23,0x51,0x02,0x49,0xC8,0x6A,0x78,0x54, + 0x23,0x49,0xE2,0x48,0xE7,0x2F,0x82,0x2A,0x64,0x51,0x02,0x49,0xED,0xED,0xAF,0xCF, + 0x44,0x51,0x02,0x49,0x80,0xB0,0xFF,0xA6,0x44,0x59,0x22,0x49,0x3F,0x29,0x81,0xB8, + 0x44,0x59,0x23,0x51,0x00,0x20,0xDB,0xF1,0x64,0x59,0x03,0x51,0xA2,0xB2,0x7A,0xFB, + 0x43,0x59,0x03,0x51,0xDE,0xFE,0xF6,0x75,0x6A,0x9B,0x43,0x59,0x25,0x25,0x25,0x2D, + 0x6A,0x9B,0xC8,0x82,0x00,0x80,0xE8,0x7A,0x29,0x93,0x67,0x72,0xE8,0x5E,0x57,0x5F, + 0x87,0x7A,0x46,0x72,0xFC,0x72,0xEE,0x9E,0x87,0x7A,0x46,0x72,0xAB,0xBE,0x3A,0xBE, + 0x87,0x7A,0x46,0x72,0xBA,0xBC,0xEF,0xBF,0x87,0x7A,0x46,0x72,0x7A,0xDA,0x9E,0x7E, + 0x67,0x7A,0x46,0x72,0x57,0x7A,0xB5,0xAD,0xA8,0x7A,0x46,0x72,0x35,0x2F,0xAF,0xFB, + 0xA8,0x7A,0x05,0x6A,0x60,0x5F,0x57,0x57,0x05,0x6A,0xC5,0x61,0xC0,0x98,0xEA,0x5F, + 0x05,0x6A,0xC5,0x61,0xE2,0xBE,0xB8,0xFF,0x26,0x6A,0xE5,0x69,0xAF,0x0A,0x0D,0x0F, + 0x47,0x72,0x06,0x6A,0x7B,0xAB,0x8F,0x2A,0x26,0x6A,0xE3,0x38,0x5A,0x7C,0x78,0xE0, + 0xC2,0x38,0x81,0x28,0xF0,0xFC,0xFC,0xFC,0x03,0x39,0x81,0x28,0x2D,0xAD,0xA9,0xAB, + 0x03,0x39,0xA2,0x38,0x7A,0xE8,0xFA,0xAA,0x65,0x49,0xC2,0x38,0xE9,0xCB,0xCB,0xE3, + 0x44,0x41,0xC2,0x38,0x0F,0xBF,0xF7,0xD7,0x24,0x41,0xC2,0x30,0x00,0xFA,0x7A,0x55, + 0x23,0x41,0xC3,0x30,0x2B,0xAB,0x63,0x7B,0xE3,0x38,0x82,0x20,0xFC,0xFE,0x5E,0x5E, + 0xC3,0x28,0x61,0x20,0xFE,0xBE,0x3F,0x2F,0x03,0x31,0x81,0x28,0xAF,0xEB,0xF8,0xFC, + 0xC2,0x28,0x61,0x20,0x2A,0x22,0x2B,0xAA,0xE3,0x38,0xC2,0x28,0x5F,0xDD,0x95,0xFD, + 0xE3,0x30,0xC2,0x30,0x02,0xA9,0x93,0x5E,0x03,0x39,0xC3,0x30,0x7E,0x37,0xAF,0xAD, + 0x04,0x39,0xC3,0x30,0xF5,0x7F,0xAF,0xDF,0xE3,0x38,0xC2,0x30,0x1F,0x8B,0x0B,0xB9, + 0x85,0x51,0x03,0x39,0x29,0x89,0xFD,0x55,0x85,0x49,0x03,0x41,0xF8,0x7A,0x5F,0x57, + 0x44,0x41,0xE3,0x38,0x8B,0xAD,0xB5,0xF7,0x24,0x41,0xE2,0x38,0x57,0x7F,0xBF,0x2F, + 0x03,0x39,0xC2,0x30,0xF9,0xEF,0xC6,0xDC,0x03,0x39,0xC2,0x30,0xAB,0x03,0x8E,0x2D, + 0x23,0x39,0xC2,0x30,0x3F,0x3E,0x36,0xBE,0x44,0x41,0x03,0x39,0x7F,0x77,0x7A,0xE2, + 0x44,0x49,0xC2,0x30,0xAA,0xAB,0x0B,0x2F,0xA5,0x51,0x03,0x41,0xAD,0xBF,0xAB,0x0A, + 0x47,0x6A,0xA5,0x51,0x2D,0x2D,0xAD,0x75,0x67,0x72,0xA5,0x59,0x80,0x80,0xFB,0xF5, + 0xC8,0x7A,0x84,0x59,0x2E,0x3F,0xBF,0xBD,0x72,0xCD,0x8C,0x93,0x83,0x82,0xA3,0x89, + 0x90,0xB4,0xAD,0x93,0x82,0xE8,0xF8,0x70,0x2F,0xA4,0x8C,0x8B,0xA0,0xEA,0x5F,0xD5, + 0xEE,0x93,0x8C,0x8B,0x7A,0x7E,0xFF,0xBD,0xCD,0x93,0x8D,0x8B,0xF7,0x79,0xFD,0x3B, + 0xCD,0x93,0x6C,0x83,0x3F,0xAA,0xFA,0x70,0xEE,0x9B,0x0A,0x7B,0xA0,0xFA,0x7E,0x7F, + 0xAD,0x93,0xEA,0x72,0xE0,0xFE,0xFD,0x5D,0x8C,0x8B,0xEB,0x72,0x3B,0xEF,0xFF,0x77, + 0x2E,0xA4,0x2B,0x7B,0x02,0x2B,0xFD,0xFD,0x32,0xBD,0xAD,0x93,0x0A,0x2B,0xBD,0xFD, + 0x43,0x51,0x03,0x49,0xBB,0xAF,0xBC,0xD6,0x23,0x49,0x02,0x49,0x3D,0x77,0x58,0x58, + 0x43,0x51,0x02,0x49,0x33,0xBD,0xFD,0xDD,0x43,0x49,0xE2,0x48,0xA2,0xEE,0xEA,0x6A, + 0x64,0x59,0x02,0x49,0xBF,0xAD,0x29,0xAA,0x43,0x51,0x03,0x51,0x80,0x28,0xA8,0xB2, + 0x44,0x51,0x23,0x51,0x73,0x63,0x08,0x7A,0x43,0x51,0x02,0x49,0xAE,0xEE,0x5C,0xDA, + 0x23,0x51,0x03,0x49,0xD5,0x65,0x5E,0x13,0x0A,0x93,0x23,0x51,0x0D,0x0D,0x09,0x09, + 0x2A,0x93,0x87,0x7A,0xF8,0x78,0xFE,0x7E,0xA7,0x7A,0x67,0x7A,0xFC,0xEE,0xBF,0x5E, + 0x87,0x7A,0x67,0x7A,0x56,0x5F,0xDA,0x83,0x87,0x7A,0x47,0x72,0x8E,0xB8,0xBA,0x08, + 0x87,0x7A,0x46,0x72,0xAE,0xBB,0x5B,0xA2,0x66,0x72,0x46,0x72,0x64,0xD6,0x5C,0xF7, + 0x87,0x7A,0x46,0x72,0xD5,0xF7,0x35,0xB9,0x87,0x7A,0x46,0x72,0xE9,0x60,0x70,0x7A, + 0x26,0x72,0xC5,0x61,0xF0,0xF8,0x6E,0x5A,0xE5,0x61,0xA4,0x61,0x9F,0x17,0x35,0xAD, + 0xE5,0x69,0xC5,0x61,0xBB,0xF8,0x5C,0x94,0x26,0x6A,0xC4,0x61,0x23,0x2B,0x25,0x2F, + 0x67,0x7A,0x26,0x72,0xFF,0xDD,0xFD,0x87,0x46,0x6A,0xE2,0x38,0xE0,0xE8,0x78,0x70, + 0xE2,0x38,0x61,0x28,0xFC,0xFE,0xD7,0xF7,0x23,0x41,0xA1,0x28,0xFD,0xBF,0xAF,0xA3, + 0x64,0x49,0xE3,0x38,0x5D,0xB9,0x2F,0x35,0x64,0x49,0xC2,0x30,0xEB,0x6A,0x78,0x78, + 0xE3,0x38,0x81,0x28,0xA8,0xFE,0x5F,0x7E,0xC3,0x30,0x82,0x20,0x20,0x2B,0xBE,0xF5, + 0xE3,0x30,0x62,0x20,0x80,0xE2,0xE2,0x7A,0xC2,0x28,0x61,0x20,0x7E,0xDF,0x75,0x77, + 0xC3,0x28,0x61,0x20,0x2F,0x2F,0xBF,0xF5,0xC3,0x30,0x82,0x20,0x58,0xF8,0xB7,0xAF, + 0xE3,0x30,0xA2,0x28,0x55,0x69,0xCB,0xAF,0xE3,0x30,0xA2,0x28,0xEB,0xEA,0xA8,0xFE, + 0xE3,0x30,0xA2,0x28,0x7E,0xF5,0xDF,0xAA,0x03,0x39,0xA2,0x30,0xAB,0xAB,0xFB,0x5E, + 0xE3,0x30,0xA2,0x30,0x3C,0xCE,0xE9,0xAF,0x03,0x39,0xA2,0x30,0xFB,0xAD,0x09,0xAA, + 0x03,0x39,0xE3,0x30,0x3E,0x8A,0xAC,0x57,0x03,0x39,0xE2,0x38,0xFB,0x57,0x58,0xB0, + 0x03,0x39,0xE2,0x38,0x00,0x30,0xBF,0xC3,0x23,0x41,0xE2,0x38,0xAE,0xF5,0x7E,0x78, + 0x23,0x41,0xC2,0x30,0xF8,0xFF,0xB7,0x29,0x44,0x41,0xE2,0x38,0xBD,0xDD,0xFF,0xA8, + 0x23,0x39,0xE2,0x30,0xF8,0xB2,0xBA,0xFB,0x23,0x39,0xE2,0x30,0x03,0x2D,0xB5,0x9D, + 0x23,0x41,0xC1,0x30,0x2A,0xF6,0xEE,0xFA,0xC5,0x51,0x02,0x39,0x8E,0xFD,0xB5,0xB5, + 0xC5,0x51,0x43,0x49,0x2D,0xAD,0xFF,0xA0,0x46,0x6A,0xA5,0x51,0xA5,0xAD,0x0D,0xF5, + 0x47,0x6A,0xA4,0x51,0x3B,0xA2,0x2F,0xB7,0x90,0xB4,0x88,0x72,0x03,0x2D,0x2D,0x0D, + 0x90,0xB4,0xAD,0x8B,0x60,0xE0,0xE0,0xC0,0x8C,0x8B,0x2B,0x83,0x0A,0x3E,0x2E,0x34, + 0xCD,0x93,0x6C,0x83,0x29,0x3A,0xAA,0xBA,0xCD,0x93,0x0A,0x73,0x80,0xC0,0xF8,0x5E, + 0x8C,0x8B,0xA9,0x6A,0xA0,0xEF,0xF7,0x57,0x2B,0x7B,0xCA,0x6A,0x80,0x82,0xFB,0xDF, + 0x2A,0x73,0xCA,0x72,0xFF,0xD6,0xF7,0xDE,0x4C,0x83,0xEA,0x72,0xB7,0xAB,0xAB,0x2A, + 0xCD,0x93,0x2B,0x7B,0xA5,0xA5,0x37,0x2F,0x0E,0x9C,0x6C,0x83,0x09,0x37,0x97,0xD4, + 0x43,0x51,0xE2,0x40,0x6E,0xD2,0xF2,0xBA,0x43,0x51,0xE2,0x40,0xB5,0xAB,0xAE,0xEA, + 0x23,0x51,0x02,0x41,0xBF,0x38,0xE0,0xDB,0x43,0x51,0x02,0x49,0xD6,0xD6,0xED,0xEB, + 0x43,0x51,0x03,0x51,0xA8,0xBB,0xAA,0xFB,0x43,0x51,0x23,0x51,0x30,0xBC,0xA9,0x41, + 0x43,0x51,0x03,0x49,0xF8,0xAA,0xAB,0x6B,0x23,0x51,0xE2,0x48,0xA8,0xB8,0x9C,0xBE, + 0x23,0x51,0xE2,0x48,0xBA,0xBF,0xBF,0x3F,0x09,0x8B,0x84,0x59,0x09,0x09,0x01,0x0B, + 0xC8,0x82,0x87,0x7A,0x78,0xF8,0x78,0x5E,0xA7,0x7A,0x67,0x7A,0x5E,0xFF,0xEF,0xEE, + 0xA8,0x82,0x67,0x72,0xFF,0xAE,0xE6,0xBC,0xA8,0x7A,0x67,0x7A,0xFF,0xB8,0xBA,0xDE, + 0x87,0x7A,0x67,0x72,0x9A,0x62,0x78,0x6A,0x66,0x72,0x46,0x72,0xE6,0x56,0xFD,0xD5, + 0x87,0x7A,0x46,0x72,0xB6,0x37,0xA9,0xBD,0x87,0x7A,0x05,0x6A,0xE0,0xFA,0x7A,0x7E, + 0x06,0x6A,0xA4,0x61,0x78,0x7A,0x76,0x9E,0x87,0x7A,0xC4,0x61,0x55,0xBD,0xB5,0x2B, + 0x67,0x7A,0x05,0x6A,0xB5,0x0B,0x00,0xBE,0xA8,0x7A,0x46,0x72,0x5F,0x8A,0xFB,0x55, + 0x87,0x7A,0x26,0x6A,0x0B,0x80,0x7F,0xD7,0x46,0x6A,0x03,0x41,0x60,0x60,0x60,0xE0, + 0xE2,0x38,0x81,0x30,0xB5,0xBF,0x3E,0x08,0x44,0x41,0xE2,0x38,0x82,0xA2,0x2B,0x3D, + 0x44,0x49,0xC2,0x30,0x2F,0xBE,0x7E,0x5C,0x44,0x49,0xC2,0x30,0xF0,0x62,0x6B,0x7F, + 0xC2,0x30,0x82,0x20,0xAA,0xA2,0xFA,0x76,0xA2,0x28,0x62,0x20,0xC8,0xCA,0xEA,0x7F, + 0xA2,0x20,0x61,0x20,0x78,0xF7,0xF5,0xEF,0xC3,0x28,0x62,0x20,0xFF,0xBD,0xB7,0xAB, + 0xA2,0x28,0x61,0x20,0xD7,0xAE,0xA8,0xA0,0xC2,0x28,0x82,0x20,0xFD,0xBF,0xAB,0xAD, + 0xC2,0x28,0xA2,0x28,0x4B,0xF6,0xE0,0xEB,0xE3,0x30,0xA2,0x28,0x5F,0xAD,0xA7,0x2D, + 0xE3,0x30,0xA2,0x28,0x02,0xE3,0xE2,0x7A,0xE3,0x38,0xA2,0x28,0xBA,0xE2,0xB7,0xF5, + 0xC2,0x30,0xA2,0x28,0x82,0xB0,0x00,0x2B,0x04,0x39,0xC3,0x30,0xE3,0x7D,0xE5,0xFD, + 0x03,0x39,0xC3,0x30,0x22,0xAF,0xEF,0x57,0x23,0x39,0xC2,0x30,0x2A,0xEA,0xEF,0xBF, + 0x03,0x39,0xE2,0x30,0x8B,0x7F,0x57,0x3A,0x23,0x39,0xE2,0x38,0x4A,0x45,0xFF,0xAE, + 0x23,0x41,0xE3,0x38,0x25,0xB5,0x35,0x2A,0x84,0x49,0x24,0x41,0x6F,0xEF,0x3B,0xAF, + 0x64,0x49,0x03,0x39,0x55,0xF7,0xBF,0x88,0x43,0x49,0xC1,0x30,0xF7,0xDF,0xFA,0xA2, + 0x43,0x41,0xE2,0x38,0xFE,0x8D,0xBB,0xBF,0x84,0x49,0xE2,0x38,0x25,0xB7,0xFF,0x9F, + 0xA4,0x51,0x43,0x49,0xE0,0x57,0xF5,0x05,0x06,0x62,0x63,0x49,0xB5,0xFD,0xAD,0x2B, + 0x27,0x62,0x84,0x51,0x97,0xBF,0xBA,0x88,0xF1,0xBC,0x27,0x62,0x0D,0x2D,0x2D,0x2D, + 0x73,0xC5,0xED,0x9B,0x7F,0x7F,0xEA,0x80,0x70,0xAC,0x48,0x62,0xFE,0xD6,0x5A,0xE0, + 0x4C,0x83,0xC7,0x51,0x00,0xEA,0xFE,0x5E,0x0B,0x73,0xA6,0x51,0xA0,0xAA,0xFF,0xF5, + 0xA9,0x6A,0x27,0x5A,0x08,0xAE,0xAB,0xF5,0xEA,0x72,0x68,0x62,0x32,0xAA,0xAF,0xBD, + 0x6C,0x8B,0xA9,0x6A,0xFF,0xBF,0x3D,0x2F,0x2E,0x9C,0x0B,0x7B,0xFD,0xAF,0x8A,0x00, + 0x0E,0x9C,0x6C,0x83,0x95,0xD7,0xE8,0xE0,0x4F,0xA4,0x6B,0x8B,0x5A,0x72,0x62,0x8A, + 0x23,0x49,0x02,0x49,0xE4,0xB9,0x0D,0x09,0x23,0x49,0x03,0x49,0x0D,0x25,0x2F,0xA0, + 0x43,0x51,0x02,0x49,0x5E,0x16,0xAE,0xBB,0x43,0x51,0x23,0x51,0x56,0x74,0xD2,0x01, + 0x43,0x51,0x03,0x49,0x0A,0xB2,0x9E,0x92,0x43,0x51,0x02,0x49,0xE2,0xEC,0x72,0xDD, + 0x23,0x51,0x03,0x49,0xD3,0x63,0x02,0xDE,0x23,0x51,0xE2,0x48,0x7B,0x60,0xEE,0xFE, + 0xE9,0x82,0xE2,0x48,0xD5,0xD5,0xB5,0x2D,0xE8,0x8A,0x26,0x6A,0x81,0x82,0x80,0xA0, + 0xC8,0x7A,0x66,0x72,0xB8,0xFE,0xFE,0xE3,0xA7,0x7A,0x66,0x72,0xFA,0xFE,0xBE,0x8B, + 0xA7,0x7A,0x66,0x7A,0xAF,0xFF,0xFB,0xA2,0x87,0x7A,0x66,0x72,0x00,0x0A,0x0A,0xA0, + 0xA7,0x7A,0x46,0x72,0xFE,0x5C,0x5F,0x7F,0x49,0x8B,0x46,0x72,0x55,0x55,0x95,0x0D, + 0x8A,0x9B,0x67,0x7A,0x55,0xD5,0xAA,0x20,0x29,0x8B,0x06,0x6A,0xFF,0x82,0xE0,0x5E, + 0x67,0x7A,0x06,0x6A,0xAE,0x70,0x57,0x55,0x26,0x6A,0xC5,0x59,0xA0,0xA2,0x02,0x7E, + 0x46,0x72,0xC4,0x59,0xFF,0xAA,0x00,0xD5,0x67,0x72,0xC5,0x61,0x2E,0xA2,0x00,0x55, + 0xA8,0x7A,0x84,0x51,0xAA,0xA2,0xA2,0x57,0x66,0x72,0x44,0x49,0x78,0x68,0x7A,0x7F, + 0x44,0x41,0xC2,0x38,0xD7,0x77,0xBE,0xE0,0x03,0x39,0xC2,0x38,0xBB,0xBF,0xAF,0x60, + 0x24,0x41,0x81,0x28,0xA0,0xA8,0xEF,0xDF,0x03,0x31,0x61,0x18,0xEA,0xF8,0xFE,0x7F, + 0xA2,0x20,0x61,0x18,0x7C,0xEC,0xEF,0xFF,0xA2,0x20,0x61,0x18,0xF5,0xAD,0xAB,0x0F, + 0xE3,0x30,0x82,0x20,0xF5,0xF5,0xBD,0xB2,0xE3,0x30,0xA2,0x28,0x5B,0xEF,0xAA,0x0A, + 0xE2,0x30,0x81,0x20,0x77,0x7F,0xFE,0xA8,0xA2,0x28,0x81,0x20,0xAB,0x67,0xEE,0x00, + 0xE2,0x30,0x82,0x20,0xBF,0xFD,0xFD,0xA2,0xC2,0x28,0x81,0x28,0x08,0xA7,0xA5,0x0B, + 0xC2,0x30,0xA2,0x28,0x62,0x6A,0xFB,0xD7,0x03,0x31,0xA2,0x28,0xB5,0xED,0x2B,0x2D, + 0x03,0x39,0xC2,0x30,0xD5,0xBF,0x8A,0x2B,0x24,0x39,0xC2,0x38,0x6B,0xCA,0x0B,0xAB, + 0x03,0x39,0xC2,0x30,0xF7,0xFD,0x22,0x32,0x23,0x39,0xE3,0x30,0xAD,0x3D,0x79,0xEF, + 0x23,0x39,0xC2,0x30,0x2A,0xAA,0xFA,0x5A,0x23,0x39,0xE2,0x30,0xFC,0xD5,0xD7,0x55, + 0x23,0x41,0xE3,0x38,0xA2,0xA9,0xBD,0x95,0x64,0x49,0x03,0x39,0x2B,0xFF,0xF5,0xB7, + 0x85,0x51,0x44,0x49,0xAE,0x73,0x63,0xEF,0x44,0x49,0x23,0x41,0x40,0x5E,0xE6,0x0F, + 0x43,0x41,0x03,0x39,0xD7,0x55,0xFF,0xAE,0x43,0x41,0x03,0x39,0x35,0xAF,0x7E,0xE2, + 0x84,0x51,0x03,0x39,0x02,0xFF,0xFD,0xEF,0xC5,0x59,0x43,0x41,0x0A,0x99,0x7D,0xDD, + 0x06,0x62,0x64,0x49,0x02,0xBF,0xF5,0xBF,0xD1,0xB4,0x06,0x62,0x2D,0x25,0x25,0xB5, + 0x93,0xCD,0xD1,0xBC,0xAA,0xAA,0xAB,0xBD,0x53,0xC5,0x2F,0xA4,0x7E,0xFE,0xF8,0xE0, + 0xB0,0xAC,0xEB,0x7A,0x7E,0xAA,0x20,0x00,0x8F,0xAC,0xE6,0x51,0x57,0xFA,0x00,0x00, + 0x6F,0xA4,0x07,0x5A,0x55,0xFF,0x00,0x00,0x4F,0xA4,0xA9,0x6A,0x55,0xFD,0x00,0x00, + 0x2E,0x9C,0xCA,0x72,0xAD,0xAB,0x00,0x00,0x6F,0xAC,0xED,0x93,0x2D,0xA9,0x8B,0xAB, + 0x4F,0xA4,0xAC,0x8B,0x70,0xF8,0xE0,0xA2,0x6F,0xAC,0xCC,0x93,0xAD,0x8D,0x0D,0x0D, + 0x23,0x51,0x02,0x41,0xA0,0x43,0xFF,0xFF,0x23,0x51,0xE2,0x40,0xA2,0x1A,0x2F,0x0F, + 0x43,0x51,0x23,0x51,0xFD,0x8B,0xA0,0x03,0x43,0x51,0x23,0x51,0x58,0x74,0x65,0x54, + 0x43,0x51,0x03,0x49,0xF3,0xBA,0xFE,0xDE,0x23,0x51,0x02,0x41,0xFC,0xA7,0x5F,0x7B, + 0x23,0x49,0x03,0x49,0x54,0x28,0x7E,0xF9,0xC4,0x61,0xA1,0x40,0xFF,0xFF,0xBF,0x3D, + 0x09,0x8B,0x43,0x51,0x0D,0x09,0x02,0x00,0x09,0x8B,0xA7,0x82,0x78,0xEC,0xFA,0x7A, + 0xE8,0x82,0x86,0x7A,0x57,0xDF,0xFF,0xF8,0xA7,0x7A,0x87,0x7A,0xDE,0x5E,0x5E,0x08, + 0xA7,0x7A,0x66,0x72,0xB2,0xEA,0x60,0x78,0x29,0x93,0x66,0x72,0x57,0x55,0x55,0x15, + 0xAB,0xA3,0x87,0x7A,0x55,0xB5,0x0B,0x00,0x8A,0x9B,0x25,0x6A,0x02,0x00,0xC0,0x78, + 0x8A,0x9B,0xC5,0x61,0xE0,0x5A,0x57,0x55,0x26,0x6A,0xA4,0x61,0xB8,0xFB,0xD7,0xAF, + 0x06,0x6A,0x44,0x49,0x00,0x68,0x5E,0x5E,0xA4,0x59,0x03,0x41,0xEC,0x77,0xF5,0xEF, + 0x43,0x49,0x23,0x41,0x0B,0xA2,0xE2,0xD8,0x43,0x49,0x03,0x41,0xE2,0xA8,0xEA,0xF7, + 0x43,0x49,0x03,0x41,0x67,0x9E,0xDE,0xD7,0x85,0x51,0x23,0x41,0xC9,0xEB,0xEF,0xD9, + 0x44,0x49,0xC2,0x30,0xA0,0xBA,0xFE,0x5E,0x03,0x39,0x82,0x20,0xE0,0xF0,0x5E,0x7E, + 0xA2,0x28,0x81,0x20,0x62,0xE2,0xAA,0xDD,0xA2,0x20,0x61,0x18,0x6A,0xE8,0xF8,0xFE, + 0xA2,0x28,0x61,0x18,0xD5,0xD5,0xA7,0xA9,0xE3,0x30,0x82,0x20,0xA5,0xF5,0xBD,0x2F, + 0x24,0x39,0xA1,0x28,0xAF,0x3D,0x37,0x3E,0x24,0x39,0xC2,0x30,0xF6,0xF7,0xA4,0xFC, + 0xE2,0x30,0x81,0x28,0xBA,0x78,0xFC,0xF8,0xE3,0x30,0xA1,0x28,0xBB,0x02,0x29,0xF5, + 0xE2,0x30,0xA2,0x28,0xE2,0xF0,0xE8,0xFE,0xE3,0x28,0x81,0x28,0xFB,0xDE,0x7E,0xFE, + 0xC2,0x28,0x81,0x20,0xEA,0xEF,0xBF,0x27,0xC2,0x28,0xA2,0x28,0x09,0x05,0x59,0x5B, + 0xE3,0x30,0xA2,0x28,0x0A,0xFF,0xF7,0xF7,0x03,0x39,0xA2,0x28,0x2B,0x2D,0xFF,0xDF, + 0x03,0x39,0xC2,0x30,0xE0,0xF0,0xFF,0x57,0x24,0x39,0xC2,0x30,0xA3,0xAF,0xED,0x95, + 0x23,0x39,0xE2,0x30,0x68,0x7E,0xEB,0xFA,0x23,0x39,0xE2,0x38,0xB5,0xB7,0x35,0xB5, + 0x23,0x41,0xC2,0x30,0xF4,0x7A,0xF8,0xFB,0x64,0x49,0xC2,0x38,0xBF,0x3F,0x2F,0x2D, + 0x85,0x49,0x23,0x41,0xAB,0xD6,0x7C,0xF0,0x44,0x49,0xE2,0x38,0x0A,0x2A,0xBF,0xF6, + 0x23,0x41,0xC2,0x38,0x00,0x02,0xFC,0xFF,0x64,0x49,0xE3,0x38,0x8B,0xAF,0xDF,0xDD, + 0x85,0x49,0xE2,0x38,0x82,0xAB,0xD5,0xF5,0xC5,0x51,0x23,0x41,0xAB,0x2B,0xA7,0x75, + 0x06,0x62,0x63,0x49,0x2B,0x2A,0xAF,0xD5,0xAC,0x93,0x64,0x51,0x2F,0x2F,0x25,0x35, + 0x11,0xBD,0x2E,0xA4,0x2B,0xAF,0xBD,0xFD,0x52,0xC5,0xB0,0xB4,0x20,0x2B,0xBF,0x7D, + 0x73,0xCD,0xF0,0xBC,0x7B,0xA8,0xA2,0xA9,0x32,0xC5,0x6F,0xAC,0xFE,0xFE,0xDC,0x68, + 0xAF,0xB4,0x4F,0xA4,0xC0,0xF8,0x5B,0xFF,0x6F,0xAC,0x2E,0xA4,0xE8,0xBA,0x55,0x7F, + 0x8F,0xAC,0x0E,0x9C,0x5E,0xE2,0xAA,0x23,0x6F,0xAC,0x0E,0x9C,0xEF,0xF7,0xFA,0xE0, + 0x6F,0xA4,0x2E,0xA4,0x4F,0xD5,0x55,0x5F,0x90,0xAC,0xED,0x9B,0x2D,0x37,0xBF,0xBF, + 0x43,0x51,0xE2,0x40,0xFF,0x9F,0x25,0x3D,0x64,0x59,0x02,0x49,0xAD,0x2B,0xA2,0xAA, + 0x83,0x51,0x23,0x51,0xF7,0xDE,0x77,0x7F,0x63,0x51,0x02,0x49,0xE8,0xFA,0xEE,0x7F, + 0x23,0x49,0x03,0x49,0xDA,0x23,0x03,0x79,0x23,0x49,0xE2,0x40,0xF8,0x2A,0x9E,0xA2, + 0x23,0x49,0x02,0x41,0x56,0x24,0xCF,0x67,0xCB,0xA3,0x03,0x49,0xB5,0x25,0x0D,0x0D, + 0x8B,0x9B,0xC8,0x82,0x7E,0xFF,0xFC,0xC8,0x08,0x8B,0xA7,0x82,0xFB,0xDE,0xFA,0xE8, + 0xA7,0x82,0xE7,0x7A,0x2A,0xAA,0x22,0xBE,0xC7,0x82,0x86,0x7A,0xFB,0x76,0x7E,0x54, + 0xAB,0xA3,0x46,0x72,0x57,0xF5,0xB7,0x2B,0xCB,0xA3,0x67,0x7A,0x2D,0x0A,0x00,0x80, + 0xAB,0xA3,0x26,0x6A,0x00,0xC0,0x78,0x56,0xE9,0x8A,0xA4,0x59,0xF8,0x5E,0x5F,0x5F, + 0xE6,0x61,0x84,0x59,0xAE,0x3D,0x2B,0x2F,0x06,0x6A,0x64,0x51,0x22,0xE8,0xE8,0x7A, + 0x84,0x51,0x23,0x49,0xA8,0xE8,0xDC,0xF7,0x64,0x49,0x23,0x41,0xFE,0x7B,0x6F,0xB2, + 0x64,0x49,0x03,0x41,0xBB,0xFF,0xE7,0x2E,0xE5,0x61,0x03,0x41,0x55,0x5D,0xD7,0x2A, + 0xC5,0x59,0x03,0x41,0x55,0x55,0xFF,0x80,0x64,0x49,0xE2,0x38,0xE8,0x5A,0x7E,0x7A, + 0xE3,0x38,0xA1,0x28,0xF8,0xBE,0xAE,0xF6,0xE3,0x30,0x81,0x20,0x72,0x70,0x78,0x7A, + 0x81,0x20,0x61,0x18,0x00,0xAA,0x08,0x80,0x82,0x20,0x61,0x18,0xB8,0xBF,0x55,0xB5, + 0xC3,0x28,0x61,0x18,0xAF,0xAF,0xAA,0x8A,0xC3,0x30,0x82,0x20,0x0F,0xBF,0xF7,0xED, + 0x04,0x39,0xA2,0x28,0x3A,0xBB,0xDF,0xD5,0x03,0x39,0xA2,0x28,0xEC,0xE6,0xFF,0x79, + 0x03,0x39,0xA2,0x30,0xFE,0xA9,0x0F,0x2F,0xE2,0x30,0xA1,0x28,0x57,0xF8,0xF8,0xC0, + 0xE3,0x30,0x81,0x28,0xFF,0xD6,0xFA,0x80,0xC2,0x30,0xA2,0x28,0xD6,0x95,0xAB,0x8E, + 0xC2,0x30,0xA2,0x28,0x55,0xBF,0x2A,0x8B,0xC2,0x30,0xA2,0x28,0x5F,0xF4,0xAD,0x5B, + 0xC2,0x28,0x82,0x28,0x00,0x0A,0xAA,0xEF,0xE2,0x30,0xA2,0x28,0xAF,0x0B,0xAF,0x3D, + 0xE2,0x30,0xA2,0x28,0xEF,0x8E,0x28,0x0A,0x24,0x39,0xC2,0x30,0xBF,0x37,0xD5,0xFF, + 0x44,0x41,0xE3,0x38,0xFA,0xC2,0xAD,0xAD,0x23,0x39,0xE2,0x30,0xAD,0x85,0xAD,0xD5, + 0x03,0x39,0xC2,0x30,0xEC,0xAA,0x8E,0xEE,0x64,0x49,0xC2,0x30,0xB5,0x35,0x37,0x2F, + 0xA5,0x51,0x24,0x41,0x68,0x60,0xE0,0xF6,0x24,0x41,0xC2,0x30,0xE8,0x9C,0xBA,0xFC, + 0x44,0x41,0xE2,0x38,0xBD,0x35,0xB7,0xF5,0x23,0x41,0xC2,0x30,0xBA,0xA8,0xBA,0x7E, + 0x65,0x41,0xE3,0x38,0xF5,0xAD,0xAF,0x2B,0xC6,0x59,0x23,0x49,0xFD,0xBF,0xAB,0x2A, + 0xE6,0x59,0x43,0x41,0xF5,0xB7,0x0F,0x88,0x0A,0x7B,0x64,0x49,0x35,0x3F,0x27,0x3F, + 0x6F,0xAC,0xCD,0x93,0x0A,0xAB,0xBD,0xB5,0xF1,0xBC,0x0E,0xA4,0x0B,0x3F,0xFF,0xF5, + 0x32,0xBD,0x4E,0xAC,0x02,0x80,0xAB,0xB5,0x32,0xC5,0x8F,0xAC,0x78,0x7A,0xEA,0xAB, + 0xD0,0xB4,0x6F,0xAC,0x57,0x6F,0xFA,0xF8,0x8F,0xAC,0x4F,0xA4,0xDE,0xFF,0xF7,0xCC, + 0x8F,0xAC,0x4F,0xA4,0xBF,0xBA,0xAB,0xDC,0x90,0xAC,0x4E,0xA4,0x6F,0xBA,0xB2,0xA9, + 0x8F,0xAC,0x4F,0xA4,0x5F,0x7E,0xDA,0x6F,0x6F,0xAC,0x2E,0xA4,0xFD,0x88,0xB2,0x5A, + 0x64,0x59,0x03,0x49,0xBD,0xAA,0x2A,0x8A,0x64,0x59,0x43,0x51,0x6E,0x08,0x82,0xAF, + 0x63,0x51,0x22,0x49,0x77,0x78,0x7F,0x5A,0x43,0x49,0x02,0x49,0x5A,0x5C,0xAA,0x9F, + 0x23,0x49,0x02,0x49,0xC0,0xC0,0x80,0xD5,0x23,0x49,0x02,0x41,0xB3,0xD5,0xED,0x66, + 0x63,0x51,0x02,0x49,0x5D,0xD5,0xD7,0x95,0xAB,0x9B,0x84,0x59,0x09,0x09,0x03,0x03, + 0x8A,0x9B,0x08,0x8B,0xE8,0xEA,0xE0,0x7A,0x08,0x8B,0xC8,0x82,0x58,0xFA,0xE8,0xEC, + 0x08,0x8B,0xA7,0x82,0x5F,0xDF,0x7F,0x2A,0xCB,0xA3,0xA7,0x82,0x55,0xB5,0x2D,0x02, + 0xCB,0xA3,0xC8,0x82,0x03,0x00,0x80,0x60,0xAB,0xA3,0x26,0x72,0xC0,0x58,0x56,0x55, + 0x67,0x72,0x05,0x6A,0x9E,0xB7,0x2E,0xF3,0x26,0x6A,0x63,0x51,0x78,0xDC,0xFE,0xBE, + 0xE6,0x61,0x63,0x49,0x0B,0x08,0xC8,0x52,0xC5,0x59,0x23,0x41,0xE8,0xFE,0x7F,0xFF, + 0x64,0x49,0x03,0x41,0x0E,0x2A,0x29,0xA2,0x85,0x51,0x23,0x49,0x7F,0xFE,0x3E,0x37, + 0x06,0x6A,0x64,0x49,0xAD,0x02,0xA0,0xE2,0xC5,0x61,0xE2,0x40,0x00,0xA8,0xFE,0x5F, + 0xC5,0x59,0x02,0x41,0xC0,0xFA,0xFF,0x55,0x23,0x41,0xC2,0x30,0xE0,0xFE,0x5E,0x5E, + 0xC2,0x30,0x81,0x20,0xEC,0x68,0x68,0xD8,0xA2,0x28,0x61,0x20,0xE0,0x7A,0x7A,0xE8, + 0x81,0x20,0x41,0x18,0x20,0xEA,0xFF,0xEE,0xC2,0x28,0x40,0x18,0xB7,0xAF,0x0B,0x0A, + 0xC3,0x30,0xA1,0x20,0x7E,0xFA,0xCA,0xAA,0xC2,0x30,0x81,0x20,0xFF,0xAF,0xEB,0xB8, + 0x03,0x39,0xA2,0x28,0xD5,0xBD,0xAF,0x8B,0x03,0x31,0xC2,0x30,0xD7,0xA8,0xF0,0x7D, + 0xE2,0x30,0x82,0x28,0xAE,0xB6,0xDE,0x8E,0x03,0x39,0xA2,0x30,0xAE,0xA5,0xA5,0xBF, + 0x02,0x39,0xC3,0x30,0xEE,0x7A,0x7B,0xDE,0xE3,0x30,0xA2,0x28,0xBF,0xBE,0xB7,0xB4, + 0xE3,0x30,0x81,0x28,0x7E,0xFA,0xF8,0xFE,0xC2,0x30,0xA2,0x28,0xA5,0x35,0xFB,0xAA, + 0xA2,0x30,0xC2,0x28,0x97,0xF5,0xFF,0x97,0xC2,0x30,0xA2,0x28,0x2F,0xAD,0xAA,0xE9, + 0xE3,0x30,0xA2,0x28,0xEA,0x2A,0xA3,0x5B,0x03,0x39,0xC3,0x30,0xBF,0xF2,0xE3,0xA9, + 0x03,0x39,0xC2,0x30,0x2F,0x2D,0xE5,0xB5,0x03,0x39,0xA2,0x30,0x2A,0x83,0xA7,0xEF, + 0x03,0x39,0xE2,0x30,0x7F,0xFE,0xDB,0x95,0x23,0x39,0xE3,0x30,0x0A,0x02,0xEA,0xE9, + 0x64,0x41,0xC3,0x30,0xA8,0x7F,0xFD,0xFF,0x03,0x39,0xC2,0x30,0xF8,0xEE,0xAB,0xAB, + 0x03,0x39,0xC2,0x30,0x23,0xAB,0xAA,0x23,0x24,0x39,0xC2,0x30,0x7A,0xDE,0xAF,0x2F, + 0x44,0x41,0xE3,0x30,0x9D,0xB5,0xBF,0x09,0xA5,0x51,0x23,0x41,0x22,0x3D,0xFD,0xF5, + 0xC5,0x59,0x44,0x49,0xA0,0xBB,0xAD,0x2D,0x2A,0x83,0xC5,0x51,0xB5,0xB5,0x35,0x35, + 0xED,0x9B,0x8C,0x8B,0x09,0xBF,0xFA,0x62,0x2E,0xA4,0x8C,0x8B,0x0A,0xAF,0xFF,0xD5, + 0x6F,0xAC,0xCD,0x93,0x0A,0xEF,0xFD,0xDD,0xF0,0xB4,0x0D,0x9C,0x0A,0x0B,0xBD,0xD5, + 0xF1,0xBC,0x8F,0xAC,0xFC,0xE2,0xE2,0xB5,0xD1,0xB4,0x70,0xAC,0x7E,0xEF,0xAE,0xB8, + 0xB0,0xB4,0x4F,0xA4,0xDF,0xFA,0x8A,0x8A,0x8F,0xAC,0x2D,0xA4,0xF6,0xFE,0xE8,0x28, + 0x6F,0xAC,0x2E,0xA4,0xAA,0xCF,0xEA,0xFE,0x4F,0xA4,0x0E,0x9C,0x7E,0xBE,0xFB,0x5A, + 0x64,0x59,0x23,0x51,0x27,0xA7,0xE7,0xAE,0x64,0x59,0x43,0x51,0x2F,0x80,0x60,0x72, + 0x64,0x51,0x02,0x49,0xFA,0x78,0xFE,0x5E,0x22,0x49,0xE1,0x40,0xA8,0xA0,0x82,0xFB, + 0x23,0x49,0xE2,0x40,0xAB,0xEC,0x7A,0xAE,0x23,0x49,0xE2,0x40,0xFA,0x9B,0x29,0x2F, + 0x25,0x6A,0xE2,0x40,0xF5,0xBD,0x35,0x37,0x8A,0x9B,0xE8,0x82,0x81,0x81,0x03,0x82, + 0x69,0x9B,0x09,0x8B,0xEA,0xEA,0x6A,0xEA,0x49,0x93,0xE8,0x8A,0x6F,0x7E,0xBF,0x2A, + 0xCB,0xA3,0xE8,0x8A,0xBD,0x0F,0x02,0x0A,0xEB,0xA3,0x86,0x7A,0x00,0x80,0xE0,0x78, + 0xAA,0x9B,0x46,0x72,0x78,0x5E,0x55,0x55,0x67,0x7A,0x26,0x6A,0xED,0x3B,0x8B,0x8B, + 0x46,0x72,0xA4,0x59,0xE0,0xE0,0x70,0x5C,0xC5,0x61,0x22,0x41,0x82,0xA2,0xFA,0x77, + 0xA5,0x51,0x23,0x41,0xF8,0x3F,0xAD,0x8B,0x84,0x51,0x44,0x49,0xF4,0xB6,0xAF,0xEF, + 0x64,0x49,0x23,0x41,0xA2,0xB6,0xAE,0xBF,0x84,0x51,0xE3,0x38,0x3F,0x2E,0xBE,0xDF, + 0x06,0x62,0x84,0x59,0xEA,0x88,0xEA,0xE9,0xA5,0x59,0x02,0x41,0x5E,0x5E,0x5C,0x78, + 0x03,0x41,0xC2,0x38,0x80,0xE0,0x60,0xE0,0x02,0x39,0xC3,0x30,0xE8,0xFF,0xDF,0x75, + 0xE3,0x30,0x81,0x20,0xDA,0xBA,0xF0,0xC0,0xC2,0x28,0x61,0x18,0xF8,0x7A,0x56,0x57, + 0xC2,0x28,0x61,0x18,0xD7,0xB5,0x0D,0xAB,0x03,0x31,0xC2,0x28,0x75,0xDD,0xDD,0x29, + 0x44,0x39,0xA2,0x28,0xDD,0xF7,0xBF,0x02,0x23,0x39,0xC2,0x30,0x75,0x6A,0x58,0xE8, + 0xE3,0x30,0x81,0x30,0xA2,0x78,0xEE,0xE8,0xE3,0x38,0xA2,0x28,0xEF,0xF5,0xED,0xA2, + 0x03,0x39,0xC2,0x30,0xED,0xBD,0xAB,0x8D,0x03,0x39,0xC2,0x30,0xB7,0xEB,0x02,0xAB, + 0x23,0x39,0xC2,0x30,0xFB,0xFB,0x68,0x7A,0x04,0x39,0xA2,0x28,0xE8,0xA0,0xFA,0xED, + 0xE3,0x30,0xA2,0x28,0x5E,0xFC,0xFE,0xB3,0xC2,0x30,0x81,0x28,0x2F,0xFF,0x7A,0x20, + 0xC2,0x28,0x82,0x28,0x00,0x80,0xAD,0xFA,0xA2,0x28,0x81,0x20,0x08,0x28,0x3E,0xF5, + 0xE2,0x30,0xA2,0x28,0x5F,0xE5,0xBD,0xAD,0xE3,0x30,0xA2,0x28,0x83,0xFB,0x8E,0x83, + 0xE3,0x30,0xA2,0x28,0xAE,0xAF,0x8F,0x0E,0x02,0x39,0xA2,0x28,0xB8,0xEE,0xFF,0xFD, + 0x03,0x31,0xA1,0x28,0x2F,0xAF,0xBD,0x2F,0x24,0x31,0xC2,0x30,0xF6,0xFF,0xAB,0x2F, + 0x03,0x31,0xA2,0x30,0xAB,0xAA,0x28,0xA0,0xE3,0x30,0xC2,0x28,0xC8,0x88,0x8A,0x83, + 0x04,0x31,0xC2,0x30,0xBB,0x5D,0x5F,0xFF,0x24,0x39,0xC3,0x28,0x27,0xB7,0xBF,0xEB, + 0x23,0x39,0xE3,0x30,0x27,0xB5,0x37,0xBF,0x85,0x49,0x23,0x41,0xBF,0xA7,0x2B,0xF5, + 0x06,0x5A,0x64,0x49,0x0D,0xA5,0xF7,0xF5,0x8C,0x8B,0x06,0x5A,0x95,0x35,0x35,0x25, + 0xED,0x9B,0xAD,0x93,0x73,0xFB,0xD7,0x62,0xAC,0x93,0x6B,0x8B,0x2B,0x58,0xF0,0x68, + 0xED,0x9B,0x6B,0x8B,0xA2,0x8B,0xA5,0xD5,0x0E,0x9C,0xAC,0x93,0x02,0x2D,0xA7,0xA7, + 0x8F,0xAC,0xED,0x9B,0x2B,0xBF,0x55,0x55,0x90,0xAC,0xED,0x9B,0x28,0xAA,0xDF,0x77, + 0x90,0xAC,0xED,0x9B,0xA0,0xBB,0x7F,0x5D,0x6E,0xAC,0xCC,0x93,0xA0,0xFA,0x5F,0x57, + 0x2E,0xA4,0xCC,0x93,0x88,0xFF,0xF5,0xD5,0x2E,0xA4,0xED,0x9B,0xEC,0x2D,0x2F,0xFD, + 0x63,0x51,0x23,0x49,0xED,0xFF,0xD7,0xD5,0x43,0x51,0x23,0x49,0x00,0xAA,0xF8,0x77, + 0x22,0x49,0x02,0x41,0x78,0xDC,0xF2,0xAA,0x23,0x49,0xE2,0x40,0xBF,0x7F,0x7E,0xB6, + 0x23,0x49,0xE2,0x40,0xAA,0xFF,0xDF,0xDF,0x23,0x49,0xE3,0x40,0xAF,0x3F,0xCB,0xEB, + 0x49,0x93,0x23,0x49,0x15,0x35,0x35,0x25,0x8A,0x9B,0x69,0x93,0x62,0x58,0x7C,0x5E, + 0x8A,0x9B,0x28,0x93,0xFF,0x9F,0x3F,0x2F,0x8A,0x9B,0x29,0x93,0xF7,0xFC,0xA0,0xAA, + 0xAB,0x9B,0x67,0x7A,0x02,0xA2,0xEA,0x58,0x49,0x8B,0x46,0x72,0x78,0x76,0xD7,0x75, + 0x87,0x72,0x46,0x72,0xB7,0xEB,0xEA,0x2F,0xA7,0x7A,0xA5,0x59,0x8A,0xA8,0xE2,0x78, + 0x05,0x62,0x02,0x41,0xF8,0xDE,0x77,0xD7,0x84,0x51,0x23,0x41,0xF5,0xBD,0x29,0x0F, + 0xA4,0x51,0x64,0x49,0x7B,0x5A,0xDA,0xD7,0x84,0x49,0x44,0x49,0xB7,0xED,0xB4,0xB8, + 0x64,0x49,0x24,0x41,0xFE,0xDE,0x7A,0x58,0x23,0x41,0xE3,0x38,0xBA,0xF0,0xF0,0xA0, + 0xA5,0x51,0xA2,0x38,0x03,0x2B,0xBF,0xD7,0x84,0x51,0x23,0x41,0x78,0xF8,0xF8,0x79, + 0x03,0x41,0xC2,0x38,0xBC,0xD6,0xF7,0xB8,0xE3,0x30,0xA2,0x30,0x02,0x0E,0xE8,0x70, + 0xE3,0x30,0x61,0x18,0xA2,0xFA,0x7F,0x5F,0x81,0x20,0x41,0x18,0xB8,0xBC,0x3F,0x3D, + 0xE3,0x30,0x81,0x20,0x2D,0x29,0x2B,0xFF,0x24,0x39,0x61,0x20,0x02,0x80,0xFB,0xFF, + 0x44,0x41,0xA2,0x28,0x80,0xFE,0x55,0x55,0x43,0x41,0xA2,0x28,0xAA,0xAB,0xEF,0xB5, + 0x03,0x39,0xC2,0x30,0xDE,0xA8,0xF8,0xEA,0x03,0x39,0xC2,0x30,0xFA,0xEF,0xD5,0x77, + 0x03,0x39,0xA2,0x28,0xAB,0x8F,0xFF,0xB5,0xE3,0x38,0xC2,0x28,0xE2,0xEC,0xFE,0xE2, + 0xE3,0x30,0x81,0x28,0xA2,0x62,0x5E,0x7E,0xE3,0x30,0x81,0x20,0x2B,0xBF,0xB5,0xA5, + 0xE3,0x30,0xC3,0x28,0xA2,0x82,0x0F,0x0D,0x03,0x31,0xA2,0x30,0x7A,0xB2,0xEA,0x6A, + 0xE3,0x30,0xA2,0x28,0x6D,0xFE,0xBA,0xAF,0x03,0x39,0x81,0x20,0x55,0xEE,0xA8,0x80, + 0x03,0x39,0xA1,0x28,0xAD,0x2F,0xA2,0x82,0xE3,0x30,0xC2,0x28,0x1C,0x2E,0x9F,0xDF, + 0xE3,0x30,0xA2,0x28,0x2A,0xEE,0xBE,0xE7,0xE3,0x30,0xA2,0x28,0xAF,0xAF,0xF5,0xDD, + 0x03,0x31,0xC2,0x30,0xBE,0x8E,0x09,0xED,0x03,0x31,0xC2,0x28,0x08,0x78,0x72,0xE0, + 0x03,0x39,0xC2,0x28,0x6C,0x5F,0x57,0xEF,0xE3,0x30,0xA2,0x28,0x21,0x3F,0xB8,0xA8, + 0x23,0x31,0xC2,0x30,0xDD,0x5D,0xFF,0xF6,0x23,0x39,0xE2,0x30,0xFF,0xFD,0x7D,0x8D, + 0x03,0x39,0xA1,0x28,0x22,0x3E,0xB8,0x9E,0x84,0x51,0x03,0x39,0xBF,0xFD,0xBF,0x09, + 0xE5,0x59,0x44,0x41,0xB5,0xB7,0x2F,0x2B,0xAC,0x93,0x25,0x62,0x25,0x2D,0x0D,0x29, + 0xEE,0x9B,0xAC,0x93,0x82,0x80,0x80,0xF7,0xCD,0x93,0x6B,0x8B,0x7C,0x50,0x78,0x5E, + 0x6B,0x8B,0x0A,0x7B,0x20,0xB8,0xE8,0x62,0xED,0x9B,0x4B,0x83,0x0A,0x2B,0x29,0xAD, + 0x0D,0x9C,0xAC,0x93,0xA0,0x8B,0xAA,0x7F,0xED,0x9B,0xCD,0x93,0x88,0x02,0xA8,0xFD, + 0xED,0x9B,0xAC,0x93,0xF8,0xAB,0x7B,0x5F,0xCD,0x93,0x8C,0x8B,0x28,0x80,0x08,0x2F, + 0xCD,0x93,0x8C,0x8B,0x28,0xBA,0xEF,0xEB,0x0E,0x9C,0xAC,0x93,0x0B,0xBF,0xB5,0xF5, + 0x43,0x49,0x02,0x49,0xAA,0xFE,0x57,0xD7,0x23,0x49,0x02,0x41,0x81,0x7A,0xFB,0xE9, + 0x23,0x49,0xE2,0x40,0xE3,0xCB,0x98,0x56,0x02,0x41,0xE2,0x38,0x08,0xCC,0x72,0x72, + 0x02,0x41,0xC2,0x38,0x2A,0x0A,0x23,0x3B,0x23,0x49,0xE2,0x40,0xEF,0xFB,0xAB,0x2B, + 0x6A,0x93,0x03,0x49,0x25,0x25,0x25,0xB5,0x8A,0x9B,0xE8,0x82,0x20,0x20,0xA2,0x55, + 0x8A,0x9B,0xE8,0x82,0xE2,0x7A,0x7E,0x55,0x6A,0x93,0x87,0x7A,0x0A,0xAF,0xFF,0x7F, + 0x29,0x93,0xE5,0x61,0x70,0xDC,0x5E,0x57,0x46,0x6A,0xE5,0x61,0x00,0x2B,0xAA,0xFD, + 0xC8,0x7A,0x84,0x59,0x2A,0xAA,0xFA,0x5F,0x67,0x72,0x43,0x49,0x70,0x5E,0x77,0xD5, + 0x63,0x49,0x02,0x41,0xFE,0x6A,0xDC,0x3E,0xA5,0x51,0x02,0x41,0x8B,0xAD,0xAD,0xB8, + 0x84,0x51,0x64,0x49,0xA7,0x09,0x79,0x6B,0x84,0x51,0x24,0x41,0xF0,0x7A,0xFE,0xEE, + 0x64,0x49,0x03,0x41,0xA8,0xEA,0xEE,0x5E,0x64,0x41,0x03,0x41,0x7B,0xFF,0x7F,0x5D, + 0x23,0x41,0xC2,0x38,0x5A,0x6A,0xEA,0xA8,0x44,0x49,0xC2,0x38,0x0D,0x2D,0x0B,0xAA, + 0x43,0x49,0xC2,0x30,0xFE,0xF8,0xDE,0xDE,0x03,0x39,0x81,0x28,0x68,0x78,0x78,0xFA, + 0xA2,0x28,0x61,0x20,0x57,0x5E,0xF6,0xB6,0xC2,0x28,0x41,0x18,0xBD,0xAF,0x8B,0x2A, + 0xA2,0x28,0x81,0x20,0x9D,0xCD,0xA1,0xBA,0xC2,0x28,0x81,0x20,0xAF,0xBF,0xFE,0xDF, + 0xA2,0x28,0x81,0x20,0xA2,0xFF,0xFB,0x5B,0xE3,0x30,0x81,0x28,0x25,0xB5,0xF5,0xD5, + 0x03,0x39,0xC2,0x30,0xBA,0xFB,0xF5,0xB9,0xE2,0x30,0xA2,0x28,0x78,0x7C,0xF8,0xCA, + 0xE3,0x30,0xA2,0x30,0x35,0xB5,0xE7,0xAF,0xE3,0x30,0xA1,0x28,0x88,0xAA,0xFB,0x59, + 0xE3,0x30,0x81,0x28,0xFE,0xE0,0xFB,0x7F,0xC2,0x28,0x61,0x20,0x8B,0xAA,0x02,0x0A, + 0xE3,0x30,0xA2,0x28,0xBF,0xAB,0xAD,0x27,0x03,0x39,0xA2,0x30,0xF2,0xEB,0xEF,0xAF, + 0x03,0x39,0xA2,0x28,0xEF,0xAD,0xBF,0x23,0x03,0x39,0xA2,0x28,0xEB,0xB2,0xA8,0xD8, + 0x23,0x39,0xC2,0x30,0xB9,0xEF,0x1F,0xBF,0x23,0x39,0xC2,0x30,0xDF,0x57,0x76,0xF2, + 0x03,0x31,0xA1,0x28,0xB7,0x3F,0x2E,0xAF,0x03,0x31,0xA2,0x28,0x7F,0xDE,0x58,0xEA, + 0x04,0x31,0xA2,0x28,0xAA,0xB7,0xD7,0x57,0x04,0x31,0xC2,0x30,0xFA,0x7A,0xF6,0xDD, + 0x03,0x31,0xA2,0x28,0x8A,0xE6,0xFB,0xAB,0x03,0x31,0xC2,0x28,0xDF,0xDD,0xFF,0x2B, + 0x03,0x31,0xE2,0x30,0x85,0x8B,0xE2,0x58,0x23,0x39,0xE2,0x30,0x87,0x2F,0xF5,0xD5, + 0x23,0x39,0xE2,0x30,0x5E,0xFB,0xFF,0x3B,0xA5,0x51,0x02,0x39,0xAD,0xAD,0xAF,0x0F, + 0x88,0x72,0x63,0x49,0x95,0xF5,0xB5,0x2F,0x8C,0x93,0xA9,0x7A,0x09,0x01,0xF9,0x7E, + 0x8C,0x8B,0x68,0x6A,0x00,0x80,0xDF,0x57,0x8C,0x8B,0x06,0x62,0x80,0xA8,0x5F,0xF7, + 0x2A,0x7B,0x06,0x5A,0x00,0xFA,0x55,0xFF,0x8B,0x8B,0x27,0x62,0x0A,0xAF,0xD5,0xFF, + 0x8C,0x93,0x27,0x62,0xA0,0x7E,0x5F,0x7F,0xCD,0x93,0x47,0x62,0x2B,0xD5,0x55,0x55, + 0xAD,0x93,0x47,0x62,0x00,0x02,0xAD,0x95,0xAC,0x93,0x4B,0x83,0x02,0xAB,0x23,0xBD, + 0xAC,0x93,0x6C,0x8B,0x00,0x00,0x8B,0xE9,0xCD,0x93,0x6B,0x8B,0x2E,0xAB,0xB7,0xFF, + 0x03,0x49,0x22,0x41,0x80,0xAA,0xAA,0x82,0x23,0x49,0xE2,0x40,0xB0,0xAB,0xCE,0xBF, + 0x23,0x41,0xE2,0x40,0x95,0xFA,0x12,0xE2,0x23,0x41,0xE2,0x40,0xDB,0xBB,0xAA,0xA2, + 0x23,0x49,0xE2,0x40,0xD7,0xBF,0xEA,0xBA,0x43,0x49,0x02,0x41,0xEF,0xFE,0x7F,0x5B, + 0x63,0x51,0xE2,0x40,0x2F,0xFD,0x57,0x5F,0x66,0x72,0x22,0x49,0x0B,0x25,0xB5,0xB5, + 0xA7,0x7A,0xE4,0x61,0x00,0xAE,0xFD,0x5D,0xC7,0x82,0x64,0x51,0xA0,0xE2,0x7B,0x7F, + 0xC5,0x61,0xC2,0x40,0x00,0xAA,0x7E,0x5F,0xC4,0x61,0x03,0x49,0x00,0x82,0x09,0x2D, + 0xA4,0x59,0x43,0x49,0x58,0x7C,0xE8,0x80,0x84,0x51,0x23,0x49,0xAD,0xBD,0x0B,0x82, + 0xA5,0x51,0x43,0x49,0x95,0x3F,0x8D,0xCA,0xA5,0x51,0x44,0x49,0xA0,0xAE,0xBE,0x77, + 0x84,0x49,0x23,0x41,0xE8,0xAA,0xFA,0xDE,0x64,0x51,0x44,0x49,0xEB,0x55,0x79,0x8D, + 0xE6,0x61,0x23,0x49,0x55,0x95,0x2D,0x02,0x06,0x6A,0x23,0x41,0x75,0x2A,0xA0,0xAA, + 0xA5,0x59,0x23,0x41,0x55,0x58,0xE0,0x60,0x64,0x49,0xE2,0x38,0xFE,0x78,0xFA,0x7F, + 0x23,0x41,0xC2,0x30,0xDE,0xF8,0xE2,0xFA,0x03,0x39,0xA2,0x28,0x78,0x60,0x42,0x4B, + 0x03,0x31,0x61,0x20,0xF7,0xAF,0x0D,0x2D,0xE3,0x30,0x81,0x20,0xF7,0xA0,0xE0,0xE8, + 0xC2,0x28,0x82,0x20,0xF8,0xE0,0xE8,0xBA,0xC2,0x28,0x81,0x20,0xDD,0xDD,0x9F,0x3F, + 0x24,0x39,0x81,0x28,0x75,0x5D,0xED,0x80,0xC2,0x30,0x61,0x28,0xBF,0xBD,0xBF,0xE0, + 0x24,0x41,0xA2,0x30,0xE9,0x89,0x0B,0x09,0x43,0x41,0xA1,0x30,0x7F,0xFA,0xFA,0xE8, + 0xE2,0x38,0xA2,0x30,0xF7,0x57,0x57,0x5A,0x03,0x31,0xA1,0x28,0x75,0xF5,0xAD,0x0F, + 0x24,0x39,0x81,0x28,0xD5,0x7F,0xAA,0x00,0x03,0x39,0x81,0x28,0xFD,0x5D,0xFF,0xA8, + 0x04,0x31,0x82,0x28,0x2F,0x35,0x3F,0xAB,0x03,0x31,0xC2,0x30,0xFA,0x92,0xB0,0x62, + 0xE3,0x30,0xA2,0x30,0x00,0x00,0xBB,0xDA,0x03,0x39,0xA2,0x30,0x6A,0xB8,0xFA,0xFA, + 0x03,0x31,0xA2,0x30,0xBF,0x3D,0xBF,0xBB,0x24,0x39,0xE3,0x30,0xDE,0xFA,0xFE,0xFA, + 0x02,0x31,0xA1,0x28,0xEE,0xFA,0xF2,0xF8,0xE2,0x30,0xC2,0x28,0xF8,0xDC,0xD5,0x7D, + 0xC2,0x28,0xA2,0x28,0x38,0x00,0x02,0xE9,0xE3,0x30,0xA1,0x28,0xA2,0x03,0x2E,0xE7, + 0x03,0x31,0xE3,0x30,0x55,0xDF,0x97,0x95,0x03,0x31,0xC2,0x28,0x2B,0xAF,0xAE,0xFE, + 0x03,0x31,0xE2,0x30,0x6A,0x4A,0xB7,0x75,0x03,0x39,0xC2,0x30,0xAE,0x3F,0x1E,0x1C, + 0x64,0x49,0x03,0x39,0xE7,0xAF,0x27,0x25,0xA5,0x51,0x03,0x41,0x09,0xAF,0xBE,0x22, + 0x4E,0xA4,0xC5,0x59,0xB5,0xB5,0x25,0x2D,0xAF,0xB4,0xCC,0x9B,0xFD,0xAB,0xA2,0x80, + 0xAF,0xB4,0x8B,0x93,0x57,0xEA,0x88,0x02,0x8F,0xB4,0x2A,0x83,0x55,0xEA,0x00,0x00, + 0x2E,0xAC,0xE9,0x7A,0x55,0x7F,0x7E,0x78,0x0A,0x7B,0xA8,0x72,0xDA,0xF8,0xE8,0x78, + 0xE9,0x7A,0x67,0x62,0xFA,0xA0,0xBB,0xD7,0xE9,0x72,0x67,0x6A,0xF7,0xF6,0xFE,0xB2, + 0xC9,0x72,0x46,0x62,0x5D,0x7F,0xFE,0xE8,0x6B,0x83,0x27,0x62,0x03,0x2F,0xD5,0x57, + 0x6B,0x8B,0x47,0x62,0x00,0x00,0x00,0x09,0x8C,0x8B,0x4B,0x83,0x0D,0x8B,0xEC,0xE8, + 0x03,0x49,0xE2,0x40,0x10,0x82,0x52,0x7F,0x03,0x41,0xE2,0x40,0x26,0x26,0x86,0x3C, + 0x23,0x49,0xE2,0x40,0x7F,0xAE,0xAA,0xAE,0x23,0x49,0x02,0x41,0xD5,0x3F,0x7C,0xE7, + 0x43,0x49,0x02,0x41,0xD7,0xD4,0x7A,0xE8,0x23,0x49,0x03,0x41,0x29,0x02,0x77,0x5F, + 0x23,0x49,0xC2,0x38,0xF8,0xE2,0xCA,0x8F,0x84,0x59,0xC2,0x40,0x2F,0x3D,0xFF,0xFF, + 0x26,0x6A,0x43,0x49,0x8A,0xA2,0xFD,0x55,0xC5,0x59,0xC2,0x40,0xA8,0xFE,0x7F,0x5F, + 0x03,0x41,0xC2,0x40,0x8A,0xCE,0xBF,0xEF,0x05,0x62,0x03,0x49,0xAD,0x2D,0x8D,0x2D, + 0xE5,0x61,0x84,0x59,0x7E,0x7A,0x6A,0xEC,0xE6,0x59,0x64,0x51,0xF5,0xDD,0xFF,0xEB, + 0xA5,0x51,0x64,0x49,0xE2,0x60,0x78,0x5A,0x85,0x51,0x22,0x39,0xEA,0xAA,0xAA,0xA0, + 0x64,0x49,0x23,0x41,0xFA,0xE8,0xA8,0x22,0x66,0x72,0x43,0x49,0xAD,0x2B,0x8A,0xA2, + 0x46,0x6A,0x22,0x49,0xA0,0xEC,0xFA,0x7A,0xA4,0x59,0xE2,0x38,0xA8,0xF8,0xDE,0x55, + 0xA4,0x51,0x03,0x41,0x70,0x7A,0xFA,0x6F,0x23,0x41,0xC2,0x30,0xEE,0x96,0xFF,0x2A, + 0x03,0x39,0xA2,0x30,0x6A,0xFE,0xF8,0xFE,0xC2,0x30,0x82,0x28,0xBB,0xD7,0xEC,0xEA, + 0xE3,0x30,0x82,0x20,0x25,0xA7,0xAD,0xAD,0xC3,0x30,0xA2,0x28,0x7C,0xA8,0x8B,0xFB, + 0x44,0x41,0xA2,0x28,0xD5,0xB5,0x25,0x0D,0x64,0x49,0xC3,0x30,0xAD,0xAA,0x28,0x82, + 0x45,0x41,0xE3,0x38,0xB8,0x54,0x56,0x5E,0x23,0x41,0xC2,0x38,0xDE,0xA8,0xA2,0xFA, + 0x23,0x41,0xE2,0x38,0x3D,0x97,0xBB,0x7F,0x64,0x49,0x03,0x41,0xFA,0x82,0x0B,0x95, + 0x44,0x49,0xA1,0x28,0x7E,0x58,0x70,0xE8,0xE3,0x30,0x81,0x28,0x0B,0xBA,0xD7,0xAE, + 0x44,0x39,0xA2,0x30,0x2A,0xBF,0xAD,0xF7,0x24,0x39,0xC2,0x28,0xE8,0xBE,0xFF,0x7B, + 0xE3,0x30,0x81,0x28,0x08,0x08,0xBE,0xFD,0xE3,0x30,0xA2,0x28,0x40,0xF8,0xEA,0xFF, + 0xC2,0x30,0xA2,0x28,0x92,0xF6,0xAF,0x58,0x03,0x39,0xC2,0x28,0xAB,0x8E,0xED,0x5D, + 0xE2,0x30,0xA2,0x28,0xB8,0xBE,0xFA,0xAF,0x03,0x31,0xC2,0x28,0x8F,0x2F,0x97,0xD7, + 0xE3,0x30,0xC2,0x28,0xEC,0x62,0xAC,0xEF,0xE2,0x30,0xA1,0x28,0xBE,0x3F,0xBA,0xEA, + 0xE2,0x30,0xA2,0x28,0x62,0x8E,0xAA,0x8B,0x03,0x31,0xA1,0x28,0xFD,0xAF,0x8B,0x2B, + 0x03,0x31,0xC2,0x30,0x8E,0x2E,0x37,0x57,0x03,0x39,0xC2,0x30,0xFA,0x80,0x0A,0xAF, + 0x03,0x39,0xC2,0x30,0xD7,0xBE,0xB8,0xAA,0x03,0x39,0xC2,0x30,0xBF,0xDB,0x72,0x62, + 0x64,0x49,0xA2,0x30,0x2F,0x2F,0x3F,0xBF,0xE9,0x7A,0x23,0x41,0xFF,0xFF,0xBD,0x35, + 0x11,0xC5,0xA9,0x72,0x25,0x2D,0x03,0x02,0x30,0xCD,0x8E,0xB4,0x7F,0xFF,0x7E,0xE8, + 0xAF,0xBC,0x6E,0xAC,0x2B,0x28,0xEF,0x94,0xD0,0xBC,0x6E,0xB4,0xAA,0x88,0xEB,0x77, + 0x8F,0xB4,0x2B,0x83,0x78,0xE0,0xA0,0x88,0x2D,0xA4,0xA9,0x72,0x77,0x7F,0xFE,0x60, + 0xC9,0x72,0x46,0x62,0xDF,0x7C,0x6A,0xA8,0xE9,0x72,0x67,0x6A,0xAF,0xA9,0xAD,0x2F, + 0x0A,0x7B,0xA8,0x6A,0x7F,0xE2,0x8A,0x0A,0xE9,0x7A,0x06,0x5A,0x7A,0xFA,0xC8,0xA8, + 0xEA,0x7A,0xE6,0x59,0x35,0xD5,0x5F,0x7E,0x6B,0x83,0xA5,0x49,0x00,0x03,0xBD,0x55, + 0x23,0x49,0xE2,0x40,0xFB,0xE8,0xAA,0x79,0x23,0x49,0xE2,0x40,0xCB,0x5B,0x56,0xB7, + 0x23,0x49,0xE2,0x40,0x8A,0xAA,0x7B,0xDC,0x23,0x49,0xE2,0x40,0xAF,0x00,0xAA,0xEB, + 0x23,0x41,0xE2,0x40,0x80,0x00,0xA2,0x68,0x23,0x49,0xC2,0x38,0xE0,0xFE,0xBF,0xAE, + 0x03,0x41,0xE2,0x40,0x09,0x43,0x5E,0xBD,0x23,0x49,0xE2,0x40,0xAA,0xBB,0xFF,0xE5, + 0x02,0x41,0xE2,0x40,0x23,0xAF,0x09,0x9D,0x23,0x49,0xC2,0x38,0x7A,0xDC,0xEE,0xFF, + 0x03,0x49,0xE2,0x40,0x05,0xBF,0x97,0x7D,0x26,0x6A,0x03,0x49,0x2D,0x29,0x0D,0x0D, + 0x06,0x62,0xA4,0x59,0x7C,0xD8,0xE8,0xAA,0xE5,0x61,0x84,0x51,0x5D,0xF8,0x6A,0x7C, + 0x84,0x51,0x03,0x41,0xA0,0xBA,0xDE,0xFE,0x64,0x49,0x23,0x41,0x80,0x80,0x9A,0xD5, + 0x64,0x49,0x03,0x41,0xAA,0xE2,0x6A,0xC7,0x26,0x6A,0x03,0x49,0x03,0x0B,0xAD,0xA5, + 0xE5,0x61,0x61,0x28,0xE0,0x78,0x7E,0x7A,0xC2,0x38,0x61,0x28,0x8A,0xA5,0xD5,0xAC, + 0x23,0x41,0xC2,0x30,0xC3,0xF9,0x7D,0xD5,0x23,0x39,0xC2,0x30,0x22,0xA2,0xF2,0x52, + 0x03,0x39,0x82,0x20,0xA0,0x8A,0xEA,0x7F,0xC2,0x28,0x61,0x20,0xA2,0xA8,0xBF,0xF5, + 0xC2,0x28,0x82,0x20,0x2A,0x0F,0x0D,0x2F,0xE2,0x28,0x81,0x28,0xEE,0x9A,0xBC,0xFA, + 0x44,0x41,0xC2,0x30,0x25,0x25,0x2D,0xAD,0x44,0x49,0x81,0x28,0x00,0xA0,0x5A,0x5E, + 0x44,0x49,0x61,0x20,0xA8,0xAA,0xF7,0xFD,0x03,0x41,0x81,0x28,0xA8,0xAA,0xAA,0x7D, + 0x03,0x41,0xC2,0x38,0xF0,0xC0,0x02,0x89,0x23,0x41,0xC2,0x38,0x37,0xBF,0x3F,0xEB, + 0x23,0x41,0xE2,0x38,0xE0,0xFF,0xBE,0xFE,0x03,0x41,0xA2,0x28,0x5F,0x7E,0xF8,0xF8, + 0xE3,0x30,0x61,0x28,0xAA,0xBC,0x7B,0xEA,0xE3,0x30,0x81,0x28,0xE8,0xF7,0xD5,0xF5, + 0xC2,0x28,0x82,0x28,0xDA,0x82,0x03,0xB5,0xE3,0x30,0xA2,0x28,0x75,0xEA,0x82,0x3F, + 0x03,0x31,0x82,0x28,0x7F,0x7E,0xE8,0xA2,0xC2,0x28,0x81,0x28,0xE3,0xAD,0xFF,0xA0, + 0xE3,0x30,0xA2,0x28,0x9D,0x77,0xAF,0xAF,0x03,0x31,0xC2,0x30,0x67,0xEF,0xCA,0xFB, + 0x03,0x31,0xC2,0x28,0xD5,0xD5,0x8F,0x0E,0x02,0x31,0xC2,0x28,0xA5,0x95,0xFF,0xDB, + 0x03,0x31,0xC2,0x28,0xEE,0xB8,0x6E,0xEE,0x24,0x39,0xC2,0x30,0x3B,0x2B,0x2B,0xED, + 0x23,0x39,0xC2,0x30,0x56,0xDE,0xDE,0x3F,0x23,0x39,0xE2,0x30,0x55,0x5D,0xD5,0xBC, + 0x24,0x39,0xC2,0x30,0xFD,0xB7,0xFF,0xFC,0x03,0x41,0xE3,0x30,0x77,0xEA,0xAA,0x2F, + 0x64,0x49,0xC2,0x38,0xFD,0xA5,0xAB,0x2F,0x0C,0xA4,0x85,0x51,0xB5,0x35,0x3D,0x2D, + 0x31,0xCD,0xAF,0xB4,0x03,0x89,0x29,0xA9,0x31,0xC5,0xD0,0xBC,0x80,0x00,0xAA,0xF9, + 0x10,0xC5,0x8E,0xB4,0x7E,0xE0,0x00,0x08,0x10,0xC5,0x4D,0xAC,0xD7,0x5E,0xF8,0x80, + 0xD0,0xBC,0x4E,0xAC,0x57,0xF5,0xF5,0xFC,0x6E,0xAC,0x6B,0x8B,0x78,0xE8,0xE0,0x80, + 0xCC,0x9B,0x88,0x6A,0x5F,0x7E,0xF8,0x88,0x0A,0x7B,0x87,0x6A,0xBD,0xBF,0xBF,0xA8, + 0x2A,0x83,0xC8,0x72,0x29,0x2F,0x2E,0x2F,0x4B,0x83,0xA9,0x6A,0x7A,0xAA,0xA0,0x82, + 0x2A,0x83,0x27,0x5A,0x7F,0xFA,0xE8,0xA0,0x88,0x6A,0x64,0x41,0x5F,0x7A,0xE8,0xE0, + 0x23,0x49,0xE2,0x40,0xDD,0xFB,0xAF,0xBB,0x23,0x49,0xE2,0x40,0xAF,0xFF,0xFA,0xA8, + 0x23,0x49,0xE2,0x40,0xFF,0xEF,0xCB,0xCB,0x23,0x49,0x02,0x41,0x6F,0xF5,0x91,0x87, + 0x03,0x41,0xC2,0x38,0xA8,0xA0,0xE0,0xBC,0x03,0x41,0xE2,0x40,0x2C,0x33,0x87,0xFF, + 0x03,0x41,0xE2,0x38,0x0A,0x0E,0xB5,0xDE,0x03,0x41,0xE2,0x40,0x6B,0xB3,0x20,0xBB, + 0x03,0x41,0xC1,0x38,0xAE,0x00,0x88,0xCF,0x23,0x41,0xE2,0x40,0xF5,0xEF,0xBF,0xFD, + 0x02,0x41,0xC2,0x40,0xA0,0x80,0xB8,0xF8,0x46,0x6A,0x02,0x41,0x8D,0x2D,0x0D,0x2D, + 0x26,0x6A,0xC5,0x59,0xDE,0xD8,0xD8,0xFA,0x05,0x62,0x03,0x41,0xE8,0xF8,0x7A,0x7C, + 0x44,0x49,0xE2,0x38,0x0A,0xA8,0xFD,0x7F,0x44,0x41,0x03,0x39,0x2E,0x2A,0x0D,0x89, + 0x44,0x41,0x03,0x41,0xEA,0xEA,0x62,0xAA,0x64,0x49,0xC2,0x30,0x2F,0xFA,0x5E,0x5E, + 0xE5,0x59,0xE3,0x38,0x82,0x8A,0xFD,0x75,0x03,0x39,0x81,0x20,0x78,0xE8,0xFC,0x7A, + 0xC2,0x30,0xA1,0x20,0xA7,0xAF,0x8B,0xAD,0xE3,0x30,0x81,0x20,0xF0,0xFA,0x6F,0x7A, + 0xC2,0x28,0x61,0x20,0x72,0x57,0x55,0xD5,0xA2,0x28,0x61,0x20,0xA5,0x2F,0x3B,0x2A, + 0xE3,0x30,0x81,0x28,0xBB,0xAB,0xAD,0x2F,0xC2,0x28,0xA2,0x28,0x00,0x33,0x1A,0xC0, + 0x24,0x39,0xA2,0x28,0x0D,0xF7,0x7F,0x57,0xE3,0x30,0x81,0x20,0x78,0xB8,0xFF,0xF5, + 0xC2,0x28,0x61,0x20,0xA9,0x88,0x00,0xA0,0xA1,0x28,0x61,0x20,0xFE,0xAE,0xEE,0xAA, + 0xE3,0x38,0x81,0x28,0x03,0x29,0xB5,0xBD,0x03,0x41,0xC2,0x30,0x0B,0xA2,0x22,0xB5, + 0x23,0x41,0xE2,0x38,0x5A,0xAA,0x88,0x08,0x23,0x41,0xA2,0x30,0xFE,0x5A,0x58,0xF8, + 0xC2,0x30,0x82,0x28,0xA8,0xA8,0xAA,0x2D,0xE3,0x30,0x81,0x28,0x6A,0xCA,0x0B,0xAF, + 0xE3,0x30,0x81,0x28,0x55,0x55,0xFE,0x62,0xC2,0x28,0x82,0x28,0x2F,0xED,0x95,0xBD, + 0x03,0x39,0xA2,0x28,0xCB,0xED,0xEF,0xEB,0xC2,0x28,0x81,0x28,0xAA,0xFE,0x7E,0xEE, + 0xE3,0x30,0x81,0x20,0xAB,0xBF,0x95,0xAF,0xE3,0x30,0xA2,0x28,0xBE,0x9F,0xD7,0xB7, + 0x03,0x39,0xA2,0x28,0x2A,0x8B,0xAD,0xAF,0x03,0x31,0xA2,0x28,0xEA,0xAE,0x8D,0x79, + 0x03,0x31,0xC2,0x28,0xAB,0x5B,0x7E,0x7D,0xC2,0x30,0xE3,0x28,0xBA,0xE8,0x0A,0xA2, + 0x23,0x41,0xC2,0x30,0xF9,0xAF,0x09,0xAF,0x23,0x41,0x03,0x39,0x5E,0x67,0x96,0x16, + 0x23,0x41,0xE3,0x38,0x72,0x22,0x0B,0x3E,0x44,0x49,0xE2,0x38,0xF5,0x2B,0x23,0xA2, + 0xC6,0x59,0x23,0x41,0xB5,0x2F,0x3B,0x0B,0xEE,0xA3,0xE6,0x59,0x2D,0xA5,0xBF,0xEF, + 0xF0,0xBC,0x2B,0x8B,0x00,0x0B,0xBD,0x55,0xF0,0xBC,0xAB,0x93,0x00,0x00,0x02,0xA5, + 0x10,0xC5,0xF0,0xBC,0x8D,0xA7,0xAF,0xBD,0x10,0xC5,0xCF,0xBC,0xA8,0xA0,0xBE,0x7E, + 0xF0,0xBC,0x8F,0xB4,0x78,0x08,0x22,0x0A,0xF0,0xBC,0x4E,0xAC,0x77,0x78,0x60,0x80, + 0x4E,0xAC,0xAC,0x93,0x5F,0xFA,0xEA,0xA8,0x2D,0xA4,0x09,0x7B,0x5F,0xE8,0x02,0x80, + 0x2D,0x9C,0x0A,0x7B,0x55,0x5F,0xE2,0x00,0xCC,0x93,0x2A,0x7B,0xF5,0x7D,0xFF,0xA0, + 0xCB,0x93,0xEA,0x7A,0x7F,0xFE,0xFB,0x80,0x8B,0x8B,0x27,0x5A,0x7F,0x7A,0xFA,0xA8, + 0x23,0x49,0xE2,0x38,0xBF,0x8B,0xAB,0x6C,0x23,0x49,0xE3,0x40,0x8A,0xAA,0xA6,0xED, + 0x23,0x49,0xE3,0x40,0xA2,0xEE,0xBE,0xFE,0x23,0x49,0xE2,0x40,0xF0,0x60,0xA8,0xDA, + 0x03,0x41,0xC2,0x38,0x7A,0x9C,0x6C,0xFA,0x03,0x41,0xC2,0x38,0xAB,0x0E,0xA3,0x77, + 0x03,0x41,0xC2,0x38,0x3E,0xAB,0xEB,0xEF,0x03,0x41,0xC2,0x38,0xB2,0xFE,0xFC,0xEC, + 0xE2,0x40,0x03,0x31,0x28,0x08,0x80,0x2A,0x03,0x41,0xE2,0x40,0xED,0x59,0xED,0xC3, + 0x03,0x41,0xC2,0x40,0x3A,0x28,0xEF,0x2A,0x67,0x72,0x02,0x41,0x2D,0x25,0x25,0x25, + 0x46,0x6A,0xE5,0x61,0xDC,0x78,0x5A,0xF8,0xE5,0x59,0x03,0x41,0x78,0x78,0x5C,0x58, + 0x44,0x41,0xE3,0x38,0xAF,0x8F,0xED,0xF9,0x23,0x39,0xE3,0x38,0xF2,0x78,0x8F,0xAE, + 0x43,0x41,0xE3,0x30,0x82,0xBF,0xDF,0x7F,0x44,0x41,0xE2,0x30,0x7A,0xF8,0xAA,0xED, + 0x23,0x39,0xC2,0x30,0x7F,0x7F,0x78,0xA2,0xE2,0x30,0xA1,0x28,0xEE,0xFF,0x57,0xF8, + 0xE3,0x28,0xA2,0x28,0xAF,0x7F,0x55,0xA6,0xE2,0x28,0x81,0x20,0x5E,0x5F,0xFB,0x20, + 0xE3,0x30,0x81,0x20,0xD5,0xAD,0x2A,0xAA,0xE3,0x30,0xA2,0x28,0xD5,0xE5,0xBB,0xAE, + 0xE3,0x30,0xA2,0x28,0x2F,0xBF,0xEA,0xA3,0xE3,0x30,0xA2,0x28,0x6A,0xE8,0x20,0x28, + 0xE3,0x30,0xA2,0x28,0xDF,0xEE,0xB8,0xEC,0xE2,0x28,0xA2,0x28,0x55,0x57,0xF6,0xF2, + 0xC2,0x28,0x81,0x20,0x63,0x6B,0xAF,0xD7,0xC2,0x28,0x82,0x20,0xEF,0xEE,0xC8,0xCE, + 0xC2,0x28,0x82,0x20,0x8B,0x8A,0xBB,0x57,0xC2,0x30,0x61,0x20,0x2A,0xBF,0xBF,0xF6, + 0x24,0x41,0x81,0x20,0x0A,0xAF,0xDD,0xD7,0x44,0x41,0xC2,0x30,0x60,0xE0,0xE3,0xFD, + 0xE3,0x30,0x81,0x28,0xF5,0xFF,0xEA,0x88,0xE2,0x30,0xA2,0x28,0x5D,0x55,0xD7,0xAA, + 0xE3,0x30,0xA2,0x28,0xBF,0x35,0x2B,0xA0,0x23,0x39,0xA2,0x28,0xFD,0xAA,0x8E,0x0B, + 0x44,0x41,0xA2,0x30,0x5D,0x7F,0xA2,0x02,0x24,0x39,0x81,0x28,0xD7,0x5F,0xFE,0x88, + 0x03,0x31,0xA2,0x28,0x89,0x0D,0xEB,0xAF,0xE3,0x30,0xA2,0x28,0xBE,0x78,0x78,0xFE, + 0xC2,0x28,0x82,0x28,0x00,0xEA,0xEB,0xFA,0xC2,0x28,0x81,0x28,0xA2,0x83,0x0D,0xC5, + 0xC2,0x30,0xA2,0x28,0xB5,0x57,0x7F,0xE9,0xC2,0x28,0x82,0x28,0x00,0x0B,0x0D,0x2E, + 0x03,0x39,0xC2,0x28,0xBB,0xDD,0x6F,0x8A,0x02,0x39,0xC2,0x30,0x2A,0xBD,0xFD,0xA7, + 0x64,0x49,0xE2,0x38,0xB7,0x8F,0x8D,0xBD,0xA5,0x51,0x03,0x41,0xFD,0x3D,0x27,0xAF, + 0x47,0x6A,0x64,0x51,0xBD,0xAD,0x2F,0x2F,0x0A,0x83,0x68,0x6A,0x09,0x09,0x0B,0x0B, + 0x0A,0x83,0xE9,0x7A,0x33,0x3D,0xA8,0x30,0xAC,0x9B,0xE9,0x7A,0x2B,0xB7,0xDD,0x55, + 0xD0,0xBC,0xEA,0x82,0x0A,0xBF,0xFD,0xD5,0xCF,0xBC,0x4B,0x8B,0x00,0x00,0x2F,0xD5, + 0xF0,0xBC,0x0E,0xA4,0x00,0x00,0x00,0x2D,0x10,0xC5,0xAE,0xB4,0x7A,0x6A,0xEA,0xC8, + 0x8E,0xB4,0x2D,0xA4,0x77,0xD6,0xDC,0xB8,0x6E,0xAC,0x0D,0xA4,0xF5,0xDE,0xFA,0xE8, + 0x4E,0xAC,0x0D,0xA4,0xAD,0x9E,0xFE,0x0A,0x4E,0xAC,0x2D,0x9C,0x7A,0xBB,0xAB,0x0A, + 0x6E,0xAC,0x2D,0xA4,0x55,0xF2,0xE2,0xA8,0x4E,0xA4,0x6B,0x83,0x7E,0xA0,0x80,0x00, + 0x03,0x41,0xC1,0x38,0xF0,0x98,0xF8,0xAA,0x43,0x41,0xE2,0x40,0x77,0xF5,0xFF,0x9F, + 0x23,0x49,0xE3,0x40,0xA2,0x2F,0xEB,0x7B,0x03,0x41,0xC2,0x38,0x80,0xA0,0xF2,0x60, + 0x02,0x41,0xC2,0x38,0xFB,0xDB,0xF3,0x3E,0x03,0x41,0xC2,0x38,0xEA,0x79,0xBA,0xAE, + 0x03,0x41,0xE2,0x38,0x3D,0x2D,0xEF,0x55,0x03,0x41,0xC2,0x38,0xEE,0xEB,0x8D,0x3B, + 0x03,0x41,0xE2,0x38,0x1E,0xB3,0xFF,0x6F,0x02,0x41,0xC2,0x38,0xAA,0x9F,0xBE,0xFB, + 0x03,0x41,0xC1,0x38,0xAA,0x9A,0xFA,0xEF,0x46,0x6A,0xE2,0x40,0x25,0x35,0x25,0x35, + 0x66,0x72,0xE5,0x61,0xFA,0xFC,0x78,0xE8,0x05,0x62,0xE2,0x38,0x58,0x7A,0x5C,0x78, + 0x03,0x39,0xE2,0x30,0x02,0x2B,0xBE,0x97,0x24,0x39,0xE3,0x38,0xE2,0xAF,0xF7,0x76, + 0x23,0x39,0x03,0x39,0x6D,0xF6,0xAD,0x55,0x44,0x41,0xE2,0x30,0xFE,0x82,0xAA,0xFF, + 0x43,0x39,0xE3,0x38,0xAD,0x7F,0xFA,0x8A,0x24,0x39,0xE3,0x30,0x7B,0xA2,0xBD,0xF8, + 0x24,0x39,0xC2,0x28,0x7D,0xEE,0xA8,0x8A,0x23,0x39,0xE3,0x30,0x5D,0xD7,0xAF,0xAA, + 0x23,0x39,0xE3,0x30,0x5D,0xCE,0xAE,0xBF,0x24,0x39,0xC2,0x30,0xDF,0xFA,0xE2,0xAA, + 0x03,0x39,0xC2,0x28,0xE5,0xFA,0x20,0x20,0x03,0x31,0xC2,0x28,0xB8,0xDA,0xDC,0xA0, + 0xE3,0x30,0xC2,0x28,0xF4,0xCA,0x2E,0x3A,0xE3,0x30,0xC2,0x28,0xFF,0xBB,0xC2,0x08, + 0xE3,0x28,0x82,0x20,0x7F,0xE8,0xAA,0xA0,0xC2,0x28,0x82,0x20,0x7F,0xEE,0xE8,0x88, + 0xC3,0x28,0x82,0x20,0x75,0x7F,0x6B,0xE2,0xA2,0x28,0x81,0x20,0xA7,0x55,0x16,0x80, + 0xA2,0x28,0x82,0x20,0x3B,0x07,0xAE,0xFD,0x03,0x39,0x82,0x28,0x8F,0x89,0x0F,0xFD, + 0xC2,0x30,0xE3,0x28,0xA0,0x82,0x0B,0x08,0x03,0x39,0xC2,0x30,0xEF,0x5C,0xAB,0x3D, + 0x03,0x39,0xC2,0x30,0xEA,0x83,0xEA,0x70,0x23,0x41,0xA2,0x28,0x02,0xAB,0xBD,0xF5, + 0x64,0x49,0xE3,0x38,0xA2,0x03,0x8B,0xD5,0x64,0x41,0xC2,0x30,0xFE,0x7C,0x78,0x6A, + 0xE3,0x30,0xA2,0x28,0xFB,0xB5,0xB5,0xFE,0xE3,0x38,0xC2,0x28,0xD1,0xEA,0xB3,0x4F, + 0xC2,0x30,0x81,0x28,0xFE,0xDA,0xBE,0x8A,0xE2,0x30,0xA2,0x28,0x55,0xF5,0xDB,0xA3, + 0xE2,0x30,0xA2,0x28,0x69,0x6B,0xEF,0xAA,0xE3,0x30,0x81,0x20,0xAF,0x39,0x2B,0xAF, + 0x23,0x39,0xE2,0x30,0x09,0x29,0x9D,0x5F,0x64,0x49,0xE2,0x30,0xE7,0xBF,0x2F,0xBF, + 0x43,0x41,0x03,0x39,0x35,0xAE,0x9B,0xF8,0x26,0x62,0x23,0x41,0xFD,0xFF,0xBF,0x2D, + 0xA8,0x72,0x84,0x51,0x2D,0x2D,0x2B,0x0A,0x0A,0x83,0xA8,0x7A,0x29,0xEB,0xCD,0xFB, + 0x0A,0x83,0xC9,0x7A,0xAA,0xF9,0xDD,0xA5,0x2B,0x83,0xCA,0x7A,0xFB,0x8B,0xA9,0xB7, + 0x2A,0x83,0xC9,0x7A,0xFB,0xB6,0xB0,0x28,0x4B,0x8B,0xEA,0x7A,0x39,0x2E,0xBB,0xDF, + 0x2E,0xA4,0x2A,0x83,0x2F,0xF5,0x55,0x55,0xF0,0xBC,0x4A,0x8B,0x02,0xAF,0xD5,0x55, + 0xD0,0xB4,0x8B,0x93,0xA8,0xAA,0xAB,0xD5,0xB0,0xB4,0x2E,0xA4,0xFE,0xAA,0xAA,0xA9, + 0x8F,0xB4,0x4E,0xAC,0x5F,0xFA,0x7A,0xCA,0x8F,0xB4,0x4E,0xAC,0xD7,0xEB,0x3A,0xB2, + 0x8F,0xB4,0x4E,0xAC,0xFD,0xBE,0x3A,0x00,0xAF,0xB4,0x4E,0xAC,0x5F,0xF7,0xAF,0x80, + 0x43,0x41,0xE2,0x40,0x7D,0xEF,0x7F,0xD5,0x03,0x41,0xE2,0x38,0x7A,0xB6,0x4E,0xCA, + 0x03,0x41,0xC2,0x38,0x0A,0xBA,0xBB,0x69,0x02,0x41,0xC2,0x38,0x6E,0xF8,0x5A,0xAD, + 0x03,0x39,0xA1,0x38,0x9B,0x2A,0xAA,0x23,0xE2,0x40,0x03,0x39,0x8B,0xAB,0x3B,0x2B, + 0x03,0x41,0xC2,0x38,0x9A,0xAA,0x78,0xE3,0x02,0x41,0xC2,0x38,0xEB,0x77,0xAF,0xED, + 0x03,0x41,0xC2,0x38,0xFA,0xDF,0xAE,0x8D,0x03,0x41,0xE2,0x38,0xCF,0x96,0x55,0xFA, + 0x03,0x41,0xC2,0x38,0x73,0x7E,0xFC,0xBE,0x46,0x6A,0xE2,0x40,0x25,0x35,0x35,0x35, + 0x87,0x72,0x05,0x62,0x78,0x7A,0x58,0x7E,0x05,0x62,0xE2,0x38,0x58,0x78,0x58,0x78, + 0x03,0x39,0xC2,0x30,0xFF,0x9F,0x8A,0x23,0x23,0x39,0xE3,0x30,0xF7,0xBA,0x87,0xE7, + 0x23,0x39,0xE2,0x30,0xEB,0xBB,0x7A,0xFD,0x23,0x39,0x03,0x39,0xB2,0x98,0x36,0x55, + 0x44,0x41,0x03,0x39,0x8B,0x2A,0xEF,0xFF,0x44,0x41,0x03,0x39,0x6E,0x8E,0x8B,0xDA, + 0x44,0x39,0x03,0x39,0x5F,0x60,0x5A,0x6E,0x24,0x39,0xE2,0x30,0x0A,0xEF,0xFF,0xDF, + 0x24,0x39,0xE3,0x38,0xE0,0xCA,0x2D,0x99,0x44,0x41,0xE3,0x30,0x57,0xF5,0xAB,0xED, + 0x24,0x41,0xE3,0x30,0xBF,0xDE,0xBE,0xCA,0x03,0x39,0xE2,0x30,0x80,0x2E,0x3E,0x5E, + 0x03,0x31,0xA2,0x30,0xA8,0x2A,0x80,0xAB,0x03,0x31,0xE3,0x30,0xB5,0xC6,0x7C,0x5B, + 0x03,0x31,0xC3,0x28,0x78,0x5A,0xBE,0xB2,0x03,0x31,0xC3,0x28,0xF7,0x6A,0xEA,0xFF, + 0xE3,0x30,0xC3,0x28,0x55,0x7F,0xFF,0xB7,0x03,0x31,0xA2,0x20,0x77,0xF7,0xFF,0xFB, + 0xE3,0x28,0x81,0x20,0xD7,0xFF,0xFA,0xAA,0xA2,0x28,0x82,0x20,0xB8,0xFC,0x3A,0xA2, + 0xC2,0x30,0x81,0x20,0x2B,0xAF,0x55,0x57,0xE3,0x30,0x81,0x28,0x0A,0x2A,0x0F,0x27, + 0x03,0x39,0xA2,0x30,0x6A,0x48,0xC3,0xE2,0xE3,0x30,0xA2,0x30,0xBF,0xFB,0xEA,0xAB, + 0xE2,0x30,0xC2,0x30,0xF5,0x77,0x5D,0xA2,0x02,0x39,0xA1,0x28,0xE8,0x6F,0xEA,0x2F, + 0x03,0x39,0xA2,0x28,0xF7,0xB5,0xEF,0xA8,0xE3,0x30,0xC2,0x30,0xEF,0xB3,0x8D,0xC1, + 0xE3,0x30,0xA2,0x28,0xF7,0xFF,0xCE,0xAD,0x44,0x41,0xA1,0x28,0xFD,0xED,0x2F,0x3F, + 0x64,0x41,0xC2,0x28,0x77,0xEF,0xAE,0x2A,0x24,0x39,0xA1,0x28,0xF5,0xFE,0xAA,0x08, + 0x23,0x39,0xE3,0x30,0xB5,0xA5,0x0F,0x0A,0x43,0x41,0x03,0x39,0x2A,0xFA,0xD2,0x23, + 0xC5,0x51,0xC2,0x38,0xFF,0xAF,0x2B,0x02,0x67,0x6A,0x63,0x49,0x3D,0x8B,0x0A,0x02, + 0xC9,0x7A,0x68,0x6A,0x2D,0xB5,0xB7,0xBD,0xC9,0x7A,0x88,0x72,0xA8,0x8B,0xFD,0xEB, + 0xEA,0x7A,0x88,0x72,0x0B,0x89,0xA2,0xBF,0xE9,0x7A,0xA9,0x72,0xBC,0xAB,0xB7,0xAE, + 0x2A,0x83,0xC9,0x7A,0xA9,0x3F,0xFB,0xB5,0x0A,0x83,0xC9,0x7A,0xAC,0x28,0x7F,0xFC, + 0x2A,0x83,0xC9,0x7A,0xAA,0x8F,0xB7,0x77,0x2A,0x8B,0xC9,0x7A,0x20,0xFC,0xDE,0xAA, + 0x4B,0x8B,0xEA,0x7A,0x2A,0xBB,0x7F,0x7F,0xED,0x9B,0xC9,0x7A,0x02,0xAF,0xF7,0x5D, + 0x4E,0xAC,0xEA,0x82,0x00,0x02,0xAF,0xFD,0x6E,0xAC,0x6B,0x8B,0x00,0x00,0x02,0xAD, + 0xAF,0xB4,0x4E,0xAC,0xAA,0xA2,0xAB,0xA9,0xD0,0xB4,0x8F,0xB4,0xAF,0xEF,0xEE,0xBF, + 0x23,0x41,0xE2,0x40,0xDB,0xEF,0xAF,0x42,0x02,0x41,0xC2,0x38,0xEA,0xA0,0x48,0xCA, + 0x03,0x39,0xC2,0x38,0xDE,0xFF,0xAB,0x2E,0x03,0x41,0xC2,0x38,0x3F,0xA6,0x8A,0x02, + 0x03,0x41,0xC2,0x38,0xCD,0xAE,0xAB,0xBE,0x03,0x41,0xC2,0x38,0xFF,0xEC,0xDE,0xFE, + 0x02,0x41,0xC2,0x38,0xBB,0xFA,0xFA,0xBA,0x03,0x41,0xC2,0x38,0x78,0xEF,0x5E,0xBF, + 0xE2,0x38,0xC2,0x38,0x82,0x00,0x30,0x00,0x03,0x39,0xC2,0x38,0xBA,0x32,0xBF,0xBF, + 0x03,0x41,0xC2,0x38,0xBF,0xF7,0x9E,0x7E,0x46,0x6A,0xE2,0x38,0x35,0x35,0x35,0x35, + 0x67,0x72,0x06,0x62,0x7C,0x7A,0xEE,0xE8,0x05,0x62,0xE2,0x38,0x78,0x78,0x78,0x58, + 0x03,0x39,0xC2,0x30,0x82,0x4C,0x8A,0xF8,0x03,0x39,0xC2,0x30,0xB6,0xE5,0xBA,0xA2, + 0x03,0x39,0xE2,0x28,0xAB,0xBB,0x2D,0xA7,0x03,0x39,0xC2,0x30,0x0E,0xB6,0xBE,0x2E, + 0x23,0x39,0xC2,0x30,0x2A,0xAD,0xFF,0xEE,0x23,0x41,0xE3,0x30,0xA0,0x88,0xB3,0xED, + 0x44,0x41,0x03,0x39,0x78,0xBD,0x55,0x55,0x23,0x39,0xE3,0x38,0x9D,0x7A,0x6A,0xE6, + 0x23,0x39,0xE3,0x30,0xA9,0x99,0xBD,0xBD,0x44,0x41,0xE3,0x30,0xF5,0xDF,0xFE,0x8B, + 0x44,0x41,0xE3,0x30,0x8B,0xA7,0xDE,0xBE,0x24,0x41,0xE3,0x38,0x76,0xB8,0xBB,0x6F, + 0x23,0x39,0xE3,0x30,0x7B,0xB7,0x8A,0xAA,0x24,0x39,0xE3,0x30,0xB5,0xFF,0xF4,0xEF, + 0x23,0x31,0xE3,0x30,0xBE,0xA2,0x6F,0xD5,0x03,0x31,0xC3,0x28,0xEA,0xAA,0xAA,0x00, + 0x03,0x31,0xC2,0x28,0xB5,0xFF,0xFF,0xAA,0xE3,0x30,0xC2,0x28,0xCE,0xA8,0x00,0xF0, + 0xC3,0x30,0xE2,0x28,0x0E,0xBE,0xAE,0xB8,0xE2,0x30,0xA2,0x20,0x5F,0x5A,0xAA,0xFE, + 0xC2,0x28,0x82,0x20,0xEB,0xEE,0xBA,0xAA,0xC2,0x28,0x81,0x20,0xBF,0xFE,0xE0,0xB0, + 0x03,0x39,0x81,0x20,0x02,0x29,0xBD,0x75,0x03,0x31,0xA2,0x28,0x7F,0xF0,0xAA,0xED, + 0x03,0x31,0xC2,0x30,0xAF,0xAB,0xC0,0x80,0x23,0x31,0xC2,0x30,0xF5,0xF7,0xDF,0x7B, + 0x03,0x31,0xC2,0x30,0x5E,0x5B,0xEE,0x6F,0x03,0x31,0xC2,0x30,0x6F,0x6F,0x83,0x82, + 0x03,0x39,0xA2,0x28,0x2D,0x2B,0x2E,0x27,0x03,0x39,0xE2,0x30,0x16,0x29,0x0F,0xAC, + 0x44,0x41,0xE2,0x30,0x0A,0xEE,0xFB,0x60,0x23,0x39,0xC2,0x28,0x20,0x2A,0xFE,0xF7, + 0x23,0x39,0xC2,0x30,0xE0,0x2E,0xBA,0xDF,0x84,0x51,0xE2,0x30,0xBF,0xBF,0xBD,0x2D, + 0x27,0x62,0x84,0x49,0xAD,0xA9,0xAF,0x2B,0x68,0x6A,0xE6,0x59,0x2F,0xBD,0x2D,0x09, + 0xA8,0x72,0x68,0x6A,0x85,0x8D,0xBD,0xFB,0xC9,0x7A,0x88,0x6A,0xEF,0x1B,0xDD,0xF7, + 0xC9,0x7A,0x88,0x72,0x3F,0xB8,0xFA,0x5D,0xEA,0x7A,0xA9,0x72,0xC0,0xFB,0xE5,0x55, + 0x0A,0x83,0xA9,0x72,0xA7,0xBD,0xCD,0x7D,0x0A,0x83,0xA9,0x72,0x2E,0x3D,0xBF,0x97, + 0x0A,0x83,0xA9,0x72,0xE8,0x88,0x2A,0xB7,0x2A,0x83,0xC9,0x7A,0x8F,0xE5,0xFD,0xFF, + 0x2B,0x83,0xC9,0x7A,0xAB,0x2F,0xFB,0xDF,0x2B,0x8B,0xEA,0x7A,0x77,0x76,0x62,0xFF, + 0x2A,0x83,0xE9,0x7A,0xAD,0xF7,0xFF,0x05,0xAC,0x93,0xE9,0x7A,0x2B,0xDD,0x55,0x57, + 0x6E,0xAC,0x0A,0x83,0x0A,0xBF,0xF5,0x55,0xAF,0xB4,0x4A,0x8B,0x00,0x0A,0xAF,0x55, + 0x03,0x41,0xC2,0x38,0xC0,0xC0,0x72,0x7C,0xE2,0x40,0xC2,0x30,0xF2,0x38,0xAA,0xA9, + 0x03,0x41,0xC2,0x38,0xAB,0x0A,0xAB,0x0F,0x03,0x39,0xC2,0x38,0x2A,0xEB,0xCA,0x68, + 0x22,0x39,0xC2,0x38,0xF6,0x7F,0x7F,0xBF,0x03,0x39,0xC2,0x38,0x6E,0xC2,0xBB,0xB2, + 0x03,0x41,0xC2,0x38,0x2F,0xBF,0xEC,0xEC,0x03,0x41,0xC2,0x38,0x7F,0xE2,0x8F,0xEB, + 0x22,0x39,0xC2,0x38,0xFE,0x7F,0x5F,0xDF,0xE2,0x38,0xC2,0x38,0x33,0x00,0xB3,0xB1, + 0xE2,0x38,0xC2,0x38,0xE0,0xF8,0xDA,0x28,0x47,0x6A,0xE2,0x38,0x35,0x25,0x35,0x35, + 0x67,0x72,0xC5,0x59,0xE0,0xE0,0x60,0x78,0xA5,0x59,0x02,0x39,0x78,0x5C,0x7E,0x56, + 0x03,0x39,0xC2,0x30,0x7C,0x8A,0xB8,0x9C,0x03,0x39,0xE3,0x30,0xBE,0xD7,0xD7,0xF1, + 0x03,0x31,0xC2,0x28,0xBE,0xDC,0xA2,0x7E,0x03,0x31,0xE2,0x30,0x7F,0x65,0x75,0x72, + 0x03,0x31,0xC2,0x30,0x8A,0xAA,0x8B,0xFA,0x03,0x31,0xE3,0x30,0x8E,0x24,0x2D,0x59, + 0x23,0x39,0xE3,0x30,0xAF,0xDD,0xDF,0xE7,0x03,0x39,0xC2,0x30,0x08,0xE8,0xFA,0xDA, + 0x24,0x39,0xE3,0x30,0xAF,0xBF,0xFE,0x38,0x44,0x41,0xE3,0x30,0xBA,0xA3,0xAB,0xF7, + 0x44,0x41,0x03,0x39,0xFF,0xEE,0x78,0x5F,0x24,0x39,0xE3,0x38,0xFB,0x88,0xBE,0xAF, + 0x24,0x39,0xC2,0x30,0xBF,0xF6,0xE8,0xAA,0x23,0x39,0xE2,0x30,0xC3,0xFF,0xEA,0xAA, + 0x23,0x39,0xE3,0x30,0xDF,0xFF,0xFD,0x9F,0x23,0x39,0xE3,0x30,0x37,0xFD,0xEB,0xFA, + 0x23,0x39,0xE3,0x30,0x7E,0xFE,0xF5,0xA3,0x03,0x31,0xC2,0x30,0xFB,0xC0,0x20,0x00, + 0x03,0x31,0xC2,0x28,0x79,0x73,0xC2,0xBA,0x03,0x31,0xC2,0x28,0x55,0xFF,0xFF,0x83, + 0xE3,0x28,0xC2,0x28,0x65,0xC5,0xF7,0xBD,0xE2,0x28,0xA2,0x20,0x7F,0x7B,0x88,0xA2, + 0xC2,0x28,0x81,0x20,0xBF,0xAF,0x2E,0x80,0xA2,0x28,0x81,0x20,0x2B,0xD8,0xBB,0xE8, + 0xE3,0x30,0x61,0x20,0x02,0xAF,0xFF,0xF7,0x03,0x39,0x82,0x20,0x82,0x22,0xAF,0xFD, + 0x03,0x39,0xC2,0x28,0xA9,0x88,0x8B,0x95,0x03,0x39,0xE3,0x30,0x42,0x62,0x5B,0x53, + 0x03,0x31,0xA2,0x28,0x2D,0xFB,0xBA,0x0B,0x23,0x39,0xE3,0x30,0xBE,0xBB,0xBA,0x83, + 0x23,0x39,0xA1,0x28,0xE0,0xA0,0xA8,0xDC,0xE3,0x30,0xA2,0x28,0x27,0x2A,0x20,0x83, + 0x44,0x41,0xC2,0x28,0xD5,0xFF,0xBF,0xAD,0xC5,0x51,0x02,0x31,0xAD,0xAD,0x0B,0x0B, + 0x27,0x62,0xA5,0x51,0x2D,0x0F,0xAF,0xAA,0x68,0x6A,0x07,0x5A,0x29,0x9F,0xB7,0xF5, + 0x88,0x6A,0x48,0x6A,0x0C,0xA2,0x6D,0xD5,0xC9,0x7A,0x68,0x6A,0xEE,0x3E,0x09,0xAD, + 0xC9,0x72,0x89,0x72,0xD9,0xF5,0x36,0x0A,0xC9,0x7A,0x88,0x72,0xFE,0x0E,0xEA,0x2B, + 0xE9,0x7A,0xA9,0x72,0xEB,0xE7,0x97,0xD6,0xC9,0x7A,0xA9,0x72,0xCC,0xC2,0x88,0x24, + 0x0A,0x83,0xA8,0x72,0xAD,0xB9,0x0B,0x2A,0x0A,0x83,0xC9,0x7A,0x3B,0x6A,0xFE,0xAE, + 0x0A,0x83,0xA9,0x7A,0xDA,0xFB,0xAA,0x08,0xEA,0x7A,0xA9,0x7A,0x21,0x00,0x8A,0x44, + 0x2B,0x83,0xC9,0x7A,0x27,0xD7,0xFF,0x7D,0x2A,0x83,0xA9,0x72,0xE8,0x8A,0x3A,0xFF, + 0x2A,0x83,0xE9,0x7A,0x09,0x3D,0x2E,0x27,0x2A,0x83,0xE9,0x7A,0x00,0xE0,0x7E,0x5A, + 0x03,0x41,0xC2,0x38,0x54,0x7F,0xDE,0x35,0x03,0x39,0xC2,0x38,0xB7,0xBA,0xA9,0xBB, + 0x23,0x41,0xC2,0x38,0xF9,0x8B,0xFA,0xFF,0x03,0x41,0xC2,0x38,0xFE,0xEC,0x68,0xBE, + 0x02,0x39,0xA1,0x30,0xBE,0xFA,0x37,0xEF,0x02,0x39,0xC2,0x38,0xBE,0xF6,0xEF,0x3D, + 0xE2,0x38,0xC2,0x38,0x23,0xEB,0xC4,0xC8,0xE2,0x38,0xC2,0x38,0x2A,0xD8,0x7B,0x7C, + 0x03,0x39,0xC2,0x38,0xEB,0xFF,0xBF,0xBA,0x03,0x39,0xC2,0x38,0xEE,0x7E,0x7F,0xFF, + 0xE2,0x38,0xC2,0x30,0x6C,0xFC,0x7B,0xFF,0x25,0x62,0xC2,0x38,0x3D,0x35,0x95,0x95, + 0x66,0x6A,0xA4,0x51,0xF8,0x78,0x78,0x5E,0x84,0x51,0xE2,0x30,0x7A,0x7A,0x70,0x78, + 0x23,0x39,0xC2,0x30,0xDF,0xFF,0x9B,0xFA,0x03,0x31,0xC2,0x28,0xFA,0xEA,0xAB,0x7F, + 0xE3,0x30,0xC2,0x28,0xBA,0x34,0x24,0xF7,0x03,0x39,0xC2,0x28,0xA2,0x5A,0xFF,0xAF, + 0x03,0x31,0xC2,0x30,0x4B,0xEA,0xEB,0xA2,0x03,0x39,0xC2,0x28,0xEF,0x8F,0x8B,0xAA, + 0x03,0x31,0xC2,0x30,0x83,0xA2,0xAA,0xBF,0x03,0x39,0xE3,0x30,0xEB,0x5C,0xFF,0x39, + 0x24,0x39,0xC2,0x30,0xAC,0xBF,0xFF,0xDA,0x23,0x39,0xC2,0x30,0xA2,0xAA,0xAE,0xE7, + 0x23,0x39,0xE3,0x30,0x88,0x2A,0xAE,0x6D,0x24,0x39,0x03,0x39,0x42,0x03,0x63,0x7D, + 0x23,0x39,0x03,0x39,0x76,0x5E,0x77,0x57,0x23,0x39,0xE3,0x38,0xBF,0x37,0x26,0xBE, + 0x23,0x39,0xE3,0x30,0xD7,0xE6,0x76,0xE8,0x44,0x39,0xE3,0x30,0x7F,0x5D,0xEF,0x29, + 0x24,0x39,0xE2,0x30,0x8A,0xE2,0xF7,0xDE,0x24,0x39,0xE2,0x30,0xFF,0x7E,0xE3,0x88, + 0x23,0x39,0xC2,0x30,0xAA,0x9A,0xB8,0x00,0x24,0x39,0xE3,0x30,0x5F,0x7C,0xF3,0xEA, + 0x24,0x39,0xC2,0x28,0x55,0xFF,0xFA,0xE8,0x03,0x31,0xC2,0x28,0x6D,0xEA,0x8B,0xCA, + 0xA2,0x30,0xE2,0x28,0xBF,0xFB,0xDD,0x77,0xE3,0x28,0xA2,0x20,0xF7,0x7B,0xAB,0x00, + 0xE3,0x28,0x82,0x20,0x57,0xFE,0xAF,0xA0,0xC3,0x28,0x81,0x20,0x95,0x7F,0xEA,0x02, + 0xC2,0x28,0x82,0x20,0x2F,0xB5,0xD5,0xBA,0x03,0x31,0x82,0x20,0x8A,0x3F,0x7D,0xF7, + 0xE3,0x30,0x81,0x20,0x20,0xEE,0xF7,0x9D,0x44,0x39,0xA2,0x28,0x0B,0xAB,0xBD,0xF5, + 0x03,0x39,0xC2,0x28,0x78,0xD6,0xD6,0xDF,0x23,0x39,0xE2,0x30,0x5D,0xF5,0xB5,0x2D, + 0xE6,0x51,0x03,0x31,0x95,0xB5,0xAD,0x2F,0x06,0x5A,0xA5,0x51,0x39,0xAF,0xAA,0x8A, + 0x27,0x62,0xC5,0x51,0xBF,0xAF,0xAD,0x27,0x68,0x6A,0x07,0x62,0x75,0xAF,0x29,0x2B, + 0xA9,0x72,0x68,0x6A,0x7D,0xFD,0xBA,0x8E,0xC9,0x72,0x48,0x6A,0x2F,0xA7,0x3F,0x2A, + 0xC9,0x7A,0x68,0x6A,0x88,0x2B,0xBA,0x7E,0xC9,0x7A,0x67,0x6A,0x8A,0xE8,0xA3,0x9F, + 0xEA,0x7A,0x88,0x72,0xFE,0x22,0x2F,0xB7,0xE9,0x7A,0xA9,0x72,0x2A,0xF7,0x5C,0x8B, + 0xE9,0x7A,0xA9,0x72,0xEE,0x8A,0xED,0xD7,0xC9,0x7A,0x88,0x72,0x3E,0xBF,0xDC,0xC3, + 0x0B,0x83,0x88,0x72,0x8A,0xFE,0x7B,0x7B,0xEA,0x7A,0xA9,0x72,0x6E,0xAA,0x8D,0x69, + 0xEA,0x7A,0xA9,0x72,0x02,0x02,0x6B,0xFD,0x0A,0x83,0xA9,0x72,0xAA,0x02,0x0D,0xFE, + 0x2A,0x83,0xA8,0x72,0xAB,0xAB,0xAE,0x3D,0x0A,0x83,0xE9,0x7A,0x28,0xCB,0xAA,0x9C, + 0x03,0x39,0xC2,0x38,0xAF,0x2F,0x37,0xAB,0x03,0x41,0xC2,0x38,0xFF,0xE3,0xEF,0xFA, + 0x22,0x39,0xC2,0x38,0xD7,0xDB,0xFF,0x77,0x03,0x41,0xC2,0x38,0xDE,0xAE,0xB7,0xAF, + 0x03,0x41,0xC2,0x38,0xDC,0xF8,0x7E,0xDE,0x02,0x39,0xC2,0x38,0xFA,0x9D,0xA9,0xEF, + 0xE2,0x38,0xC2,0x38,0xC0,0x0F,0xCA,0x43,0x03,0x41,0xC2,0x38,0x6E,0x3F,0xDF,0xEB, + 0x02,0x39,0xA1,0x30,0xAE,0xB4,0xBA,0xBB,0x02,0x41,0xA2,0x30,0xDF,0xAF,0x3B,0x2B, + 0x03,0x41,0xA1,0x30,0xFE,0xFE,0xF8,0x7E,0x23,0x49,0xA1,0x30,0x37,0xB5,0x95,0x3D, + 0x47,0x6A,0xA4,0x51,0xFE,0x7F,0x7D,0xF8,0xA4,0x51,0xE2,0x30,0xD8,0x78,0x70,0x70, + 0x03,0x39,0xC2,0x30,0xA8,0x08,0x2F,0xAA,0x03,0x31,0xA3,0x30,0xAE,0x88,0x88,0x0A, + 0x23,0x31,0xC2,0x30,0x75,0xB7,0x7F,0xF7,0x03,0x31,0xC2,0x28,0xFF,0x8B,0xFB,0xDA, + 0x03,0x31,0xC2,0x28,0x8A,0x87,0xED,0xCA,0x03,0x31,0xA2,0x30,0x2A,0x2A,0xA2,0xAE, + 0x03,0x31,0xA2,0x30,0x2A,0x88,0x28,0x3A,0x03,0x31,0xC2,0x28,0xAE,0xEB,0xF2,0xF2, + 0x03,0x39,0xE3,0x30,0x3D,0x7D,0x5A,0xD7,0x23,0x39,0xE3,0x30,0xE7,0xAF,0xAF,0xD5, + 0x23,0x39,0xE3,0x30,0x83,0xAD,0x7E,0x5F,0x23,0x39,0xE3,0x30,0x3A,0xBF,0xAB,0xFD, + 0x23,0x39,0xE3,0x38,0xD7,0x87,0xDF,0xF7,0x24,0x41,0xE3,0x38,0xCD,0x27,0xE9,0xE5, + 0x44,0x41,0xE3,0x38,0x7A,0xF4,0xDB,0x77,0x23,0x39,0x03,0x39,0x29,0xDF,0x57,0x55, + 0x24,0x41,0xE3,0x30,0xFA,0xDA,0x3A,0xB2,0x23,0x39,0xE3,0x30,0x5E,0xD7,0xFA,0xFA, + 0x44,0x41,0xC3,0x30,0xA2,0xF7,0xFF,0xFE,0x24,0x39,0xE3,0x30,0xAE,0xEA,0x2D,0xEE, + 0x23,0x39,0xE3,0x30,0x6E,0xFE,0xBA,0x2B,0x24,0x39,0xE2,0x30,0x7A,0xDB,0xFE,0xB8, + 0x23,0x31,0xE3,0x30,0x5B,0xDC,0xDE,0x7A,0x03,0x39,0xE3,0x28,0x7F,0xFF,0xF8,0x08, + 0x24,0x39,0xC3,0x28,0x57,0x5F,0x5A,0xE8,0x03,0x31,0xC3,0x28,0x77,0x7D,0x2A,0x08, + 0x03,0x31,0xA2,0x28,0x7D,0xFD,0xFA,0x88,0x03,0x31,0xC3,0x28,0x57,0x9F,0xAA,0x02, + 0x23,0x31,0xA2,0x28,0xDD,0xEF,0xAA,0xAA,0x24,0x39,0xA2,0x28,0xBD,0xBB,0xA2,0x08, + 0x23,0x39,0xE3,0x30,0xF7,0xDF,0xBA,0x0A,0xA5,0x49,0x03,0x31,0xBD,0xB5,0xB9,0x0F, + 0x27,0x62,0xA5,0x49,0xF5,0xAD,0x8D,0x2F,0x26,0x62,0xE6,0x59,0xD5,0xBD,0x8A,0x36, + 0x47,0x62,0xE6,0x59,0x85,0xBF,0xBF,0x1E,0x89,0x72,0x27,0x62,0x8D,0x29,0x2F,0xAF, + 0xA9,0x72,0x48,0x6A,0x8B,0x8E,0x77,0x77,0xC9,0x72,0x68,0x6A,0x20,0xAA,0xBD,0xD5, + 0xC9,0x7A,0x67,0x6A,0xFE,0x22,0xAB,0xF6,0xC9,0x7A,0x88,0x72,0x5E,0x2F,0x58,0x77, + 0xC9,0x7A,0x88,0x72,0x21,0xEE,0xEA,0x2B,0xE9,0x7A,0x88,0x72,0xBA,0xB2,0xBA,0x7E, + 0xE9,0x7A,0xA9,0x72,0xEA,0x8E,0xBE,0xB7,0xE9,0x7A,0xA8,0x72,0x89,0xAF,0xB8,0xBA, + 0x0A,0x7B,0xA9,0x72,0xD7,0xF5,0xDF,0xE3,0x0A,0x7B,0xA9,0x72,0xA9,0xA2,0xFF,0xF7, + 0xEA,0x7A,0x89,0x72,0x9F,0xF2,0xE8,0x3A,0xEA,0x7A,0xA9,0x72,0x38,0xEF,0x7E,0x8B, + 0xEA,0x7A,0xA9,0x72,0x3D,0xBA,0x00,0x0B,0x0A,0x7B,0xC9,0x7A,0xA0,0xE9,0x25,0x8B, + 0x03,0x41,0xC2,0x38,0xAA,0xDB,0xBA,0xAF,0x03,0x41,0xE2,0x38,0xD6,0x5B,0x7D,0x6B, + 0x03,0x41,0xC2,0x38,0xDE,0x8F,0x8E,0xEB,0x03,0x41,0xC2,0x38,0xED,0xDF,0xDA,0xAA, + 0x03,0x41,0xA2,0x30,0xAE,0x2A,0xEF,0xDA,0x23,0x39,0xC2,0x38,0x7F,0xFF,0x9D,0xFF, + 0x23,0x39,0xC2,0x38,0x57,0xFF,0xF5,0xFB,0xE2,0x38,0xC2,0x38,0x00,0xE8,0xD8,0xE0, + 0xE2,0x38,0xC2,0x38,0xAE,0xC8,0xBF,0xB7,0xE2,0x38,0xC2,0x38,0xEA,0x0F,0x8A,0x4C, + 0xE2,0x38,0x81,0x30,0xE8,0xF8,0x9E,0xAB,0x67,0x6A,0xC2,0x30,0xF5,0xB5,0x35,0x35, + 0xE8,0x7A,0xA5,0x59,0xFA,0xF8,0xE8,0x70,0xC5,0x59,0xE2,0x30,0x58,0x78,0xFA,0x7F, + 0x03,0x39,0xE2,0x30,0x5C,0x7C,0x5A,0x5F,0x03,0x31,0xE3,0x30,0x2C,0x5D,0x65,0xFD, + 0x03,0x31,0xE3,0x30,0x4D,0x47,0x69,0xCD,0x03,0x31,0xE3,0x30,0x59,0x7D,0x1D,0x6D, + 0xE3,0x30,0xC2,0x30,0x22,0x82,0x3A,0xA3,0x03,0x31,0xC2,0x30,0x2F,0x3F,0xBF,0xFF, + 0x03,0x31,0xC2,0x28,0xEE,0xFF,0xEA,0xEE,0x03,0x31,0xC2,0x30,0x9F,0xEA,0xFE,0x2B, + 0x03,0x31,0xA2,0x30,0x2A,0xAA,0xE6,0xBE,0x03,0x31,0xC2,0x30,0xAA,0xEA,0xFB,0xFF, + 0x03,0x31,0xC2,0x30,0xBE,0xFA,0x0B,0xF5,0x03,0x39,0xE3,0x30,0x8D,0xAB,0xDA,0xED, + 0x03,0x39,0xE2,0x30,0xAA,0xDF,0xA2,0xB7,0x03,0x39,0xC2,0x30,0x87,0xB5,0x3E,0xF2, + 0x24,0x39,0xE3,0x30,0xFF,0x57,0xEA,0xCF,0xE3,0x38,0x03,0x31,0xFE,0xAE,0xA7,0xF7, + 0x23,0x39,0xE3,0x30,0xEB,0xB9,0xB3,0xF9,0x24,0x39,0xE3,0x38,0xFD,0xBD,0xF2,0xA6, + 0x24,0x39,0xE3,0x38,0xFA,0xBC,0xAF,0xBE,0x24,0x39,0xE3,0x38,0x6B,0xAF,0xAF,0xA8, + 0x24,0x39,0xC2,0x30,0x2B,0x8A,0xFA,0xEA,0x23,0x39,0xE2,0x30,0x00,0x1B,0xDF,0xFE, + 0x44,0x39,0x03,0x31,0xF3,0xAB,0xA5,0x97,0x65,0x41,0x03,0x31,0x55,0xFE,0xFE,0xEA, + 0x44,0x39,0x03,0x39,0x5F,0xF2,0xEA,0xEA,0x24,0x39,0xE3,0x30,0xE5,0xEA,0x2A,0x02, + 0x24,0x39,0xE3,0x30,0xFF,0xBB,0x80,0x20,0x24,0x41,0x03,0x31,0xFD,0x7D,0xFE,0xAC, + 0x44,0x41,0xE3,0x30,0xF5,0xEE,0xAF,0x2A,0x64,0x41,0x04,0x39,0xF5,0x55,0xDF,0x2A, + 0xC5,0x51,0x24,0x39,0x55,0xF5,0xD5,0x2F,0x06,0x5A,0x65,0x41,0x95,0xA5,0xAB,0x00, + 0x07,0x5A,0xC6,0x59,0x7F,0xCB,0x2B,0xA0,0x47,0x6A,0xC6,0x59,0xBE,0xAD,0xAB,0x00, + 0x68,0x6A,0x06,0x5A,0xB7,0xA8,0xA8,0xBE,0x88,0x6A,0x47,0x62,0xA9,0xED,0x3A,0x8A, + 0x88,0x6A,0x48,0x6A,0xBC,0x74,0xAE,0x38,0xA9,0x72,0x68,0x6A,0x55,0xA5,0x37,0xCE, + 0xA9,0x72,0x68,0x6A,0x6E,0xDF,0xFB,0x0F,0xA8,0x72,0x68,0x6A,0x2A,0x00,0x01,0x03, + 0xC9,0x7A,0x88,0x6A,0xBE,0xAC,0x3E,0xA9,0xCA,0x72,0x68,0x6A,0xAB,0xE7,0xAE,0xAB, + 0xEA,0x7A,0x88,0x6A,0x7E,0x7B,0xDB,0xFA,0xE9,0x7A,0x88,0x6A,0xEA,0x0B,0xF7,0xFD, + 0xE9,0x72,0x88,0x6A,0x0F,0xAC,0xEB,0xEF,0xEA,0x7A,0x88,0x72,0x8A,0x3E,0x0D,0xBA, + 0xEA,0x7A,0xA8,0x72,0x09,0x59,0xAA,0x02,0x0A,0x7B,0xA9,0x72,0xBF,0xAF,0xFD,0xDC, + 0x0A,0x7B,0xA9,0x72,0x3A,0x02,0xAB,0xB7,0x0A,0x7B,0xA9,0x72,0x9E,0xAF,0xAE,0x22, + 0x02,0x39,0xC2,0x38,0xB6,0xA4,0xEF,0xCE,0x03,0x41,0xC2,0x38,0xAA,0xEB,0xFF,0x57, + 0x03,0x39,0xC2,0x38,0x0E,0xAE,0xEF,0xE9,0x03,0x39,0xA1,0x30,0xAE,0xA8,0xAE,0xF5, + 0xE2,0x38,0xC2,0x38,0xD3,0x0D,0x0B,0x28,0xE2,0x38,0xC2,0x30,0xF8,0x2E,0x04,0x27, + 0x02,0x41,0xC2,0x38,0xEB,0x6A,0xFE,0xEF,0xE2,0x38,0xC2,0x38,0xAB,0xEE,0x35,0xCE, + 0xE2,0x38,0xA1,0x30,0x08,0x82,0x60,0x6A,0xE2,0x38,0xA2,0x30,0x7A,0x7E,0xFE,0x9F, + 0xE2,0x38,0xA2,0x30,0x09,0xA2,0x80,0x88,0x46,0x6A,0xC2,0x30,0x35,0x95,0x55,0x55, + 0xA7,0x72,0xC3,0x38,0xE8,0xFF,0x5D,0x55,0x24,0x41,0xC2,0x30,0xEA,0xE8,0xAE,0xA5, + 0x03,0x39,0xC2,0x30,0xA2,0xE8,0xBC,0xFF,0x03,0x31,0xA2,0x30,0x2A,0x88,0xCA,0x2A, + 0x03,0x31,0xC2,0x28,0xBE,0xBA,0xFA,0xFF,0x03,0x31,0xC2,0x30,0xE3,0xBE,0x8A,0xFA, + 0xE3,0x30,0xC2,0x28,0xE9,0x00,0xAA,0xAB,0xE3,0x30,0xC2,0x28,0x2D,0xA8,0x02,0x8C, + 0x03,0x31,0xC2,0x28,0xBA,0x27,0x07,0xEE,0x23,0x39,0xC3,0x30,0xEF,0xBF,0xAF,0xD8, + 0x03,0x39,0xC2,0x28,0xDE,0xBC,0xAA,0xEE,0xA2,0x38,0x03,0x31,0xDF,0x76,0x7F,0xFF, + 0x02,0x39,0xC3,0x30,0xB7,0x7F,0xEA,0xFB,0x24,0x39,0xC2,0x28,0xBF,0xBD,0x3F,0xBD, + 0x03,0x39,0xC2,0x28,0xA7,0xFC,0xE3,0x8A,0x03,0x31,0xE3,0x30,0xFB,0xDF,0x77,0x95, + 0xC3,0x38,0x03,0x31,0xDF,0x57,0x5F,0xE9,0x24,0x39,0xE3,0x30,0xAF,0x2E,0xBF,0xD7, + 0x24,0x39,0xE3,0x30,0xF5,0xEE,0xAF,0x2E,0x24,0x39,0xE3,0x38,0xBF,0xEA,0xBC,0xBA, + 0x24,0x39,0xE3,0x38,0xAF,0xAE,0x9F,0xBA,0x24,0x39,0xE3,0x38,0xEF,0x2B,0xCE,0xA7, + 0x24,0x41,0x03,0x31,0x9A,0x7A,0xFE,0xA3,0x45,0x39,0x03,0x39,0xF7,0x5D,0xB6,0x97, + 0x23,0x39,0x03,0x39,0x23,0xB2,0xA8,0x0D,0x64,0x41,0x03,0x39,0xFD,0x55,0x55,0x73, + 0x44,0x41,0xE3,0x30,0x22,0xA5,0xB7,0xAA,0x85,0x41,0xE3,0x38,0xEA,0xAA,0x0B,0xAD, + 0x85,0x49,0x24,0x39,0xD5,0x2F,0x8A,0x20,0xA6,0x51,0x24,0x39,0xD5,0xAE,0x0B,0xAE, + 0xA5,0x51,0x24,0x39,0xB7,0xAE,0x00,0x0A,0xC6,0x51,0x44,0x41,0xDD,0xBF,0x2B,0x0A, + 0x27,0x62,0x85,0x49,0xAD,0xBF,0x89,0x0A,0x27,0x62,0xE6,0x59,0xB8,0x29,0x03,0xAA, + 0x48,0x6A,0x06,0x62,0x5F,0x99,0x3E,0x22,0x67,0x6A,0x06,0x5A,0x8E,0xA3,0xBB,0x9E, + 0x68,0x6A,0x06,0x62,0xAA,0x26,0x2A,0xAA,0xA8,0x6A,0x47,0x62,0x2F,0xB2,0xBA,0xDB, + 0xA9,0x72,0x27,0x62,0xF8,0xAA,0xF6,0x7F,0xA8,0x72,0x68,0x6A,0x05,0x0D,0x0E,0xF9, + 0xEA,0x7A,0x88,0x6A,0xF5,0x7D,0xFB,0x8D,0xC9,0x72,0x88,0x72,0x98,0xFF,0xD6,0xBE, + 0xA8,0x72,0x68,0x6A,0xE0,0xF8,0xEA,0xE0,0xA9,0x72,0x68,0x6A,0xAA,0xEA,0x75,0x7D, + 0xC9,0x72,0x68,0x6A,0xAA,0xBB,0xAB,0x7D,0xE9,0x7A,0x89,0x6A,0xAD,0xFF,0xFB,0x2F, + 0xC9,0x72,0x88,0x72,0xBC,0x24,0x2B,0x0B,0xC9,0x7A,0x67,0x6A,0xAB,0xF2,0xFC,0xD8, + 0xC9,0x72,0x88,0x6A,0x80,0x29,0x9D,0xEF,0xEA,0x72,0x88,0x6A,0xD2,0xBE,0xBE,0xBE, + 0xEA,0x7A,0x88,0x72,0x29,0xAF,0x9E,0xF0,0xE9,0x7A,0xA9,0x72,0x80,0xE2,0x20,0xBD, +}; + +static const size_t pixel_2_width = 128; +static const size_t pixel_2_height = 128; +static const size_t pixel_2_size = 8192; +static const unsigned char pixel_2_data[8192] = +{ + 0x87,0x62,0x23,0x41,0x7F,0xE3,0xAD,0xFF,0xE5,0x51,0xE2,0x30,0xEE,0x3A,0x68,0xBA, + 0xE6,0x51,0x02,0x31,0xA6,0xBE,0xE3,0xDB,0x06,0x52,0x23,0x39,0xB7,0xDF,0x73,0xDE, + 0xE6,0x51,0x23,0x39,0x37,0x7F,0x73,0xD8,0xE6,0x51,0x02,0x39,0x37,0x5B,0xFB,0xF8, + 0xE6,0x59,0x43,0x41,0x0D,0xF9,0xBD,0xAC,0xE5,0x59,0x23,0x39,0xBE,0x72,0xDE,0x5C, + 0xC6,0x51,0x23,0x39,0xFF,0x72,0x1C,0xFC,0x27,0x5A,0x24,0x39,0xD7,0x7A,0x9C,0xFF, + 0xE6,0x51,0x03,0x39,0x9E,0xFE,0x3C,0xFA,0x26,0x52,0x44,0x41,0x17,0xF7,0x9F,0x73, + 0x26,0x5A,0x64,0x41,0x17,0xB5,0x97,0xEB,0x27,0x5A,0x44,0x41,0xF8,0xBF,0xB6,0xD7, + 0x47,0x62,0x43,0x39,0x2B,0x0B,0x2E,0x57,0x66,0x62,0x43,0x41,0x82,0xF0,0x6A,0x55, + 0x46,0x62,0x43,0x41,0x00,0x0A,0xEB,0xD5,0x67,0x62,0x44,0x41,0xF7,0xDC,0x7F,0x57, + 0xE6,0x51,0x43,0x39,0xCD,0xF7,0xF8,0xFD,0xC5,0x51,0x23,0x39,0xC1,0xBF,0x57,0x0A, + 0x4E,0xA4,0x02,0x39,0x3F,0xF5,0x55,0xFF,0x96,0xEE,0xE6,0x59,0x00,0x03,0x0D,0x0D, + 0xD7,0xF6,0x75,0xEE,0x2B,0xCA,0xD2,0x7C,0xF7,0xF6,0x34,0xE6,0xAA,0xAA,0x7A,0x5F, + 0xD7,0xF6,0x14,0xDE,0x00,0x00,0x0A,0x95,0x18,0xFF,0x75,0xE6,0x0A,0xA2,0xB7,0x7A, + 0x18,0xFF,0x96,0xE6,0xA0,0x0A,0xAA,0xAD,0x18,0xF7,0xD7,0xF6,0x7E,0xEA,0xAB,0x7A, + 0xD7,0xF6,0xB7,0xEE,0x0A,0xBE,0x70,0xE8,0xD7,0xF6,0xB2,0xD5,0x68,0xE0,0xC8,0xA8, + 0x14,0xE6,0x71,0xCD,0x82,0x81,0x29,0x0D,0x34,0xDE,0xF3,0xDD,0x5F,0x5D,0xDE,0x5A, + 0xA8,0x72,0x63,0x41,0xB7,0xDF,0x5E,0x5C,0x27,0x5A,0x43,0x39,0xFF,0xFC,0x57,0x0B, + 0xE6,0x51,0x23,0x39,0xFF,0xFE,0x75,0x00,0x67,0x62,0x03,0x31,0x7E,0x72,0x55,0xAA, + 0xC6,0x51,0x23,0x39,0x62,0xF9,0x55,0x00,0xC6,0x51,0x23,0x39,0xFF,0x55,0xF6,0x00, + 0xE6,0x69,0x43,0x41,0x2D,0x25,0x09,0x0A,0x68,0x7A,0x03,0x39,0xFE,0x5A,0xAA,0x0A, + 0x0D,0x9C,0x24,0x39,0x75,0x55,0x77,0x02,0xAF,0xAC,0x23,0x39,0x55,0x55,0xFF,0x00, + 0xD3,0xD5,0x85,0x49,0x55,0x55,0x55,0x00,0x35,0xE6,0x64,0x41,0x55,0x55,0xFF,0x00, + 0x96,0xEE,0x84,0x49,0x55,0x55,0xBF,0x00,0x75,0xEE,0x84,0x49,0x55,0x55,0xAA,0x00, + 0xD7,0xFE,0xA5,0x51,0x55,0x55,0xAA,0xE0,0x55,0xEE,0xE6,0x59,0x55,0xD5,0x0F,0x25, + 0xB7,0xF6,0xE6,0x59,0x55,0xFF,0x00,0x00,0xB6,0xEE,0x06,0x5A,0x55,0xAB,0x00,0x00, + 0xB7,0xF6,0x26,0x62,0x55,0x2A,0x00,0x00,0x96,0xEE,0x87,0x6A,0x55,0x00,0x00,0x00, + 0xB6,0xEE,0x2A,0x83,0xD5,0x00,0x00,0x00,0xB6,0xF6,0x8E,0xAC,0x09,0x00,0x00,0x00, + 0xB6,0xF6,0x14,0xDE,0xE8,0x68,0xFA,0xB6,0xD7,0xF6,0x14,0xDE,0xFD,0x0D,0x02,0x08, + 0xD7,0xF6,0xF3,0xD5,0x7A,0xAA,0xA0,0x00,0xD7,0xF6,0xD3,0xD5,0x0D,0xBE,0xA2,0x08, + 0x18,0xF7,0x35,0xDE,0x9E,0xFA,0x8B,0x2A,0x18,0xF7,0x96,0xEE,0x88,0x29,0xAA,0xE8, + 0x18,0xF7,0x96,0xE6,0xFE,0xF8,0x7A,0x7A,0x75,0xEE,0xD3,0xD5,0x00,0xA0,0xAC,0xE6, + 0x34,0xE6,0x92,0xCD,0xA5,0xA7,0x36,0x26,0x34,0xE6,0xF3,0xDD,0xDA,0xFE,0xD6,0x56, + 0x96,0xEE,0xE5,0x51,0x56,0xA8,0x00,0x00,0xB6,0xEE,0x06,0x5A,0x55,0xAA,0x00,0x00, + 0x96,0xEE,0x47,0x62,0x55,0x02,0x00,0x00,0x75,0xEE,0xC9,0x72,0xD5,0x00,0x00,0x00, + 0x96,0xEE,0x8B,0x93,0xF5,0x00,0x00,0x00,0xB6,0xEE,0x10,0xBD,0xD5,0x02,0x00,0x00, + 0xD7,0xF6,0xE5,0x69,0x5A,0x58,0x58,0x58,0x0A,0x8B,0xC5,0x69,0x3D,0xDD,0xF5,0xD5, + 0x96,0xEE,0x46,0x72,0x02,0x03,0x09,0x25,0xB6,0xF6,0x96,0xEE,0xF5,0xAA,0x82,0x02, + 0xB6,0xF6,0x96,0xEE,0xAB,0xAB,0x02,0x20,0xB6,0xF6,0xD6,0xEE,0x20,0xC0,0x60,0xFC, + 0xF7,0xF6,0xD7,0xF6,0xF5,0x82,0x02,0x00,0xF7,0xF6,0x71,0xCD,0x00,0x00,0x80,0x60, + 0x55,0xEE,0x87,0x7A,0x70,0x58,0x56,0x55,0xB7,0xF6,0x46,0x72,0x25,0x25,0x25,0x0D, + 0xF8,0xFE,0x17,0xF7,0xFA,0xFE,0xFF,0xF7,0xF7,0xF6,0xD7,0xF6,0x7E,0xFC,0xF8,0x62, + 0xD7,0xF6,0xF7,0xEE,0x00,0x00,0x28,0x80,0xD7,0xF6,0xF7,0xEE,0x00,0xA0,0x08,0xA8, + 0xF7,0xF6,0x96,0xEE,0x2A,0x8A,0xE2,0x78,0x96,0xEE,0xF3,0xDD,0x80,0xE0,0x70,0x5C, + 0xB7,0xF6,0xD2,0xD5,0xB7,0x25,0x0B,0x02,0xD7,0xF6,0x34,0xE6,0xBD,0x57,0xAA,0x28, + 0xF8,0xF6,0x55,0xE6,0x0A,0x2D,0xFB,0xAA,0xF7,0xF6,0xB7,0xEE,0xD7,0x7E,0x6A,0x89, + 0x18,0xF7,0xD7,0xF6,0x3F,0xA9,0x29,0xFF,0x39,0xFF,0xB6,0xEE,0xE8,0xF2,0x62,0xEE, + 0xD7,0xF6,0x34,0xE6,0xC0,0x8A,0x6B,0x6F,0x34,0xE6,0x10,0xC5,0x8C,0x04,0xA6,0x26, + 0x76,0xEE,0xCF,0xBC,0xAE,0x2A,0x3E,0x9A,0x96,0xEE,0xD3,0xD5,0x7F,0x7A,0xA8,0x2A, + 0xD6,0xF6,0xB6,0xEE,0xFD,0xF7,0xFF,0xAD,0xD6,0xF6,0xB6,0xEE,0xFB,0xFA,0xBA,0xE9, + 0xD6,0xF6,0xB6,0xEE,0xDF,0xEE,0xBB,0xFA,0xB5,0xF6,0x96,0xEE,0xD7,0xDD,0xBE,0xFE, + 0xD7,0xF6,0x96,0xEE,0x2F,0x27,0x2F,0x2F,0xD7,0xF6,0xB6,0xEE,0xCA,0x08,0x08,0x82, + 0x95,0xF6,0xA5,0x61,0x58,0x7C,0x5C,0x54,0x06,0x72,0x44,0x59,0x2C,0xB8,0x7A,0x79, + 0x92,0xD5,0x84,0x59,0x2D,0xB5,0xF5,0xD5,0xD6,0xF6,0xEC,0xA3,0x00,0x00,0x02,0x09, + 0xD7,0xF6,0xB6,0xF6,0x77,0xDE,0xDE,0xB8,0xD6,0xF6,0xB6,0xF6,0x0B,0x2D,0x2E,0x08, + 0xF7,0xF6,0x55,0xEE,0x00,0x00,0x80,0x40,0x17,0xFF,0x46,0x7A,0xE0,0x78,0x5E,0x57, + 0x87,0x8A,0x26,0x7A,0x0F,0x27,0xA9,0xFB,0xF7,0xFE,0x87,0x82,0x0D,0x0D,0x09,0x09, + 0x18,0xFF,0x17,0xF7,0xEE,0xBB,0xEE,0xEA,0xF7,0xF6,0xD7,0xF6,0xE8,0xE8,0xEA,0xEA, + 0xF7,0xF6,0xD7,0xF6,0xF5,0xD7,0x7F,0xEB,0x17,0xFF,0xB7,0xEE,0xAF,0xCB,0x6A,0x5A, + 0xD6,0xF6,0xD3,0xD5,0xA0,0xA8,0xE8,0x7A,0xD7,0xF6,0x92,0xD5,0x9E,0x27,0x09,0x02, + 0xF7,0xF6,0xB6,0xEE,0xBF,0xAA,0xEE,0xEA,0xD7,0xF6,0xB6,0xEE,0xD8,0xAE,0x8A,0xE8, + 0xF7,0xF6,0xB6,0xEE,0x15,0x57,0x77,0xEF,0x38,0xFF,0xD7,0xEE,0xEF,0xAB,0x2D,0xB5, + 0x39,0xFF,0xD7,0xF6,0xDF,0x7F,0xDE,0x78,0xF8,0xF6,0xB6,0xEE,0xF8,0xF8,0xFE,0xD7, + 0xB6,0xEE,0xF3,0xD5,0xCE,0x8E,0x8C,0x26,0xF3,0xDD,0x30,0xC5,0x24,0x3C,0x2A,0x3A, + 0x96,0xF6,0x30,0xC5,0x1F,0x3D,0x35,0x35,0xB6,0xF6,0x34,0xE6,0xDE,0xDC,0xDC,0xFC, + 0xB6,0xF6,0xD6,0xEE,0xEB,0xFF,0xFB,0xFF,0xD6,0xF6,0xB7,0xEE,0xAA,0x82,0x0A,0x22, + 0xD6,0xF6,0xB6,0xEE,0xEA,0xAE,0xC0,0x80,0xD6,0xF6,0x96,0xEE,0xFF,0xFF,0xBB,0xBE, + 0xF7,0xF6,0xB6,0xEE,0xB5,0xB5,0xBD,0xA7,0xD6,0xF6,0xF7,0xEE,0x00,0x08,0xA2,0xA8, + 0x95,0xEE,0x43,0x51,0x5C,0x5C,0x58,0x50,0x85,0x59,0xE2,0x40,0xC2,0xFE,0x7B,0x76, + 0x67,0x72,0x03,0x41,0x3D,0xAD,0x25,0x25,0x34,0xE6,0x09,0x83,0x0D,0xF5,0x55,0x55, + 0x95,0xEE,0xC8,0x7A,0x00,0xBF,0xD5,0x55,0xB6,0xF6,0x09,0x8B,0x00,0x22,0x7D,0x55, + 0x76,0xF6,0x46,0x72,0x80,0x60,0x5F,0x55,0x67,0x82,0xE5,0x71,0x2C,0x0B,0xE7,0xD7, + 0x29,0x9B,0x26,0x82,0xD7,0xF5,0xBD,0x2D,0xF7,0xFE,0x4B,0xA3,0x01,0x03,0x02,0x02, + 0x38,0xFF,0x18,0xF7,0x7E,0x6B,0x7F,0xFF,0x17,0xF7,0xD7,0xF6,0xFF,0xEE,0xEE,0xA0, + 0x18,0xFF,0x75,0xEE,0x2A,0x82,0xE2,0x58,0xF7,0xFE,0x55,0xEE,0xF8,0xEE,0x6E,0x7F, + 0xD7,0xF6,0xF4,0xDD,0xBE,0x27,0x09,0x02,0xF7,0xF6,0xD7,0xF6,0x7D,0x7B,0x5A,0xEE, + 0xD7,0xF6,0xB6,0xEE,0x00,0xA0,0x80,0x80,0xD7,0xF6,0xB6,0xEE,0xAA,0xA0,0xE8,0xAA, + 0xD7,0xF6,0xB7,0xEE,0x80,0x0B,0xAF,0x0A,0xF8,0xF6,0xD7,0xF6,0x2D,0x3D,0x25,0xAB, + 0x39,0xFF,0x97,0xEE,0xE0,0x6A,0x4A,0xEA,0xB6,0xEE,0x76,0xEE,0x38,0xBF,0x9F,0xFF, + 0xB7,0xF6,0x71,0xCD,0x24,0x06,0x24,0x26,0x35,0xE6,0x92,0xCD,0xD6,0x9E,0xDC,0x54, + 0xF3,0xDD,0x8E,0xB4,0x27,0x37,0x07,0x09,0x96,0xEE,0x34,0xE6,0xD8,0xFB,0xDB,0xFB, + 0xD6,0xF6,0xB7,0xEE,0xAA,0x8A,0x00,0x2A,0xD7,0xF6,0xD6,0xEE,0xAA,0xAA,0xAA,0x0A, + 0xF7,0xF6,0xD7,0xF6,0x75,0x77,0xF5,0xAD,0xD6,0xF6,0xB6,0xEE,0xDF,0xD6,0xEA,0xA8, + 0xF7,0xF6,0xB6,0xEE,0xAD,0xA7,0xAF,0xAF,0xF7,0xF6,0xD7,0xF6,0xF5,0x7E,0xA7,0xAB, + 0xD7,0xF6,0x02,0x41,0x70,0x70,0x60,0x60,0xE5,0x61,0xE2,0x40,0x7F,0xFF,0xBD,0x09, + 0x67,0x72,0x44,0x49,0x2D,0xAF,0xFB,0xEA,0xA8,0x7A,0xE5,0x61,0x80,0xA2,0xFD,0x5F, + 0x88,0x72,0xE5,0x61,0x22,0xBA,0xFE,0xD5,0x2A,0x8B,0xE5,0x61,0x02,0xAA,0x7B,0x55, + 0x67,0x7A,0xC5,0x61,0x34,0xB7,0xED,0xC3,0x26,0x7A,0x43,0x59,0x2C,0x26,0xB5,0x15, + 0xE9,0x92,0x47,0x82,0x35,0x25,0xB5,0x3F,0xF7,0xFE,0x10,0xCD,0x01,0x01,0x03,0x03, + 0x38,0xFF,0xF7,0xF6,0xAA,0xAF,0xFF,0x5B,0x38,0xFF,0xD6,0xF6,0xA8,0xE0,0x6B,0x5B, + 0xD7,0xF6,0x54,0xE6,0xA8,0x80,0x60,0x40,0xF8,0xFE,0xD3,0xDD,0x5E,0xD6,0x83,0x82, + 0xD7,0xF6,0xB2,0xD5,0x25,0x37,0xBE,0xFA,0xF7,0xF6,0xB6,0xF6,0x02,0x02,0xAB,0x09, + 0xF7,0xF6,0xD7,0xF6,0x7F,0x5A,0xBF,0xDF,0xF7,0xF6,0x97,0xEE,0xAA,0x0E,0x22,0x8A, + 0xF7,0xF6,0xD7,0xF6,0x85,0xC2,0x8B,0xAA,0xF8,0xF6,0xD7,0xF6,0x02,0xEA,0x0A,0xCA, + 0xF8,0xF6,0xB7,0xEE,0x8A,0x2A,0xBE,0xB7,0x96,0xEE,0x76,0xEE,0xAE,0x9C,0xBE,0xE0, + 0x96,0xEE,0x51,0xCD,0x24,0x24,0x2E,0x2C,0x55,0xEE,0xF0,0xBC,0xFC,0xF8,0x78,0x58, + 0x34,0xE6,0x10,0xC5,0x2D,0x2B,0x01,0x0B,0x96,0xEE,0x55,0xE6,0x5B,0xFA,0xF3,0x33, + 0xD6,0xF6,0xB6,0xE6,0x28,0x82,0x20,0x88,0xD7,0xF6,0xD6,0xEE,0x8A,0xAA,0x2B,0xAA, + 0xF6,0xF6,0xD7,0xF6,0xFD,0x7F,0x77,0x7D,0xD6,0xF6,0xB7,0xEE,0x00,0x08,0x2A,0xAE, + 0xF7,0xF6,0xD7,0xF6,0xD5,0xA7,0x2D,0xA5,0xF7,0xF6,0xD6,0xF6,0xBA,0xAA,0xCA,0x02, + 0xB6,0xF6,0x66,0x72,0x60,0x60,0x70,0x70,0xC8,0x82,0xC5,0x59,0xE5,0x0A,0x2A,0xFE, + 0xA8,0x7A,0xA4,0x59,0x7A,0xE0,0x68,0x7B,0x67,0x72,0x64,0x51,0x82,0xC3,0xFF,0xF5, + 0x46,0x72,0xC5,0x59,0xFD,0xE5,0xD5,0x39,0x2A,0x93,0xC5,0x61,0xD5,0xB5,0x2F,0x0A, + 0x8E,0xC4,0x88,0x82,0x7D,0xDB,0xEB,0x0A,0x8B,0xA3,0xC5,0x69,0x97,0xEA,0x8A,0xE8, + 0xD7,0xFE,0x67,0x7A,0xD5,0x15,0x25,0x0D,0x17,0xFF,0xB8,0xF6,0x21,0x22,0x22,0x20, + 0x18,0xFF,0xB6,0xEE,0x28,0x88,0x6A,0x5A,0x17,0xFF,0x34,0xE6,0xA8,0x7A,0x7F,0xA2, + 0x39,0xFF,0x96,0xEE,0xE2,0xC1,0x83,0x88,0x18,0xFF,0xD8,0xF6,0xE9,0x89,0xAB,0xAB, + 0x18,0xFF,0x14,0xE6,0x7F,0x7E,0xFC,0x78,0x18,0xFF,0x55,0xE6,0x2B,0x29,0xAD,0xAD, + 0x38,0xFF,0xD7,0xF6,0x57,0x7F,0xFF,0xFB,0xF7,0xF6,0xD7,0xF6,0xD9,0x0B,0x00,0x00, + 0x18,0xFF,0xD7,0xF6,0xFD,0xAE,0xBB,0xFA,0xF7,0xF6,0x95,0xEE,0x80,0xA0,0xE8,0xE8, + 0xD7,0xF6,0x96,0xEE,0x37,0x0D,0x09,0xAD,0x96,0xEE,0x55,0xE6,0xA8,0xA8,0xBB,0xBD, + 0x55,0xEE,0xB3,0xD5,0x04,0x24,0x04,0x24,0x55,0xEE,0x6E,0xB4,0x78,0x78,0x58,0x5A, + 0x76,0xEE,0x92,0xD5,0xA9,0xA9,0x29,0x03,0xB6,0xF6,0x34,0xE6,0x3B,0x25,0x2E,0xAF, + 0xD6,0xF6,0x55,0xEE,0x00,0x00,0x00,0x09,0xD6,0xF6,0xF7,0xEE,0x20,0x88,0x88,0x20, + 0xD6,0xF6,0xD7,0xEE,0x8A,0xAA,0x88,0x22,0xD6,0xF6,0xB6,0xEE,0xEE,0xBE,0xAA,0x00, + 0xD6,0xF6,0xB6,0xEE,0x02,0x8A,0xBB,0x80,0xF7,0xF6,0xB6,0xEE,0xAA,0xAB,0xEB,0xFE, + 0x75,0xEE,0x63,0x49,0x78,0x58,0x58,0x5C,0xE5,0x61,0xA1,0x28,0x00,0xEF,0xD7,0xD5, + 0xC5,0x59,0xE2,0x38,0xA8,0xB7,0xBD,0x35,0x09,0x93,0x84,0x51,0xFD,0xEB,0x7A,0x72, + 0x2A,0x8B,0x23,0x49,0x2F,0x2B,0x3F,0xB5,0xEC,0xAB,0x87,0x82,0xBA,0x80,0x0B,0x2D, + 0x4E,0xBC,0x47,0x7A,0x0A,0xAE,0xFE,0x7A,0xEC,0xAB,0x26,0x72,0x5C,0xD6,0x3F,0x2B, + 0xF8,0xFE,0xCB,0xA3,0x09,0x02,0x02,0x02,0x18,0xFF,0xD6,0xF6,0xA0,0xA2,0xE0,0x70, + 0x59,0xFF,0xD6,0xF6,0xD7,0xA5,0xAD,0x0D,0x38,0xFF,0x75,0xE6,0x70,0xD0,0xDC,0x9C, + 0x38,0xFF,0xF9,0xF6,0xCA,0x6A,0xEA,0xEE,0x18,0xFF,0xF8,0xF6,0xB9,0xBF,0xAF,0xA7, + 0x18,0xFF,0x55,0xEE,0x78,0xE0,0xE0,0xA8,0xF7,0xF6,0x55,0xEE,0x2D,0x2F,0x0F,0x2A, + 0x18,0xFF,0xF7,0xF6,0x55,0x55,0xFD,0xA5,0xF7,0xF6,0xD7,0xF6,0x28,0x62,0x00,0x00, + 0xF7,0xF6,0x96,0xEE,0x80,0x28,0xF8,0x7A,0xD7,0xF6,0x55,0xE6,0xE0,0xF0,0xDE,0xF7, + 0xD7,0xF6,0x76,0xEE,0x89,0x89,0xF3,0xBB,0x75,0xEE,0xF4,0xDD,0x0A,0x07,0x25,0xA7, + 0x56,0xEE,0x92,0xCD,0x2C,0x2E,0x2E,0x66,0x14,0xE6,0xAF,0xBC,0xD8,0xF8,0xF0,0xD2, + 0x34,0xE6,0x31,0xCD,0x82,0x7F,0xD7,0xD7,0x35,0xE6,0x92,0xD5,0x0F,0x0D,0x2D,0xBD, + 0x34,0xE6,0xE8,0x82,0x2D,0x55,0x55,0x55,0xB6,0xF6,0x08,0x83,0x00,0x2F,0x55,0x55, + 0xB6,0xF6,0xE8,0x82,0x00,0x00,0x0B,0xD5,0xD6,0xF6,0xF0,0xC4,0x00,0x00,0x00,0x2D, + 0xB7,0xFE,0xF6,0xF6,0xFF,0xFF,0xBF,0xEA,0xF7,0xFE,0xB6,0xF6,0xFF,0xAE,0xEE,0xAA, + 0x95,0xEE,0x43,0x41,0x5C,0x5C,0x5C,0x58,0x44,0x41,0xA1,0x28,0xD5,0xF7,0xA0,0x80, + 0x06,0x72,0xE2,0x38,0xB5,0x35,0x35,0x2D,0xC8,0x82,0xE3,0x40,0x60,0x70,0x7A,0x5E, + 0xE6,0x61,0x81,0x28,0x2F,0xFF,0x77,0x5F,0x09,0x93,0xC2,0x30,0x0A,0x2F,0xB5,0xB5, + 0x6B,0x9B,0x67,0x7A,0xD8,0xDE,0xFF,0xFF,0xCB,0xA3,0x06,0x6A,0xC2,0xAA,0xFB,0x7F, + 0x34,0xE6,0x67,0x72,0x2D,0x95,0x55,0x55,0xD7,0xF6,0x4B,0x93,0x00,0x00,0x02,0x0D, + 0x79,0xFF,0xD7,0xF6,0xA9,0xEB,0xEA,0x6E,0xF7,0xFE,0x35,0xE6,0x3C,0x3F,0x37,0x27, + 0x38,0xFF,0xF7,0xF6,0xE3,0xEB,0xEB,0xEB,0xF8,0xFE,0x18,0xF7,0xEA,0xAB,0xAA,0xAA, + 0x18,0xFF,0xD7,0xF6,0x7A,0x5A,0xFE,0xFA,0xF8,0xF6,0xD7,0xF6,0xD5,0xBA,0x0A,0x0B, + 0x18,0xFF,0xF7,0xF6,0xA7,0xF6,0xBF,0x9B,0x18,0xFF,0xB7,0xF6,0xA8,0xE2,0x68,0x7A, + 0xD7,0xF6,0x55,0xE6,0xE8,0xFA,0x7E,0xFF,0x75,0xEE,0x35,0xE6,0x20,0xA8,0xAF,0x38, + 0xB7,0xF6,0x76,0xEE,0x3E,0xAA,0xEE,0x7F,0x75,0xEE,0x92,0xD5,0x2F,0x25,0xA5,0xB5, + 0xF4,0xDD,0x51,0xCD,0x48,0xC8,0x00,0x00,0xD3,0xDD,0x6E,0xB4,0xFA,0xDA,0xDA,0xD8, + 0x72,0xD5,0xF0,0xC4,0x2F,0x2D,0xAF,0xB7,0xD3,0xDD,0x30,0xC5,0x22,0xE2,0x62,0x5F, + 0xE8,0x82,0x65,0x72,0x2A,0xA8,0x2B,0x55,0xE8,0x82,0xA7,0x7A,0xA2,0xBA,0xEA,0xAD, + 0xE8,0x82,0xC8,0x82,0x23,0xAA,0xFF,0x57,0x4D,0xAC,0xE8,0x82,0x35,0x55,0x55,0x55, + 0x75,0xEE,0xE8,0x82,0x02,0xB5,0x55,0x55,0xB6,0xF6,0x09,0x8B,0x00,0x02,0xB5,0x55, + 0x75,0xEE,0x63,0x51,0x70,0x60,0xC0,0xEF,0xA5,0x51,0x23,0x41,0x60,0xE2,0xAD,0xA5, + 0x09,0x93,0x64,0x51,0xB5,0x2D,0x0B,0x0B,0x87,0x82,0x24,0x49,0x5C,0xF8,0xB8,0x88, + 0x47,0x7A,0xC2,0x30,0x55,0x5F,0xE8,0x60,0x06,0x72,0xA2,0x30,0x3D,0x2F,0xEE,0xBF, + 0x88,0x7A,0xC5,0x61,0xBC,0xD5,0x99,0xAB,0xA8,0x7A,0x22,0x41,0xF8,0xDE,0x96,0xB7, + 0x09,0x8B,0xC5,0x61,0xAF,0xAF,0x2F,0x27,0xB6,0xF6,0xA8,0x82,0x25,0x35,0xD5,0x55, + 0x18,0xFF,0xF0,0xCC,0x80,0x80,0xA0,0x89,0xF8,0xFE,0x55,0xEE,0x25,0x25,0x25,0x0D, + 0x18,0xFF,0xF8,0xF6,0x82,0xE2,0xE2,0xC2,0x18,0xFF,0xF8,0xF6,0x7E,0x5F,0xF7,0x57, + 0x18,0xFF,0xD7,0xF6,0xFF,0xBB,0xEF,0xAB,0x18,0xFF,0xD7,0xF6,0xAF,0xBF,0xAA,0xAE, + 0x18,0xFF,0xD7,0xF6,0xBA,0xFA,0xFA,0xFE,0xF8,0xF6,0x76,0xEE,0xE8,0x78,0x7A,0x5E, + 0x76,0xEE,0x35,0xE6,0xE0,0xE0,0xE8,0x68,0x96,0xEE,0x35,0xE6,0x3F,0x2E,0xAB,0x2D, + 0x96,0xEE,0x55,0xEE,0x88,0xC2,0xEE,0x4A,0x14,0xE6,0x71,0xCD,0x27,0xB5,0xBE,0xA8, + 0xD3,0xDD,0xCF,0xBC,0x00,0x80,0x70,0x58,0x92,0xD5,0x6E,0xB4,0x58,0x7B,0xEF,0xA7, + 0x51,0xCD,0x4E,0xAC,0x2E,0x0E,0x26,0x26,0x72,0xCD,0x10,0xC5,0x16,0xB5,0x0D,0xA3, + 0xA7,0x7A,0x66,0x72,0xDD,0xFA,0xAA,0xAB,0xA7,0x7A,0x46,0x72,0xBF,0xDA,0xA2,0x08, + 0xE8,0x82,0x46,0x72,0x0A,0xBD,0xF7,0xFB,0xE8,0x8A,0x66,0x72,0x22,0xAA,0x3D,0x55, + 0xE8,0x82,0x87,0x7A,0x08,0xA0,0x82,0xA5,0x08,0x8B,0xC8,0x82,0xAE,0xFF,0xFF,0xF5, + 0x08,0x8B,0xC4,0x59,0xC0,0xE2,0x68,0xE2,0xA4,0x59,0xC2,0x30,0x2A,0x0A,0xBF,0xDF, + 0xE8,0x92,0xA4,0x59,0x09,0x8B,0x0B,0xAD,0xA8,0x8A,0xA5,0x61,0xE8,0xFE,0x7A,0x7E, + 0x46,0x72,0x23,0x49,0xE8,0x7A,0x5F,0x5F,0xA5,0x51,0x23,0x41,0xB5,0xB7,0x3F,0xEF, + 0x88,0x72,0x64,0x49,0x8B,0xAB,0xFF,0x55,0x47,0x72,0x03,0x49,0xB7,0xBF,0x2F,0x03, + 0xE9,0x92,0x06,0x6A,0xAD,0x8B,0xEB,0xFE,0xE9,0x8A,0x23,0x49,0x82,0xA2,0x7A,0x5E, + 0x14,0xE6,0xE5,0x61,0x0B,0x2D,0xB5,0xD5,0xD7,0xFE,0x0D,0xAC,0x08,0x02,0x02,0xB5, + 0x18,0xFF,0xB7,0xF6,0x80,0x80,0x82,0x89,0xD7,0xFE,0xF8,0xF6,0xF5,0x7D,0xD7,0xF5, + 0x18,0xFF,0xF7,0xF6,0xDD,0xB5,0xFF,0xED,0x18,0xFF,0xD7,0xF6,0x8E,0xAA,0xAA,0x6A, + 0xF8,0xFE,0x96,0xEE,0xF0,0x7A,0x7A,0x5E,0xB6,0xF6,0x55,0xE6,0xFC,0xEF,0x75,0xF7, + 0x76,0xEE,0x35,0xEE,0xEA,0x88,0x2A,0xA8,0x76,0xEE,0x14,0xE6,0x0B,0x0E,0x7A,0xF8, + 0x96,0xF6,0xF4,0xE5,0x82,0x8A,0xC3,0x6A,0x14,0xE6,0xD3,0xDD,0xEA,0xBE,0x03,0x61, + 0xD3,0xDD,0x8E,0xB4,0x58,0x5C,0xFC,0x7E,0x51,0xCD,0xCC,0x9B,0x2F,0xAF,0xFE,0x7A, + 0x10,0xC5,0xAB,0x9B,0x08,0x08,0x0F,0x0D,0x72,0xCD,0x11,0xC5,0x02,0x00,0x03,0xAF, + 0x67,0x72,0x25,0x6A,0x25,0x55,0xDD,0xBE,0xA8,0x7A,0x25,0x6A,0x82,0xBD,0x55,0x55, + 0xA7,0x7A,0x26,0x72,0xA2,0x80,0x2D,0x55,0xA7,0x7A,0x46,0x7A,0xA8,0x0A,0xA0,0x2D, + 0xA7,0x7A,0x66,0x7A,0xD7,0xE8,0xE2,0x8A,0xC8,0x82,0x66,0x72,0x0A,0xD7,0xFB,0xAA, + 0xE8,0x82,0x86,0x7A,0x60,0x22,0xD5,0x77,0x86,0x7A,0xA2,0x38,0x57,0x5C,0xF8,0xE0, + 0xE6,0x69,0xC2,0x40,0x2D,0x2D,0xFF,0xFF,0x67,0x7A,0x03,0x49,0x20,0x00,0x8B,0xF5, + 0xA8,0x82,0xC2,0x38,0xFA,0xF8,0x7A,0x5F,0x44,0x49,0xE2,0x38,0xBC,0xF7,0xFD,0xAB, + 0xA4,0x59,0xA2,0x30,0xDF,0xB7,0x37,0x2F,0x67,0x7A,0x84,0x59,0x09,0x2D,0xFD,0xFF, + 0x06,0x6A,0x44,0x51,0xA8,0xB8,0xBE,0xD7,0xA5,0x59,0x03,0x41,0x9C,0x9C,0x3E,0xA7, + 0xE9,0x8A,0xA5,0x59,0x3F,0xAF,0xEB,0xED,0x4A,0x93,0x67,0x7A,0x37,0xB5,0xED,0x55, + 0x96,0xF6,0x67,0x7A,0x02,0xB7,0x55,0x55,0x97,0xF6,0x67,0x7A,0x00,0x00,0xB7,0x55, + 0xD7,0xFE,0x67,0x72,0x00,0x00,0x0A,0x75,0xD7,0xFE,0xB0,0xBC,0x00,0x00,0x00,0x29, + 0xD7,0xF6,0x55,0xEE,0xE8,0x7E,0xFF,0x5F,0x96,0xF6,0x35,0xE6,0xEA,0xAA,0xAB,0xE5, + 0x96,0xF6,0x55,0xEE,0x7F,0xEE,0x2A,0x7D,0x76,0xEE,0x55,0xEE,0x5A,0x3A,0xD7,0x09, + 0x75,0xEE,0xB3,0xD5,0xE8,0x62,0x68,0x68,0x75,0xEE,0xB3,0xD5,0xAD,0xAF,0xAD,0xBD, + 0x75,0xEE,0x10,0xC5,0x56,0x78,0x82,0x00,0x35,0xE6,0x8B,0x93,0x6A,0xEA,0xAA,0xA8, + 0x30,0xC5,0x68,0x72,0x0B,0xAD,0xD7,0x5C,0xF0,0xC4,0xC9,0x7A,0x00,0x00,0x02,0x35, + 0x66,0x72,0x46,0x72,0xD7,0x5B,0xDD,0xAE,0x67,0x7A,0x46,0x6A,0x55,0xFF,0xAA,0xAB, + 0x66,0x72,0x26,0x6A,0xFE,0xEB,0xAA,0x8A,0x66,0x72,0x26,0x72,0x3D,0xFF,0xFB,0xAA, + 0xA7,0x7A,0x25,0x6A,0x0A,0xBD,0x5F,0xFF,0xA7,0x82,0x46,0x72,0x08,0x0A,0xB5,0x55, + 0xC7,0x82,0x46,0x72,0x2A,0x88,0x0A,0xAD,0xE8,0x8A,0xE5,0x69,0x6A,0xEA,0x80,0x02, + 0xE8,0x8A,0x84,0x59,0x55,0xFA,0x68,0x78,0x85,0x51,0xA2,0x30,0x20,0xE8,0x7A,0x57, + 0x44,0x49,0xA2,0x28,0xDC,0xBF,0xFF,0xFD,0x64,0x49,0xC2,0x30,0xFA,0xB7,0xB7,0x15, + 0x85,0x59,0x23,0x41,0x3D,0xAF,0x2E,0x25,0x27,0x72,0x44,0x49,0xC0,0xC3,0x6B,0x7B, + 0xA5,0x59,0xE2,0x38,0xAE,0xA5,0x37,0x27,0xA5,0x59,0x03,0x41,0xAF,0xEF,0x78,0x5C, + 0xC8,0x82,0xE3,0x40,0x0B,0x09,0xAD,0xFD,0x67,0x7A,0x44,0x51,0x28,0xA8,0xFF,0xD5, + 0xE9,0x8A,0xE5,0x61,0x8A,0x0B,0xAD,0xFD,0xC9,0x8A,0x27,0x72,0x5F,0x78,0x68,0x8A, + 0x67,0x72,0xA5,0x59,0x02,0x80,0xAA,0x58,0x55,0xEE,0x06,0x62,0x2D,0xF5,0x55,0x55, + 0x34,0xEE,0x47,0x72,0x00,0x0A,0x2D,0xB5,0x35,0xE6,0x93,0xDD,0x20,0x2A,0xE8,0xA9, + 0x14,0xE6,0xD3,0xDD,0x3A,0x20,0xFF,0x56,0x96,0xF6,0xF4,0xE5,0x8A,0xAB,0xFB,0x5D, + 0x55,0xEE,0xD3,0xDD,0x60,0xAA,0xF2,0xF2,0x55,0xE6,0xB3,0xD5,0xAD,0xEA,0xAA,0xBB, + 0x96,0xEE,0x14,0xE6,0x82,0x0B,0x03,0x01,0x76,0xEE,0x92,0xD5,0x78,0xE0,0x00,0x00, + 0x35,0xE6,0x0D,0xA4,0x7A,0xA2,0x08,0x20,0xB2,0xD5,0xC9,0x7A,0xB5,0xA8,0xC0,0x00, + 0x66,0x72,0x27,0x72,0x82,0xA0,0x02,0xA9,0x47,0x7A,0x66,0x72,0xF5,0x5F,0xDF,0x7F, + 0x86,0x7A,0x46,0x72,0xF7,0xEF,0xBB,0xBA,0x86,0x7A,0x46,0x72,0xDF,0xEE,0xBA,0xA2, + 0x86,0x7A,0x46,0x72,0xFF,0xFF,0xEA,0xA8,0x66,0x7A,0x46,0x72,0xBF,0x0A,0x08,0x00, + 0x87,0x7A,0x45,0x7A,0xD7,0xFB,0xAA,0x82,0xAB,0xA3,0x66,0x7A,0xDD,0xD5,0x95,0x35, + 0x09,0x93,0xC2,0x38,0x78,0x78,0x78,0x78,0xC2,0x30,0x81,0x28,0x7C,0xA8,0x08,0x08, + 0xC2,0x30,0xA2,0x28,0xAF,0xEE,0x68,0x18,0x44,0x41,0xA2,0x28,0x2D,0x89,0x8B,0xE2, + 0x64,0x51,0xE2,0x38,0x2D,0x2D,0x81,0x43,0x85,0x51,0xE3,0x38,0x62,0xE8,0x5A,0x55, + 0x44,0x41,0xE3,0x38,0x0F,0x7F,0x63,0xB5,0x65,0x49,0x03,0x41,0xF6,0x6F,0x61,0x27, + 0x85,0x51,0xE3,0x38,0x2F,0x05,0x35,0xAF,0xA5,0x59,0x03,0x41,0xFE,0xD6,0x36,0x2E, + 0x26,0x6A,0x84,0x59,0xAD,0xA2,0x63,0xDE,0x87,0x82,0x64,0x59,0x00,0x3B,0xFD,0xFD, + 0x47,0x72,0x64,0x51,0xF8,0xA8,0x5F,0x5D,0xC5,0x59,0x44,0x49,0x0A,0x88,0x9F,0xB5, + 0xC8,0x7A,0x64,0x49,0x0F,0xBD,0xFF,0x7F,0xD3,0xE5,0x26,0x72,0x0B,0x2D,0xB5,0xF5, + 0xD4,0xDD,0x10,0xC5,0x00,0x80,0xA0,0xA9,0x14,0xE6,0x93,0xD5,0xA2,0x2F,0x09,0xAB, + 0x35,0xEE,0x51,0xCD,0xA0,0x08,0x2E,0x16,0x55,0xEE,0xF4,0xDD,0x7D,0xBE,0x82,0xE8, + 0xB6,0xF6,0x14,0xE6,0x29,0x29,0x89,0x8B,0x96,0xF6,0xF4,0xDD,0x70,0x60,0xC8,0xAA, + 0x35,0xE6,0x92,0xD5,0x5F,0x5D,0x5F,0x5C,0xB3,0xD5,0x51,0xCD,0xA0,0x7E,0x5E,0x7E, + 0x25,0x72,0x64,0x59,0x3D,0xD5,0x55,0x55,0x66,0x72,0x63,0x59,0x00,0x29,0xD5,0x55, + 0x66,0x72,0x63,0x51,0x00,0x00,0x0B,0xD5,0x87,0x7A,0xE5,0x69,0x00,0x08,0x80,0x0D, + 0x87,0x7A,0x66,0x7A,0xEA,0xA2,0xEE,0xBB,0x66,0x82,0x87,0x7A,0xBB,0xFB,0x7F,0x7F, + 0x66,0x8A,0x87,0x7A,0x75,0x5F,0xDD,0xDD,0xEC,0xAB,0x87,0x82,0x25,0x05,0x09,0x02, + 0x69,0x9B,0x43,0x49,0x7C,0x7E,0x5C,0x5C,0x02,0x39,0xA2,0x28,0x7C,0x5C,0xDE,0xF8, + 0x23,0x41,0xA2,0x28,0xD5,0xD5,0xDD,0x2F,0x24,0x41,0xC2,0x30,0xFA,0x25,0x2D,0x02, + 0x23,0x41,0xE3,0x38,0xCB,0xF9,0x82,0xE0,0x44,0x49,0xC2,0x30,0x6D,0xFB,0xF0,0xE0, + 0x64,0x49,0xA2,0x30,0xB5,0xBD,0x2D,0xBA,0x44,0x49,0xE3,0x38,0x2A,0xF0,0xFF,0x9E, + 0x65,0x51,0x03,0x39,0x83,0xEB,0xF5,0xB7,0xA5,0x59,0x03,0x41,0x2B,0x9F,0x57,0xDF, + 0xA5,0x59,0x03,0x41,0x20,0xBE,0xD7,0xD7,0x06,0x6A,0x23,0x49,0x0A,0xAA,0xFB,0x5F, + 0xC6,0x59,0x23,0x41,0xB6,0xF8,0xDB,0x55,0xA5,0x51,0x44,0x49,0x8F,0x25,0xF5,0x55, + 0xC5,0x59,0x23,0x41,0x2A,0xBE,0xD7,0xF5,0x09,0x8B,0xC5,0x59,0x0F,0xAD,0xFD,0xFD, + 0xB3,0xDD,0xC8,0x82,0x0B,0x0D,0x35,0x15,0x35,0xE6,0xB3,0xD5,0x8B,0x00,0x82,0x60, + 0xF3,0xDD,0xF0,0xC4,0x34,0xBE,0xB7,0xFF,0x96,0xEE,0x15,0xE6,0x5E,0xBE,0x2B,0x09, + 0x96,0xEE,0x55,0xEE,0x63,0x7A,0xFC,0xF8,0x75,0xEE,0x55,0xE6,0xAF,0xFE,0x9F,0xF7, + 0x55,0xEE,0x92,0xD5,0x78,0x80,0x00,0x00,0x76,0xEE,0x51,0xCD,0x5F,0x7F,0xEA,0x00, + 0x84,0x59,0x43,0x59,0xE7,0xC5,0xAD,0xAB,0x84,0x61,0x43,0x51,0x6E,0x72,0xD6,0x5F, + 0x63,0x59,0x23,0x51,0x5F,0xF7,0xFE,0x3F,0xE5,0x69,0x43,0x59,0x25,0xFD,0xFF,0xBF, + 0x87,0x7A,0x43,0x59,0x02,0xBD,0x57,0x5D,0x87,0x7A,0x43,0x59,0x00,0x00,0x2D,0x55, + 0xCB,0xA3,0xE5,0x69,0xFF,0x3F,0x2F,0x0D,0xCB,0xAB,0x6A,0x9B,0x22,0xA8,0xBE,0xF7, + 0x8A,0x9B,0x43,0x49,0x5C,0x78,0x58,0xF8,0x23,0x41,0xC2,0x30,0x5C,0x56,0xB7,0xFE, + 0x64,0x49,0xC2,0x30,0xAD,0x2D,0x3F,0xAA,0x64,0x49,0x03,0x41,0xFE,0xEA,0x7C,0xF6, + 0x85,0x51,0x03,0x39,0xD5,0x27,0x05,0xAF,0xA5,0x59,0x24,0x41,0xFD,0xAD,0xAB,0xB2, + 0x06,0x62,0xE3,0x38,0xDF,0x7B,0x7A,0xF0,0x24,0x41,0xC2,0x30,0x28,0xAE,0xED,0x29, + 0xA5,0x51,0x03,0x41,0x35,0x15,0xF5,0xD5,0x64,0x51,0x03,0x41,0x94,0xDE,0xFE,0xAA, + 0x85,0x49,0x23,0x49,0xD7,0xFB,0xE2,0xEE,0x64,0x51,0xE3,0x38,0xA8,0xB8,0xFE,0xDE, + 0x64,0x49,0xE3,0x38,0xDF,0xDF,0x9F,0xA2,0x64,0x49,0xE3,0x38,0xE8,0x7B,0xF8,0x2B, + 0x85,0x51,0x23,0x41,0x25,0x25,0xF7,0xF7,0xA8,0x7A,0x44,0x49,0x8B,0x2F,0xAF,0xBD, + 0x8A,0x9B,0x26,0x72,0x2F,0xBF,0xF5,0xD5,0xD3,0xDD,0x29,0x8B,0x00,0x83,0x81,0x8D, + 0x51,0xD5,0xD0,0xC4,0x2B,0xAF,0x2D,0xAD,0x96,0xEE,0xAF,0xBC,0x02,0x03,0xFB,0x7F, + 0x76,0xEE,0x8E,0xB4,0x00,0x00,0xFB,0x55,0x75,0xEE,0x4E,0xAC,0x00,0x80,0x7F,0x55, + 0x76,0xEE,0x8F,0xB4,0x00,0xFE,0xD5,0xBD,0x15,0xDE,0xB0,0xB4,0x80,0xED,0xFE,0x7E, + 0x64,0x59,0x23,0x51,0xC0,0x7A,0xFE,0xDF,0x63,0x59,0x23,0x51,0xAB,0xFF,0xB9,0xAA, + 0x84,0x61,0x43,0x59,0xF5,0xFD,0xBE,0xFB,0x84,0x61,0x43,0x59,0xC2,0x6A,0x5E,0x55, + 0x63,0x59,0x03,0x49,0xA2,0xEC,0x73,0xDE,0x25,0x72,0x23,0x51,0x55,0x55,0x55,0x95, + 0x8B,0x9B,0x02,0x51,0x09,0x03,0x02,0x00,0x8B,0x9B,0x29,0x93,0x00,0x0A,0xB6,0xB7, + 0x49,0x93,0xA4,0x59,0x78,0x60,0xE8,0xE8,0xE5,0x69,0xE3,0x40,0x5F,0x5F,0xF7,0xDC, + 0x85,0x51,0xE3,0x38,0xFA,0xF2,0x7B,0x5E,0x44,0x49,0xE3,0x38,0x8C,0xEA,0x62,0xE3, + 0x23,0x41,0xE3,0x38,0xE0,0xEA,0xAB,0xAD,0xC6,0x61,0x23,0x49,0xF1,0x71,0xE3,0xBD, + 0x85,0x59,0xE3,0x38,0x42,0x4A,0xEA,0x60,0x24,0x41,0xA2,0x30,0x2B,0xAD,0xFD,0xAD, + 0x85,0x59,0x23,0x41,0xFF,0xAD,0xAF,0x2A,0xA5,0x59,0xE3,0x38,0xE2,0xE8,0xFA,0x7F, + 0x44,0x49,0xE2,0x38,0x2C,0xBA,0xDF,0x2D,0x44,0x41,0xE3,0x38,0xFA,0xFE,0xEB,0xF0, + 0x85,0x51,0x03,0x39,0x8B,0xAD,0x7D,0x75,0x64,0x49,0xE3,0x38,0x2F,0xBE,0xBD,0xFD, + 0x85,0x51,0x23,0x41,0xEA,0x2F,0xE5,0x35,0xE6,0x61,0x44,0x49,0x2D,0xF7,0xAF,0x3D, + 0xA8,0x7A,0xE5,0x61,0x2A,0x3D,0xF5,0x9F,0x11,0xC5,0xA8,0x7A,0x0D,0x0D,0x25,0x15, + 0x31,0xCD,0x8E,0xB4,0x2B,0x2F,0xFF,0xD7,0x11,0xC5,0x2E,0xAC,0xC0,0x70,0x7C,0x0B, + 0x93,0xCD,0x2D,0xAC,0x55,0xAD,0x0B,0x82,0xB4,0xCD,0x6F,0xAC,0x2D,0xA0,0xE0,0xE2, + 0x94,0xCD,0x2E,0xA4,0x88,0x8A,0xEB,0xDB,0xF1,0xBC,0x8F,0xAC,0x60,0xF2,0x9E,0xBF, + 0x63,0x59,0x03,0x49,0xBF,0xAE,0xA2,0xA0,0x84,0x59,0x43,0x59,0xFD,0x7D,0x2D,0xCF, + 0x84,0x61,0x43,0x59,0x7E,0x52,0x7A,0x5F,0x64,0x59,0x23,0x51,0x9B,0xEB,0x7E,0x5F, + 0x44,0x51,0xE2,0x40,0xE8,0xAA,0xBF,0xFE,0x6B,0x9B,0x03,0x49,0x35,0x25,0x0D,0x09, + 0xED,0xAB,0x4A,0x93,0x5E,0x7E,0x72,0xE8,0x6A,0x9B,0x29,0x93,0x3D,0xF7,0xB7,0x80, + 0x09,0x8B,0x47,0x72,0xFC,0x78,0x5C,0x5C,0x67,0x72,0x24,0x49,0x58,0x68,0xA2,0xA8, + 0xC5,0x61,0xC2,0x38,0x76,0x5F,0x5F,0x78,0x64,0x49,0xE3,0x38,0xCB,0x49,0xFD,0xFD, + 0x23,0x41,0xE3,0x38,0xAF,0x9E,0xBB,0x25,0x85,0x59,0x03,0x41,0x2F,0x29,0x95,0xBF, + 0x85,0x59,0xC3,0x38,0x40,0x70,0x70,0x78,0x04,0x41,0xA2,0x30,0x0B,0xF5,0xBB,0xA1, + 0xA6,0x59,0xE3,0x38,0x02,0x03,0x09,0xAF,0x85,0x51,0xE3,0x38,0x7E,0x5E,0xFC,0x5E, + 0x64,0x49,0xE3,0x38,0x2F,0x25,0xA5,0xB5,0x44,0x41,0xE2,0x38,0x78,0x6A,0x82,0xEA, + 0x24,0x41,0xE2,0x38,0xAE,0x2D,0xBF,0x55,0x23,0x39,0xE2,0x30,0xFB,0xAE,0x3F,0xBD, + 0xA5,0x59,0x23,0x41,0xFD,0xDD,0xB9,0xA3,0xE6,0x61,0x44,0x49,0x95,0xD5,0xB7,0x0B, + 0x47,0x72,0x84,0x59,0x2B,0xA5,0xFF,0x3F,0x4E,0xB4,0x26,0x72,0x3F,0x3F,0xBD,0xF5, + 0x55,0xEE,0xD0,0xBC,0x57,0x2A,0x02,0x03,0x35,0xE6,0xD0,0xBC,0xBD,0xC8,0xC0,0xE0, + 0x93,0xCD,0x52,0xC5,0x43,0x62,0xC2,0xBC,0x93,0xCD,0xB0,0xB4,0x0E,0xBE,0xFA,0x7A, + 0x52,0xC5,0x4C,0x8B,0xB8,0xAC,0xAF,0xAD,0xD0,0xB4,0x90,0xAC,0xBE,0xF6,0xEA,0x56, + 0x63,0x59,0x43,0x51,0xAD,0x0D,0x29,0x3B,0x84,0x61,0x43,0x51,0xAA,0xE2,0xD6,0x55, + 0x63,0x59,0x23,0x51,0xAA,0xEF,0x5A,0x5F,0x43,0x51,0x04,0x49,0xB8,0xEA,0xEA,0xFE, + 0x44,0x59,0xE2,0x48,0x7F,0x3E,0x0B,0x02,0xAB,0xA3,0xA5,0x61,0x09,0x01,0x03,0x03, + 0xCC,0xAB,0x49,0x93,0xF7,0x7E,0xF8,0x60,0x6A,0x9B,0xC8,0x82,0x88,0xFB,0x7A,0xDF, + 0xC8,0x82,0x26,0x72,0x5C,0x7C,0xFC,0x7C,0x46,0x72,0x06,0x6A,0x9E,0xA6,0x2E,0x28, + 0xA8,0x82,0x03,0x41,0x5A,0x78,0x60,0xC0,0x24,0x41,0xC2,0x30,0x8B,0xAB,0xFD,0x57, + 0x44,0x49,0xC2,0x30,0x3F,0xBF,0xBD,0x6D,0x65,0x51,0xE3,0x38,0x2E,0xBE,0x7F,0xFD, + 0xA6,0x59,0xE3,0x38,0x58,0x7A,0x7F,0xFF,0x03,0x39,0xA2,0x30,0x0B,0x2B,0x97,0xB6, + 0x65,0x49,0x03,0x41,0xCD,0xE9,0xE9,0x81,0x24,0x41,0xE3,0x38,0xFA,0xB6,0xFC,0x54, + 0x44,0x41,0xE3,0x30,0x3F,0x3F,0xF5,0x55,0x44,0x41,0xC2,0x30,0x7A,0xD8,0xFF,0xF7, + 0x23,0x39,0xE2,0x30,0xFD,0xAE,0xAB,0xF7,0x23,0x39,0xC3,0x38,0xAB,0x3E,0x9A,0xBA, + 0x64,0x49,0x03,0x39,0x29,0x75,0x57,0x5F,0x47,0x6A,0x03,0x41,0xAF,0x2D,0xBD,0xFD, + 0x47,0x72,0xA5,0x59,0x33,0xEF,0xB0,0x63,0x09,0x83,0x26,0x6A,0x25,0xB5,0xEF,0xED, + 0x15,0xE6,0x8B,0x93,0x03,0x01,0x09,0xA9,0x14,0xE6,0x32,0xC5,0xF8,0xD8,0xDA,0xDE, + 0x93,0xCD,0xF1,0xBC,0xA0,0xE8,0xBC,0xDA,0x52,0xC5,0x6C,0x8B,0xA0,0xE8,0xE8,0x6A, + 0x90,0xAC,0xEE,0x9B,0x09,0x89,0xED,0xB9,0x8F,0xAC,0x4F,0xA4,0x3E,0x89,0x59,0x1E, + 0x63,0x59,0x23,0x51,0xAA,0xC0,0xFE,0xDF,0x43,0x51,0x03,0x49,0x02,0x2B,0xCA,0xFA, + 0x43,0x51,0x02,0x49,0xBE,0xAE,0xED,0xBB,0x44,0x59,0x03,0x51,0x7F,0xBB,0x3F,0x0F, + 0xC6,0x69,0x03,0x51,0xFD,0xBF,0xBF,0x3F,0xEC,0xAB,0xE9,0x8A,0x29,0x09,0x2B,0x8A, + 0x2D,0xB4,0x8B,0x9B,0x78,0xFA,0xAA,0x55,0xAB,0xA3,0x87,0x7A,0xFE,0xFA,0xE0,0x7A, + 0xA7,0x82,0x25,0x6A,0x7C,0xDC,0x7E,0x5F,0xA8,0x82,0x25,0x6A,0xBD,0x27,0x0D,0x03, + 0xA8,0x82,0xE5,0x69,0xC0,0x80,0xE8,0x56,0xE5,0x61,0xA2,0x30,0x5F,0x54,0x5C,0x58, + 0xE3,0x38,0xA2,0x30,0x8B,0xF5,0xD7,0xAA,0x24,0x49,0xC2,0x30,0x2F,0xAD,0xFD,0xBB, + 0x65,0x49,0x03,0x39,0x7C,0x5F,0x5B,0xFB,0x03,0x41,0xA2,0x28,0xBE,0xB6,0x5E,0xD8, + 0x65,0x49,0xC2,0x30,0x03,0xAB,0xED,0xED,0x23,0x41,0xA2,0x28,0xF8,0xBE,0x77,0xF7, + 0x03,0x39,0xC3,0x30,0xEF,0xAB,0x9F,0x35,0x03,0x39,0xC2,0x30,0xBF,0x7D,0xFF,0xFE, + 0x23,0x41,0xE3,0x38,0x55,0x55,0xFD,0xCB,0x23,0x41,0xC2,0x30,0xF5,0xBE,0xAE,0x20, + 0x44,0x49,0x03,0x39,0xEF,0xE3,0x7A,0x78,0x44,0x49,0x03,0x41,0x27,0xD5,0xD7,0x5A, + 0xC5,0x61,0x23,0x41,0x0E,0xBB,0xAF,0xAD,0xA8,0x7A,0xC5,0x61,0x09,0x09,0x0B,0xAB, + 0x52,0xCD,0xA8,0x7A,0x09,0x09,0x0D,0x2D,0x73,0xCD,0xD0,0xB4,0x8C,0x0C,0x0C,0xC7, + 0x32,0xC5,0x2E,0xA4,0x80,0xEA,0xF8,0x78,0xF1,0xBC,0xAD,0x93,0x5A,0xBA,0xA8,0xFF, + 0x31,0xBD,0xED,0x9B,0xAF,0x02,0xBF,0xD5,0x32,0xC5,0x8F,0xAC,0x55,0x5F,0xAA,0x25, + 0x43,0x51,0x02,0x49,0xB8,0xE0,0xFA,0x6A,0x43,0x51,0x02,0x49,0xD8,0x96,0xB5,0x2D, + 0x43,0x51,0x23,0x51,0xDD,0xFA,0x3C,0x25,0x44,0x59,0x23,0x51,0xAA,0xA8,0x80,0x4E, + 0x29,0x93,0x23,0x51,0x95,0x95,0x15,0x35,0xAB,0xA3,0x87,0x7A,0x82,0xE0,0x7A,0x5E, + 0x0A,0x93,0x67,0x72,0xA0,0x7E,0x55,0x55,0xC8,0x82,0x46,0x72,0x78,0x7F,0x7F,0x77, + 0x87,0x7A,0x26,0x6A,0xFF,0xAF,0x3F,0x2B,0xC8,0x82,0xC5,0x61,0xA2,0xF8,0x7E,0x5F, + 0x26,0x6A,0xC4,0x61,0xDE,0xEA,0x2F,0x3F,0x06,0x6A,0x82,0x30,0x78,0xE0,0xC0,0x80, + 0x03,0x39,0x81,0x28,0x0B,0x3D,0x9F,0xBF,0x44,0x49,0xA2,0x30,0xAF,0x37,0xAF,0x2F, + 0x65,0x49,0xC3,0x30,0xA8,0xAA,0xEB,0x77,0x24,0x41,0x82,0x20,0xE8,0xE2,0xF2,0x7A, + 0x24,0x41,0x82,0x20,0xA3,0xBF,0xF5,0xED,0xE3,0x30,0xA2,0x28,0x80,0xF8,0xED,0xB5, + 0x24,0x41,0xA2,0x30,0x0D,0xAF,0xFF,0xBF,0x04,0x39,0xC2,0x30,0xB4,0xFF,0xFF,0xFF, + 0x85,0x49,0x03,0x39,0xFF,0xE9,0xE3,0x7D,0x44,0x49,0xE3,0x38,0x80,0xE0,0x5B,0xFD, + 0x23,0x41,0xE2,0x38,0x82,0x57,0xD5,0x55,0x43,0x41,0xC2,0x30,0xAA,0xA9,0xAF,0x8F, + 0x85,0x51,0x02,0x39,0x2E,0x3F,0x3D,0x29,0x67,0x72,0xC5,0x59,0xBD,0xCD,0x89,0xDD, + 0x31,0xC5,0x06,0x62,0x0D,0x0D,0x05,0x25,0x53,0xCD,0x8C,0x8B,0x02,0xEA,0xFF,0x5E, + 0x90,0xAC,0xAD,0x93,0x78,0x5F,0x55,0x55,0xEE,0x9B,0x4B,0x83,0x22,0x2B,0xEB,0x7E, + 0x0E,0x9C,0x2B,0x7B,0x30,0xB8,0xD7,0x55,0xF1,0xBC,0x4B,0x83,0x0A,0x0A,0x2B,0xB5, + 0x23,0x51,0x02,0x41,0xF2,0xEC,0x9E,0xAC,0x23,0x49,0x02,0x49,0x80,0xCB,0xEA,0x0C, + 0x43,0x51,0x23,0x51,0xA1,0xE3,0x8F,0xA7,0x44,0x51,0x02,0x49,0xB8,0x68,0xFA,0x5E, + 0x09,0x8B,0x03,0x49,0x35,0x35,0x25,0x25,0xE9,0x8A,0x47,0x72,0xF8,0xF8,0xFA,0xFE, + 0x87,0x7A,0x67,0x72,0xFF,0xAA,0x80,0x00,0x87,0x7A,0x46,0x72,0x7E,0x7E,0xD8,0x5A, + 0x87,0x7A,0x26,0x6A,0xAB,0xCB,0xCA,0x7A,0x26,0x72,0xA4,0x61,0x7C,0xDE,0xB6,0x2F, + 0x87,0x7A,0xE5,0x61,0xD5,0xD5,0x8B,0xAA,0x87,0x7A,0x23,0x41,0xEA,0x60,0xC0,0xEA, + 0x23,0x41,0x81,0x28,0xB7,0xA5,0x0D,0x0B,0x44,0x49,0xE2,0x38,0xEF,0x43,0x4F,0x57, + 0xC2,0x30,0x82,0x20,0x20,0xFE,0x7A,0x5F,0xE3,0x30,0x61,0x20,0x78,0xDE,0xF7,0xFD, + 0xC3,0x28,0x82,0x20,0xC9,0xBD,0xD5,0xB7,0xE3,0x30,0xA2,0x28,0xA7,0xEB,0xFF,0xBF, + 0xE3,0x30,0xA2,0x28,0x0F,0xEB,0xA8,0x9E,0x03,0x39,0xC3,0x30,0xDD,0xB5,0xF5,0x95, + 0x03,0x39,0xC2,0x30,0xA2,0x8A,0x0A,0xA7,0x03,0x41,0xE2,0x30,0xA2,0xCE,0xBF,0x2F, + 0x65,0x49,0xE2,0x38,0xD7,0xFD,0xAD,0x0F,0x43,0x49,0xE3,0x30,0xB6,0xDF,0x5B,0xE0, + 0x84,0x49,0xE2,0x38,0x2D,0x97,0xBD,0xFF,0x06,0x62,0x63,0x49,0x2D,0x3F,0xD5,0xB5, + 0x6F,0xAC,0xE6,0x59,0x25,0x35,0x35,0x35,0xD0,0xB4,0xCA,0x72,0xF8,0xF8,0x5A,0x60, + 0xAD,0x8B,0x07,0x5A,0x00,0x80,0xFA,0x57,0x4B,0x7B,0x68,0x5A,0x20,0xEB,0xFD,0xF5, + 0xED,0x93,0xEA,0x72,0xD5,0xF5,0xB5,0x0D,0x0E,0x9C,0x4B,0x83,0x3D,0xFD,0xCF,0x08, + 0x23,0x49,0x03,0x49,0x1B,0xA3,0xE8,0x97,0x43,0x51,0x23,0x51,0x75,0xA5,0x6B,0xF8, + 0x43,0x51,0x03,0x49,0xA2,0x7E,0xDE,0x7F,0x64,0x51,0xE2,0x48,0xFF,0xFF,0xFF,0x1F, + 0xE8,0x82,0x02,0x49,0x05,0x09,0x03,0x00,0xC7,0x82,0x87,0x7A,0x57,0x5F,0x77,0xF8, + 0xA7,0x7A,0x66,0x72,0xEB,0xBA,0x7A,0x1C,0xAA,0x9B,0x67,0x72,0x55,0xD5,0x2D,0xC2, + 0x49,0x93,0xE5,0x61,0xAF,0xE0,0x5C,0x55,0x67,0x7A,0x23,0x49,0xA8,0xAA,0x5A,0xD7, + 0x46,0x72,0x43,0x41,0x02,0x2A,0x55,0x55,0x47,0x72,0x03,0x41,0xC0,0xE8,0xF5,0xD5, + 0x23,0x41,0x81,0x28,0xAA,0xA8,0xE0,0x7A,0x23,0x39,0x81,0x20,0x68,0x7F,0x57,0x5D, + 0xC3,0x28,0x61,0x18,0xDF,0xBF,0xB5,0x29,0x03,0x39,0x82,0x20,0xFD,0xAF,0xA3,0x02, + 0xE2,0x30,0x82,0x20,0xD7,0xFA,0x2E,0xAC,0xE2,0x30,0xA2,0x28,0xD5,0xDF,0x5C,0x7A, + 0xE3,0x30,0x81,0x28,0x3E,0x2B,0xBF,0xED,0x04,0x39,0xA2,0x28,0x8B,0x22,0x3F,0xFD, + 0x24,0x39,0xC3,0x30,0x3D,0xEA,0xAE,0xD5,0x03,0x39,0xE2,0x30,0xA0,0x54,0x38,0x38, + 0x44,0x41,0xE2,0x38,0x0F,0xBD,0xB7,0x17,0x64,0x49,0x03,0x41,0xE0,0xB0,0xB2,0x58, + 0x44,0x41,0xE2,0x38,0x3F,0xCA,0x2A,0xF5,0xA5,0x51,0xE2,0x38,0x2A,0xAF,0x2A,0xBD, + 0x0E,0xA4,0xC5,0x59,0x35,0x15,0x95,0x95,0x52,0xC5,0x6F,0xAC,0x70,0xC2,0x29,0xB5, + 0x52,0xC5,0xEA,0x72,0x5F,0xAA,0xA0,0x80,0x6F,0xA4,0x89,0x62,0xD5,0x00,0x00,0x00, + 0x6F,0xA4,0x6B,0x83,0x2D,0x2A,0x28,0x80,0x6F,0xAC,0xCD,0x93,0xB6,0x3E,0x3A,0xAA, + 0x64,0x59,0xE2,0x40,0x3F,0xA9,0x0A,0x02,0x43,0x51,0x02,0x49,0x88,0xA8,0x68,0xF8, + 0x22,0x49,0x03,0x49,0xFE,0x5A,0xF8,0x7F,0xCB,0xA3,0x03,0x49,0x95,0x35,0x35,0x25, + 0x6A,0x9B,0xC7,0x82,0x5F,0x78,0x78,0xF8,0x8A,0x9B,0x86,0x7A,0x77,0x57,0x9F,0x2F, + 0xCB,0xA3,0x66,0x7A,0x35,0x0B,0xE2,0x58,0x8A,0x9B,0xA4,0x59,0x70,0x7E,0x5F,0x5F, + 0xE5,0x61,0x43,0x49,0x0A,0x82,0x62,0x5C,0x84,0x51,0x24,0x41,0x78,0xFF,0xFB,0xBF, + 0x06,0x62,0x03,0x41,0x5D,0xFD,0xA2,0x78,0xA4,0x51,0xC2,0x38,0xEF,0xFA,0x70,0x7F, + 0xE3,0x38,0x61,0x18,0xC8,0xEA,0xFE,0x6E,0xC2,0x30,0x61,0x18,0xDF,0x5F,0xD7,0x25, + 0xC2,0x28,0x81,0x20,0x3D,0xFA,0xB8,0xA2,0xE3,0x30,0xA2,0x28,0xA0,0xE7,0x0B,0x82, + 0xE2,0x30,0xA2,0x28,0xF2,0xC2,0x39,0x3F,0xE3,0x30,0xA2,0x28,0xD5,0xFA,0xF0,0xB8, + 0xC2,0x30,0xA2,0x28,0xFD,0xFA,0x96,0xA4,0xE2,0x30,0xA2,0x28,0xAF,0xB5,0xFF,0xFF, + 0x03,0x31,0xC2,0x30,0x35,0xFF,0xE7,0xB5,0x23,0x39,0xC2,0x30,0xB0,0xB2,0xF9,0xDD, + 0x44,0x41,0xC2,0x30,0x9F,0x3F,0xAF,0xBF,0x85,0x51,0xE3,0x30,0x78,0x78,0x5F,0xD5, + 0x24,0x39,0xC3,0x28,0xA2,0xEB,0xEB,0xBE,0xA5,0x51,0x03,0x39,0xBD,0x0D,0xA5,0xF5, + 0x88,0x6A,0x64,0x49,0x35,0x3F,0x37,0x3D,0xD0,0xB4,0xAD,0x93,0x2B,0xBF,0xF5,0x55, + 0x31,0xBD,0xED,0x9B,0x80,0xAB,0xAF,0xD5,0xF0,0xB4,0x4F,0xA4,0xDF,0xFE,0xF8,0xAA, + 0xB0,0xAC,0x4E,0xA4,0xFF,0xFF,0x5F,0xE2,0x6F,0xAC,0x0E,0x9C,0xA8,0xA0,0xFA,0x7A, + 0x64,0x51,0x23,0x49,0x0B,0x8B,0xEF,0xDD,0x43,0x51,0x02,0x49,0xFC,0x5E,0x57,0x57, + 0x23,0x49,0xE2,0x40,0xEA,0xBE,0xBB,0xA7,0x6A,0x93,0x23,0x49,0x05,0x0D,0x0D,0x09, + 0x6A,0x9B,0x08,0x8B,0x5A,0xFE,0xAA,0x02,0xCB,0xA3,0x66,0x72,0x02,0xC2,0x72,0x5E, + 0x29,0x93,0x05,0x62,0xFC,0xDF,0xFF,0x7F,0x46,0x72,0x43,0x49,0xF8,0x7C,0x57,0x55, + 0x84,0x51,0x44,0x49,0xFE,0xB3,0x98,0xE8,0x64,0x51,0x03,0x39,0x3A,0xFA,0x7E,0x7A, + 0xC5,0x61,0xE2,0x40,0x60,0xE0,0xEB,0xE5,0x03,0x41,0xC2,0x30,0xE8,0x7C,0xFE,0x7E, + 0xE2,0x30,0x61,0x18,0x6A,0x58,0x7A,0x57,0x24,0x39,0x61,0x18,0xBD,0xAD,0x0B,0xFF, + 0x23,0x39,0xA2,0x28,0xFF,0x82,0xA8,0xB5,0x03,0x39,0xA2,0x28,0xDF,0xFF,0xAA,0xB8, + 0x03,0x39,0xA2,0x28,0xAB,0x8A,0xA3,0xEF,0x03,0x31,0x82,0x20,0x88,0xA8,0xBA,0xD7, + 0xE3,0x30,0xA2,0x28,0x56,0x7E,0x80,0x82,0xE3,0x30,0x81,0x28,0xFA,0x5F,0xFE,0x0A, + 0x03,0x39,0xA2,0x28,0xFD,0xBD,0xBB,0xF8,0xE2,0x30,0xA1,0x28,0x8B,0xE2,0xBA,0xFF, + 0x03,0x31,0xC2,0x28,0xB9,0x0D,0x8A,0xEB,0x03,0x31,0xC3,0x30,0xFB,0xF8,0xD6,0x7D, + 0x03,0x31,0xC2,0x30,0x1F,0xAF,0x27,0x2E,0x64,0x49,0xC2,0x28,0x2F,0x0F,0xAF,0x25, + 0x4B,0x8B,0x64,0x49,0xBD,0x35,0x25,0x2D,0xEE,0x9B,0x6B,0x8B,0xFA,0xFA,0x60,0x6A, + 0xED,0x9B,0x2A,0x83,0x02,0x2B,0x2F,0xB7,0x6F,0xA4,0xCD,0x93,0x02,0xF7,0xFF,0x55, + 0x6F,0xAC,0xCD,0x93,0xC8,0x7F,0x55,0x55,0x2E,0x9C,0xAC,0x93,0x2A,0xAF,0xB5,0xD5, + 0x23,0x49,0x02,0x41,0xE0,0xEE,0xEF,0xDF,0x23,0x49,0xE2,0x40,0xFA,0x76,0xFF,0xAE, + 0x23,0x49,0xE2,0x40,0xFF,0xAD,0x8F,0xAA,0x49,0x93,0x03,0x49,0x01,0x09,0xF5,0xD5, + 0x29,0x93,0x84,0x59,0x00,0xA8,0xEA,0x7F,0xC8,0x82,0x03,0x41,0xA8,0xAA,0xFF,0xD5, + 0x67,0x72,0x43,0x51,0x60,0x7E,0x57,0xDF,0x85,0x51,0x22,0x41,0x37,0xB7,0x03,0xA2, + 0x84,0x49,0x44,0x49,0x62,0x7A,0x7E,0xD7,0xE6,0x61,0x23,0x41,0x57,0x55,0xBD,0x82, + 0xC4,0x59,0x03,0x39,0x55,0xD5,0x7F,0x5C,0x23,0x41,0xA2,0x28,0x68,0x6E,0x6A,0xEC, + 0x03,0x31,0x61,0x20,0xD5,0xF7,0xEB,0xAB,0x81,0x28,0xC2,0x20,0xE8,0xAA,0x8F,0xAB, + 0xE3,0x30,0x81,0x28,0x97,0xD5,0xDF,0x70,0x23,0x41,0xA1,0x28,0x7E,0xFB,0xEB,0x83, + 0xE3,0x30,0xA2,0x28,0x29,0xFB,0xDF,0x37,0x03,0x39,0x81,0x28,0xDE,0xFF,0xF7,0xE0, + 0x03,0x31,0xA2,0x28,0xEF,0xB9,0xA9,0x89,0x03,0x39,0xC2,0x30,0xFD,0x69,0xEE,0x75, + 0x03,0x39,0xC2,0x30,0xF3,0xEB,0x0D,0x8D,0xE3,0x30,0xC2,0x28,0x71,0x4B,0xEE,0x54, + 0xE3,0x30,0xA1,0x28,0x02,0x87,0x8F,0xBF,0x03,0x31,0xC2,0x28,0xFB,0xB7,0xBA,0xEB, + 0x23,0x39,0xE2,0x30,0xBD,0xDF,0x57,0xDD,0x84,0x51,0xE2,0x30,0x37,0x2D,0x3B,0x8B, + 0x2D,0xA4,0x84,0x51,0xA5,0xED,0x09,0x0B,0x8F,0xB4,0xA8,0x72,0xFF,0x55,0xEA,0x00, + 0xCD,0x9B,0x67,0x62,0xBF,0x55,0xFF,0xF8,0x4B,0x83,0x47,0x62,0xBC,0x57,0xFF,0xFF, + 0xAC,0x8B,0x67,0x62,0x00,0x2D,0xB5,0x57,0xAD,0x93,0x09,0x7B,0x00,0x22,0xAA,0xA9, + 0x02,0x41,0xE3,0x40,0x30,0xAE,0x00,0xB0,0x23,0x49,0xE2,0x40,0xAF,0xAA,0x22,0xE6, + 0x23,0x41,0xE2,0x40,0x0A,0xE0,0xE0,0x9C,0x44,0x49,0xE2,0x40,0x36,0xBD,0xFF,0xF5, + 0xE5,0x61,0x02,0x41,0xE0,0x5F,0x55,0x55,0x06,0x62,0xE2,0x40,0xB5,0x35,0x35,0x35, + 0xE5,0x61,0x84,0x51,0x5E,0xFE,0x78,0xE0,0xA5,0x51,0x23,0x41,0xE8,0xE8,0xEF,0xD7, + 0x26,0x6A,0x44,0x49,0x35,0x05,0x25,0xD5,0xE4,0x61,0x82,0x30,0xA0,0xF8,0x5C,0x56, + 0x84,0x51,0xC2,0x30,0x78,0xDA,0xFF,0xF5,0x03,0x39,0x81,0x20,0x7A,0xFA,0xF8,0x5F, + 0xC2,0x28,0x82,0x28,0x81,0x83,0xA2,0x8B,0x64,0x49,0xA2,0x28,0xAD,0x89,0x8B,0x7B, + 0x24,0x41,0x81,0x28,0x88,0xA8,0xAA,0xFD,0x44,0x49,0xE2,0x38,0x0D,0x2F,0xD7,0xDD, + 0x44,0x41,0xA1,0x28,0xDE,0x5C,0x7A,0xFA,0x04,0x39,0x81,0x28,0x00,0xA3,0xFF,0xD7, + 0xE3,0x30,0xA2,0x28,0xC0,0xF5,0xF7,0xAD,0xE3,0x30,0xA2,0x28,0x0F,0xAF,0x57,0x78, + 0x03,0x31,0xA2,0x28,0x2F,0xFF,0xAD,0xAF,0x03,0x31,0xC2,0x28,0x5F,0x7F,0xD5,0xE3, + 0x23,0x39,0xC2,0x28,0xD5,0xFD,0xAF,0xBF,0x03,0x39,0xC2,0x30,0x8B,0xBF,0xA6,0xAA, + 0x03,0x39,0xC2,0x30,0xFF,0xCA,0xAB,0x2A,0x4A,0x8B,0x03,0x39,0xF5,0xB5,0xB5,0x35, + 0x31,0xC5,0x4A,0x83,0xA9,0x82,0x02,0x00,0x10,0xC5,0x6E,0xAC,0xBF,0xF7,0x7C,0xA0, + 0x6E,0xAC,0x0A,0x83,0x5C,0x70,0x80,0x80,0x6B,0x93,0x67,0x6A,0xD5,0xF7,0xDE,0xE8, + 0x4A,0x83,0x47,0x62,0x7E,0xEA,0xAA,0x02,0x4B,0x83,0xA5,0x49,0x0F,0xDF,0x7E,0xF8, + 0x23,0x49,0xE3,0x40,0xBF,0xAB,0xAB,0xBE,0x23,0x49,0x03,0x41,0xF5,0xBF,0x4F,0x77, + 0x03,0x41,0xC2,0x38,0x28,0x2C,0xAE,0xFE,0x03,0x41,0xE2,0x38,0xA2,0xAF,0x79,0x65, + 0x02,0x41,0xE2,0x38,0x32,0x2B,0xFD,0xAF,0x26,0x6A,0xE2,0x40,0x35,0x35,0x35,0x15, + 0x26,0x6A,0x23,0x41,0xE8,0x68,0x68,0x68,0x44,0x41,0x03,0x39,0xA2,0x35,0x7D,0x5D, + 0x44,0x41,0xE2,0x30,0xBA,0x68,0x4A,0xBF,0xA4,0x51,0xA2,0x28,0x70,0x7B,0x57,0x7F, + 0xC2,0x28,0x81,0x20,0x83,0xC2,0x60,0x0A,0xE3,0x28,0x61,0x20,0xD7,0xF5,0xAB,0x22, + 0xE3,0x30,0xA2,0x28,0xFF,0xF9,0xAB,0x8A,0x03,0x31,0xA2,0x28,0x73,0x57,0x5F,0xFE, + 0xC2,0x28,0x81,0x20,0x5B,0x78,0xBE,0xAF,0x03,0x41,0x81,0x20,0x0B,0xAD,0xFF,0x57, + 0x44,0x41,0xA2,0x28,0xFA,0xEA,0x8B,0xE5,0xE2,0x30,0x81,0x28,0xEE,0x3B,0xFD,0xA8, + 0x03,0x39,0x81,0x20,0xF5,0xDE,0xAF,0x2A,0x24,0x41,0xA2,0x28,0x5F,0x5F,0x5F,0xE0, + 0x03,0x39,0x82,0x28,0xFF,0xBD,0xE3,0xEA,0x03,0x31,0x81,0x28,0xA2,0xB3,0xFF,0xDF, + 0xE2,0x30,0xA2,0x28,0x28,0xA8,0x95,0xDF,0x23,0x39,0xC2,0x30,0xAB,0x23,0xF7,0xFF, + 0x65,0x51,0x03,0x39,0xD7,0xBD,0xBD,0x39,0x6C,0x93,0x85,0x51,0x35,0xB5,0xAD,0xAD, + 0xF0,0xBC,0x0A,0x83,0x02,0x2D,0xD5,0x55,0xF0,0xBC,0xE9,0x7A,0x00,0x00,0x03,0xFD, + 0x10,0xC5,0x6E,0xAC,0x7A,0xEA,0xA2,0x8B,0x6E,0xAC,0x6B,0x8B,0x7E,0xAA,0xA8,0x80, + 0x2D,0xA4,0x0A,0x7B,0x75,0xE8,0x00,0x00,0x4E,0xA4,0x68,0x62,0x7F,0xFA,0x80,0x00, + 0x03,0x41,0xE2,0x40,0x34,0x27,0xF8,0xBB,0x23,0x49,0xE2,0x38,0xEA,0x7E,0x7F,0x55, + 0x03,0x41,0xC2,0x38,0xFF,0xAA,0xAF,0xAB,0x03,0x41,0xC2,0x38,0xA3,0xBB,0xFE,0xBA, + 0x03,0x41,0xE2,0x38,0xFA,0x5F,0xF5,0xFD,0x05,0x62,0xE2,0x40,0x15,0x15,0x15,0x95, + 0x46,0x6A,0x03,0x39,0x68,0x60,0x60,0x68,0x03,0x39,0xE2,0x30,0x02,0xAB,0x25,0x3B, + 0x23,0x39,0xE3,0x38,0x8A,0x2B,0x8B,0xBF,0x44,0x41,0xE3,0x30,0x6F,0xFA,0xA2,0xAA, + 0x44,0x39,0xE3,0x30,0x55,0xBF,0xFC,0xFA,0x24,0x41,0xE3,0x30,0x7F,0xFF,0xFA,0x3B, + 0x23,0x39,0xE3,0x30,0x55,0x7F,0xFE,0xFA,0x03,0x31,0xC3,0x28,0xFF,0xFF,0x2A,0xCA, + 0x03,0x31,0xA2,0x20,0x57,0x7E,0xAA,0xAA,0xE3,0x28,0x82,0x20,0x5D,0xF6,0xAA,0xA2, + 0x03,0x39,0x82,0x20,0x3D,0xBD,0x77,0x7F,0xE3,0x30,0x82,0x20,0x02,0x0A,0x2B,0x35, + 0x23,0x41,0xA2,0x30,0xAA,0xDE,0xFE,0xFE,0x44,0x41,0xC2,0x30,0xE0,0xCA,0x75,0xDD, + 0xE2,0x30,0xA2,0x30,0x8F,0xAF,0xA9,0x22,0x22,0x39,0xA2,0x28,0x55,0xF5,0xFD,0x3F, + 0x44,0x41,0xA1,0x28,0xD7,0xDD,0xFE,0xA2,0x43,0x41,0xE3,0x30,0xBB,0x35,0xA9,0x8B, + 0x47,0x62,0x23,0x41,0xF5,0x95,0x25,0x2B,0xE9,0x7A,0xC5,0x59,0x09,0x2B,0x8A,0x2A, + 0x0A,0x83,0xA9,0x72,0x2A,0x2B,0xFB,0xFF,0x2B,0x83,0xC9,0x7A,0x2F,0x28,0xEB,0xFF, + 0xCF,0xB4,0x0A,0x83,0x2D,0xDD,0x55,0x55,0x6E,0xAC,0x0A,0x83,0x00,0x0A,0xB5,0x55, + 0x6E,0xAC,0x4A,0x8B,0x00,0x00,0x00,0x25,0xAF,0xB4,0x4E,0xAC,0x7F,0xAB,0x0A,0x0B, + 0x03,0x41,0xC2,0x38,0xA0,0xC0,0xE8,0xFE,0x03,0x41,0xE2,0x38,0xD5,0xAD,0xD1,0x79, + 0x02,0x41,0xE2,0x38,0x7D,0x5D,0x55,0xF5,0x03,0x41,0xE2,0x38,0x77,0x57,0x5D,0xD7, + 0xE2,0x38,0xC2,0x38,0x00,0x00,0x00,0xA8,0x06,0x62,0xE2,0x38,0x95,0x15,0x95,0x15, + 0x67,0x72,0x03,0x41,0x68,0x68,0x78,0x78,0x03,0x39,0xE2,0x30,0x5E,0xEE,0xDF,0xF7, + 0x02,0x39,0xE3,0x30,0xDF,0x99,0x55,0x75,0x23,0x39,0xE3,0x30,0x0B,0xA7,0xFF,0xD5, + 0x24,0x39,0xE3,0x38,0x68,0xBB,0xFF,0x5F,0x24,0x41,0xE3,0x30,0xFF,0x29,0x8F,0xAE, + 0x24,0x41,0x03,0x39,0x71,0x57,0x7A,0x5C,0x24,0x39,0xE2,0x30,0xFF,0xFA,0xBD,0xAE, + 0x03,0x31,0xE3,0x30,0x60,0xAE,0x2E,0x03,0x03,0x31,0xC2,0x28,0xFF,0xEB,0xC8,0x00, + 0x03,0x31,0xA2,0x20,0x7E,0xFB,0xBA,0xA8,0xE2,0x28,0xA2,0x28,0x55,0x67,0x73,0xAA, + 0x03,0x31,0x81,0x20,0xA2,0xAD,0xDF,0x7F,0x03,0x39,0x82,0x20,0xA2,0xA8,0x0B,0xF5, + 0x03,0x31,0xC2,0x30,0xF7,0x2E,0x82,0xA9,0x23,0x39,0xC2,0x28,0xB9,0xA9,0xAD,0x2F, + 0x23,0x41,0xC2,0x28,0xA0,0xF8,0xDC,0xFE,0xA5,0x51,0xC2,0x28,0xFF,0xB7,0x3D,0x2F, + 0x68,0x6A,0xC5,0x51,0xBD,0x3D,0xA9,0xBF,0xC9,0x72,0x48,0x6A,0xAB,0xAB,0xAF,0x3D, + 0xE9,0x7A,0x89,0x72,0x8F,0xFF,0xB5,0xBB,0xEA,0x82,0xA9,0x7A,0x3B,0xB9,0xFB,0xF7, + 0x0A,0x83,0xC9,0x72,0x3A,0xBF,0xE9,0xAB,0x0A,0x83,0xC9,0x7A,0xA2,0x0E,0xF7,0xDA, + 0x4B,0x8B,0xEA,0x7A,0x2F,0x5D,0xFD,0x55,0x8F,0xAC,0x0A,0x83,0x0B,0xBD,0x55,0x55, + 0x03,0x39,0xC2,0x38,0xE7,0xBF,0xEB,0xEB,0x03,0x41,0xE2,0x38,0x5B,0x7F,0x55,0xD5, + 0x22,0x39,0xC2,0x38,0xF7,0xDD,0xF6,0xFF,0xE2,0x38,0xC2,0x38,0xAA,0xEA,0x02,0x0A, + 0xE2,0x38,0xC2,0x38,0x80,0xC0,0xDA,0x2A,0x84,0x51,0xC2,0x30,0x35,0x95,0xD7,0x57, + 0x26,0x6A,0x03,0x39,0x78,0x78,0x7A,0x68,0x03,0x39,0xE3,0x30,0x57,0x56,0x5A,0xBD, + 0xE2,0x30,0xC3,0x30,0x0F,0x23,0x03,0x82,0x03,0x31,0xE3,0x30,0xDD,0x97,0xF9,0x55, + 0x03,0x31,0xA2,0x30,0x82,0x2A,0xA2,0xCA,0x03,0x39,0xC3,0x30,0x0A,0xAE,0x2A,0x2A, + 0x23,0x39,0xE3,0x30,0x82,0xAF,0xAA,0xF7,0xE3,0x38,0x24,0x31,0xAB,0xEB,0xEE,0xCA, + 0x23,0x39,0xE3,0x38,0xFF,0x2E,0xAE,0xFE,0x23,0x39,0xE2,0x30,0xFA,0x8F,0x7E,0xE8, + 0x23,0x39,0xE3,0x30,0x7F,0xA8,0xAA,0xBF,0x23,0x39,0xC2,0x28,0xF7,0xBA,0xEA,0x8A, + 0x03,0x31,0xA2,0x20,0x7F,0xBA,0x88,0x00,0x03,0x31,0x81,0x20,0xD7,0xFE,0xAA,0x08, + 0xE3,0x30,0x82,0x20,0x2D,0xFF,0xAE,0x00,0x24,0x39,0xA2,0x20,0x2F,0xF5,0xBF,0x2A, + 0x65,0x41,0xC2,0x28,0xF7,0xF5,0xAF,0x2E,0x27,0x62,0x03,0x31,0xAD,0x2B,0x2A,0x02, + 0x68,0x6A,0xE6,0x59,0xBD,0xAD,0x2D,0x0F,0xC9,0x72,0x48,0x6A,0xBF,0xBA,0x8B,0xB7, + 0xC9,0x72,0x88,0x72,0xAA,0xFF,0xBE,0x6D,0xC9,0x7A,0xA8,0x72,0x28,0x81,0x8F,0x7B, + 0xC9,0x7A,0xA9,0x72,0xD0,0x6B,0x20,0x02,0xE9,0x7A,0xA9,0x72,0xAA,0xB6,0x2D,0xBA, + 0x0A,0x83,0xA9,0x72,0x2A,0xB7,0xF7,0xFF,0x0A,0x83,0xC9,0x7A,0x8B,0x8B,0xA5,0x9B, + 0x03,0x41,0xC2,0x38,0xAE,0xAE,0xEB,0xFB,0x03,0x41,0xC2,0x38,0xFB,0xEA,0xBB,0xDE, + 0xE2,0x38,0xC2,0x38,0x80,0x26,0xAB,0x32,0xE2,0x38,0xC2,0x38,0x8A,0xE0,0xB0,0xB0, + 0xE2,0x38,0xA2,0x30,0x08,0x2A,0x62,0xFC,0xE5,0x59,0xC2,0x38,0x95,0x15,0x95,0x55, + 0xA8,0x72,0xE3,0x38,0x78,0x78,0x5E,0x55,0x03,0x39,0xE3,0x30,0xF6,0xD7,0xFC,0xD5, + 0x03,0x31,0xE3,0x30,0x7D,0xFB,0xD7,0x55,0xE3,0x30,0xC2,0x28,0x20,0x2A,0xB2,0x0B, + 0x03,0x31,0xE3,0x30,0x55,0x55,0xB5,0xED,0x03,0x31,0xC2,0x30,0xAA,0xF7,0xAE,0xBA, + 0x03,0x31,0xC2,0x30,0x2E,0x8B,0xBF,0x3E,0x03,0x31,0xC3,0x30,0x9A,0xA8,0xAB,0xAA, + 0xE3,0x38,0x24,0x31,0xAA,0xAA,0xEE,0xAA,0x24,0x39,0xE3,0x30,0xFB,0xEE,0xAF,0xEB, + 0x24,0x39,0x03,0x39,0x57,0x75,0xDD,0xD5,0x24,0x39,0xE2,0x30,0xA3,0xF6,0xA8,0x0A, + 0x03,0x39,0x64,0x31,0xAA,0xA8,0x8A,0x2A,0x64,0x41,0x03,0x39,0x57,0xFF,0xAF,0x3D, + 0x85,0x49,0x03,0x31,0x55,0xDF,0xAB,0x08,0xC6,0x51,0x03,0x31,0x55,0xFD,0xBB,0x22, + 0x07,0x62,0x44,0x41,0x95,0xAD,0x0B,0x00,0x47,0x62,0xE6,0x59,0x95,0xAD,0x0E,0x82, + 0x88,0x72,0x27,0x62,0xBD,0x2F,0x2F,0x8F,0xA8,0x72,0x48,0x62,0xBF,0xAE,0x3E,0x27, + 0xC9,0x72,0x88,0x6A,0xB5,0x9D,0xED,0xF2,0xA9,0x72,0x68,0x6A,0xA0,0x20,0xA8,0x7C, + 0xC9,0x72,0x89,0x72,0x0E,0xFE,0xBF,0x2D,0xC9,0x7A,0x88,0x6A,0x02,0x2A,0xFE,0x63, + 0xEA,0x7A,0xA9,0x72,0x2F,0xE2,0x7D,0xF5,0x0A,0x7B,0xA9,0x72,0xB2,0xAB,0xED,0xBF, +}; + +static const size_t pixel_3_width = 64; +static const size_t pixel_3_height = 64; +static const size_t pixel_3_size = 2048; +static const unsigned char pixel_3_data[2048] = +{ + 0x26,0x5A,0x43,0x41,0xFE,0x7B,0xFA,0xB4,0x05,0x52,0x23,0x39,0xFF,0xFF,0x4F,0xFE, + 0xA5,0x49,0x43,0x39,0xDB,0x64,0x5E,0x8B,0x26,0x6A,0x44,0x41,0xFF,0x7F,0x69,0x03, + 0x2A,0x83,0x44,0x41,0x55,0x77,0x55,0x02,0x6E,0xA4,0x84,0x49,0x55,0x55,0x55,0x0A, + 0x52,0xC5,0xA5,0x49,0x55,0x55,0x55,0x00,0xF4,0xE5,0xC5,0x51,0x75,0x55,0x55,0x38, + 0x97,0xEE,0x64,0x49,0x5D,0x55,0xFF,0x00,0xB6,0xEE,0x84,0x49,0x55,0x55,0xBB,0x00, + 0x75,0xEE,0x64,0x49,0x0D,0x35,0x0A,0x00,0xD7,0xF6,0x34,0xE6,0xA2,0x6C,0x9E,0x27, + 0xF7,0xF6,0x55,0xE6,0x02,0xED,0xD7,0xBA,0x38,0xFF,0x76,0xEE,0xAA,0xAB,0xA7,0xAB, + 0xD7,0xF6,0x34,0xE6,0x60,0xE0,0xF8,0x50,0x14,0xDE,0x92,0xD5,0xA2,0x01,0x01,0x83, + 0xB6,0xEE,0x8B,0x8B,0x57,0x00,0x00,0x00,0xB6,0xEE,0xED,0x9B,0xF5,0x00,0x00,0x00, + 0xB6,0xF6,0x51,0xC5,0xF5,0x00,0x00,0x00,0xB3,0xD5,0xC5,0x69,0xD4,0x54,0x54,0x56, + 0xB6,0xF6,0xE5,0x69,0x02,0x03,0x0D,0x05,0xD6,0xF6,0xB6,0xF6,0xD5,0x15,0x37,0xAE, + 0xD7,0xF6,0x46,0x7A,0x00,0x00,0xC0,0x70,0xF7,0xFE,0x67,0x7A,0x96,0x17,0x35,0x35, + 0x18,0xF7,0xD7,0xF6,0x72,0xF8,0xF0,0xF0,0xF7,0xF6,0xB6,0xF6,0xEB,0xAA,0x2E,0xCA, + 0xD7,0xF6,0x14,0xDE,0xE0,0x60,0xDC,0x36,0xD7,0xF6,0xD3,0xDD,0xB9,0x82,0x00,0x00, + 0x18,0xFF,0xB6,0xEE,0x7D,0xF5,0x25,0x3F,0x38,0xFF,0xB7,0xEE,0xCB,0xEB,0xFF,0x7C, + 0xB6,0xEE,0x71,0xCD,0xF0,0xD8,0xD2,0xF2,0x96,0xEE,0x31,0xC5,0xAB,0x8F,0x8B,0x89, + 0xD6,0xF6,0xB6,0xE6,0x8A,0x22,0x88,0x02,0xF7,0xF6,0xB6,0xEE,0x5F,0x5E,0x7A,0xFA, + 0xF7,0xF6,0xB6,0xEE,0xED,0xAB,0xA9,0x2B,0x96,0xEE,0x44,0x51,0x56,0x54,0x54,0x5C, + 0x6E,0xB4,0x23,0x49,0x2D,0xAD,0xFD,0xFF,0x14,0xE6,0x06,0x6A,0x02,0xF7,0xFD,0x55, + 0x55,0xEE,0xE6,0x71,0x58,0x57,0x55,0x55,0x17,0xFF,0x87,0x8A,0x25,0x25,0x25,0x05, + 0x38,0xFF,0xD7,0xF6,0xFA,0xEA,0xA2,0x6E,0xF7,0xF6,0xF3,0xDD,0xA0,0xA8,0x78,0x28, + 0xF7,0xF6,0xD3,0xDD,0x0B,0x02,0x09,0x2F,0xF7,0xF6,0xB7,0xEE,0xFE,0xEE,0xBA,0x2A, + 0xF7,0xF6,0xD7,0xF6,0x15,0xB5,0x8B,0xA2,0x18,0xFF,0x76,0xEE,0xF8,0x58,0x5A,0x7A, + 0x75,0xEE,0x10,0xC5,0xE2,0xE2,0xE2,0x62,0x55,0xEE,0xEF,0xBC,0x0D,0x09,0x0B,0x02, + 0xD6,0xF6,0xB6,0xEE,0x22,0x08,0x00,0x01,0xF7,0xF6,0xB6,0xEE,0xAA,0xFA,0xFE,0xBA, + 0xF7,0xF6,0x96,0xEE,0x22,0x02,0xAA,0xAA,0x34,0xEE,0x02,0x41,0xF8,0xFC,0x5C,0x56, + 0xA8,0x82,0xE2,0x38,0xA8,0xBA,0xAF,0xCD,0xAB,0xA3,0x43,0x49,0xFF,0xBF,0x0B,0x2D, + 0x0D,0xB4,0x87,0x82,0x5F,0xF2,0x72,0xB6,0xF7,0xFE,0xA8,0x82,0x0D,0x09,0x02,0x00, + 0x38,0xFF,0x96,0xEE,0x7A,0x7E,0x4A,0x63,0x18,0xFF,0xF8,0xF6,0xDD,0x90,0xB0,0xB0, + 0x18,0xFF,0x55,0xE6,0xB7,0xB6,0xBC,0xB8,0x18,0xFF,0xD7,0xF6,0xDF,0xEE,0xFB,0xBA, + 0xF7,0xF6,0x75,0xEE,0x80,0x80,0x60,0x5E,0xD7,0xF6,0xF4,0xDD,0xA2,0xE2,0xB2,0xD8, + 0x76,0xEE,0xAE,0xBC,0x62,0x62,0xE2,0x6A,0x96,0xEE,0x52,0xCD,0x0B,0x22,0xBF,0xB5, + 0x95,0xEE,0xE8,0x82,0x2D,0x55,0x55,0x55,0xD6,0xF6,0xE8,0x82,0x00,0x0F,0x55,0x55, + 0xD6,0xF6,0xE8,0x8A,0x00,0x00,0x0B,0xD5,0x96,0xF6,0x23,0x41,0x56,0x56,0x5C,0x5A, + 0xE8,0x92,0xE3,0x38,0xCD,0x6D,0xE3,0xE2,0xC8,0x82,0xE2,0x38,0x2D,0xD5,0xD5,0xDE, + 0x4A,0x93,0x84,0x59,0x08,0xEA,0x7F,0x5F,0xD7,0xF6,0x88,0x7A,0x0D,0x25,0x95,0xD5, + 0x38,0xFF,0x55,0xEE,0xF0,0x98,0x9C,0x9D,0x18,0xFF,0xF8,0xF6,0xF0,0xF8,0xF8,0x58, + 0x18,0xFF,0xD7,0xF6,0x76,0xBE,0xBF,0xAB,0x18,0xFF,0x96,0xEE,0x82,0xC8,0x68,0x7A, + 0xB6,0xF6,0x55,0xE6,0xF8,0x76,0xF7,0xD7,0x96,0xEE,0x92,0xD5,0xB0,0xD0,0xD0,0xF8, + 0xD3,0xDD,0xAF,0xBC,0x60,0x60,0x70,0xDC,0x92,0xD5,0xAF,0xBC,0x03,0x8B,0xA9,0xAD, + 0xA7,0x7A,0x25,0x6A,0xAA,0xA2,0x3D,0x57,0xC7,0x82,0x45,0x72,0x0A,0xBB,0xEE,0xBD, + 0xE8,0x8A,0x87,0x7A,0x02,0xAB,0xD5,0x77,0xE8,0x82,0xC2,0x38,0xF8,0x78,0x70,0xE2, + 0xC8,0x8A,0x44,0x51,0xA2,0xE3,0xAD,0xD5,0x06,0x6A,0x03,0x41,0xFC,0xFF,0x5C,0x56, + 0x26,0x72,0x03,0x41,0xB0,0x2F,0x25,0xAD,0xA8,0x82,0x44,0x49,0x02,0x68,0x5F,0x5F, + 0x96,0xF6,0x47,0x7A,0x0B,0x2D,0x55,0x55,0xF7,0xF6,0x88,0x7A,0x00,0x00,0x0B,0xD5, + 0xF8,0xFE,0xEC,0xA3,0x00,0x00,0x00,0x2D,0xF7,0xF6,0x55,0xEE,0xF8,0x5E,0x7E,0x57, + 0x76,0xEE,0x35,0xE6,0x38,0x6A,0x80,0x20,0x76,0xEE,0xD3,0xDD,0xF0,0xF8,0x9E,0xD4, + 0x75,0xEE,0x4D,0xAC,0xD6,0x7F,0x7E,0xA0,0x31,0xCD,0xC8,0x7A,0x00,0x03,0x0B,0xB7, + 0x66,0x72,0x46,0x72,0x57,0xAE,0x0A,0x29,0x66,0x72,0x26,0x72,0xFE,0xAA,0x82,0x00, + 0xA7,0x82,0x46,0x72,0x29,0xD5,0xDF,0xFF,0x09,0x8B,0x66,0x7A,0x7F,0xAF,0xD5,0x15, + 0x87,0x82,0xA2,0x30,0xFA,0x78,0x5C,0x5C,0x23,0x41,0xA2,0x28,0xAE,0x3B,0x35,0x87, + 0x06,0x6A,0xE3,0x38,0x0F,0xEB,0xFD,0x7F,0x85,0x51,0x03,0x39,0xAB,0x49,0xFD,0xF5, + 0xC8,0x8A,0x23,0x41,0xA3,0xFD,0x5D,0xD5,0xC9,0x8A,0xC5,0x61,0xE2,0x8B,0xB5,0x57, + 0xEC,0xAB,0x84,0x51,0x3F,0xDF,0x57,0x55,0xF4,0xE5,0x06,0x6A,0x00,0x09,0x35,0xD5, + 0x55,0xEE,0x92,0xD5,0x0A,0xAF,0xBF,0xB5,0x55,0xEE,0xB3,0xDD,0xB8,0xBA,0xAA,0xAD, + 0xB6,0xF6,0xD3,0xDD,0x6A,0xA2,0xC3,0xAA,0xF3,0xDD,0x2D,0xAC,0x5C,0x80,0xA8,0x88, + 0x46,0x72,0x63,0x59,0x2D,0xD5,0x55,0x55,0x66,0x7A,0x43,0x51,0x00,0x0B,0xD5,0xD5, + 0x87,0x7A,0x64,0x59,0x00,0x00,0x0B,0xD5,0xCC,0xAB,0x87,0x7A,0x15,0x25,0x0D,0xA9, + 0x29,0x93,0xC2,0x38,0x5E,0x5E,0x5C,0x5C,0x44,0x49,0xC2,0x30,0xF5,0xB5,0x81,0x8A, + 0x84,0x51,0xE2,0x38,0x57,0xEF,0xBB,0x03,0xC6,0x61,0xA2,0x30,0xFD,0xFF,0xFE,0xD8, + 0x65,0x49,0x03,0x41,0x2A,0xF9,0xE1,0xED,0xC6,0x61,0x03,0x41,0x0A,0xE5,0xFF,0x5E, + 0xA5,0x51,0x03,0x39,0xAA,0xBE,0x75,0xFF,0xA8,0x82,0x23,0x41,0x2F,0xA5,0x3D,0xB5, + 0x14,0xE6,0x87,0x7A,0x03,0x09,0x85,0xB5,0x96,0xEE,0x10,0xC5,0xAF,0x0D,0x25,0x75, + 0x75,0xEE,0x8F,0xB4,0x00,0x00,0x00,0x57,0x55,0xEE,0xF1,0xBC,0xE8,0x80,0xBA,0x7D, + 0x84,0x59,0x23,0x51,0xFE,0xF7,0xAD,0x3E,0x84,0x59,0x23,0x51,0x8B,0xEA,0xFC,0x7E, + 0x6B,0x9B,0x23,0x51,0x55,0x55,0x95,0x35,0xAB,0xA3,0x67,0x7A,0x21,0xAA,0xA8,0xA0, + 0xE8,0x8A,0x03,0x41,0x58,0x78,0xE8,0xE8,0x64,0x51,0xE2,0x38,0xEC,0xE6,0xB7,0xF4, + 0x85,0x51,0x03,0x41,0x85,0x85,0x35,0x95,0xA5,0x59,0xC3,0x30,0xDA,0xDE,0x5C,0xDE, + 0xA5,0x59,0x03,0x39,0xEB,0xFB,0x70,0x7B,0x44,0x41,0xE3,0x38,0xEA,0xEB,0xC1,0xA1, + 0x65,0x41,0xE3,0x38,0xB2,0xFF,0xFF,0xDD,0xC5,0x59,0x23,0x41,0x3F,0x3D,0xFD,0x3B, + 0x31,0xCD,0x06,0x6A,0x35,0xB5,0xF5,0xD5,0x35,0xE6,0xAF,0xBC,0x7D,0x55,0xAE,0x82, + 0x93,0xCD,0x4E,0xAC,0x2D,0x8A,0xA0,0xA0,0x32,0xC5,0x0E,0x9C,0xA0,0xAA,0xBE,0xED, + 0x84,0x59,0x23,0x51,0x8B,0xFE,0xFE,0x57,0x43,0x59,0x23,0x49,0xF0,0x7C,0xDD,0xBD, + 0xAB,0xA3,0x44,0x59,0x35,0x25,0x05,0x05,0x0C,0xAC,0xE8,0x8A,0x7B,0x7E,0x78,0x6A, + 0xA7,0x82,0x26,0x6A,0x54,0xFE,0x9E,0x3F,0x67,0x7A,0xA2,0x30,0xDC,0x58,0x70,0x60, + 0x44,0x49,0xC2,0x30,0x2B,0xAF,0x95,0xF5,0x65,0x51,0xA2,0x30,0xFC,0xDA,0xFE,0x7A, + 0x44,0x49,0xC3,0x30,0xE2,0xE2,0xF2,0x5B,0x24,0x39,0xC2,0x30,0xC2,0xFF,0xFF,0xFD, + 0x03,0x41,0xE3,0x30,0xBB,0xEA,0xDF,0x0A,0xE6,0x59,0x03,0x41,0x3D,0xB5,0x55,0x77, + 0x88,0x7A,0x64,0x51,0x2A,0x0E,0x2D,0x25,0x15,0xDE,0x6B,0x93,0x82,0xA3,0xA9,0xA9, + 0x73,0xCD,0xED,0x9B,0xE0,0x68,0x7A,0xFE,0x11,0xBD,0x2E,0xA4,0xFD,0xF5,0xEA,0x2D, + 0x44,0x51,0x03,0x49,0xEC,0x9E,0xFF,0xFF,0x43,0x51,0x03,0x49,0x0A,0x82,0xA2,0x62, + 0x6A,0x93,0x23,0x51,0x0D,0x8D,0xA9,0xA9,0xE9,0x8A,0x46,0x72,0xF8,0xDF,0x5F,0x7F, + 0xA7,0x7A,0xC4,0x61,0x8A,0x7A,0x7A,0xDA,0x67,0x72,0x03,0x49,0x6A,0xCA,0xCA,0x80, + 0x23,0x41,0xA2,0x30,0xB9,0x3D,0x0D,0xA1,0x24,0x41,0x81,0x20,0xC0,0xEA,0x7F,0x57, + 0xE3,0x38,0x82,0x20,0xA2,0xBB,0xAD,0xBD,0x04,0x39,0xC3,0x30,0xB1,0xFB,0xD5,0xD5, + 0x44,0x49,0xE2,0x30,0x82,0xFA,0xFF,0xF5,0x44,0x41,0xE2,0x38,0xBF,0x95,0xFD,0xC3, + 0x26,0x6A,0x03,0x39,0x2F,0x2D,0xBD,0xB5,0xF1,0xBC,0x06,0x62,0x03,0xA1,0xA9,0xC9, + 0x2F,0xA4,0x89,0x62,0x28,0xAA,0xFA,0x55,0x11,0xBD,0x0B,0x7B,0x2F,0xB5,0xF5,0xFD, + 0x64,0x59,0x02,0x49,0xF7,0xE7,0xE9,0xF2,0x09,0x8B,0x23,0x49,0x55,0x55,0x95,0x15, + 0x49,0x93,0x84,0x59,0xA9,0xAA,0xA8,0x28,0xAB,0xA3,0xE5,0x61,0xFF,0xAF,0x62,0x7C, + 0xC7,0x82,0x44,0x49,0xE0,0x7E,0x5F,0x57,0x06,0x6A,0xE2,0x38,0x00,0xFF,0x7F,0x7A, + 0x03,0x41,0x61,0x18,0xA8,0xF8,0x7E,0xDF,0xE3,0x30,0x81,0x20,0xB5,0x0D,0xAF,0x2E, + 0xE2,0x30,0xA2,0x28,0x55,0x6B,0xF8,0xCB,0x03,0x39,0xA2,0x28,0x2F,0xF5,0xDD,0xF7, + 0x23,0x39,0xC2,0x30,0xEB,0xAF,0x8D,0xFD,0x64,0x49,0xE2,0x30,0x8B,0xCD,0xCD,0x7D, + 0x84,0x51,0xE2,0x30,0x2F,0xBF,0x37,0xBD,0xD1,0xB4,0x85,0x51,0x09,0x0D,0x2D,0xA5, + 0x11,0xBD,0xAC,0x8B,0x57,0xF0,0xA8,0xAB,0x6F,0xAC,0xCD,0x93,0xB9,0xA8,0x80,0xA0, + 0x64,0x59,0x02,0x41,0xF2,0x5B,0x57,0x5D,0x69,0x93,0x02,0x41,0x15,0x35,0x35,0xD5, + 0x69,0x93,0x84,0x59,0x08,0x80,0xF8,0x5F,0x66,0x72,0x43,0x49,0xE0,0x50,0x5E,0x77, + 0xA5,0x51,0x03,0x41,0xFA,0x7A,0x7A,0x2E,0xC5,0x59,0xC2,0x30,0x58,0xDB,0x7F,0x5E, + 0xE3,0x30,0x61,0x20,0x3E,0x27,0xFF,0xEA,0x03,0x39,0x81,0x20,0xB2,0xA2,0xAD,0x06, + 0xE3,0x30,0xA2,0x28,0x00,0xF2,0x7B,0xEF,0xE3,0x30,0x82,0x28,0xFE,0xA0,0x2A,0x02, + 0x03,0x39,0xC2,0x30,0xD5,0x5F,0x5E,0x73,0x03,0x31,0xC2,0x28,0xEB,0xFA,0xF9,0xAD, + 0x64,0x49,0xE3,0x30,0xB5,0x95,0x3D,0x25,0x0D,0xA4,0xA5,0x51,0x8D,0x29,0xE9,0x03, + 0x6F,0xAC,0xA9,0x72,0x2A,0xAB,0x55,0x57,0x2E,0x9C,0xA8,0x72,0x20,0xAA,0xAB,0xB5, + 0x23,0x49,0x03,0x41,0xD5,0xF5,0xDD,0xFD,0x23,0x49,0xE2,0x40,0x38,0xFE,0xDF,0x55, + 0xA4,0x59,0xE2,0x40,0x1C,0x15,0x1D,0x15,0xE5,0x61,0x23,0x39,0xEA,0x78,0x58,0x5C, + 0xE5,0x61,0xA2,0x30,0xC2,0x73,0x6F,0x7F,0x44,0x49,0x81,0x20,0xF8,0x7A,0x57,0xFF, + 0x24,0x41,0xA2,0x28,0x3D,0xA5,0x7F,0x7F,0x23,0x49,0x81,0x20,0x2A,0xAA,0xB7,0xDD, + 0x03,0x39,0xA2,0x28,0xAC,0x7C,0xD8,0xF3,0x03,0x39,0xA2,0x28,0xBF,0x7D,0x75,0xCB, + 0xE2,0x30,0xA2,0x28,0x8A,0xA3,0x8D,0x7C,0x03,0x39,0xA1,0x28,0xAB,0xA2,0x0F,0xA7, + 0xC9,0x7A,0x03,0x39,0xD5,0x15,0x35,0x3D,0x10,0xC5,0x2A,0x83,0x2A,0x80,0x0A,0xB5, + 0xD0,0xBC,0xA8,0x72,0x5E,0x58,0xA0,0xA0,0x2D,0xA4,0x06,0x5A,0xDF,0x7B,0xEA,0x00, + 0x03,0x41,0xE2,0x38,0x03,0x7A,0xFC,0x77,0x03,0x49,0xE2,0x38,0xFD,0x7D,0x55,0xDD, + 0x84,0x59,0xE2,0x38,0x15,0x95,0x95,0x95,0x46,0x6A,0x03,0x39,0x5C,0x5C,0x5C,0x54, + 0x24,0x39,0xE3,0x30,0xCA,0x0B,0xA7,0xF5,0x23,0x39,0xE2,0x30,0xFF,0xAC,0xBA,0x3F, + 0x23,0x39,0xE3,0x30,0x57,0x5E,0xEE,0xB8,0x03,0x31,0xA2,0x20,0x57,0xFA,0xA0,0x00, + 0xE3,0x30,0x81,0x20,0x2B,0xBF,0xFA,0xA0,0x44,0x41,0xA2,0x28,0xAB,0xFF,0xFF,0xD5, + 0x03,0x39,0xA2,0x28,0xDF,0xBB,0xAA,0x2A,0x64,0x49,0xC2,0x28,0xB5,0xBF,0xBE,0x37, + 0xA9,0x72,0x44,0x49,0x25,0x09,0x0B,0x2A,0x0A,0x83,0xA9,0x72,0x0A,0x8F,0xFD,0xF5, + 0x6F,0xAC,0xEA,0x7A,0x2B,0xF5,0x55,0x55,0x6E,0xAC,0x0A,0x83,0x00,0x02,0x35,0x55, + 0x03,0x41,0xE2,0x38,0xF5,0x55,0x7F,0x55,0xE2,0x38,0xC2,0x38,0xA3,0x20,0xA2,0x8A, + 0x43,0x49,0xA2,0x30,0xBF,0xFF,0x1F,0xF7,0x66,0x6A,0xE3,0x30,0x5E,0x5E,0x5C,0x57, + 0xE3,0x30,0xC3,0x30,0x03,0x02,0x00,0x80,0x03,0x31,0xE3,0x30,0x3F,0xBF,0xD5,0x7F, + 0x23,0x39,0xE3,0x30,0xEA,0xBB,0x7D,0xD5,0x03,0x39,0x04,0x31,0xBA,0xA0,0x0A,0x2B, + 0x24,0x39,0xE3,0x30,0x5E,0xEB,0xBA,0x2A,0x44,0x41,0xA2,0x20,0x5F,0xFB,0xA2,0x0A, + 0x65,0x49,0xA2,0x28,0xD5,0xFF,0xAB,0x00,0x48,0x6A,0x03,0x31,0xB5,0xA5,0x2B,0x0A, + 0xA9,0x72,0x06,0x62,0x2D,0x29,0xAB,0xAB,0xC9,0x7A,0x88,0x6A,0x2B,0xAB,0xED,0x7E, + 0xE9,0x7A,0x88,0x72,0xAE,0x2A,0xBB,0xED,0x0A,0x83,0xA9,0x72,0x2B,0xAF,0xEF,0xFD, +}; + +static const size_t pixel_4_width = 32; +static const size_t pixel_4_height = 32; +static const size_t pixel_4_size = 512; +static const unsigned char pixel_4_data[512] = +{ + 0xD7,0xF6,0xA4,0x49,0x55,0x55,0xAA,0x00,0x75,0xEE,0xA5,0x51,0x55,0x55,0x70,0x70, + 0xB6,0xF6,0x85,0x49,0x55,0xDD,0x02,0x03,0xF7,0xFE,0xE6,0x59,0x55,0xFF,0xF0,0x9C, + 0xF7,0xF6,0x85,0x49,0x55,0xAA,0x00,0x00,0x96,0xEE,0x46,0x5A,0x09,0x02,0x00,0x00, + 0xF8,0xF6,0x75,0xEE,0x0B,0x27,0x0A,0x82,0xD7,0xEE,0xB2,0xD5,0xF8,0xD8,0xD6,0x96, + 0xD6,0xF6,0xB6,0xEE,0x4A,0x82,0x00,0x02,0xD6,0xF6,0x43,0x49,0x70,0x60,0xE0,0x70, + 0x8F,0xBC,0x02,0x41,0x09,0xFF,0xFF,0xBD,0xB6,0xF6,0x47,0x82,0x17,0x15,0x37,0x07, + 0x18,0xFF,0x95,0xEE,0x68,0x70,0xAE,0x0C,0xF7,0xF6,0x35,0xE6,0x83,0x21,0x0B,0x08, + 0xF7,0xF6,0x55,0xE6,0xC2,0xC0,0x60,0x6E,0x75,0xEE,0x51,0xCD,0x1C,0x3E,0x26,0xB6, + 0xB6,0xF6,0xA7,0x7A,0x2F,0x55,0x55,0x55,0x95,0xF6,0x02,0x49,0x70,0x6A,0x7F,0x7F, + 0x47,0x7A,0xE3,0x38,0x9B,0xF8,0xF0,0x6B,0xF3,0xE5,0xA5,0x59,0x3F,0xF5,0x75,0x55, + 0xD7,0xF6,0x47,0x7A,0x00,0x00,0x0B,0xB5,0xF8,0xF6,0xB3,0xD5,0x00,0x80,0x80,0xA9, + 0x76,0xEE,0xF4,0xDD,0x40,0x40,0x48,0x70,0xB3,0xD5,0xCC,0x9B,0x28,0xA8,0xAE,0xD8, + 0x66,0x72,0x43,0x59,0x00,0x00,0x2D,0xD7,0x8A,0xA3,0xE5,0x69,0xFF,0xBF,0x3F,0x25, + 0x06,0x6A,0xC2,0x30,0xDC,0x54,0xD4,0xF4,0xC5,0x61,0x03,0x39,0xF3,0xDF,0x55,0x7F, + 0x67,0x7A,0x44,0x49,0x0E,0xA5,0xD5,0x55,0x72,0xDD,0x43,0x49,0x2F,0xB5,0xD5,0x55, + 0x14,0xE6,0xE8,0x82,0x00,0x00,0x23,0x29,0x55,0xE6,0xF0,0xBC,0x60,0xE0,0x80,0xFE, + 0x63,0x59,0x23,0x51,0x0A,0xE3,0x72,0x56,0xCB,0xA3,0x44,0x59,0x25,0x8D,0x89,0x81, + 0x87,0x7A,0x23,0x41,0x54,0x58,0x68,0x60,0x65,0x51,0xC2,0x30,0x43,0x4B,0x6B,0x6D, + 0x64,0x49,0xE3,0x30,0xE8,0xB8,0x7E,0x57,0x85,0x51,0xE3,0x38,0x2F,0x27,0x3D,0xF5, + 0x93,0xD5,0x84,0x59,0x8F,0x0D,0x0D,0x2D,0x72,0xCD,0x4E,0xA4,0xEA,0xF8,0x5C,0xF7, + 0xC5,0x61,0x23,0x49,0xD5,0x75,0x55,0x17,0x29,0x8B,0xC5,0x61,0xE1,0xB9,0xAB,0xC8, + 0x67,0x7A,0x23,0x41,0xE0,0xAC,0xF8,0x7F,0x03,0x39,0x81,0x20,0x82,0x72,0x9E,0xB7, + 0xE3,0x30,0xA2,0x28,0x0B,0xAD,0x3F,0xFE,0x44,0x49,0xE2,0x30,0xFA,0xBF,0x3D,0xFD, + 0xD1,0xBC,0x43,0x41,0x2D,0xB5,0x35,0xB5,0x4F,0xA4,0xEA,0x72,0x3A,0xB5,0x88,0x00, + 0x87,0x7A,0x02,0x41,0x17,0x95,0x55,0x55,0x29,0x93,0x23,0x49,0xE0,0x7E,0x75,0x75, + 0x64,0x51,0xA2,0x28,0xC8,0xE0,0x68,0x5E,0x03,0x41,0x82,0x20,0xAD,0xBF,0x23,0xFF, + 0xE3,0x38,0xC2,0x28,0x7E,0xB7,0x5E,0xFC,0xE3,0x30,0xC2,0x28,0x0F,0x38,0x0A,0x15, + 0xAF,0xB4,0x03,0x39,0xB5,0xA5,0x05,0x2D,0xAF,0xB4,0x27,0x5A,0xAA,0xBF,0x7E,0xA8, + 0x03,0x41,0xE2,0x38,0xFA,0x7F,0x5D,0x55,0xA5,0x51,0xE2,0x38,0xCD,0x4D,0x45,0x45, + 0x24,0x39,0xE3,0x30,0xE2,0xBD,0xF5,0x55,0x03,0x39,0xC2,0x28,0x5A,0xA0,0x00,0x0A, + 0x24,0x39,0xA2,0x28,0xBD,0xDF,0xEA,0x08,0x27,0x62,0xC2,0x28,0xD5,0xDD,0xB5,0x2F, + 0x0A,0x83,0xA5,0x51,0x09,0xAB,0x2B,0xAB,0x6E,0xAC,0xC9,0x7A,0x0B,0xD5,0xD5,0x55, +}; + +static const size_t pixel_5_width = 16; +static const size_t pixel_5_height = 16; +static const size_t pixel_5_size = 128; +static const unsigned char pixel_5_data[128] = +{ + 0x96,0xEE,0x64,0x49,0x55,0xC0,0xC0,0xC0,0x55,0xEE,0x47,0x6A,0x55,0xC2,0x9D,0x35, + 0xD7,0xF6,0x8B,0x8B,0x35,0x00,0x00,0x00,0xD7,0xF6,0xB2,0xD5,0xE0,0xF0,0xF0,0xD8, + 0x71,0xCD,0x43,0x59,0xC3,0x7F,0xFF,0xF5,0x6A,0x9B,0xE3,0x38,0x2F,0xFF,0xD7,0x57, + 0xF7,0xF6,0xC5,0x59,0x00,0x0B,0xD5,0x55,0x76,0xEE,0xAF,0xB4,0xF0,0x78,0xC2,0xAD, + 0x49,0x93,0x43,0x51,0x15,0x25,0xB5,0xA5,0x26,0x6A,0xC2,0x30,0xFC,0x58,0x50,0x5A, + 0x64,0x51,0xC2,0x28,0x2C,0xBF,0xFD,0xB5,0xD0,0xB4,0x43,0x49,0x03,0x03,0xA9,0x89, + 0xC8,0x82,0x02,0x41,0xCD,0xD5,0xD5,0x55,0x44,0x41,0xA2,0x28,0xD8,0xFC,0xFA,0xAF, + 0x85,0x49,0xC2,0x30,0xD5,0x55,0xF5,0x3F,0x0D,0xA4,0x64,0x49,0xA9,0x81,0x2B,0xEF, +}; + +static const size_t pixel_6_width = 8; +static const size_t pixel_6_height = 8; +static const size_t pixel_6_size = 32; +static const unsigned char pixel_6_data[32] = +{ + 0x34,0xE6,0x64,0x51,0xEF,0xB8,0xDB,0x5D,0xB7,0xF6,0x47,0x6A,0x02,0x80,0x82,0xA5, + 0x67,0x7A,0xC2,0x30,0xE3,0x63,0x7B,0x5D,0xF1,0xBC,0x03,0x39,0x25,0xB5,0xB5,0xB5, +}; + +static const size_t pixel_7_width = 4; +static const size_t pixel_7_height = 4; +static const size_t pixel_7_size = 8; +static const unsigned char pixel_7_data[8] = +{ + 0x14,0xDE,0x44,0x49,0x0A,0x27,0xD5,0xD5, +}; + +static const size_t pixel_8_width = 2; +static const size_t pixel_8_height = 2; +static const size_t pixel_8_size = 8; +static const unsigned char pixel_8_data[8] = +{ + 0x92,0xCD,0x44,0x49,0x33,0xDD,0x33,0xDD, +}; + +static const size_t pixel_9_width = 1; +static const size_t pixel_9_height = 1; +static const size_t pixel_9_size = 8; +static const unsigned char pixel_9_data[8] = +{ + 0x2A,0x83,0x0A,0x83,0xFB,0xEF,0xEE,0xEF, +}; |