SDL: Added support for HDR10 video on Apple platforms

From 8afba41aef4e58632503530e58982fc880d5d648 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 6 Feb 2024 15:25:05 -0800
Subject: [PATCH] Added support for HDR10 video on Apple platforms

---
 src/render/metal/SDL_render_metal.m           |   38 +-
 src/render/metal/SDL_shaders_metal.metal      |   45 +
 src/render/metal/SDL_shaders_metal_ios.h      | 4698 +++++++++--------
 .../metal/SDL_shaders_metal_iphonesimulator.h | 4564 +++++++++-------
 src/render/metal/SDL_shaders_metal_macos.h    | 4496 ++++++++--------
 src/render/metal/SDL_shaders_metal_tvos.h     | 4698 +++++++++--------
 .../metal/SDL_shaders_metal_tvsimulator.h     | 3855 ++++++++------
 src/video/SDL_pixels.c                        |    6 -
 test/testffmpeg.c                             |    5 +
 9 files changed, 12299 insertions(+), 10106 deletions(-)

diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m
index 0216dad68430..7fa4c1b5a9b1 100644
--- a/src/render/metal/SDL_render_metal.m
+++ b/src/render/metal/SDL_render_metal.m
@@ -76,7 +76,9 @@
 static const size_t CONSTANTS_OFFSET_DECODE_BT601_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT601_LIMITED + sizeof(float) * 4 * 4);
 static const size_t CONSTANTS_OFFSET_DECODE_BT709_LIMITED = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT601_FULL + sizeof(float) * 4 * 4);
 static const size_t CONSTANTS_OFFSET_DECODE_BT709_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT709_LIMITED + sizeof(float) * 4 * 4);
-static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT709_FULL + sizeof(float) * 4 * 4;
+static const size_t CONSTANTS_OFFSET_DECODE_BT2020_LIMITED = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT709_FULL + sizeof(float) * 4 * 4);
+static const size_t CONSTANTS_OFFSET_DECODE_BT2020_FULL = ALIGN_CONSTANTS(16, CONSTANTS_OFFSET_DECODE_BT2020_LIMITED + sizeof(float) * 4 * 4);
+static const size_t CONSTANTS_LENGTH = CONSTANTS_OFFSET_DECODE_BT2020_FULL + sizeof(float) * 4 * 4;
 
 typedef enum SDL_MetalVertexFunction
 {
@@ -91,6 +93,7 @@
     SDL_METAL_FRAGMENT_YUV,
     SDL_METAL_FRAGMENT_NV12,
     SDL_METAL_FRAGMENT_NV21,
+    SDL_METAL_FRAGMENT_HDR10,
     SDL_METAL_FRAGMENT_COUNT,
 } SDL_MetalFragmentFunction;
 
@@ -248,6 +251,8 @@ static MTLBlendFactor GetBlendFactor(SDL_BlendFactor factor)
         return @"SDL_NV12_fragment";
     case SDL_METAL_FRAGMENT_NV21:
         return @"SDL_NV21_fragment";
+    case SDL_METAL_FRAGMENT_HDR10:
+        return @"SDL_HDR10_fragment";
     default:
         return nil;
     }
@@ -387,6 +392,7 @@ void MakeShaderPipelines(METAL_RenderData *data, METAL_ShaderPipelines *pipeline
     MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_YUV], "SDL YUV pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_YUV);
     MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_NV12], "SDL NV12 pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_NV12);
     MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_NV21], "SDL NV21 pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_NV21);
+    MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_HDR10], "SDL HDR10 pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_HDR10);
 }
 
 static METAL_ShaderPipelines *ChooseShaderPipelines(METAL_RenderData *data, MTLPixelFormat rtformat)
@@ -551,10 +557,8 @@ size_t GetBT601ConversionMatrix( SDL_Colorspace colorspace )
     case SDL_COLOR_RANGE_LIMITED:
     case SDL_COLOR_RANGE_UNKNOWN:
         return CONSTANTS_OFFSET_DECODE_BT601_LIMITED;
-        break;
     case SDL_COLOR_RANGE_FULL:
         return CONSTANTS_OFFSET_DECODE_BT601_FULL;
-        break;
     default:
         break;
     }
@@ -567,10 +571,8 @@ size_t GetBT709ConversionMatrix(SDL_Colorspace colorspace)
     case SDL_COLOR_RANGE_LIMITED:
     case SDL_COLOR_RANGE_UNKNOWN:
         return CONSTANTS_OFFSET_DECODE_BT709_LIMITED;
-        break;
     case SDL_COLOR_RANGE_FULL:
         return CONSTANTS_OFFSET_DECODE_BT709_FULL;
-        break;
     default:
         break;
     }
@@ -582,11 +584,9 @@ size_t GetBT2020ConversionMatrix(SDL_Colorspace colorspace)
     switch (SDL_COLORSPACERANGE(colorspace)) {
     case SDL_COLOR_RANGE_LIMITED:
     case SDL_COLOR_RANGE_UNKNOWN:
-        return 0;
-        break;
+        return CONSTANTS_OFFSET_DECODE_BT2020_LIMITED;
     case SDL_COLOR_RANGE_FULL:
-        return 0;
-        break;
+        return CONSTANTS_OFFSET_DECODE_BT2020_FULL;
     default:
         break;
     }
@@ -671,6 +671,9 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
         case SDL_PIXELFORMAT_NV21:
             pixfmt = MTLPixelFormatR8Unorm;
             break;
+        case SDL_PIXELFORMAT_P010:
+            pixfmt = MTLPixelFormatR16Unorm;
+            break;
         case SDL_PIXELFORMAT_RGBA64_FLOAT:
             pixfmt = MTLPixelFormatRGBA16Float;
             break;
@@ -706,8 +709,8 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
 
         mtltextureUv = nil;
 #if SDL_HAVE_YUV
-        yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12);
-        nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21);
+        yuv = (texture->format == SDL_PIXELFORMAT_IYUV || texture->format == SDL_PIXELFORMAT_YV12);
+        nv12 = (texture->format == SDL_PIXELFORMAT_NV12 || texture->format == SDL_PIXELFORMAT_NV21 || texture->format == SDL_PIXELFORMAT_P010);
 
         if (yuv) {
             mtltexdesc.pixelFormat = MTLPixelFormatR8Unorm;
@@ -715,6 +718,10 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
             mtltexdesc.height = (texture->h + 1) / 2;
             mtltexdesc.textureType = MTLTextureType2DArray;
             mtltexdesc.arrayLength = 2;
+        } else if (texture->format == SDL_PIXELFORMAT_P010) {
+            mtltexdesc.pixelFormat = MTLPixelFormatRG16Unorm;
+            mtltexdesc.width = (texture->w + 1) / 2;
+            mtltexdesc.height = (texture->h + 1) / 2;
         } else if (nv12) {
             mtltexdesc.pixelFormat = MTLPixelFormatRG8Unorm;
             mtltexdesc.width = (texture->w + 1) / 2;
@@ -750,6 +757,8 @@ static int METAL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL
             texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV12;
         } else if (texture->format == SDL_PIXELFORMAT_NV21) {
             texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV21;
+        } else if (texture->format == SDL_PIXELFORMAT_P010) {
+            texturedata.fragmentFunction = SDL_METAL_FRAGMENT_HDR10;
         } else
 #endif
         {
@@ -2011,6 +2020,8 @@ in case we want to use it later (recreating the renderer)
         SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT601_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT601_FULL, 0, 0, 8), YCbCr_shader_matrix_size);
         SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_LIMITED, 0, 0, 8), YCbCr_shader_matrix_size);
         SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT709_FULL, 0, 0, 8), YCbCr_shader_matrix_size);
+        SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT2020_LIMITED, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT2020_LIMITED, 0, 0, 10), YCbCr_shader_matrix_size);
+        SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT2020_FULL, SDL_GetYCbCRtoRGBConversionMatrix(SDL_COLORSPACE_BT2020_FULL, 0, 0, 10), YCbCr_shader_matrix_size);
 
         mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared];
 
@@ -2139,7 +2150,7 @@ in case we want to use it later (recreating the renderer)
     {
         "metal",
         (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
-        8,
+        9,
         { SDL_PIXELFORMAT_ARGB8888,
           SDL_PIXELFORMAT_ABGR8888,
           SDL_PIXELFORMAT_RGBA64_FLOAT,
@@ -2147,7 +2158,8 @@ in case we want to use it later (recreating the renderer)
           SDL_PIXELFORMAT_YV12,
           SDL_PIXELFORMAT_IYUV,
           SDL_PIXELFORMAT_NV12,
-          SDL_PIXELFORMAT_NV21 },
+          SDL_PIXELFORMAT_NV21,
+          SDL_PIXELFORMAT_P010 },
         0,
         0,
     }
diff --git a/src/render/metal/SDL_shaders_metal.metal b/src/render/metal/SDL_shaders_metal.metal
index d8f14c9f9298..70949a00a84f 100644
--- a/src/render/metal/SDL_shaders_metal.metal
+++ b/src/render/metal/SDL_shaders_metal.metal
@@ -34,6 +34,19 @@ float sRGBfromLinear(float v)
     return v;
 }
 
+float3 PQtoNits(float3 v)
+{
+    const float c1 = 0.8359375;
+    const float c2 = 18.8515625;
+    const float c3 = 18.6875;
+    const float oo_m1 = 1.0 / 0.1593017578125;
+    const float oo_m2 = 1.0 / 78.84375;
+
+    float3 num = max(pow(abs(v), oo_m2) - c1, 0.0);
+    float3 den = c2 - c3 * pow(abs(v), oo_m2);
+    return 10000.0 * pow(abs(num / den), oo_m1);
+}
+
 float4 GetOutputColor(float4 rgba, float color_scale)
 {
     float4 output;
@@ -215,3 +228,35 @@ fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
     return GetOutputColorFromSRGB(rgb, c.scRGB_output, c.color_scale) * vert.color;
 }
 
+fragment float4 SDL_HDR10_fragment(CopyVertexOutput vert [[stage_in]],
+                                   constant ShaderConstants &c [[buffer(0)]],
+                                   constant YUVDecode &decode [[buffer(1)]],
+                                   texture2d<float> texY [[texture(0)]],
+                                   texture2d<float> texUV [[texture(1)]],
+                                   sampler s [[sampler(0)]])
+{
+    const float3x3 mat2020to709 = {
+        { 1.660496, -0.587656, -0.072840 },
+        { -0.124547, 1.132895, -0.008348 },
+        { -0.018154, -0.100597, 1.118751 }
+    };
+
+    float3 yuv;
+    yuv.x = texY.sample(s, vert.texcoord).r;
+    yuv.yz = texUV.sample(s, vert.texcoord).rg;
+
+    float3 rgb;
+    yuv += decode.offset;
+    rgb.r = dot(yuv, decode.Rcoeff);
+    rgb.g = dot(yuv, decode.Gcoeff);
+    rgb.b = dot(yuv, decode.Bcoeff);
+
+    rgb = PQtoNits(rgb);
+
+    rgb = rgb * mat2020to709;
+
+    rgb = scRGBfromNits(rgb);
+
+    return GetOutputColorFromSCRGB(rgb, c.scRGB_output, c.color_scale) * vert.color;
+}
+
diff --git a/src/render/metal/SDL_shaders_metal_ios.h b/src/render/metal/SDL_shaders_metal_ios.h
index a1906147054d..425872975d3f 100644
--- a/src/render/metal/SDL_shaders_metal_ios.h
+++ b/src/render/metal/SDL_shaders_metal_ios.h
@@ -1,12 +1,12 @@
 const unsigned char sdl_metallib[] = {
   0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x7e, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xa8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x04, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x6e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x48, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x22, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0xf8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x76, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
   0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f,
   0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54,
   0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00,
@@ -77,2157 +77,2557 @@ const unsigned char sdl_metallib[] = {
   0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x53,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00,
   0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54,
-  0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x15, 0x00, 0x02, 0x00,
-  0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x63,
-  0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, 0x41, 0x54, 0x59, 0x04,
-  0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, 0x54, 0x35, 0x00, 0x00,
-  0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, 0x00, 0x70, 0x6f, 0x73,
-  0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f,
-  0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64,
-  0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, 0x00, 0x03, 0x00, 0x04,
-  0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e,
-  0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00,
-  0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e,
-  0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00,
-  0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e,
-  0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00,
-  0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e,
-  0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00,
-  0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00,
-  0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xac, 0x0c, 0x00, 0x00, 0xff, 0xff,
-  0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x28, 0x03,
-  0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00,
-  0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10,
-  0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04,
-  0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10,
-  0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a,
-  0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07,
-  0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00,
-  0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x1b, 0x7e,
-  0x24, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x08, 0x07,
-  0x78, 0x80, 0x07, 0x79, 0x78, 0x07, 0x7c, 0x68, 0x03, 0x73, 0xa8, 0x07,
-  0x77, 0x18, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07,
-  0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xda,
-  0x21, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xce, 0x21, 0x1c, 0xd8,
-  0xa1, 0x0d, 0xec, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda,
-  0xe0, 0x1e, 0xd2, 0x81, 0x1c, 0xe8, 0x01, 0x1d, 0x80, 0x38, 0x90, 0x03,
-  0x3c, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x10, 0x87, 0x7a, 0x48, 0x07,
-  0x76, 0xa0, 0x87, 0x74, 0x70, 0x87, 0x79, 0x00, 0x08, 0x77, 0x78, 0x87,
-  0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87,
-  0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07,
-  0x76, 0x48, 0x87, 0x76, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00,
-  0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca,
-  0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4,
-  0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0xda, 0xc0, 0x1d, 0xde,
-  0xc1, 0x1d, 0xda, 0x80, 0x1d, 0xca, 0x21, 0x1c, 0xcc, 0x01, 0xa0, 0x07,
-  0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07,
-  0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87,
-  0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00,
-  0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xdc, 0x21, 0x1c, 0xdc, 0x61, 0x1e, 0xda,
-  0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00,
-  0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83,
-  0x79, 0x48, 0x87, 0x73, 0x70, 0x87, 0x72, 0x20, 0x87, 0x36, 0xd0, 0x87,
-  0x72, 0x90, 0x87, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83,
-  0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca,
-  0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x80, 0x1e, 0xe4, 0x21, 0x1c, 0xe0,
-  0x01, 0x1e, 0xd2, 0xc1, 0x1d, 0xce, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8,
-  0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x98, 0x07,
-  0x7a, 0x08, 0x87, 0x71, 0x58, 0x87, 0x36, 0x80, 0x07, 0x79, 0x78, 0x07,
-  0x7a, 0x28, 0x87, 0x71, 0xa0, 0x87, 0x77, 0x90, 0x87, 0x36, 0x10, 0x87,
-  0x7a, 0x30, 0x07, 0x73, 0x28, 0x07, 0x79, 0x68, 0x83, 0x79, 0x48, 0x07,
-  0x7d, 0x28, 0x07, 0x00, 0x0f, 0x00, 0xa2, 0x1e, 0xdc, 0x61, 0x1e, 0xc2,
-  0xc1, 0x1c, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2,
-  0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x36,
-  0x6c, 0xc2, 0x00, 0x2c, 0x40, 0x35, 0x84, 0x43, 0x3a, 0xc8, 0x43, 0x1b,
-  0x88, 0x43, 0x3d, 0x98, 0x83, 0x39, 0x94, 0x83, 0x3c, 0xb4, 0x81, 0x3b,
-  0xbc, 0x43, 0x1b, 0x84, 0x03, 0x3b, 0xa4, 0x43, 0x38, 0xcc, 0x03, 0xb0,
-  0x61, 0x1b, 0x08, 0x60, 0x01, 0xaa, 0x21, 0x1c, 0xd2, 0x41, 0x1e, 0xda,
-  0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xdc,
-  0xe1, 0x1d, 0xda, 0x20, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x00,
-  0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86,
-  0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00,
-  0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22,
-  0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c,
-  0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08,
-  0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, 0x82, 0x00, 0x24, 0x41, 0x98, 0x89,
-  0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76,
-  0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70,
-  0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84,
-  0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, 0x10, 0x30, 0x47, 0x00, 0x06, 0x29,
-  0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, 0x21, 0x10, 0x86, 0x11, 0x08, 0x65,
-  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79,
-  0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72,
-  0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37,
-  0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07,
-  0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06,
-  0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e,
-  0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07,
-  0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06,
-  0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07,
-  0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07,
-  0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07,
-  0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07,
+  0x7a, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44,
+  0x4c, 0x5f, 0x48, 0x44, 0x52, 0x31, 0x30, 0x5f, 0x66, 0x72, 0x61, 0x67,
+  0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01,
+  0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x7f, 0x0d, 0x34, 0x9a, 0x8f, 0x13,
+  0x0c, 0x15, 0x9c, 0xed, 0xa0, 0xc5, 0x7b, 0x45, 0x8a, 0xf8, 0x3b, 0x97,
+  0x06, 0x06, 0x19, 0xde, 0x30, 0xf1, 0xa8, 0x8f, 0x56, 0xa8, 0xc1, 0x27,
+  0xc2, 0xbb, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x8e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53,
+  0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e,
+  0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x15, 0x00,
+  0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00,
+  0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, 0x41, 0x54,
+  0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, 0x54, 0x35,
+  0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, 0x00, 0x70,
+  0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x63, 0x6f,
+  0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f,
+  0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, 0x00, 0x03,
+  0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00,
+  0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54,
+  0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00,
+  0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54,
+  0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00,
+  0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54,
+  0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00,
+  0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54,
+  0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00,
+  0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54,
+  0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+  0xac, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde,
+  0x21, 0x0c, 0x00, 0x00, 0x28, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91,
+  0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c,
+  0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02,
+  0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49,
+  0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80,
+  0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0,
+  0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00,
+  0x79, 0x00, 0x00, 0x00, 0x1b, 0x7e, 0x24, 0xf8, 0xff, 0xff, 0xff, 0xff,
+  0x01, 0x90, 0x80, 0x8a, 0x08, 0x07, 0x78, 0x80, 0x07, 0x79, 0x78, 0x07,
+  0x7c, 0x68, 0x03, 0x73, 0xa8, 0x07, 0x77, 0x18, 0x87, 0x36, 0x30, 0x07,
+  0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4,
+  0xa1, 0x1e, 0xca, 0x01, 0x20, 0xda, 0x21, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8,
+  0xa1, 0x1c, 0xce, 0x21, 0x1c, 0xd8, 0xa1, 0x0d, 0xec, 0xa1, 0x1c, 0xc6,
+  0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0xe0, 0x1e, 0xd2, 0x81, 0x1c, 0xe8,
+  0x01, 0x1d, 0x80, 0x38, 0x90, 0x03, 0x3c, 0x00, 0x06, 0x77, 0x78, 0x87,
+  0x36, 0x10, 0x87, 0x7a, 0x48, 0x07, 0x76, 0xa0, 0x87, 0x74, 0x70, 0x87,
+  0x79, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87,
+  0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87,
+  0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x00, 0xe8,
+  0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc,
+  0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2,
+  0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2,
+  0xa1, 0x1d, 0xda, 0xc0, 0x1d, 0xde, 0xc1, 0x1d, 0xda, 0x80, 0x1d, 0xca,
+  0x21, 0x1c, 0xcc, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08,
+  0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03,
+  0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8,
+  0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xdc,
+  0x21, 0x1c, 0xdc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda,
+  0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07,
+  0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x79, 0x48, 0x87, 0x73, 0x70, 0x87,
+  0x72, 0x20, 0x87, 0x36, 0xd0, 0x87, 0x72, 0x90, 0x87, 0x77, 0x98, 0x87,
+  0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07,
+  0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda,
+  0x80, 0x1e, 0xe4, 0x21, 0x1c, 0xe0, 0x01, 0x1e, 0xd2, 0xc1, 0x1d, 0xce,
+  0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87,
+  0x7a, 0x28, 0x07, 0x80, 0x98, 0x07, 0x7a, 0x08, 0x87, 0x71, 0x58, 0x87,
+  0x36, 0x80, 0x07, 0x79, 0x78, 0x07, 0x7a, 0x28, 0x87, 0x71, 0xa0, 0x87,
+  0x77, 0x90, 0x87, 0x36, 0x10, 0x87, 0x7a, 0x30, 0x07, 0x73, 0x28, 0x07,
+  0x79, 0x68, 0x83, 0x79, 0x48, 0x07, 0x7d, 0x28, 0x07, 0x00, 0x0f, 0x00,
+  0xa2, 0x1e, 0xdc, 0x61, 0x1e, 0xc2, 0xc1, 0x1c, 0xca, 0xa1, 0x0d, 0xcc,
+  0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07,
+  0x79, 0xa8, 0x87, 0x72, 0x00, 0x36, 0x6c, 0xc2, 0x00, 0x2c, 0x40, 0x35,
+  0x84, 0x43, 0x3a, 0xc8, 0x43, 0x1b, 0x88, 0x43, 0x3d, 0x98, 0x83, 0x39,
+  0x94, 0x83, 0x3c, 0xb4, 0x81, 0x3b, 0xbc, 0x43, 0x1b, 0x84, 0x03, 0x3b,
+  0xa4, 0x43, 0x38, 0xcc, 0x03, 0xb0, 0x61, 0x1b, 0x08, 0x60, 0x01, 0xaa,
+  0x21, 0x1c, 0xd2, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc,
+  0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xda, 0x20, 0x1c, 0xd8,
+  0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00,
+  0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09,
+  0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3,
+  0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c,
+  0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30,
+  0x82, 0x00, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a,
+  0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76,
+  0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c,
+  0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33,
+  0x10, 0x30, 0x47, 0x00, 0x06, 0x29, 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10,
+  0x21, 0x10, 0x86, 0x11, 0x08, 0x65, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70,
+  0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79,
+  0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e,
+  0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07,
+  0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07,
+  0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07,
+  0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07,
+  0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07,
+  0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07,
   0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06,
-  0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07,
-  0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07,
-  0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07,
-  0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07,
-  0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06,
-  0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07,
-  0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07,
-  0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07,
-  0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07,
-  0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07,
-  0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06,
-  0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07,
-  0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07,
-  0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07,
-  0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07,
-  0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07,
-  0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07,
-  0x73, 0x20, 0x07, 0x43, 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e,
-  0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04,
-  0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, 0x20, 0x65,
-  0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x42, 0x24, 0x00,
-  0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1a, 0x03,
-  0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4,
-  0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43,
-  0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22,
-  0x28, 0x07, 0xdf, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0xa4, 0xad, 0x8c,
-  0x2e, 0x8c, 0x0d, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64,
-  0x46, 0x06, 0x46, 0x66, 0xc6, 0x25, 0x07, 0x07, 0x04, 0xa5, 0xad, 0x8c,
-  0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x46, 0x06, 0x46, 0x66, 0xc6, 0x25,
-  0x07, 0x27, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x45,
-  0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50,
-  0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97,
-  0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45,
-  0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, 0x61,
-  0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66,
-  0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61,
-  0x62, 0x6c, 0x65, 0x43, 0x84, 0x64, 0x21, 0x19, 0x84, 0xa5, 0xc9, 0xb9,
-  0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5,
-  0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d,
-  0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, 0x86,
-  0x4c, 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b,
-  0x1b, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c,
-  0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc,
-  0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9,
-  0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58,
-  0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, 0x1d,
-  0x1d, 0x5c, 0x1d, 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba,
-  0x32, 0x32, 0x94, 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, 0x9a,
-  0x2f, 0xb3, 0x14, 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, 0xa4,
-  0x4a, 0xac, 0x04, 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x3a, 0x61, 0x69, 0x72,
-  0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x2c,
-  0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0x98, 0xc0, 0xbd, 0xa5, 0xb9, 0xd1, 0x4d,
-  0xa5, 0xe9, 0x95, 0x0d, 0x51, 0x92, 0x2c, 0x81, 0x12, 0x2d, 0x91, 0x92,
-  0x6d, 0x88, 0x91, 0x50, 0x09, 0x96, 0x70, 0x84, 0xc2, 0xd2, 0xe4, 0x5c,
-  0xec, 0xca, 0xe4, 0xe8, 0xca, 0xf0, 0xbe, 0xd2, 0xdc, 0xe0, 0xea, 0xe8,
-  0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, 0xbd,
-  0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0xd1, 0x3b, 0x2b, 0x73, 0x2b,
-  0x93, 0x0b, 0xa3, 0x2b, 0x23, 0x43, 0xf9, 0xfa, 0x0a, 0x4b, 0x93, 0xfb,
-  0x82, 0x63, 0x0b, 0x1b, 0x2b, 0x43, 0x7b, 0x63, 0x23, 0x2b, 0x93, 0xfb,
-  0xfa, 0x4a, 0xa1, 0x61, 0xc6, 0xf6, 0x16, 0x46, 0x27, 0x33, 0x84, 0x52,
-  0x84, 0xc4, 0x4b, 0x3e, 0x45, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, 0x09,
-  0x83, 0x44, 0x4a, 0xa6, 0x21, 0x94, 0x12, 0x24, 0x5e, 0xf2, 0x29, 0x81,
-  0x12, 0x24, 0x60, 0x90, 0x40, 0x49, 0x94, 0x48, 0xc9, 0x45, 0x25, 0x2c,
-  0x4d, 0xce, 0x45, 0xac, 0xce, 0xcc, 0xac, 0x4c, 0x8e, 0x4f, 0x58, 0x9a,
-  0x9c, 0x8b, 0x58, 0x9d, 0x99, 0x59, 0x99, 0xdc, 0xd7, 0x5c, 0x9a, 0x5e,
-  0x19, 0x91, 0xb0, 0x34, 0x39, 0x17, 0xb9, 0xb2, 0x30, 0x32, 0x46, 0x61,
-  0

(Patch may be truncated, please check the link at the top of this post.)