diff --git a/configure.in b/configure.in index 3d42b8410..0872ab302 100644 --- a/configure.in +++ b/configure.in @@ -2053,6 +2053,19 @@ AC_HELP_STRING([--enable-video-cocoa], [use Cocoa video driver [[default=yes]]]) fi } +CheckMETAL() +{ + AC_ARG_ENABLE(render-metal, +AC_HELP_STRING([--enable-render-metal], [enable the Metal render driver [[default=no]]]), + , enable_render_metal=no) + if test x$enable_render = xyes -a x$enable_render_metal = xyes; then + dnl This should maybe make sure you have a supported SDK version. + AC_DEFINE(SDL_VIDEO_RENDER_METAL, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/render/metal/*.m" + fi +} + + dnl Find DirectFB CheckDirectFB() { @@ -2103,7 +2116,6 @@ AC_HELP_STRING([--enable-directfb-shared], [dynamically load directfb support [[ , enable_directfb_shared=yes) AC_DEFINE(SDL_VIDEO_DRIVER_DIRECTFB, 1, [ ]) - AC_DEFINE(SDL_VIDEO_RENDER_DIRECTFB, 1, [ ]) SOURCES="$SOURCES $srcdir/src/video/directfb/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $DIRECTFB_CFLAGS" @@ -3636,8 +3648,9 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau CheckDiskAudio CheckDummyAudio CheckDLOPEN - CheckPTHREAD + CheckMETAL CheckVulkan + CheckPTHREAD # Set up files for the audio library if test x$enable_audio = xyes; then @@ -3701,6 +3714,10 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,OpenGLES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,QuartzCore" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,UIKit" + + if test x$enable_render = xyes -a x$enable_render_metal = xyes; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Metal" + fi ;; *-*-darwin* ) # This could be either full "Mac OS X", or plain "Darwin" which is @@ -3719,6 +3736,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau CheckDummyAudio CheckDLOPEN CheckCOCOA + CheckMETAL CheckX11 CheckMacGL CheckOpenGLX11 diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index 0ddaffebd..7c2c0cac4 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -356,6 +356,7 @@ #cmakedefine SDL_VIDEO_RENDER_OGL_ES @SDL_VIDEO_RENDER_OGL_ES@ #cmakedefine SDL_VIDEO_RENDER_OGL_ES2 @SDL_VIDEO_RENDER_OGL_ES2@ #cmakedefine SDL_VIDEO_RENDER_DIRECTFB @SDL_VIDEO_RENDER_DIRECTFB@ +#cmakedefine SDL_VIDEO_RENDER_METAL @SDL_VIDEO_RENDER_METAL@ /* Enable OpenGL support */ #cmakedefine SDL_VIDEO_OPENGL @SDL_VIDEO_OPENGL@ diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index cd38126f6..1cfcde44e 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -354,6 +354,7 @@ #undef SDL_VIDEO_RENDER_OGL_ES #undef SDL_VIDEO_RENDER_OGL_ES2 #undef SDL_VIDEO_RENDER_DIRECTFB +#undef SDL_VIDEO_RENDER_METAL /* Enable OpenGL support */ #undef SDL_VIDEO_OPENGL diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 91ff495b6..2257c3c6c 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -183,6 +183,10 @@ #define SDL_VIDEO_RENDER_OGL_ES2 1 #endif +#ifndef SDL_VIDEO_RENDER_METAL +#define SDL_VIDEO_RENDER_METAL 1 +#endif + /* Enable OpenGL support */ #ifndef SDL_VIDEO_OPENGL #define SDL_VIDEO_OPENGL 1 diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 7a4dfeffd..e93d307ad 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -92,6 +92,9 @@ static const SDL_RenderDriver *render_drivers[] = { #if SDL_VIDEO_RENDER_DIRECTFB &DirectFB_RenderDriver, #endif +#if SDL_VIDEO_RENDER_METAL + &METAL_RenderDriver, +#endif #if SDL_VIDEO_RENDER_PSP &PSP_RenderDriver, #endif diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index 138407ce8..b204474ad 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -184,6 +184,7 @@ extern SDL_RenderDriver GL_RenderDriver; extern SDL_RenderDriver GLES2_RenderDriver; extern SDL_RenderDriver GLES_RenderDriver; extern SDL_RenderDriver DirectFB_RenderDriver; +extern SDL_RenderDriver METAL_RenderDriver; extern SDL_RenderDriver PSP_RenderDriver; extern SDL_RenderDriver SW_RenderDriver; diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m new file mode 100644 index 000000000..3456b6e3f --- /dev/null +++ b/src/render/metal/SDL_render_metal.m @@ -0,0 +1,760 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2015 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../SDL_internal.h" + +#if SDL_VIDEO_RENDER_METAL && !SDL_RENDER_DISABLED + +#include "SDL_hints.h" +#include "SDL_log.h" +#include "SDL_assert.h" +#include "SDL_syswm.h" +#include "../SDL_sysrender.h" + +#include +#include +#include + +// these are in SDL_shaders_metal.c, regenerate it with build-metal-shaders.sh +extern const unsigned char sdl_metallib[]; +extern const unsigned int sdl_metallib_len; + + +/* Apple Metal renderer implementation */ + +static SDL_Renderer *METAL_CreateRenderer(SDL_Window * window, Uint32 flags); +static void METAL_WindowEvent(SDL_Renderer * renderer, + const SDL_WindowEvent *event); +static int METAL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h); +static int METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, + int pitch); +static int METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); +static int METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, void **pixels, int *pitch); +static void METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static int METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture); +static int METAL_UpdateViewport(SDL_Renderer * renderer); +static int METAL_UpdateClipRect(SDL_Renderer * renderer); +static int METAL_RenderClear(SDL_Renderer * renderer); +static int METAL_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_FPoint * points, int count); +static int METAL_RenderDrawLines(SDL_Renderer * renderer, + const SDL_FPoint * points, int count); +static int METAL_RenderFillRects(SDL_Renderer * renderer, + const SDL_FRect * rects, int count); +static int METAL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect); +static int METAL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip); +static int METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 pixel_format, void * pixels, int pitch); +static void METAL_RenderPresent(SDL_Renderer * renderer); +static void METAL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static void METAL_DestroyRenderer(SDL_Renderer * renderer); + +SDL_RenderDriver METAL_RenderDriver = { + METAL_CreateRenderer, + { + "metal", + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), + 2, + {SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ABGR8888}, + 4096, // !!! FIXME: how do you query Metal for this? + 4096} +}; + +typedef struct METAL_BufferList +{ + id mtlbuffer; + struct METAL_BufferPool *next; +} METAL_BufferList; + +typedef struct +{ + id mtldevice; + id mtlcmdqueue; + id mtlcmdbuffer; + id mtlcmdencoder; + id mtllibrary; + id mtlbackbuffer; + id mtlpipelineprims[4]; + id mtlpipelinecopy[4]; + id mtlbufclearverts; + CAMetalLayer *mtllayer; + MTLRenderPassDescriptor *mtlpassdesc; +} METAL_RenderData; + + +static int +IsMetalAvailable(const SDL_SysWMinfo *syswm) +{ + if (syswm->subsystem != SDL_SYSWM_COCOA) { // !!! FIXME: SDL_SYSWM_UIKIT for iOS, too! + return SDL_SetError("Metal render target only supports Cocoa video target at the moment."); + } + + // this checks a weak symbol. +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100 + if (MTLCreateSystemDefaultDevice == NULL) { // probably on 10.10 or lower. + return SDL_SetError("Metal framework not available on this system"); + } +#endif + + return 0; +} + +static id +MakePipelineState(METAL_RenderData *data, NSString *label, NSString *vertfn, + NSString *fragfn, const SDL_BlendMode blendmode) +{ + id mtlvertfn = [data->mtllibrary newFunctionWithName:vertfn]; + id mtlfragfn = [data->mtllibrary newFunctionWithName:fragfn]; + SDL_assert(mtlvertfn != nil); + SDL_assert(mtlfragfn != nil); + + MTLRenderPipelineDescriptor *mtlpipedesc = [[MTLRenderPipelineDescriptor alloc] init]; + mtlpipedesc.vertexFunction = mtlvertfn; + mtlpipedesc.fragmentFunction = mtlfragfn; + mtlpipedesc.colorAttachments[0].pixelFormat = data->mtlbackbuffer.texture.pixelFormat; + + switch (blendmode) { + case SDL_BLENDMODE_NONE: + mtlpipedesc.colorAttachments[0].blendingEnabled = NO; + break; + + case SDL_BLENDMODE_BLEND: + mtlpipedesc.colorAttachments[0].blendingEnabled = YES; + mtlpipedesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; + mtlpipedesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + mtlpipedesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; + mtlpipedesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + mtlpipedesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; + mtlpipedesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + break; + + case SDL_BLENDMODE_ADD: + mtlpipedesc.colorAttachments[0].blendingEnabled = YES; + mtlpipedesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; + mtlpipedesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + mtlpipedesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; + mtlpipedesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOne; + mtlpipedesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorZero; + mtlpipedesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOne; + break; + + case SDL_BLENDMODE_MOD: + mtlpipedesc.colorAttachments[0].blendingEnabled = YES; + mtlpipedesc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; + mtlpipedesc.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + mtlpipedesc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorZero; + mtlpipedesc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorSourceColor; + mtlpipedesc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorZero; + mtlpipedesc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOne; + break; + } + + mtlpipedesc.label = label; + + NSError *err = nil; + id retval = [data->mtldevice newRenderPipelineStateWithDescriptor:mtlpipedesc error:&err]; + SDL_assert(err == nil); + [mtlpipedesc release]; // !!! FIXME: can these be reused for each creation, or does the pipeline obtain it? + [mtlvertfn release]; + [mtlfragfn release]; + [label release]; + + return retval; +} + +static void +MakePipelineStates(METAL_RenderData *data, id *states, + NSString *label, NSString *vertfn, NSString *fragfn) +{ + int i = 0; + states[i++] = MakePipelineState(data, [label stringByAppendingString:@" (blendmode=none)"], vertfn, fragfn, SDL_BLENDMODE_NONE); + states[i++] = MakePipelineState(data, [label stringByAppendingString:@" (blendmode=blend)"], vertfn, fragfn, SDL_BLENDMODE_BLEND); + states[i++] = MakePipelineState(data, [label stringByAppendingString:@" (blendmode=add)"], vertfn, fragfn, SDL_BLENDMODE_ADD); + states[i++] = MakePipelineState(data, [label stringByAppendingString:@" (blendmode=mod)"], vertfn, fragfn, SDL_BLENDMODE_MOD); +} + +static inline id +ChoosePipelineState(id *states, const SDL_BlendMode blendmode) +{ + switch (blendmode) { + case SDL_BLENDMODE_NONE: return states[0]; + case SDL_BLENDMODE_BLEND: return states[1]; + case SDL_BLENDMODE_ADD: return states[2]; + case SDL_BLENDMODE_MOD: return states[3]; + } + return nil; +} + +static SDL_Renderer * +METAL_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_Renderer *renderer = NULL; + METAL_RenderData *data = NULL; + SDL_SysWMinfo syswm; + + SDL_VERSION(&syswm.version); + if (!SDL_GetWindowWMInfo(window, &syswm)) { + return NULL; + } + + if (IsMetalAvailable(&syswm) == -1) { + return NULL; + } + + data = (METAL_RenderData *) SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return NULL; + } + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_free(data); + SDL_OutOfMemory(); + return NULL; + } + + renderer->driverdata = data; + renderer->window = window; + + data->mtldevice = MTLCreateSystemDefaultDevice(); // !!! FIXME: MTLCopyAllDevices() can find other GPUs... + if (data->mtldevice == nil) { + SDL_free(renderer); + SDL_free(data); + SDL_SetError("Failed to obtain Metal device"); + return NULL; + } + + // !!! FIXME: error checking on all of this. + + NSView *nsview = [syswm.info.cocoa.window contentView]; + + // !!! FIXME: on iOS, we need to override +[UIView layerClass] to return [CAMetalLayer class] right from the start, and that's more complicated. + CAMetalLayer *layer = [CAMetalLayer layer]; + + layer.device = data->mtldevice; + //layer.pixelFormat = MTLPixelFormatBGRA8Unorm; // !!! FIXME: MTLPixelFormatBGRA8Unorm_sRGB ? + layer.framebufferOnly = YES; + //layer.drawableSize = (CGSize) [nsview convertRectToBacking:[nsview bounds]].size; + //layer.colorspace = nil; + + [nsview setWantsLayer:YES]; + [nsview setLayer:layer]; + + [layer retain]; + data->mtllayer = layer; + data->mtlcmdqueue = [data->mtldevice newCommandQueue]; + data->mtlcmdqueue.label = @"SDL Metal Renderer"; + + data->mtlpassdesc = [MTLRenderPassDescriptor renderPassDescriptor]; // !!! FIXME: is this autoreleased? + + // we don't specify a depth or stencil buffer because the render API doesn't currently use them. + MTLRenderPassColorAttachmentDescriptor *colorAttachment = data->mtlpassdesc.colorAttachments[0]; + data->mtlbackbuffer = [data->mtllayer nextDrawable]; + colorAttachment.texture = data->mtlbackbuffer.texture; + colorAttachment.loadAction = MTLLoadActionClear; + colorAttachment.clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f); + data->mtlcmdbuffer = [data->mtlcmdqueue commandBuffer]; + + // Just push a clear to the screen to start so we're in a good state. + data->mtlcmdencoder = [data->mtlcmdbuffer renderCommandEncoderWithDescriptor:data->mtlpassdesc]; + data->mtlcmdencoder.label = @"Initial drawable clear"; + + METAL_RenderPresent(renderer); + + renderer->WindowEvent = METAL_WindowEvent; + renderer->GetOutputSize = METAL_GetOutputSize; + renderer->CreateTexture = METAL_CreateTexture; + renderer->UpdateTexture = METAL_UpdateTexture; + renderer->UpdateTextureYUV = METAL_UpdateTextureYUV; + renderer->LockTexture = METAL_LockTexture; + renderer->UnlockTexture = METAL_UnlockTexture; + renderer->SetRenderTarget = METAL_SetRenderTarget; + renderer->UpdateViewport = METAL_UpdateViewport; + renderer->UpdateClipRect = METAL_UpdateClipRect; + renderer->RenderClear = METAL_RenderClear; + renderer->RenderDrawPoints = METAL_RenderDrawPoints; + renderer->RenderDrawLines = METAL_RenderDrawLines; + renderer->RenderFillRects = METAL_RenderFillRects; + renderer->RenderCopy = METAL_RenderCopy; + renderer->RenderCopyEx = METAL_RenderCopyEx; + renderer->RenderReadPixels = METAL_RenderReadPixels; + renderer->RenderPresent = METAL_RenderPresent; + renderer->DestroyTexture = METAL_DestroyTexture; + renderer->DestroyRenderer = METAL_DestroyRenderer; + + renderer->info = METAL_RenderDriver.info; + renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + + // !!! FIXME: how do you control this in Metal? + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + + NSError *err = nil; + + // The compiled .metallib is embedded in a static array in SDL_shaders_metal.c, + // but the original shader source code is in SDL_shaders_metal.metal. + dispatch_data_t mtllibdata = dispatch_data_create(sdl_metallib, sdl_metallib_len, dispatch_get_global_queue(0, 0), ^{}); + data->mtllibrary = [data->mtldevice newLibraryWithData:mtllibdata error:&err]; + SDL_assert(err == nil); + dispatch_release(mtllibdata); + data->mtllibrary.label = @"SDL Metal renderer shader library"; + + MakePipelineStates(data, data->mtlpipelineprims, @"SDL primitives pipeline", @"SDL_Simple_vertex", @"SDL_Simple_fragment"); + MakePipelineStates(data, data->mtlpipelinecopy, @"SDL_RenderCopy pipeline", @"SDL_Copy_vertex", @"SDL_Copy_fragment"); + + static const float clearverts[] = { -1, -1, -1, 1, 1, 1, 1, -1, -1, -1 }; + data->mtlbufclearverts = [data->mtldevice newBufferWithBytes:clearverts length:sizeof(clearverts) options:MTLResourceCPUCacheModeWriteCombined|MTLResourceStorageModePrivate]; + data->mtlbufclearverts.label = @"SDL_RenderClear vertices"; + + // !!! FIXME: force more clears here so all the drawables are sane to start, and our static buffers are definitely flushed. + + return renderer; +} + +static void +METAL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +{ + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED || + event->event == SDL_WINDOWEVENT_SHOWN || + event->event == SDL_WINDOWEVENT_HIDDEN) { + // !!! FIXME: write me + } +} + +static int +METAL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + *w = (int) data->mtlbackbuffer.texture.width; + *h = (int) data->mtlbackbuffer.texture.height; + return 0; +} + +static int +METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + MTLPixelFormat mtlpixfmt; + + switch (texture->format) { + case SDL_PIXELFORMAT_ABGR8888: mtlpixfmt = MTLPixelFormatRGBA8Unorm; break; + case SDL_PIXELFORMAT_ARGB8888: mtlpixfmt = MTLPixelFormatBGRA8Unorm; break; + default: return SDL_SetError("Texture format %s not supported by Metal", SDL_GetPixelFormatName(texture->format)); + } + + // !!! FIXME: autorelease or nah? + MTLTextureDescriptor *mtltexdesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:mtlpixfmt + width:(NSUInteger)texture->w height:(NSUInteger)texture->h mipmapped:NO]; + + id mtltexture = [data->mtldevice newTextureWithDescriptor:mtltexdesc]; + [mtltexdesc release]; + if (mtltexture == nil) { + return SDL_SetError("Texture allocation failed"); + } + + texture->driverdata = mtltexture; + + return 0; +} + +static int +METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) +{ + // !!! FIXME: this is a synchronous call; it doesn't return until data is uploaded in some form. + // !!! FIXME: Maybe move this off to a thread that marks the texture as uploaded and only stall the main thread if we try to + // !!! FIXME: use this texture before the marking is done? Is it worth it? Or will we basically always be uploading a bunch of + // !!! FIXME: stuff way ahead of time and/or using it immediately after upload? + id mtltexture = (id) texture->driverdata; + [mtltexture replaceRegion:MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h) mipmapLevel:0 withBytes:pixels bytesPerRow:pitch]; + return 0; +} + +static int +METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) +{ + return SDL_Unsupported(); // !!! FIXME +} + +static int +METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, void **pixels, int *pitch) +{ + return SDL_Unsupported(); // !!! FIXME: write me +} + +static void +METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + // !!! FIXME: write me +} + +static int +METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + id mtltexture = texture ? (id) texture->driverdata : nil; + data->mtlpassdesc.colorAttachments[0].texture = mtltexture; + return 0; +} + +static int +METAL_UpdateViewport(SDL_Renderer * renderer) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + if (data->mtlcmdencoder != nil) { + MTLViewport viewport; + viewport.originX = renderer->viewport.x; + viewport.originY = renderer->viewport.y; + viewport.width = renderer->viewport.w; + viewport.height = renderer->viewport.h; + viewport.znear = 0.0; + viewport.zfar = 1.0; + [data->mtlcmdencoder setViewport:viewport]; + } + return 0; +} + +static int +METAL_UpdateClipRect(SDL_Renderer * renderer) +{ + // !!! FIXME: should this care about the viewport? + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + if (data->mtlcmdencoder != nil) { + MTLScissorRect mtlrect; + if (renderer->clipping_enabled) { + const SDL_Rect *rect = &renderer->clip_rect; + mtlrect.x = renderer->viewport.x + rect->x; + mtlrect.y = renderer->viewport.x + rect->y; + mtlrect.width = rect->w; + mtlrect.height = rect->h; + } else { + mtlrect.x = renderer->viewport.x; + mtlrect.y = renderer->viewport.y; + mtlrect.width = renderer->viewport.w; + mtlrect.height = renderer->viewport.h; + } + [data->mtlcmdencoder setScissorRect:mtlrect]; + } + return 0; +} + +static int +METAL_RenderClear(SDL_Renderer * renderer) +{ + // We could dump the command buffer and force a clear on a new one, but this will respect the scissor state. + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + + // !!! FIXME: render color should live in a dedicated uniform buffer. + const float color[4] = { ((float)renderer->r) / 255.0f, ((float)renderer->g) / 255.0f, ((float)renderer->b) / 255.0f, ((float)renderer->a) / 255.0f }; + + MTLViewport viewport; // RenderClear ignores the viewport state, though, so reset that. + viewport.originX = viewport.originY = 0.0; + viewport.width = data->mtlbackbuffer.texture.width; + viewport.height = data->mtlbackbuffer.texture.height; + viewport.znear = 0.0; + viewport.zfar = 1.0; + + // Draw as if we're doing a simple filled rect to the screen now. + [data->mtlcmdencoder setViewport:viewport]; + [data->mtlcmdencoder setRenderPipelineState:ChoosePipelineState(data->mtlpipelineprims, renderer->blendMode)]; + [data->mtlcmdencoder setVertexBuffer:data->mtlbufclearverts offset:0 atIndex:0]; + [data->mtlcmdencoder setFragmentBytes:color length:sizeof(color) atIndex:0]; + [data->mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:5]; + + // reset the viewport for the rest of our usual drawing work... + viewport.originX = renderer->viewport.x; + viewport.originY = renderer->viewport.y; + viewport.width = renderer->viewport.w; + viewport.height = renderer->viewport.h; + viewport.znear = 0.0; + viewport.zfar = 1.0; + [data->mtlcmdencoder setViewport:viewport]; + + return 0; +} + +// normalize a value from 0.0f to len into -1.0f to 1.0f. +static inline float +norm(const float _val, const float len) +{ + const float val = (_val < 0.0f) ? 0.0f : (_val > len) ? len : _val; + return ((val / len) * 2.0f) - 1.0f; // !!! FIXME: is this right? +} + +// normalize a value from 0.0f to len into -1.0f to 1.0f. +static inline float +normy(const float _val, const float len) +{ + return norm(len - ((_val < 0.0f) ? 0.0f : (_val > len) ? len : _val), len); +} + +// normalize a value from 0.0f to len into 0.0f to 1.0f. +static inline float +normtex(const float _val, const float len) +{ + const float val = (_val < 0.0f) ? 0.0f : (_val > len) ? len : _val; + return (val / len); +} + +static int +DrawVerts(SDL_Renderer * renderer, const SDL_FPoint * points, int count, + const MTLPrimitiveType primtype) +{ + const size_t vertlen = (sizeof (float) * 2) * count; + float *verts = SDL_malloc(vertlen); + if (!verts) { + return SDL_OutOfMemory(); + } + + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + + // !!! FIXME: render color should live in a dedicated uniform buffer. + const float color[4] = { ((float)renderer->r) / 255.0f, ((float)renderer->g) / 255.0f, ((float)renderer->b) / 255.0f, ((float)renderer->a) / 255.0f }; + + [data->mtlcmdencoder setRenderPipelineState:ChoosePipelineState(data->mtlpipelineprims, renderer->blendMode)]; + [data->mtlcmdencoder setFragmentBytes:color length:sizeof(color) atIndex:0]; + + const float w = (float) data->mtlpassdesc.colorAttachments[0].texture.width; + const float h = (float) data->mtlpassdesc.colorAttachments[0].texture.height; + + // !!! FIXME: we can convert this in the shader. This will save the malloc and for-loop, but we still need to upload. + float *ptr = verts; + for (int i = 0; i < count; i++, points++) { + *ptr = norm(points->x, w); ptr++; + *ptr = normy(points->y, h); ptr++; + } + + [data->mtlcmdencoder setVertexBytes:verts length:vertlen atIndex:0]; + [data->mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count]; + + SDL_free(verts); + return 0; +} + +static int +METAL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points, int count) +{ + return DrawVerts(renderer, points, count, MTLPrimitiveTypePoint); +} + +static int +METAL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points, int count) +{ + return DrawVerts(renderer, points, count, MTLPrimitiveTypeLineStrip); +} + +static int +METAL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + + // !!! FIXME: render color should live in a dedicated uniform buffer. + const float color[4] = { ((float)renderer->r) / 255.0f, ((float)renderer->g) / 255.0f, ((float)renderer->b) / 255.0f, ((float)renderer->a) / 255.0f }; + + [data->mtlcmdencoder setRenderPipelineState:ChoosePipelineState(data->mtlpipelineprims, renderer->blendMode)]; + [data->mtlcmdencoder setFragmentBytes:color length:sizeof(color) atIndex:0]; + + const float w = (float) data->mtlpassdesc.colorAttachments[0].texture.width; + const float h = (float) data->mtlpassdesc.colorAttachments[0].texture.height; + + for (int i = 0; i < count; i++, rects++) { + if ((rects->w <= 0.0f) || (rects->h <= 0.0f)) continue; + + const float verts[] = { + norm(rects->x, w), normy(rects->y + rects->h, h), + norm(rects->x, w), normy(rects->y, h), + norm(rects->x + rects->w, w), normy(rects->y, h), + norm(rects->x, w), normy(rects->y + rects->h, h), + norm(rects->x + rects->w, w), normy(rects->y + rects->h, h) + }; + + [data->mtlcmdencoder setVertexBytes:verts length:sizeof(verts) atIndex:0]; + [data->mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:5]; + } + + return 0; +} + +static int +METAL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + id mtltexture = (id) texture->driverdata; + const float w = (float) data->mtlpassdesc.colorAttachments[0].texture.width; + const float h = (float) data->mtlpassdesc.colorAttachments[0].texture.height; + const float texw = (float) mtltexture.width; + const float texh = (float) mtltexture.height; + + const float xy[] = { + norm(dstrect->x, w), normy(dstrect->y + dstrect->h, h), + norm(dstrect->x, w), normy(dstrect->y, h), + norm(dstrect->x + dstrect->w, w), normy(dstrect->y, h), + norm(dstrect->x, w), normy(dstrect->y + dstrect->h, h), + norm(dstrect->x + dstrect->w, w), normy(dstrect->y + dstrect->h, h) + }; + + const float uv[] = { + normtex(srcrect->x, texw), normtex(srcrect->y + srcrect->h, texh), + normtex(srcrect->x, texw), normtex(srcrect->y, texh), + normtex(srcrect->x + srcrect->w, texw), normtex(srcrect->y, texh), + normtex(srcrect->x, texw), normtex(srcrect->y + srcrect->h, texh), + normtex(srcrect->x + srcrect->w, texw), normtex(srcrect->y + srcrect->h, texh) + }; + + float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + if (texture->modMode) { + color[0] = ((float)texture->r) / 255.0f; + color[1] = ((float)texture->g) / 255.0f; + color[2] = ((float)texture->b) / 255.0f; + color[3] = ((float)texture->a) / 255.0f; + } + + [data->mtlcmdencoder setRenderPipelineState:ChoosePipelineState(data->mtlpipelinecopy, texture->blendMode)]; + [data->mtlcmdencoder setFragmentBytes:color length:sizeof(color) atIndex:0]; + [data->mtlcmdencoder setFragmentTexture:mtltexture atIndex:0]; + [data->mtlcmdencoder setVertexBytes:xy length:sizeof(xy) atIndex:0]; + [data->mtlcmdencoder setVertexBytes:uv length:sizeof(uv) atIndex:1]; + [data->mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:5]; + + return 0; +} + +static int +METAL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) +{ + return SDL_Unsupported(); // !!! FIXME +} + +static int +METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 pixel_format, void * pixels, int pitch) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + MTLRenderPassColorAttachmentDescriptor *colorAttachment = data->mtlpassdesc.colorAttachments[0]; + id mtltexture = colorAttachment.texture; + MTLRegion mtlregion; + + mtlregion.origin.x = rect->x; + mtlregion.origin.y = rect->y; + mtlregion.origin.z = 0; + mtlregion.size.width = rect->w; + mtlregion.size.height = rect->w; + mtlregion.size.depth = 1; + + // we only do BGRA8 or RGBA8 at the moment, so 4 will do. + const int temp_pitch = rect->w * 4; + void *temp_pixels = SDL_malloc(temp_pitch * rect->h); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + + [mtltexture getBytes:temp_pixels bytesPerRow:temp_pitch fromRegion:mtlregion mipmapLevel:0]; + + const Uint32 temp_format = (mtltexture.pixelFormat == MTLPixelFormatBGRA8Unorm) ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_ABGR8888; + const int status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, temp_pitch, pixel_format, pixels, pitch); + SDL_free(temp_pixels); + return status; +} + +static void +METAL_RenderPresent(SDL_Renderer * renderer) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + MTLRenderPassColorAttachmentDescriptor *colorAttachment = data->mtlpassdesc.colorAttachments[0]; + id mtlbackbuffer = data->mtlbackbuffer; + + [data->mtlcmdencoder endEncoding]; + [data->mtlcmdbuffer presentDrawable:mtlbackbuffer]; + + [data->mtlcmdbuffer addCompletedHandler:^(id mtlcmdbuffer){ + [mtlbackbuffer release]; + }]; + + [data->mtlcmdbuffer commit]; + + // Start next frame, once we can. + // we don't specify a depth or stencil buffer because the render API doesn't currently use them. + data->mtlbackbuffer = [data->mtllayer nextDrawable]; + SDL_assert(data->mtlbackbuffer); + colorAttachment.texture = data->mtlbackbuffer.texture; + colorAttachment.loadAction = MTLLoadActionDontCare; + data->mtlcmdbuffer = [data->mtlcmdqueue commandBuffer]; + data->mtlcmdencoder = [data->mtlcmdbuffer renderCommandEncoderWithDescriptor:data->mtlpassdesc]; + data->mtlcmdencoder.label = @"SDL metal renderer frame"; + + // Set up our current renderer state for the next frame... + METAL_UpdateViewport(renderer); + METAL_UpdateClipRect(renderer); +} + +static void +METAL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + id mtltexture = (id) texture->driverdata; + [mtltexture release]; + texture->driverdata = NULL; +} + +static void +METAL_DestroyRenderer(SDL_Renderer * renderer) +{ + METAL_RenderData *data = (METAL_RenderData *) renderer->driverdata; + + if (data) { + int i; + [data->mtlcmdencoder endEncoding]; + [data->mtlcmdencoder release]; + [data->mtlcmdbuffer release]; + [data->mtlcmdqueue release]; + for (i = 0; i < 4; i++) { + [data->mtlpipelineprims[i] release]; + [data->mtlpipelinecopy[i] release]; + } + [data->mtlbufclearverts release]; + [data->mtllibrary release]; + [data->mtldevice release]; + [data->mtlpassdesc release]; + [data->mtllayer release]; + SDL_free(data); + } + SDL_free(renderer); +} + +#endif /* SDL_VIDEO_RENDER_METAL && !SDL_RENDER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/metal/SDL_shaders_metal.c b/src/render/metal/SDL_shaders_metal.c new file mode 100644 index 000000000..f884a82e2 --- /dev/null +++ b/src/render/metal/SDL_shaders_metal.c @@ -0,0 +1,796 @@ +const unsigned char sdl_metallib[] = { + 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x80, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0x4e, 0xf9, 0x51, 0x29, 0x42, 0xed, 0x04, 0x84, 0x5a, 0xc0, 0xc4, + 0x13, 0x2d, 0xa5, 0x2a, 0x35, 0xe7, 0x5a, 0x54, 0x23, 0xcd, 0x36, 0x84, + 0x57, 0x8f, 0x93, 0x2e, 0xa8, 0xa4, 0x5c, 0x1b, 0xb6, 0x4f, 0x46, 0x46, + 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x77, 0x00, 0x00, + 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, + 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, + 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, + 0xac, 0x1b, 0x43, 0xd2, 0xc0, 0xc8, 0x71, 0x6a, 0x29, 0xad, 0xf0, 0xbf, + 0xb5, 0x9c, 0x42, 0x74, 0xae, 0x2c, 0xed, 0xec, 0xdf, 0xbc, 0x83, 0x45, + 0xcb, 0x5f, 0x10, 0x2d, 0x62, 0x6d, 0x26, 0x95, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x7b, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x14, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, + 0x48, 0x20, 0x00, 0x3e, 0xa9, 0x42, 0x17, 0x9f, 0x76, 0x62, 0xf8, 0x5a, + 0x5b, 0x00, 0xa1, 0x7f, 0x79, 0xd0, 0x2d, 0xd1, 0xca, 0x17, 0xec, 0xae, + 0x00, 0xfd, 0xf8, 0xa4, 0xf8, 0x26, 0x8b, 0x02, 0x77, 0xc6, 0xca, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, + 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, + 0x53, 0x48, 0x20, 0x00, 0xf0, 0xdb, 0xe7, 0x05, 0x3f, 0xb8, 0x23, 0x80, + 0x5c, 0x3d, 0xff, 0x62, 0x99, 0xd5, 0xbc, 0x6b, 0x46, 0x4e, 0x38, 0x96, + 0x44, 0xb8, 0x3e, 0xa5, 0x64, 0x47, 0x1c, 0x04, 0xef, 0x6a, 0x32, 0xd7, + 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x17, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, + 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 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, 0x80, 0x07, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xdd, 0x01, 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, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 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, 0x08, + 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, + 0x51, 0x18, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0x20, 0x00, + 0x16, 0xa0, 0xda, 0x10, 0x1b, 0xc2, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, + 0x04, 0x54, 0x04, 0x3b, 0x94, 0xc3, 0x3c, 0xcc, 0x43, 0x1b, 0xc0, 0x83, + 0x3c, 0x94, 0xc3, 0x38, 0xa4, 0xc3, 0x3c, 0x94, 0x43, 0x1b, 0x98, 0x03, + 0x3c, 0xb4, 0x43, 0x38, 0x90, 0x03, 0x40, 0x0f, 0xf2, 0x50, 0x0f, 0xe5, + 0x00, 0x10, 0xee, 0xf0, 0x0e, 0x6d, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xed, + 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0xef, 0x90, 0x0e, 0xee, 0x40, 0x0f, 0xe5, + 0x20, 0x0f, 0x6d, 0x50, 0x0e, 0xec, 0x90, 0x0e, 0xed, 0x00, 0xd0, 0x83, + 0x3c, 0xd4, 0x43, 0x39, 0x00, 0x83, 0x3b, 0xbc, 0x43, 0x1b, 0x98, 0x83, + 0x3c, 0x84, 0x43, 0x3b, 0x94, 0x43, 0x1b, 0xc0, 0xc3, 0x3b, 0xa4, 0x83, + 0x3b, 0xd0, 0x43, 0x39, 0xc8, 0x43, 0x1b, 0x94, 0x03, 0x3b, 0xa4, 0x43, + 0x3b, 0xb4, 0x81, 0x3b, 0xbc, 0x83, 0x3b, 0xb4, 0x01, 0x3b, 0x94, 0x43, + 0x38, 0x98, 0x03, 0x40, 0xb8, 0xc3, 0x3b, 0xb4, 0x41, 0x3a, 0xb8, 0x83, + 0x39, 0xcc, 0x43, 0x1b, 0x98, 0x03, 0x3c, 0xb4, 0x41, 0x3b, 0x84, 0x03, + 0x3d, 0xa0, 0x03, 0x40, 0x0f, 0xf2, 0x50, 0x0f, 0xe5, 0x00, 0x10, 0xee, + 0xf0, 0x0e, 0x6d, 0xe0, 0x0e, 0xe1, 0xe0, 0x0e, 0xf3, 0xd0, 0x06, 0xe6, + 0x00, 0x0f, 0x6d, 0xd0, 0x0e, 0xe1, 0x40, 0x0f, 0xe8, 0x00, 0xd0, 0x83, + 0x3c, 0xd4, 0x43, 0x39, 0x00, 0xc4, 0x3c, 0xd0, 0x43, 0x38, 0x8c, 0xc3, + 0x3a, 0xb4, 0x01, 0x3c, 0xc8, 0xc3, 0x3b, 0xd0, 0x43, 0x39, 0x8c, 0x03, + 0x3d, 0xbc, 0x83, 0x3c, 0xb4, 0x81, 0x38, 0xd4, 0x83, 0x39, 0x98, 0x43, + 0x39, 0xc8, 0x43, 0x1b, 0xcc, 0x43, 0x3a, 0xe8, 0x43, 0x39, 0x00, 0x78, + 0x00, 0x10, 0xf5, 0xe0, 0x0e, 0xf3, 0x10, 0x0e, 0xe6, 0x50, 0x0e, 0x6d, + 0x60, 0x0e, 0xf0, 0xd0, 0x06, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x00, + 0x3d, 0xc8, 0x43, 0x3d, 0x94, 0x03, 0x40, 0xd4, 0xc3, 0x3c, 0x94, 0x43, + 0x1b, 0xcc, 0xc3, 0x3b, 0x98, 0x03, 0x3d, 0xb4, 0x81, 0x39, 0xb0, 0xc3, + 0x3b, 0x84, 0x03, 0x3d, 0x00, 0xe6, 0x10, 0x0e, 0xec, 0x30, 0x0f, 0xe5, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, + 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, + 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x28, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, + 0x8c, 0x20, 0x00, 0x83, 0x08, 0x82, 0x30, 0x47, 0x00, 0x06, 0x65, 0x88, + 0x21, 0xaa, 0x81, 0x80, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, 0x00, 0x00, + 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, + 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, + 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, + 0x70, 0x03, 0x38, 0xd8, 0xf0, 0x1e, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, + 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0e, 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, + 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, + 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, + 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0x60, 0x0e, + 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x31, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0xa2, 0x12, 0x18, 0x01, 0x28, 0x08, 0x00, 0x00, 0x00, + 0x79, 0x18, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x43, 0x84, 0x23, 0x58, + 0x10, 0xb1, 0x02, 0x2b, 0xd8, 0x42, 0x2b, 0x80, 0x81, 0x3d, 0x94, 0x83, + 0x3c, 0xcc, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0x80, 0xc1, 0x1c, 0xb8, 0x41, + 0x1d, 0x80, 0xc1, 0x10, 0x83, 0x08, 0x88, 0x81, 0x10, 0x86, 0x20, 0x07, + 0x41, 0x04, 0x44, 0x40, 0x08, 0x0b, 0x8a, 0x56, 0x28, 0x05, 0x5a, 0x08, + 0x05, 0x56, 0x18, 0x22, 0x1c, 0xc6, 0x82, 0x2d, 0x1c, 0xd2, 0x41, 0x1e, + 0xdc, 0x60, 0x1c, 0xde, 0xa1, 0x1d, 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, + 0xdc, 0x80, 0x1c, 0xca, 0xc1, 0x1d, 0xde, 0x41, 0x1e, 0xda, 0x61, 0x1e, + 0x7e, 0x81, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, + 0x86, 0x08, 0x07, 0xb2, 0x80, 0x0b, 0x87, 0x74, 0x90, 0x07, 0x37, 0x18, + 0x87, 0x77, 0x68, 0x07, 0x78, 0x48, 0x07, 0x76, 0x28, 0x07, 0x37, 0x30, + 0x87, 0x70, 0x98, 0x07, 0x7a, 0xf8, 0x85, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x87, 0x5f, 0x28, 0x07, 0x77, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x18, + 0x22, 0x1c, 0xca, 0x82, 0x32, 0x08, 0x87, 0x74, 0x90, 0x07, 0x37, 0x18, + 0x87, 0x77, 0x68, 0x07, 0x78, 0x48, 0x07, 0x76, 0x28, 0x07, 0x37, 0x30, + 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x07, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x5f, 0x30, 0x87, 0x72, 0xa0, 0x87, 0x71, 0x40, + 0x87, 0x5f, 0x20, 0x87, 0x74, 0x98, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, + 0x87, 0x21, 0xc2, 0xc1, 0x2c, 0x08, 0x83, 0x70, 0x48, 0x07, 0x79, 0x70, + 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0x70, + 0x03, 0x77, 0x08, 0x07, 0x7a, 0x48, 0x07, 0x7b, 0x28, 0x87, 0x5f, 0x20, + 0x87, 0x77, 0xa8, 0x07, 0x71, 0x60, 0x87, 0x72, 0xf8, 0x05, 0x72, 0x48, + 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x18, 0x62, 0x18, 0xc0, + 0xe1, 0x1c, 0xd5, 0x10, 0xe1, 0x78, 0x86, 0x30, 0x07, 0x74, 0x40, 0x47, + 0x74, 0x48, 0xc7, 0x74, 0x50, 0x0b, 0x98, 0x70, 0x48, 0x07, 0x79, 0x70, + 0x03, 0x78, 0x78, 0x87, 0x79, 0x48, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, + 0x87, 0x05, 0x51, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x41, 0x38, 0xc8, 0xc3, + 0x39, 0xfc, 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0xc3, 0x2f, 0xb8, 0x43, + 0x38, 0xb4, 0x43, 0x39, 0x2c, 0x30, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, + 0xe8, 0x81, 0x0e, 0x16, 0x30, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe1, + 0x20, 0x0f, 0xe7, 0xf0, 0x0b, 0xee, 0x10, 0x0e, 0xed, 0x50, 0x0e, 0x0b, + 0xa2, 0x59, 0x20, 0x05, 0x56, 0xf8, 0x85, 0x59, 0x48, 0x87, 0x76, 0x80, + 0x07, 0x76, 0x28, 0x87, 0x5f, 0xb0, 0x87, 0x72, 0x90, 0x07, 0x7a, 0x28, + 0x07, 0x7c, 0x18, 0x42, 0x1c, 0xd6, 0xe1, 0x0d, 0xe1, 0x08, 0xe1, 0xb8, + 0x0e, 0x8c, 0x10, 0x88, 0xe0, 0xc8, 0x0e, 0x8d, 0x18, 0x8e, 0x8d, 0x18, + 0x8e, 0xe8, 0xe0, 0x8e, 0xe9, 0xe8, 0x16, 0x28, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xe2, 0x50, 0x0f, 0xe6, 0x60, 0x0e, 0xe5, 0x20, 0x0f, 0x0b, + 0xa4, 0x70, 0x48, 0x07, 0x79, 0x70, 0x03, 0x76, 0x78, 0x87, 0x71, 0x08, + 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x5f, 0x48, 0x07, 0x77, 0x20, + 0x87, 0x72, 0xc0, 0x87, 0x05, 0x48, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, + 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x82, 0x28, 0x1c, 0xd2, 0x41, 0x1e, + 0xdc, 0x20, 0x1c, 0xe4, 0xe1, 0x1c, 0x7e, 0x81, 0x1e, 0xf2, 0x01, 0x1e, + 0xca, 0xe1, 0x17, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x16, 0x5c, 0xe1, + 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe1, 0x20, 0x0f, 0xe7, 0xf0, 0x0b, 0xf4, + 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0xbf, 0x10, 0x0e, 0xec, 0x90, 0x0e, 0xe7, + 0xe0, 0x0e, 0xbf, 0x30, 0x0f, 0xe9, 0xa0, 0x0f, 0xe5, 0xb0, 0xc0, 0x30, + 0x07, 0x76, 0x78, 0x87, 0x70, 0xa0, 0x07, 0x39, 0x58, 0x80, 0xc0, 0xc3, + 0x3b, 0xcc, 0x43, 0x3a, 0xd0, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0x0c, 0x61, + 0x88, 0xe0, 0xf8, 0x8e, 0xe8, 0x00, 0x83, 0x63, 0x3a, 0xc2, 0x60, 0x41, + 0x13, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, + 0x50, 0x0e, 0xf8, 0xf0, 0x0b, 0xe9, 0x40, 0x0e, 0x0b, 0x88, 0x7a, 0x48, + 0x07, 0x77, 0xa0, 0x87, 0x05, 0x83, 0x3d, 0xa4, 0x03, 0x39, 0x8c, 0x50, + 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0x20, 0x1d, 0xc8, 0xa1, 0x1c, + 0xdc, 0x81, 0x1e, 0xa6, 0x04, 0xc0, 0x88, 0x25, 0x1c, 0xd2, 0x41, 0x1e, + 0xdc, 0xc0, 0x1e, 0xca, 0x41, 0x1e, 0xe6, 0x21, 0x1d, 0xde, 0xc1, 0x1d, + 0xa6, 0x04, 0xc2, 0x08, 0x2a, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x80, 0x1d, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1e, 0xc2, 0xe1, 0x1c, 0xca, 0xe1, 0x17, + 0xec, 0xa1, 0x1c, 0xe4, 0x61, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, 0x4a, + 0x30, 0x8c, 0x98, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xc6, 0xe1, 0x1d, + 0xda, 0x01, 0x1e, 0xd2, 0x81, 0x1d, 0xca, 0xe1, 0x17, 0xde, 0x01, 0x1e, + 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0xe6, 0x61, 0x0a, 0x51, 0x1c, 0xc9, + 0x32, 0x42, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, 0x72, 0x90, + 0x07, 0x7a, 0x28, 0x07, 0x7c, 0x98, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x79, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x07, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0xb3, 0x08, 0xf3, 0x2c, 0xc4, 0x5f, 0x11, + 0xd1, 0x44, 0x5c, 0x00, 0x61, 0x20, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x44, 0x65, 0x50, 0x04, 0x14, 0x33, 0x00, 0x04, 0x63, 0x04, 0x20, 0x08, + 0x82, 0xf8, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x67, 0x60, 0x8c, 0x27, + 0x20, 0x01, 0x05, 0x64, 0x0c, 0x21, 0x60, 0xe6, 0x18, 0x8e, 0xa0, 0x19, + 0x43, 0x18, 0x9e, 0x39, 0x06, 0x21, 0x80, 0xe6, 0x18, 0x02, 0x64, 0x99, + 0x63, 0x08, 0x94, 0x26, 0x83, 0x70, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x56, 0x30, 0x54, 0xc8, 0x60, 0x04, 0xc8, 0xe3, 0x48, 0xc8, 0x84, 0x38, + 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x78, 0x08, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, + 0xde, 0x21, 0x0c, 0x00, 0x00, 0x1b, 0x02, 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, 0x10, 0x45, + 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 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, 0x08, 0x11, 0x62, 0xa8, + 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, + 0x00, 0x4e, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0x20, 0x00, 0x16, 0xa0, 0xda, + 0x60, 0x08, 0x02, 0xb0, 0x00, 0xd5, 0x86, 0xd8, 0x18, 0xfe, 0xff, 0xff, + 0xff, 0x7f, 0x00, 0x24, 0xa0, 0x22, 0xd8, 0xa1, 0x1c, 0xe6, 0x61, 0x1e, + 0xda, 0x00, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x21, 0x1d, 0xe6, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x1d, 0xc2, 0x81, 0x1c, 0x00, 0x7a, 0x90, + 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 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, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, + 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, + 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, + 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, + 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, + 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, + 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, + 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, + 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x2c, 0x33, + 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x17, 0x49, 0x53, 0x44, + 0x09, 0x93, 0xcf, 0x39, 0x0f, 0xf6, 0x12, 0xd1, 0x44, 0x5c, 0x48, 0x08, + 0x19, 0x44, 0x10, 0x84, 0x39, 0x02, 0x30, 0x28, 0xc4, 0x10, 0x15, 0xd9, + 0x40, 0xc0, 0x1c, 0x01, 0x28, 0x8c, 0x00, 0x00, 0x00, 0x13, 0xb2, 0x70, + 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, + 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, + 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, + 0xd8, 0xf0, 0x1e, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, + 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, + 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, + 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x78, 0x00, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0x30, 0x84, 0x39, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x02, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, + 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, + 0xaa, 0x12, 0x28, 0x88, 0x11, 0x80, 0x22, 0xa0, 0x1c, 0x01, 0x00, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x43, 0x04, 0x24, + 0x58, 0x10, 0xb1, 0x02, 0x2b, 0xd8, 0x42, 0x2b, 0x80, 0x81, 0x3d, 0x94, + 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0x80, 0xc1, 0x1c, 0xb8, + 0x41, 0x1d, 0x80, 0xc1, 0x10, 0xa3, 0x08, 0x0a, 0xa1, 0x18, 0x86, 0x20, + 0x08, 0x51, 0x04, 0x45, 0x50, 0x0c, 0x0b, 0x8a, 0x56, 0x28, 0x05, 0x5a, + 0x08, 0x05, 0x56, 0x18, 0x22, 0x20, 0xc6, 0x82, 0x2d, 0x1c, 0xd2, 0x41, + 0x1e, 0xdc, 0x60, 0x1c, 0xde, 0xa1, 0x1d, 0xe0, 0x21, 0x1d, 0xd8, 0xa1, + 0x1c, 0xdc, 0x80, 0x1c, 0xca, 0xc1, 0x1d, 0xde, 0x41, 0x1e, 0xda, 0x61, + 0x1e, 0x7e, 0x81, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, + 0x1c, 0x86, 0x08, 0x08, 0xb2, 0x80, 0x0b, 0x87, 0x74, 0x90, 0x07, 0x37, + 0x18, 0x87, 0x77, 0x68, 0x07, 0x78, 0x48, 0x07, 0x76, 0x28, 0x07, 0x37, + 0x30, 0x87, 0x70, 0x98, 0x07, 0x7a, 0xf8, 0x85, 0x76, 0x08, 0x07, 0x7a, + 0x40, 0x87, 0x5f, 0x28, 0x07, 0x77, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, + 0x18, 0x22, 0x20, 0xca, 0x82, 0x32, 0x08, 0x87, 0x74, 0x90, 0x07, 0x37, + 0x18, 0x87, 0x77, 0x68, 0x07, 0x78, 0x48, 0x07, 0x76, 0x28, 0x07, 0x37, + 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x07, 0x71, 0xa8, 0x07, 0x73, + 0x30, 0x87, 0x72, 0x90, 0x87, 0x5f, 0x30, 0x87, 0x72, 0xa0, 0x87, 0x71, + 0x40, 0x87, 0x5f, 0x20, 0x87, 0x74, 0x98, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x21, 0x02, 0xc2, 0x2c, 0x08, 0x83, 0x70, 0x48, 0x07, 0x79, + 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, + 0x70, 0x03, 0x77, 0x08, 0x07, 0x7a, 0x48, 0x07, 0x7b, 0x28, 0x87, 0x5f, + 0x20, 0x87, 0x77, 0xa8, 0x07, 0x71, 0x60, 0x87, 0x72, 0xf8, 0x05, 0x72, + 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x18, 0x62, 0x1c, + 0x00, 0xe2, 0x20, 0xda, 0x10, 0x02, 0x79, 0x90, 0x6a, 0x88, 0x82, 0x40, + 0x48, 0x84, 0x48, 0xc8, 0x84, 0x50, 0x0b, 0x98, 0x70, 0x48, 0x07, 0x79, + 0x70, 0x03, 0x78, 0x78, 0x87, 0x79, 0x48, 0x07, 0x7a, 0x48, 0x87, 0x77, + 0x70, 0x87, 0x05, 0x51, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x41, 0x38, 0xc8, + 0xc3, 0x39, 0xfc, 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0xc3, 0x2f, 0xb8, + 0x43, 0x38, 0xb4, 0x43, 0x39, 0x2c, 0x30, 0xcc, 0x81, 0x1d, 0xde, 0x21, + 0x1c, 0xe8, 0x81, 0x0e, 0x16, 0x30, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, + 0xe1, 0x20, 0x0f, 0xe7, 0xf0, 0x0b, 0xee, 0x10, 0x0e, 0xed, 0x50, 0x0e, + 0x0b, 0x10, 0x78, 0x78, 0x87, 0x79, 0x48, 0x07, 0x7a, 0x48, 0x87, 0x77, + 0x70, 0x87, 0x21, 0x0c, 0x62, 0x21, 0x17, 0x12, 0x21, 0x18, 0x32, 0x21, + 0xd9, 0x82, 0x28, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0xc0, 0x1e, 0xca, 0x41, + 0x1e, 0xe8, 0xa1, 0x1c, 0xf0, 0xe1, 0x17, 0xde, 0xa1, 0x1e, 0xe8, 0x01, + 0x1e, 0xea, 0x81, 0x1e, 0x16, 0x64, 0xe7, 0x50, 0x0e, 0xee, 0x50, 0x0e, + 0xf2, 0x10, 0x0e, 0xf4, 0x50, 0x0e, 0xe4, 0x80, 0x06, 0x78, 0x40, 0x0f, + 0xe5, 0x80, 0x0f, 0xe3, 0xf0, 0x0e, 0xef, 0x20, 0x0f, 0xe4, 0x40, 0x0a, + 0xf6, 0x20, 0x07, 0xbf, 0x60, 0x0e, 0x69, 0xb0, 0xc0, 0x30, 0x07, 0x76, + 0x78, 0x87, 0x70, 0xa0, 0x07, 0x39, 0x58, 0x80, 0xd0, 0x43, 0x39, 0xe0, + 0xc3, 0x38, 0xbc, 0xc3, 0x3b, 0xc8, 0x03, 0x39, 0x0c, 0x31, 0x90, 0x0d, + 0x09, 0x03, 0x64, 0x0c, 0x86, 0x70, 0xc5, 0x80, 0x70, 0x48, 0x57, 0x0c, + 0x45, 0x80, 0x78, 0xc8, 0x57, 0x08, 0x08, 0x18, 0x14, 0x02, 0x12, 0x21, + 0x18, 0x32, 0x21, 0xd4, 0x02, 0x25, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x40, + 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0x61, 0x81, 0x14, 0x0e, + 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xef, 0x30, 0x0e, 0xe1, 0x40, 0x0f, + 0xe9, 0xf0, 0x0e, 0xee, 0xf0, 0x0b, 0xe9, 0xe0, 0x0e, 0xe4, 0x50, 0x0e, + 0xf8, 0xb0, 0x00, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x90, 0x87, 0x72, + 0x08, 0x07, 0x72, 0x58, 0x10, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x84, + 0x83, 0x3c, 0x9c, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xfc, + 0xc2, 0x3c, 0xa4, 0x83, 0x3e, 0x94, 0xc3, 0x82, 0x2b, 0x1c, 0xd2, 0x41, + 0x1e, 0xdc, 0x20, 0x1c, 0xe4, 0xe1, 0x1c, 0x7e, 0x81, 0x1e, 0xf2, 0x01, + 0x1e, 0xca, 0xe1, 0x17, 0xc2, 0x81, 0x1d, 0xd2, 0xe1, 0x1c, 0xdc, 0xe1, + 0x17, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x86, 0x70, 0x45, 0x80, 0x70, + 0x48, 0x57, 0x04, 0x45, 0x80, 0x78, 0xc8, 0x57, 0x08, 0x08, 0x18, 0x14, + 0x02, 0x12, 0x21, 0x18, 0x32, 0x21, 0x62, 0xb0, 0x20, 0xa1, 0x87, 0x72, + 0xc0, 0x87, 0x71, 0x78, 0x87, 0x77, 0x90, 0x07, 0x72, 0x98, 0x87, 0x21, + 0x4c, 0x41, 0x20, 0x64, 0x80, 0x44, 0x48, 0x19, 0x20, 0x13, 0x62, 0x06, + 0x0b, 0x9a, 0x70, 0x48, 0x07, 0x79, 0x70, 0x03, 0x7b, 0x28, 0x07, 0x79, + 0xa0, 0x87, 0x72, 0xc0, 0x87, 0x5f, 0x48, 0x07, 0x72, 0x58, 0x40, 0xd4, + 0x43, 0x3a, 0xb8, 0x03, 0x3d, 0x2c, 0x18, 0xec, 0x21, 0x1d, 0xc8, 0x61, + 0x88, 0x81, 0xa0, 0x01, 0x82, 0x06, 0x49, 0x31, 0xc4, 0x40, 0xd2, 0x00, + 0x51, 0x83, 0xa4, 0x58, 0xf0, 0xbc, 0x43, 0x3b, 0xb8, 0x43, 0x3a, 0xc0, + 0xc3, 0x3b, 0xd0, 0x43, 0x39, 0xb8, 0x03, 0x3d, 0x80, 0xc1, 0x38, 0xa0, + 0x43, 0x38, 0xc8, 0xc3, 0x10, 0x01, 0x59, 0x83, 0x05, 0xd1, 0x2c, 0xa4, + 0x43, 0x3b, 0xc0, 0x03, 0x3b, 0x94, 0x03, 0x18, 0x8c, 0xc2, 0x1b, 0x8c, + 0xc2, 0x1a, 0xac, 0x01, 0x18, 0xd0, 0x82, 0x28, 0x84, 0x42, 0x28, 0x8c, + 0x50, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0x20, 0x1d, 0xc8, 0xa1, + 0x1c, 0xdc, 0x81, 0x1e, 0xa6, 0x04, 0xc0, 0x88, 0x25, 0x1c, 0xd2, 0x41, + 0x1e, 0xdc, 0xc0, 0x1e, 0xca, 0x41, 0x1e, 0xe6, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0xa6, 0x04, 0xc2, 0x08, 0x2a, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x80, + 0x1d, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1e, 0xc2, 0xe1, 0x1c, 0xca, 0xe1, + 0x17, 0xec, 0xa1, 0x1c, 0xe4, 0x61, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, + 0x4a, 0x30, 0x8c, 0x98, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xc6, 0xe1, + 0x1d, 0xda, 0x01, 0x1e, 0xd2, 0x81, 0x1d, 0xca, 0xe1, 0x17, 0xde, 0x01, + 0x1e, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0xe6, 0x61, 0x0a, 0x51, 0x1c, + 0xc9, 0x32, 0x42, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, 0x72, + 0x90, 0x07, 0x7a, 0x28, 0x07, 0x7c, 0x98, 0x12, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x07, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x06, 0xf0, 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, + 0x4d, 0xc4, 0x05, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x21, 0x00, 0x00, + 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x54, 0x65, 0x40, 0x30, 0x46, 0x00, 0x82, 0x20, 0x88, 0x7f, 0x14, + 0x33, 0x00, 0x34, 0x33, 0x00, 0x04, 0x23, 0x00, 0x00, 0x67, 0x64, 0x8c, + 0x27, 0x24, 0x01, 0x05, 0x64, 0x0c, 0x21, 0x70, 0xe6, 0x18, 0x8e, 0xe0, + 0x19, 0x43, 0x18, 0xa4, 0x39, 0x06, 0x21, 0x98, 0xe6, 0x18, 0x02, 0x24, + 0x9a, 0x63, 0x08, 0x98, 0x66, 0x3c, 0x01, 0x4a, 0x28, 0x20, 0xb3, 0x0d, + 0xcd, 0x00, 0xcc, 0x36, 0x04, 0x42, 0x90, 0x41, 0x38, 0x10, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x86, 0x30, 0x54, 0xc8, 0x60, 0x06, 0xc8, + 0xe3, 0x48, 0xc8, 0x84, 0x38, 0x8d, 0x1d, 0x24, 0x13, 0x71, 0x09, 0x8e, + 0x13, 0x0d, 0x12, 0x00, 0x00, 0x01, 0x31, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x5b, 0x06, 0x25, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x7c, 0x07, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0xdc, 0x01, 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, 0x10, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0x84, 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, 0x08, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x4d, 0x00, + 0x00, 0x00, 0x1b, 0x8c, 0x20, 0x00, 0x16, 0xa0, 0xda, 0x10, 0x1b, 0xc2, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x54, 0x04, 0x3b, 0x94, 0xc3, + 0x3c, 0xcc, 0x43, 0x1b, 0xc0, 0x83, 0x3c, 0x94, 0xc3, 0x38, 0xa4, 0xc3, + 0x3c, 0x94, 0x43, 0x1b, 0x98, 0x03, 0x3c, 0xb4, 0x43, 0x38, 0x90, 0x03, + 0x40, 0x0f, 0xf2, 0x50, 0x0f, 0xe5, 0x00, 0x10, 0xee, 0xf0, 0x0e, 0x6d, + 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xed, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0xef, + 0x90, 0x0e, 0xee, 0x40, 0x0f, 0xe5, 0x20, 0x0f, 0x6d, 0x50, 0x0e, 0xec, + 0x90, 0x0e, 0xed, 0x00, 0xd0, 0x83, 0x3c, 0xd4, 0x43, 0x39, 0x00, 0x83, + 0x3b, 0xbc, 0x43, 0x1b, 0x98, 0x83, 0x3c, 0x84, 0x43, 0x3b, 0x94, 0x43, + 0x1b, 0xc0, 0xc3, 0x3b, 0xa4, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xc8, 0x43, + 0x1b, 0x94, 0x03, 0x3b, 0xa4, 0x43, 0x3b, 0xb4, 0x81, 0x3b, 0xbc, 0x83, + 0x3b, 0xb4, 0x01, 0x3b, 0x94, 0x43, 0x38, 0x98, 0x03, 0x40, 0xb8, 0xc3, + 0x3b, 0xb4, 0x41, 0x3a, 0xb8, 0x83, 0x39, 0xcc, 0x43, 0x1b, 0x98, 0x03, + 0x3c, 0xb4, 0x41, 0x3b, 0x84, 0x03, 0x3d, 0xa0, 0x03, 0x40, 0x0f, 0xf2, + 0x50, 0x0f, 0xe5, 0x00, 0x10, 0xee, 0xf0, 0x0e, 0x6d, 0xe0, 0x0e, 0xe1, + 0xe0, 0x0e, 0xf3, 0xd0, 0x06, 0xe6, 0x00, 0x0f, 0x6d, 0xd0, 0x0e, 0xe1, + 0x40, 0x0f, 0xe8, 0x00, 0xd0, 0x83, 0x3c, 0xd4, 0x43, 0x39, 0x00, 0xc4, + 0x3c, 0xd0, 0x43, 0x38, 0x8c, 0xc3, 0x3a, 0xb4, 0x01, 0x3c, 0xc8, 0xc3, + 0x3b, 0xd0, 0x43, 0x39, 0x8c, 0x03, 0x3d, 0xbc, 0x83, 0x3c, 0xb4, 0x81, + 0x38, 0xd4, 0x83, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x1b, 0xcc, 0x43, + 0x3a, 0xe8, 0x43, 0x39, 0x00, 0x78, 0x00, 0x10, 0xf5, 0xe0, 0x0e, 0xf3, + 0x10, 0x0e, 0xe6, 0x50, 0x0e, 0x6d, 0x60, 0x0e, 0xf0, 0xd0, 0x06, 0xed, + 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x00, 0x3d, 0xc8, 0x43, 0x3d, 0x94, 0x03, + 0x40, 0xd4, 0xc3, 0x3c, 0x94, 0x43, 0x1b, 0xcc, 0xc3, 0x3b, 0x98, 0x03, + 0x3d, 0xb4, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, 0x3d, 0x00, 0xe6, + 0x10, 0x0e, 0xec, 0x30, 0x0f, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x88, 0x10, 0x08, 0x45, 0x08, 0xa1, + 0x19, 0x08, 0x98, 0x23, 0x00, 0x83, 0x39, 0x02, 0x50, 0x18, 0x01, 0x00, + 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0xf0, 0x1e, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, + 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, + 0x60, 0x0e, 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x21, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x11, 0x80, 0x12, 0x28, 0x90, 0x82, + 0xa0, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xc6, 0x00, + 0x00, 0x00, 0x43, 0x84, 0x22, 0x58, 0x10, 0xb1, 0x02, 0x2b, 0xd8, 0x42, + 0x2b, 0x80, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, 0x83, + 0x3b, 0x80, 0xc1, 0x1c, 0xb8, 0x41, 0x1d, 0x80, 0xc1, 0x10, 0xc3, 0x10, + 0x0c, 0xc2, 0x08, 0x86, 0x20, 0x05, 0x61, 0x08, 0x86, 0x60, 0x04, 0x0b, + 0x8a, 0x56, 0x28, 0x05, 0x5a, 0x08, 0x05, 0x56, 0x18, 0x22, 0x14, 0xc6, + 0x82, 0x2d, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x60, 0x1c, 0xde, 0xa1, 0x1d, + 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, 0xdc, 0x80, 0x1c, 0xca, 0xc1, 0x1d, + 0xde, 0x41, 0x1e, 0xda, 0x61, 0x1e, 0x7e, 0x81, 0x1c, 0xd2, 0x61, 0x1e, + 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0x86, 0x08, 0x05, 0xb2, 0x80, 0x0b, + 0x87, 0x74, 0x90, 0x07, 0x37, 0x18, 0x87, 0x77, 0x68, 0x07, 0x78, 0x48, + 0x07, 0x76, 0x28, 0x07, 0x37, 0x30, 0x87, 0x70, 0x98, 0x07, 0x7a, 0xf8, + 0x85, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x87, 0x5f, 0x28, 0x07, 0x77, 0x08, + 0x07, 0x71, 0x60, 0x87, 0x72, 0x18, 0x22, 0x14, 0xca, 0x82, 0x32, 0x08, + 0x87, 0x74, 0x90, 0x07, 0x37, 0x18, 0x87, 0x77, 0x68, 0x07, 0x78, 0x48, + 0x07, 0x76, 0x28, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, + 0x07, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x5f, 0x30, + 0x87, 0x72, 0xa0, 0x87, 0x71, 0x40, 0x87, 0x5f, 0x20, 0x87, 0x74, 0x98, + 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x21, 0x42, 0xc1, 0x2c, 0x08, + 0x83, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, + 0x87, 0x74, 0x60, 0x87, 0x72, 0x70, 0x03, 0x77, 0x08, 0x07, 0x7a, 0x48, + 0x07, 0x7b, 0x28, 0x87, 0x5f, 0x20, 0x87, 0x77, 0xa8, 0x07, 0x71, 0x60, + 0x87, 0x72, 0xf8, 0x05, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x18, 0x62, 0x10, 0x40, 0xe1, 0x14, 0xd5, 0x10, 0xa1, 0x78, + 0x86, 0x30, 0x05, 0x64, 0x04, 0x45, 0x54, 0x48, 0xc5, 0x54, 0x50, 0x0b, + 0xa2, 0x70, 0x48, 0x07, 0x79, 0x70, 0x03, 0x79, 0x28, 0x07, 0x77, 0x20, + 0x87, 0x72, 0x90, 0x87, 0x5f, 0xa0, 0x87, 0x70, 0x90, 0x87, 0x73, 0x28, + 0x07, 0x7a, 0x58, 0x10, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x84, 0x83, + 0x3c, 0x9c, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xfc, 0x82, + 0x3b, 0x84, 0x43, 0x3b, 0x94, 0xc3, 0x02, 0xc3, 0x1c, 0xd8, 0xe1, 0x1d, + 0xc2, 0x81, 0x1e, 0xe8, 0x60, 0x01, 0x13, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, + 0x10, 0x0e, 0xf2, 0x70, 0x0e, 0xbf, 0xe0, 0x0e, 0xe1, 0xd0, 0x0e, 0xe5, + 0xb0, 0x60, 0x9a, 0x05, 0x52, 0x60, 0x85, 0x5f, 0x98, 0x85, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x72, 0xf8, 0x05, 0x73, 0x90, 0x87, 0x70, 0x38, + 0x87, 0x76, 0x28, 0x07, 0x77, 0xa0, 0x87, 0x21, 0x42, 0x61, 0x0d, 0x01, + 0x03, 0x23, 0x28, 0xae, 0x02, 0x33, 0x86, 0x22, 0x33, 0x02, 0x43, 0x28, + 0xb4, 0x62, 0x33, 0x86, 0x82, 0x33, 0x86, 0x22, 0x2a, 0xa4, 0x62, 0x2a, + 0xba, 0x05, 0x4a, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x38, 0xd4, 0x83, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0xc3, 0x82, 0x27, 0x1c, 0xd2, 0x41, 0x1e, + 0xdc, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xe1, 0x17, + 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x16, 0x48, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xec, 0xf0, 0x0e, 0xe3, 0x10, 0x0e, 0xf4, 0x90, 0x0e, 0xef, + 0xe0, 0x0e, 0xbf, 0x90, 0x0e, 0xee, 0x40, 0x0e, 0xe5, 0x80, 0x0f, 0x0b, + 0x90, 0x70, 0x48, 0x07, 0x79, 0x70, 0x03, 0x79, 0x28, 0x87, 0x70, 0x20, + 0x87, 0x05, 0x51, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x41, 0x38, 0xc8, 0xc3, + 0x39, 0xfc, 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0xc3, 0x2f, 0xcc, 0x43, + 0x3a, 0xe8, 0x43, 0x39, 0x2c, 0xb8, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, + 0xc2, 0x41, 0x1e, 0xce, 0xe1, 0x17, 0xe8, 0x21, 0x1f, 0xe0, 0xa1, 0x1c, + 0x7e, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0x7e, 0x61, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x61, 0xc1, 0x30, 0x0e, 0xef, 0xc0, 0x0e, 0x43, + 0x8c, 0xe2, 0x2b, 0xbe, 0xa3, 0x18, 0x62, 0x14, 0x60, 0x50, 0x84, 0xc1, + 0x51, 0x2c, 0x78, 0xde, 0xa1, 0x1d, 0xdc, 0x21, 0x1d, 0xe0, 0xe1, 0x1d, + 0xe8, 0xa1, 0x1c, 0xdc, 0x81, 0x1e, 0xc0, 0x60, 0x1c, 0xd0, 0x21, 0x1c, + 0xe4, 0x61, 0x88, 0x50, 0x88, 0xc1, 0x82, 0x68, 0x16, 0xd2, 0xa1, 0x1d, + 0xe0, 0x81, 0x1d, 0xca, 0x01, 0x0c, 0x46, 0xe1, 0x0d, 0x46, 0x61, 0x0d, + 0xd6, 0x00, 0x0c, 0x68, 0x41, 0x14, 0x42, 0x21, 0x14, 0x46, 0x28, 0xec, + 0xc0, 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, + 0x40, 0x0f, 0x53, 0x02, 0x60, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, + 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, + 0x02, 0x61, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, + 0xe0, 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, + 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x18, + 0x46, 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, + 0x00, 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, + 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x85, 0x28, 0x8e, 0x64, 0x19, + 0xc1, 0x84, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x98, 0x83, 0x3c, 0x84, 0xc3, + 0x39, 0xb4, 0x43, 0x39, 0xb8, 0x03, 0x3d, 0x4c, 0x09, 0x1a, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x07, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x06, 0x30, 0xb1, 0x5d, 0xf9, 0xb3, 0x08, 0xf3, 0x2c, 0xc4, + 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x01, 0x05, 0x25, 0x83, + 0x70, 0x20, 0x02, 0x00, 0x00, 0x00, 0x66, 0x30, 0x08, 0xce, 0x02, 0x00, + 0x00, 0x00, 0x01, 0x31, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x06, + 0x20, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0xc8, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, + 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xaf, 0x02, 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, 0x9c, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0x60, 0x00, 0x16, + 0xa0, 0xda, 0xf0, 0x1a, 0xc2, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x44, + 0xb0, 0x43, 0x39, 0xcc, 0xc3, 0x3c, 0xb4, 0x01, 0x3c, 0xc8, 0x43, 0x39, + 0x8c, 0x43, 0x3a, 0xcc, 0x43, 0x39, 0xb4, 0x81, 0x39, 0xc0, 0x43, 0x3b, + 0x84, 0x03, 0x39, 0x00, 0xf4, 0x20, 0x0f, 0xf5, 0x50, 0x0e, 0x00, 0xe1, + 0x0e, 0xef, 0xd0, 0x06, 0xe6, 0x20, 0x0f, 0xe1, 0xd0, 0x0e, 0xe5, 0xd0, + 0x06, 0xf0, 0xf0, 0x0e, 0xe9, 0xe0, 0x0e, 0xf4, 0x50, 0x0e, 0xf2, 0xd0, + 0x06, 0xe5, 0xc0, 0x0e, 0xe9, 0xd0, 0x0e, 0x00, 0x3d, 0xc8, 0x43, 0x3d, + 0x94, 0x03, 0x30, 0xb8, 0xc3, 0x3b, 0xb4, 0x81, 0x39, 0xc8, 0x43, 0x38, + 0xb4, 0x43, 0x39, 0xb4, 0x01, 0x3c, 0xbc, 0x43, 0x3a, 0xb8, 0x03, 0x3d, + 0x94, 0x83, 0x3c, 0xb4, 0x41, 0x39, 0xb0, 0x43, 0x3a, 0xb4, 0x43, 0x1b, + 0xb8, 0xc3, 0x3b, 0xb8, 0x43, 0x1b, 0xb0, 0x43, 0x39, 0x84, 0x83, 0x39, + 0x00, 0x84, 0x3b, 0xbc, 0x43, 0x1b, 0xa4, 0x83, 0x3b, 0x98, 0xc3, 0x3c, + 0xb4, 0x81, 0x39, 0xc0, 0x43, 0x1b, 0xb4, 0x43, 0x38, 0xd0, 0x03, 0x3a, + 0x00, 0xf4, 0x20, 0x0f, 0xf5, 0x50, 0x0e, 0x00, 0xe1, 0x0e, 0xef, 0xd0, + 0x06, 0xee, 0x10, 0x0e, 0xee, 0x30, 0x0f, 0x6d, 0x60, 0x0e, 0xf0, 0xd0, + 0x06, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x00, 0x3d, 0xc8, 0x43, 0x3d, + 0x94, 0x03, 0x40, 0xcc, 0x03, 0x3d, 0x84, 0xc3, 0x38, 0xac, 0x43, 0x1b, + 0xc0, 0x83, 0x3c, 0xbc, 0x03, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, + 0xc8, 0x43, 0x1b, 0x88, 0x43, 0x3d, 0x98, 0x83, 0x39, 0x94, 0x83, 0x3c, + 0xb4, 0xc1, 0x3c, 0xa4, 0x83, 0x3e, 0x94, 0x03, 0x80, 0x07, 0x00, 0x51, + 0x0f, 0xee, 0x30, 0x0f, 0xe1, 0x60, 0x0e, 0xe5, 0xd0, 0x06, 0xe6, 0x00, + 0x0f, 0x6d, 0xd0, 0x0e, 0xe1, 0x40, 0x0f, 0xe8, 0x00, 0xd0, 0x83, 0x3c, + 0xd4, 0x43, 0x39, 0x00, 0x44, 0x3d, 0xcc, 0x43, 0x39, 0xb4, 0xc1, 0x3c, + 0xbc, 0x83, 0x39, 0xd0, 0x43, 0x1b, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, + 0xd0, 0x03, 0x60, 0x0e, 0xe1, 0xc0, 0x0e, 0xf3, 0x50, 0x0e, 0xc0, 0x06, + 0x62, 0x20, 0x00, 0x31, 0xd8, 0x40, 0x10, 0x06, 0x20, 0x06, 0x1b, 0x5a, + 0xa3, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x81, 0x60, 0x87, 0x72, 0x98, 0x87, + 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 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, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 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, 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, 0x88, + 0x7a, 0x98, 0x87, 0x72, 0x68, 0x83, 0x79, 0x78, 0x07, 0x73, 0xa0, 0x87, + 0x36, 0x30, 0x07, 0x76, 0x78, 0x87, 0x70, 0xa0, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x80, 0x0d, 0x84, 0xf1, 0xff, 0xff, 0xff, + 0xff, 0x03, 0x20, 0x01, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x98, 0x30, 0x0c, 0x44, 0x31, 0x61, + 0x18, 0x08, 0x03, 0x89, 0x20, 0x00, 0x00, 0x1e, 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, 0x48, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, + 0x20, 0x00, 0x83, 0x08, 0x81, 0x70, 0x94, 0x34, 0x45, 0x94, 0x30, 0xf9, + 0xff, 0x44, 0x5c, 0x13, 0x15, 0x11, 0xbf, 0x3d, 0xfc, 0xd3, 0x18, 0x01, + 0x30, 0x88, 0x40, 0x04, 0xa5, 0x08, 0x41, 0x8c, 0x42, 0xe6, 0x22, 0x69, + 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, + 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x39, 0x82, 0x60, 0x8e, 0x00, 0x0c, + 0x86, 0x11, 0x84, 0xa5, 0x20, 0xa1, 0x24, 0xa1, 0x98, 0x02, 0xd4, 0x06, + 0x02, 0xe6, 0x08, 0x40, 0x61, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, + 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, + 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, + 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, + 0x03, 0x38, 0xd8, 0xf0, 0x1e, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, + 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0x60, 0x0e, 0x78, 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, + 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, + 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, + 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, + 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, + 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x78, + 0x00, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, + 0x80, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0x30, 0x84, 0x39, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xc2, 0x38, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0x81, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, + 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, + 0x04, 0x43, 0x5a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x05, 0x51, 0x04, 0x65, + 0x40, 0x70, 0x04, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x1a, + 0x01, 0x00, 0x00, 0x43, 0x84, 0x27, 0x58, 0x10, 0xb1, 0x02, 0x2b, 0xd8, + 0x42, 0x2b, 0x80, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, + 0x83, 0x3b, 0x80, 0xc1, 0x1c, 0xb8, 0x41, 0x1d, 0x80, 0xc1, 0x10, 0x63, + 0x11, 0x96, 0x62, 0x19, 0x86, 0x20, 0x0f, 0xb1, 0x08, 0x8b, 0xb0, 0x0c, + 0x0b, 0x8a, 0x56, 0x28, 0x05, 0x5a, 0x08, 0x05, 0x56, 0x18, 0x22, 0x3c, + 0xc6, 0x82, 0x2d, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x60, 0x1c, 0xde, 0xa1, + 0x1d, 0xe0, 0x21, 0x1d, 0xd8, 0xa1, 0x1c, 0xdc, 0x80, 0x1c, 0xca, 0xc1, + 0x1d, 0xde, 0x41, 0x1e, 0xda, 0x61, 0x1e, 0x7e, 0x81, 0x1c, 0xd2, 0x61, + 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0x86, 0x08, 0x0f, 0xb2, 0x80, + 0x0b, 0x87, 0x74, 0x90, 0x07, 0x37, 0x18, 0x87, 0x77, 0x68, 0x07, 0x78, + 0x48, 0x07, 0x76, 0x28, 0x07, 0x37, 0x30, 0x87, 0x70, 0x98, 0x07, 0x7a, + 0xf8, 0x85, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x87, 0x5f, 0x28, 0x07, 0x77, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x18, 0x22, 0x3c, 0xca, 0x82, 0x32, + 0x08, 0x87, 0x74, 0x90, 0x07, 0x37, 0x18, 0x87, 0x77, 0x68, 0x07, 0x78, + 0x48, 0x07, 0x76, 0x28, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, + 0x28, 0x07, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x5f, + 0x30, 0x87, 0x72, 0xa0, 0x87, 0x71, 0x40, 0x87, 0x5f, 0x20, 0x87, 0x74, + 0x98, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x21, 0xc2, 0xc3, 0x2c, + 0x08, 0x83, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, + 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0x70, 0x03, 0x77, 0x08, 0x07, 0x7a, + 0x48, 0x07, 0x7b, 0x28, 0x87, 0x5f, 0x20, 0x87, 0x77, 0xa8, 0x07, 0x71, + 0x60, 0x87, 0x72, 0xf8, 0x05, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, + 0x60, 0x87, 0x72, 0x18, 0x62, 0x1c, 0xc0, 0xe3, 0x3c, 0xd5, 0x10, 0xe1, + 0x79, 0x86, 0x30, 0x0f, 0xb4, 0x0c, 0x4f, 0xf4, 0x48, 0xcf, 0xf4, 0x50, + 0x0b, 0xa2, 0x70, 0x48, 0x07, 0x79, 0x70, 0x03, 0x79, 0x28, 0x07, 0x77, + 0x20, 0x87, 0x72, 0x90, 0x87, 0x5f, 0xa0, 0x87, 0x70, 0x90, 0x87, 0x73, + 0x28, 0x07, 0x7a, 0x58, 0x10, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x84, + 0x83, 0x3c, 0x9c, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xfc, + 0x82, 0x3b, 0x84, 0x43, 0x3b, 0x94, 0xc3, 0x02, 0xc3, 0x1c, 0xd8, 0xe1, + 0x1d, 0xc2, 0x81, 0x1e, 0xe8, 0x60, 0x01, 0x13, 0x0e, 0xe9, 0x20, 0x0f, + 0x6e, 0x10, 0x0e, 0xf2, 0x70, 0x0e, 0xbf, 0xe0, 0x0e, 0xe1, 0xd0, 0x0e, + 0xe5, 0xb0, 0x20, 0x9a, 0x05, 0x52, 0x60, 0x85, 0x5f, 0x18, 0x85, 0x77, + 0x80, 0x87, 0x7c, 0xf8, 0x05, 0x73, 0x90, 0x87, 0x70, 0x38, 0x87, 0x76, + 0x28, 0x07, 0x77, 0xa0, 0x87, 0x21, 0xc8, 0x63, 0x3d, 0xdb, 0x13, 0x06, + 0x4f, 0x1a, 0x0c, 0x81, 0x96, 0xe1, 0xb9, 0x1e, 0xec, 0xc9, 0x9e, 0xe8, + 0x91, 0x9e, 0xe9, 0xd1, 0x16, 0x30, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, + 0xf0, 0xf0, 0x0e, 0xf3, 0x90, 0x0e, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, + 0x0b, 0x94, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x28, 0x07, 0x77, + 0xa0, 0x87, 0x72, 0x90, 0x87, 0x05, 0x52, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x3b, 0xbc, 0xc3, 0x2f, 0xc0, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xc0, + 0x43, 0x39, 0x8c, 0x03, 0x3d, 0xa4, 0x83, 0x3d, 0x94, 0xc3, 0x02, 0x04, + 0x1e, 0xde, 0x61, 0x1e, 0xd2, 0x81, 0x1e, 0xd2, 0xe1, 0x1d, 0xdc, 0x61, + 0x88, 0xb4, 0x08, 0x0f, 0xf7, 0x74, 0x0f, 0xf6, 0x78, 0x4f, 0xf4, 0x7c, + 0xcf, 0xf4, 0x80, 0xc1, 0x02, 0x29, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0xc0, + 0x1c, 0xe4, 0x21, 0x1c, 0xce, 0xa1, 0x1d, 0xca, 0xc1, 0x1d, 0xe8, 0xe1, + 0x17, 0xd2, 0xc1, 0x1d, 0xe0, 0xa1, 0x1e, 0xe8, 0x61, 0x41, 0x76, 0x0e, + 0xe5, 0xe0, 0x0e, 0xe5, 0x20, 0x0f, 0xe1, 0x40, 0x0f, 0xe5, 0x40, 0x0e, + 0x68, 0x80, 0x07, 0xf4, 0x50, 0x0e, 0xf8, 0x30, 0x0e, 0xef, 0xf0, 0x0e, + 0xf2, 0x40, 0x0e, 0xa4, 0x60, 0x0f, 0x72, 0xf0, 0x0b, 0xe6, 0x90, 0x06, + 0x0b, 0x9e, 0x70, 0x48, 0x07, 0x79, 0x70, 0x03, 0x78, 0x28, 0x07, 0x79, + 0x98, 0x07, 0x78, 0x28, 0x87, 0x71, 0xa0, 0x87, 0x74, 0xb0, 0x87, 0x72, + 0x58, 0x60, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, 0x83, 0x1c, 0x2c, + 0x40, 0xe8, 0xa1, 0x1c, 0xf0, 0x61, 0x1c, 0xde, 0xe1, 0x1d, 0xe4, 0x81, + 0x1c, 0x86, 0x80, 0xc1, 0x62, 0x3c, 0x62, 0xf0, 0x8c, 0xc1, 0x42, 0x3c, + 0x64, 0xb0, 0x0c, 0x8b, 0xf0, 0x94, 0xc1, 0x63, 0x06, 0x0b, 0xf1, 0x9c, + 0xc1, 0x42, 0x3c, 0xd1, 0x23, 0x3d, 0xd3, 0x83, 0x06, 0x0b, 0x94, 0x70, + 0x48, 0x07, 0x79, 0x70, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, + 0x90, 0x87, 0x05, 0x4f, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x38, 0xd4, + 0x83, 0x39, 0x98, 0x43, 0x39, 0xc8, 0xc3, 0x2f, 0xcc, 0x43, 0x3a, 0xe8, + 0x43, 0x39, 0x2c, 0x90, 0xc2, 0x21, 0x1d, 0xe4, 0xc1, 0x0d, 0xd8, 0xe1, + 0x1d, 0xc6, 0x21, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x21, + 0x1d, 0xdc, 0x81, 0x1c, 0xca, 0x01, 0x1f, 0x16, 0x20, 0xe1, 0x90, 0x0e, + 0xf2, 0xe0, 0x06, 0xf2, 0x50, 0x0e, 0xe1, 0x40, 0x0e, 0x0b, 0xa2, 0x70, + 0x48, 0x07, 0x79, 0x70, 0x83, 0x70, 0x90, 0x87, 0x73, 0xf8, 0x05, 0x7a, + 0xc8, 0x07, 0x78, 0x28, 0x87, 0x5f, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, + 0x58, 0x70, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x84, 0x83, 0x3c, 0x9c, + 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xfc, 0x42, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xfc, 0xc2, 0x3c, 0xa4, 0x83, 0x3e, 0x94, + 0xc3, 0x82, 0x61, 0x1c, 0xde, 0x81, 0x1d, 0x86, 0x50, 0xcb, 0xf1, 0xa8, + 0xc1, 0x43, 0x06, 0xcb, 0xb0, 0x08, 0xcf, 0x1a, 0x3c, 0xd1, 0xc3, 0x06, + 0xcf, 0xf4, 0xb4, 0xc1, 0x82, 0x25, 0x1c, 0xd2, 0x41, 0x1e, 0xdc, 0x80, + 0x1e, 0xca, 0x01, 0x1f, 0xe8, 0xa1, 0x1e, 0xe4, 0xa1, 0x1c, 0x16, 0x28, + 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xf3, 0x10, 0x0e, 0xed, 0x00, 0x0f, + 0xec, 0x50, 0x0e, 0x0b, 0x30, 0x7a, 0x28, 0x07, 0x7c, 0xa0, 0x87, 0x7a, + 0x90, 0x87, 0x72, 0x90, 0x03, 0x72, 0xe0, 0x03, 0x73, 0x60, 0x87, 0x77, + 0x08, 0x07, 0x7a, 0x60, 0x03, 0x30, 0x98, 0x87, 0x70, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x72, 0xf0, 0x83, 0x05, 0x03, 0x3d, 0x94, 0x03, 0x3e, 0x0c, + 0x31, 0x9e, 0x37, 0x78, 0xde, 0x00, 0x42, 0x86, 0x18, 0x0f, 0x1c, 0x3c, + 0x71, 0x00, 0x21, 0x0b, 0x9e, 0x77, 0x68, 0x07, 0x77, 0x48, 0x07, 0x78, + 0x78, 0x07, 0x7a, 0x28, 0x07, 0x77, 0xa0, 0x07, 0x30, 0x18, 0x07, 0x74, + 0x08, 0x07, 0x79, 0x18, 0x22, 0x3c, 0x72, 0xb0, 0x20, 0x9a, 0x85, 0x74, + 0x68, 0x07, 0x78, 0x60, 0x87, 0x72, 0x00, 0x83, 0x51, 0x78, 0x83, 0x51, + 0x58, 0x83, 0x35, 0x00, 0x03, 0x5a, 0x10, 0x85, 0x50, 0x08, 0x85, 0x11, + 0x0a, 0x3b, 0xb0, 0x83, 0x3d, 0xb4, 0x83, 0x1b, 0xa4, 0x03, 0x39, 0x94, + 0x83, 0x3b, 0xd0, 0xc3, 0x94, 0x00, 0x18, 0xb1, 0x84, 0x43, 0x3a, 0xc8, + 0x83, 0x1b, 0xd8, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x94, 0x40, 0x18, 0x41, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0xb0, + 0x43, 0x38, 0xb8, 0xc3, 0x39, 0xd4, 0x43, 0x38, 0x9c, 0x43, 0x39, 0xfc, + 0x82, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0x4c, + 0x09, 0x86, 0x11, 0x53, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0xc1, 0x38, 0xbc, + 0x43, 0x3b, 0xc0, 0x43, 0x3a, 0xb0, 0x43, 0x39, 0xfc, 0xc2, 0x3b, 0xc0, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x3c, 0x4c, 0x21, 0x8a, 0x23, + 0x59, 0x46, 0x30, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe6, 0x20, 0x0f, + 0xe1, 0x70, 0x0e, 0xed, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, 0x06, + 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x33, + 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, + 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, + 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, + 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, + 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, + 0x87, 0x70, 0x20, 0x07, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, + 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, 0x48, 0xe4, 0x4b, + 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, + 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x1f, + 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x04, 0xeb, 0xdd, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3f, 0x80, 0xd8, 0x08, 0x00, 0xa9, 0x1a, 0x18, 0x01, 0xa0, 0x64, + 0x0a, 0x1b, 0x08, 0x8c, 0x00, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x48, + 0x87, 0x90, 0x10, 0xc5, 0x10, 0x50, 0x52, 0x4c, 0x08, 0xe4, 0x93, 0x41, + 0x38, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x96, 0xc0, 0x54, 0x44, 0x34, + 0xf9, 0x82, 0x43, 0x44, 0x02, 0x41, 0x9b, 0x02, 0x53, 0x11, 0xd1, 0xe4, + 0x0b, 0x0e, 0x11, 0x09, 0x44, 0x6d, 0x0c, 0xca, 0x44, 0x5c, 0xbe, 0xe0, + 0x10, 0x91, 0x40, 0xd8, 0xc2, 0x20, 0x38, 0x0b, 0x00, 0x00, 0x00, 0x01, + 0x31, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0x70, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; +const unsigned int sdl_metallib_len = 9508; diff --git a/src/render/metal/SDL_shaders_metal.metal b/src/render/metal/SDL_shaders_metal.metal new file mode 100644 index 000000000..2320f4d92 --- /dev/null +++ b/src/render/metal/SDL_shaders_metal.metal @@ -0,0 +1,34 @@ +#include + +using namespace metal; + +vertex float4 SDL_Simple_vertex(constant float2 *position [[buffer(0)]], uint vid [[vertex_id]]) +{ + return float4(position[vid].x, position[vid].y, 0.0f, 1.0f); +} + +fragment float4 SDL_Simple_fragment(constant float4 &col [[buffer(0)]]) +{ + return col; +} + +struct CopyVertex +{ + float4 position [[position]]; + float2 texcoord; +}; + +vertex CopyVertex SDL_Copy_vertex(constant float2 *position [[buffer(0)]], constant float2 *texcoords [[buffer(1)]], uint vid [[vertex_id]]) +{ + CopyVertex retval; + retval.position = float4(position[vid].x, position[vid].y, 0.0f, 1.0f); + retval.texcoord = texcoords[vid]; + return retval; +} + +fragment float4 SDL_Copy_fragment(CopyVertex vert [[stage_in]], constant float4 &col [[buffer(0)]], texture2d tex [[texture(0)]]) +{ + constexpr sampler samp; // !!! FIXME: linear sampling, etc? + return tex.sample(samp, vert.texcoord) * col; +} + diff --git a/src/render/metal/build-metal-shaders.sh b/src/render/metal/build-metal-shaders.sh new file mode 100644 index 000000000..42e9a2298 --- /dev/null +++ b/src/render/metal/build-metal-shaders.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -x +set -e + +cd `dirname "$0"` +rm -f sdl.air sdl.metalar sdl.metallib +/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/usr/bin/metal -std=osx-metal1.1 -Wall -O3 -o ./sdl.air ./SDL_shaders_metal.metal +/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/usr/bin/metal-ar rc sdl.metalar sdl.air +/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/usr/bin/metallib -o sdl.metallib sdl.metalar +xxd -i sdl.metallib |perl -w -p -e 's/\Aunsigned /const unsigned /;' >./SDL_shaders_metal.c +rm -f sdl.air sdl.metalar sdl.metallib +