Compare commits

..

14 Commits

Author SHA1 Message Date
Geoffrey McRae
f77986b863 [client] wayland: set the application icon
Some checks are pending
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / module (push) Waiting to run
build / host-linux (push) Waiting to run
build / host-windows-cross (push) Waiting to run
build / host-windows-native (push) Waiting to run
build / idd (push) Waiting to run
build / obs (clang) (push) Waiting to run
build / obs (gcc) (push) Waiting to run
build / docs (push) Waiting to run
2026-07-17 03:12:06 +10:00
Geoffrey McRae
aa25b0cfe3 [idd] hdr: correct the BT.709 to BT.2020 conversion 2026-07-17 03:10:55 +10:00
Geoffrey McRae
e332dc77f2 [obs] fix HDR support to properly convert from PQ 2026-07-16 23:13:36 +10:00
Geoffrey McRae
adb4fcb57a [client] fix the HDR colorspace mapping to SDR
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-07-16 20:25:20 +10:00
Geoffrey McRae
ef8a4e2923 [idd] use the actual surface colorspace instead of guessing 2026-07-16 20:24:23 +10:00
Geoffrey McRae
4734a4028a [idd] collapse duplicate messages to the latest event only 2026-07-16 19:43:24 +10:00
Geoffrey McRae
97d43f17b6 [client] fix reversed event timestamp logic 2026-07-16 19:43:02 +10:00
Geoffrey McRae
5e6d88f382 [idd] debounce resolution changes 2026-07-16 19:32:12 +10:00
Geoffrey McRae
1ce446f97a [idd] stop using IddCxMonitorUpdateModes(2)
While it would make much more sense to use these then a full replug to
change modes, Microsoft have not properly implemented the API to clear
the cached monitor mode states internally, making these calls useless.

Revert to just replugging the device on mode change
2026-07-16 19:24:24 +10:00
Geoffrey McRae
b97a0b79f1 [idd] don't rebuild the monitor from inside the old monitor's context
Some checks are pending
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / module (push) Waiting to run
build / host-linux (push) Waiting to run
build / host-windows-cross (push) Waiting to run
build / host-windows-native (push) Waiting to run
build / idd (push) Waiting to run
build / obs (clang) (push) Waiting to run
build / obs (gcc) (push) Waiting to run
build / docs (push) Waiting to run
2026-07-16 16:13:24 +10:00
Geoffrey McRae
fbf564f2e1 [idd] prevent races from corrupting the mode list and edid 2026-07-16 15:26:21 +10:00
Geoffrey McRae
0140a3f6fb [client/idd] hdr: fix incorrect tone mapping knee bug
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
2026-07-16 10:48:10 +10:00
Geoffrey McRae
e502af7d9d Revert "[idd/client] correct HDR luminance when PQ conversion is in use"
This reverts commit 05d8bc5311.
2026-07-16 09:58:44 +10:00
Geoffrey McRae
05d8bc5311 [idd/client] correct HDR luminance when PQ conversion is in use 2026-07-16 09:34:02 +10:00
33 changed files with 1560 additions and 852 deletions

View File

@@ -16,6 +16,7 @@ add_library(displayserver_Wayland STATIC
colormgmt.c
cursor.c
gl.c
icon.c
idle.c
input.c
output.c
@@ -33,6 +34,7 @@ add_subdirectory(desktops)
target_link_libraries(displayserver_Wayland
PkgConfig::DISPLAYSERVER_Wayland
lg_common
lg_resources
wayland_protocol
wayland_desktops
)

View File

@@ -142,6 +142,11 @@ static bool libdecor_shellInit(
libdecor_frame_set_title(state.libdecorFrame, title);
libdecor_frame_map(state.libdecorFrame);
// Get the xdg_toplevel for icon setting
struct xdg_surface * xdgSurface = libdecor_frame_get_xdg_surface(state.libdecorFrame);
if (xdgSurface)
wlWm.xdgToplevel = xdg_surface_get_toplevel(xdgSurface);
if (fullscreen)
libdecor_frame_set_fullscreen(state.libdecorFrame, NULL);

View File

@@ -149,6 +149,7 @@ bool xdg_shellInit(struct wl_display * display, struct wl_surface * surface,
xdg_toplevel_add_listener(state.toplevel, &xdgToplevelListener, NULL);
xdg_toplevel_set_title(state.toplevel, title);
xdg_toplevel_set_app_id(state.toplevel, appId);
wlWm.xdgToplevel = state.toplevel;
if (fullscreen)
xdg_toplevel_set_fullscreen(state.toplevel, NULL);

View File

@@ -280,22 +280,21 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
hdrPQ ? WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ
: WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_EXT_LINEAR);
// Set luminance range from metadata.
// min_lum is in 0.0001 cd/m² units (multiplied by 10000 as per protocol).
// max_lum and reference_lum are in unscaled cd/m² units.
// Set the primary colour volume luminances.
// min_lum : 0.0001 cd/m² (source already scaled) -> pass through
// max_lum : cd/m² (used only for scRGB; ignored for PQ, where the
// compositor forces it to min_lum + 10000 cd/m²)
// reference_lum : cd/m² -> BT.2408 diffuse white (203 PQ / 80 scRGB)
if (wlWm.cmHasLuminances)
wp_image_description_creator_params_v1_set_luminances(
wlWm.hdrImageCreator,
minDisplayLuminance > 0 ? minDisplayLuminance : 50,
maxDisplayLuminance > 0 ? maxDisplayLuminance / 10000 : 1000,
hdrPQ ? 203 : 80);
maxDisplayLuminance > 0 ? maxDisplayLuminance : 1000,
hdrPQ ? 203 : 80);
// Set mastering display primaries from frame HDR metadata.
// Always set when the compositor supports it, falling back to the
// primaries from the metadata (even if zero, in which case the
// compositor uses its own defaults).
// Advertise the content primaries (BT.2020 for PQ). These describe the real
// colour gamut of the signal and are safe to forward.
if (wlWm.cmHasMasteringPrimaries)
{
wp_image_description_creator_params_v1_set_mastering_display_primaries(
wlWm.hdrImageCreator,
displayPrimary[0][0], displayPrimary[0][1],
@@ -303,19 +302,16 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
displayPrimary[2][0], displayPrimary[2][1],
whitePoint[0], whitePoint[1]);
// Set mastering luminance range so the compositor knows the target
// color volume for tone mapping. min_lum is in ×10000 units (0.0001 cd/m²),
// max_lum is in unscaled cd/m².
wp_image_description_creator_params_v1_set_mastering_luminance(
wlWm.hdrImageCreator,
minDisplayLuminance > 0 ? minDisplayLuminance : 50,
maxDisplayLuminance > 0 ? maxDisplayLuminance / 10000 : 1000);
}
if (maxCLL > 0)
wp_image_description_creator_params_v1_set_max_cll(wlWm.hdrImageCreator, maxCLL);
if (maxFALL > 0)
wp_image_description_creator_params_v1_set_max_fall(wlWm.hdrImageCreator, maxFALL);
// NOTE: we deliberately do NOT forward the host's mastering luminance range,
// MaxCLL or MaxFALL. Those values describe the *virtual display* the IDD
// advertises to Windows (~1000 cd/m² from our EDID), not the content. LG
// captures the full-range scRGB desktop composition and passes it through to
// PQ without tone mapping, so the signal spans the entire PQ range (scRGB
// 125.0 == 10000 cd/m²). Advertising the virtual display's peak as the
// content peak makes the compositor place its tone-mapping knee there and
// hard-clip everything brighter, crushing highlights. Leaving these unset
// lets the content be treated as standard full-range PQ so the compositor
// tone-maps it to the actual physical display.
wlWm.hdrImageDesc =
wp_image_description_creator_params_v1_create(wlWm.hdrImageCreator);
@@ -342,8 +338,10 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL);
wlWm.hdrActive = true;
DEBUG_INFO("HDR image description set on surface (%s, %s, %u nits)",
hdrPQ ? "PQ" : "scRGB", hdrPQ ? "BT.2020" : "sRGB", maxDisplayLuminance);
DEBUG_INFO("HDR image description set on surface (%s, %s, "
"maxLum:%u cd/m² minLum:%u (0.0001 cd/m²) maxCLL:%u maxFALL:%u)",
hdrPQ ? "PQ" : "scRGB", hdrPQ ? "BT.2020" : "sRGB",
maxDisplayLuminance, minDisplayLuminance, maxCLL, maxFALL);
}
bool waylandRequestHDR(const uint16_t displayPrimary[3][2],

View File

@@ -0,0 +1,136 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _GNU_SOURCE
#include "wayland.h"
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
#include <unistd.h>
#include <wayland-client.h>
#include "common/debug.h"
#include "resources/icondata.h"
// icondata is defined as an array of unsigned long, but on 64-bit platforms
// unsigned long is 8 bytes while the actual data is 32-bit ARGB packed in
// unsigned long values (the top 32 bits are zero). The first two values are
// width and height (both 64), followed by pixel rows.
// We need to convert this to a uint32_t buffer for wl_shm (ARGB8888).
//
// Note: sizeof(icondata) / sizeof(icondata[0]) gives the total array length,
// which includes the 2 header values + 64*64 = 4096 pixel values = 4098 total.
#define ICON_SIZE 64
// header: width and height, then pixel data
#define ICON_HEADER_WORDS 2
#define ICON_PIXEL_WORDS (ICON_SIZE * ICON_SIZE)
#define ICON_TOTAL_WORDS (ICON_HEADER_WORDS + ICON_PIXEL_WORDS)
static uint32_t g_iconPixels[ICON_SIZE * ICON_SIZE];
bool waylandIconInit(void)
{
if (!wlWm.iconManager || !wlWm.xdgToplevel || !wlWm.shm)
return true; // not an error, just no support
for (size_t i = 0; i < ICON_TOTAL_WORDS; ++i)
{
if (i >= icondataSize / sizeof(icondata[0]))
{
DEBUG_ERROR("Icon data array is smaller than expected");
return true;
}
uint32_t val = (uint32_t)icondata[i];
// First two words are width/height, skip them
if (i >= ICON_HEADER_WORDS)
g_iconPixels[i - ICON_HEADER_WORDS] = val;
}
// Create shared memory buffer for the icon
size_t dataSize = sizeof(g_iconPixels);
int fd = memfd_create("lg-icon", 0);
if (fd < 0)
{
DEBUG_ERROR("Failed to create icon shared memory: %d", errno);
return true; // not fatal
}
struct wl_buffer * buffer = NULL;
struct xdg_toplevel_icon_v1 * icon = NULL;
if (ftruncate(fd, (off_t)dataSize) < 0)
{
DEBUG_ERROR("Failed to ftruncate icon shared memory: %d", errno);
goto fail;
}
void * shm_data = mmap(NULL, dataSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shm_data == MAP_FAILED)
{
DEBUG_ERROR("Failed to mmap icon shared memory: %d", errno);
goto fail;
}
memcpy(shm_data, g_iconPixels, dataSize);
munmap(shm_data, dataSize);
struct wl_shm_pool * pool = wl_shm_create_pool(wlWm.shm, fd, (int32_t)dataSize);
buffer = wl_shm_pool_create_buffer(pool, 0, ICON_SIZE, ICON_SIZE,
ICON_SIZE * 4, WL_SHM_FORMAT_ARGB8888);
wl_shm_pool_destroy(pool);
if (!buffer)
{
DEBUG_ERROR("Failed to create wl_buffer for icon");
goto fail;
}
icon = xdg_toplevel_icon_manager_v1_create_icon(wlWm.iconManager);
if (!icon)
{
DEBUG_ERROR("Failed to create icon object");
goto fail;
}
xdg_toplevel_icon_v1_add_buffer(icon, buffer, 1);
xdg_toplevel_icon_manager_v1_set_icon(wlWm.iconManager,
(struct xdg_toplevel *)wlWm.xdgToplevel, icon);
// After set_icon, the icon object is immutable. We can destroy it;
// the compositor retains its data.
xdg_toplevel_icon_v1_destroy(icon);
wl_buffer_destroy(buffer);
close(fd);
return true;
fail:
if (icon)
xdg_toplevel_icon_v1_destroy(icon);
if (buffer)
wl_buffer_destroy(buffer);
close(fd);
return true; // not fatal
}

View File

@@ -69,6 +69,9 @@ wayland_generate(
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/staging/color-management/color-management-v1.xml"
"${CMAKE_BINARY_DIR}/wayland/wayland-color-management-v1-client-protocol")
wayland_generate(
"${WAYLAND_PROTOCOLS_BASE}/staging/xdg-toplevel-icon/xdg-toplevel-icon-v1.xml"
"${CMAKE_BINARY_DIR}/wayland/wayland-xdg-toplevel-icon-v1-client-protocol")
target_link_libraries(wayland_protocol
PkgConfig::WAYLAND

View File

@@ -77,6 +77,9 @@ static void registryGlobalHandler(void * data, struct wl_registry * registry,
else if (!strcmp(interface, wp_color_manager_v1_interface.name))
wlWm.colorManager = wl_registry_bind(wlWm.registry, name,
&wp_color_manager_v1_interface, 1);
else if (!strcmp(interface, xdg_toplevel_icon_manager_v1_interface.name))
wlWm.iconManager = wl_registry_bind(wlWm.registry, name,
&xdg_toplevel_icon_manager_v1_interface, 1);
else if (wlWm.desktop->registryGlobalHandler(
data, registry, name, interface, version))
return;

View File

@@ -170,6 +170,8 @@ static bool waylandInit(const LG_DSInitParams params)
if (!waylandEGLInit(params.w, params.h))
return false;
waylandIconInit();
#ifdef ENABLE_OPENGL
if (params.opengl && !waylandOpenGLInit())
return false;

View File

@@ -50,6 +50,7 @@
#include "wayland-fractional-scale-v1-client-protocol.h"
#include "wayland-content-type-v1-client-protocol.h"
#include "wayland-color-management-v1-client-protocol.h"
#include "wayland-xdg-toplevel-icon-v1-client-protocol.h"
#include "scale.h"
@@ -205,6 +206,12 @@ struct WaylandDSState
bool cmHasPerceptualIntent;
bool cmCanDoHDR; // true if compositor supports features needed for HDR
// toplevel icon manager
struct xdg_toplevel_icon_manager_v1 * iconManager;
// set by the active desktop backend during shellInit
void * xdgToplevel;
// Pending HDR format to apply (set by frame thread, applied in swap buffers).
// pendingHDRApply and pendingHDRClear are accessed from multiple threads
// without a lock, so they must be atomic.
@@ -370,3 +377,6 @@ bool waylandWaitFrame(void);
void waylandSkipFrame(void);
void waylandStopWaitFrame(void);
void waylandNeedsResize(void);
// icon module
bool waylandIconInit(void);

View File

@@ -617,7 +617,7 @@ static bool x11Init(const LG_DSInitParams params)
32,
PropModeReplace,
(unsigned char *)icondata,
sizeof(icondata) / sizeof(icondata[0])
icondataSize / sizeof(icondata[0])
);
/* create the blank cursor */

View File

@@ -102,7 +102,12 @@ vec3 bt2020to709(vec3 bt2020)
vec3 mapToSDR(vec3 color, float gain, bool pq)
{
if (pq)
{
// HDR10: PQ-encoded BT.2020. Linearise then convert the gamut to BT.709.
color = pq2lin(color.rgb, gain);
color = bt2020to709(color);
color = bt2020to709(color);
}
// else: scRGB is already linear BT.709 (1.0 == SDR white), so no EOTF or
// gamut conversion is required - only highlight compression below.
return lin2srgb(compress(color));
}

View File

@@ -102,7 +102,7 @@ void lgMessage_process(void)
case LG_MSG_WINDOWSIZE:
{
// retain the last/latest windowsize event
if (!windowSize || windowSize->timestamp > event->timestamp)
if (!windowSize || event->timestamp > windowSize->timestamp)
{
free(windowSize);
windowSize = event;
@@ -135,14 +135,14 @@ void lgMessage_process(void)
}
else
{
if (event->msg.windowSize.width != this.lastWindowSize.width ||
event->msg.windowSize.height != this.lastWindowSize.height)
if (windowSize->msg.windowSize.width != this.lastWindowSize.width ||
windowSize->msg.windowSize.height != this.lastWindowSize.height)
{
this.lastWindowSize.width = event->msg.windowSize.width;
this.lastWindowSize.height = event->msg.windowSize.height;
this.lastWindowSize.width = windowSize->msg.windowSize.width;
this.lastWindowSize.height = windowSize->msg.windowSize.height;
core_onWindowSizeChanged(
event->msg.windowSize.width,
event->msg.windowSize.height);
windowSize->msg.windowSize.width,
windowSize->msg.windowSize.height);
}
free(windowSize);
}

View File

@@ -167,7 +167,11 @@ typedef struct KVMFRFrame
// Display color primaries in 0.00002 units (SMPTE ST 2086 format)
uint16_t hdrDisplayPrimary[3][2]; // Rx,Ry, Gx,Gy, Bx,By
uint16_t hdrWhitePoint[2]; // Wx, Wy
uint32_t hdrMaxDisplayLuminance; // Max mastering display luminance (0.0001 cd/m²)
// Mastering display luminances follow SMPTE ST 2086 units: the maximum is
// in whole cd/m², the minimum in 0.0001 cd/m². (Note: the DXGI docs
// describe MaxMasteringLuminance as 0.0001 cd/m², but IddCx/ST 2086 provide
// it in whole cd/m².)
uint32_t hdrMaxDisplayLuminance; // Max mastering display luminance (cd/m²)
uint32_t hdrMinDisplayLuminance; // Min mastering display luminance (0.0001 cd/m²)
uint32_t hdrMaxContentLightLevel; // MaxCLL (cd/m²)
uint32_t hdrMaxFrameAverageLightLevel; // MaxFALL (cd/m²)

View File

@@ -24,6 +24,7 @@
#include <wdf.h>
#include <wrl.h>
#include <d3d12.h>
#include <atomic>
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
@@ -40,7 +41,7 @@ class CD3D12CommandQueue
ComPtr<ID3D12CommandList > m_cmdList;
ComPtr<ID3D12Fence > m_fence;
bool m_pending = false;
std::atomic<bool> m_pending = false;
HandleT<HANDLENullTraits> m_event;
HANDLE m_waitHandle = INVALID_HANDLE_VALUE;
UINT64 m_fenceValue = 0;

View File

@@ -147,6 +147,22 @@ void CD3D12Device::DeInit()
m_infoQueue.Reset();
}
void CD3D12Device::WaitForIdle()
{
// A queue is ready once its GPU work has signalled and its completion
// callback has run (clearing the pending flag). Bound the wait so a
// removed/hung device cannot stall teardown indefinitely.
auto drain = [](CD3D12CommandQueue& queue)
{
for (int i = 0; i < 1000 && !queue.IsReady(); ++i)
Sleep(1);
};
for (int i = 0; i < ARRAYSIZE(m_copyQueue); ++i)
drain(m_copyQueue[i]);
drain(m_computeQueue);
}
bool CD3D12Device::HeapTest()
{
D3D12_RESOURCE_DESC desc = {};

View File

@@ -69,6 +69,11 @@ struct CD3D12Device
InitResult Init(CIVSHMEM &ivshmem, UINT64 &alignSize);
void DeInit();
// Wait for all command queues to finish in-flight GPU work and run their
// completion callbacks. Used at swap-chain teardown so no callback touches
// resources we are about to release.
void WaitForIdle();
ComPtr<ID3D12Device3> GetDevice() { return m_device; }
ComPtr<ID3D12Heap > GetHeap() { return m_ivshmemHeap; }
bool IsIndirectCopy() { return m_indirectCopy; }

View File

@@ -43,6 +43,16 @@ CIVSHMEM::~CIVSHMEM()
bool CIVSHMEM::Init()
{
// Init may be called more than once (the adapter init is retried at boot
// until IVSHMEM enumerates). Release any handle from a prior attempt so we
// do not leak it when re-enumerating.
if (m_handle != INVALID_HANDLE_VALUE)
{
Close();
CloseHandle(m_handle);
m_handle = INVALID_HANDLE_VALUE;
}
HDEVINFO devInfoSet;
SP_DEVINFO_DATA devInfoData;
SP_DEVICE_INTERFACE_DATA devInterfaceData;

View File

@@ -99,19 +99,89 @@ void CIndirectDeviceContext::PopulateDefaultModes()
{
g_settings.LoadModes();
m_displayModes.clear();
m_displayModes.reserve(g_settings.GetDisplayModes().size());
// Build the new mode list and EDID into locals first so we only hold the
// lock for the swap. IddCx readers may be iterating the live containers on
// another thread; a clear()/push_back() under them would reallocate the
// backing store and crash. std::move makes the publish a pointer swap.
CSettings::DisplayModes newModes;
newModes.reserve(g_settings.GetDisplayModes().size());
for (auto& dm : g_settings.GetDisplayModes())
m_displayModes.push_back(dm);
newModes.push_back(dm);
m_edid.Build(m_displayModes);
CEdid newEdid;
newEdid.Build(newModes);
AcquireSRWLockExclusive(&m_modeLock);
m_displayModes = std::move(newModes);
m_edid = std::move(newEdid);
ReleaseSRWLockExclusive(&m_modeLock);
}
void CIndirectDeviceContext::ScheduleInitRetry()
{
// Create the retry timer once; if it already exists it is either running or
// will be (re)started below.
if (!m_initTimer)
{
WDF_TIMER_CONFIG config;
WDF_TIMER_CONFIG_INIT_PERIODIC(&config,
[](WDFTIMER timer) -> void
{
WDFOBJECT parent = WdfTimerGetParentObject(timer);
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(parent);
wrapper->context->InitAdapter();
},
500);
config.AutomaticSerialization = FALSE;
WDF_OBJECT_ATTRIBUTES attribs;
WDF_OBJECT_ATTRIBUTES_INIT(&attribs);
attribs.ParentObject = m_wdfDevice;
attribs.ExecutionLevel = WdfExecutionLevelDispatch;
NTSTATUS status = WdfTimerCreate(&config, &attribs, &m_initTimer);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR_HR(status, "Init retry timer creation failed");
m_initTimer = nullptr;
return;
}
}
WdfTimerStart(m_initTimer, WDF_REL_TIMEOUT_IN_MS(500));
}
void CIndirectDeviceContext::StopInitRetry()
{
if (m_initTimer)
WdfTimerStop(m_initTimer, FALSE);
}
void CIndirectDeviceContext::InitAdapter()
{
if (!m_ivshmem.Init() || !m_ivshmem.Open())
// The adapter only needs to be created once. D0Entry and the retry timer can
// both land here, so guard against re-entrancy and repeated creation.
if (m_adapter)
return;
if (InterlockedCompareExchange(&m_initInProgress, 1, 0) != 0)
return;
// At boot the IVSHMEM PCI device may not have enumerated yet. Rather than
// silently abandoning the adapter (leaving the device loaded but with no
// monitor), retry from a timer until the shared memory becomes available.
if (!m_ivshmemOpened)
{
if (!m_ivshmem.Init() || !m_ivshmem.Open())
{
DEBUG_WARN("IVSHMEM not available yet, scheduling init retry");
ScheduleInitRetry();
InterlockedExchange(&m_initInProgress, 0);
return;
}
m_ivshmemOpened = true;
}
QueryIddCxCapabilities();
PopulateDefaultModes();
@@ -170,6 +240,7 @@ void CIndirectDeviceContext::InitAdapter()
if (!NT_SUCCESS(status))
{
DEBUG_ERROR_HR(status, "IddCxAdapterInitAsync Failed");
InterlockedExchange(&m_initInProgress, 0);
return;
}
@@ -199,13 +270,37 @@ void CIndirectDeviceContext::InitAdapter()
auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(m_adapter);
wrapper->context = this;
// Adapter is up; no need to keep retrying.
StopInitRetry();
InterlockedExchange(&m_initInProgress, 0);
}
void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
{
// We support a single monitor; never create a second one if one already
// exists (a replug must clear m_monitor via departure first).
AcquireSRWLockExclusive(&m_stateLock);
bool haveMonitor = m_monitor != WDF_NO_HANDLE;
ReleaseSRWLockExclusive(&m_stateLock);
if (haveMonitor)
{
DEBUG_WARN("FinishInit skipped: a monitor already exists");
return;
}
WDF_OBJECT_ATTRIBUTES attr;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, CIndirectMonitorContextWrapper);
// Take a private copy of the EDID so a concurrent PopulateDefaultModes on
// the timer thread cannot reallocate the buffer out from under
// IddCxMonitorCreate. The copy lives for the duration of the synchronous
// create call below.
std::vector<BYTE> edid;
AcquireSRWLockShared(&m_modeLock);
edid.assign(m_edid.Data(), m_edid.Data() + m_edid.Size());
ReleaseSRWLockShared(&m_modeLock);
IDDCX_MONITOR_INFO info = {};
info.Size = sizeof(info);
info.MonitorType = DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI;
@@ -213,8 +308,8 @@ void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
info.MonitorDescription.Size = sizeof(info.MonitorDescription);
info.MonitorDescription.Type = IDDCX_MONITOR_DESCRIPTION_TYPE_EDID;
info.MonitorDescription.DataSize = m_edid.Size();
info.MonitorDescription.pData = const_cast<BYTE*>(m_edid.Data());
info.MonitorDescription.DataSize = (UINT)edid.size();
info.MonitorDescription.pData = edid.empty() ? nullptr : edid.data();
CoCreateGuid(&info.MonitorContainerId);
@@ -230,7 +325,10 @@ void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
return;
}
AcquireSRWLockExclusive(&m_stateLock);
m_monitor = createOut.MonitorObject;
ReleaseSRWLockExclusive(&m_stateLock);
auto * wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(m_monitor);
wrapper->context = new CIndirectMonitorContext(m_monitor, this);
@@ -245,62 +343,67 @@ void CIndirectDeviceContext::FinishInit(UINT connectorIndex)
void CIndirectDeviceContext::ReplugMonitor()
{
if (m_monitor == WDF_NO_HANDLE)
AcquireSRWLockExclusive(&m_stateLock);
if (m_replugMonitor)
{
ReleaseSRWLockExclusive(&m_stateLock);
return;
}
IDDCX_MONITOR monitor = m_monitor;
if (monitor == WDF_NO_HANDLE)
{
ReleaseSRWLockExclusive(&m_stateLock);
// Either no monitor yet, or one is already pending; build it now and
// cancel any queued rebuild so we do not create two.
InterlockedExchange(&m_finishInitQueued, 0);
FinishInit(0);
return;
}
if (m_replugMonitor)
return;
// Clear the handle before departing so nothing calls an IddCx monitor API on
// a departing/destroyed handle. FinishInit publishes the new one.
m_replugMonitor = true;
m_monitor = nullptr;
ReleaseSRWLockExclusive(&m_stateLock);
DEBUG_TRACE("ReplugMonitor");
m_replugMonitor = true;
NTSTATUS status = IddCxMonitorDeparture(m_monitor);
NTSTATUS status = IddCxMonitorDeparture(monitor);
if (!NT_SUCCESS(status))
{
AcquireSRWLockExclusive(&m_stateLock);
m_replugMonitor = false;
m_monitor = monitor;
ReleaseSRWLockExclusive(&m_stateLock);
DEBUG_ERROR("IddCxMonitorDeparture Failed (0x%08x)", status);
return;
}
// Always queue the rebuild here rather than relying on the unassign callback:
// if the monitor had no swap chain (e.g. recovering from a lost path) no
// unassign fires. The timer runs FinishInit off this thread.
InterlockedExchange(&m_finishInitQueued, 1);
}
void CIndirectDeviceContext::OnMonitorDestroyed(IDDCX_MONITOR monitor)
{
AcquireSRWLockExclusive(&m_stateLock);
if (m_monitor == monitor)
m_monitor = nullptr;
ReleaseSRWLockExclusive(&m_stateLock);
}
void CIndirectDeviceContext::OnAssignSwapChain()
{
InterlockedExchange(&m_recoverModeUpdateSwapChain, 0);
AcquireSRWLockExclusive(&m_stateLock);
bool doSetMode = m_doSetMode;
CSettings::DisplayMode mode = m_setMode;
m_doSetMode = false;
ReleaseSRWLockExclusive(&m_stateLock);
if (m_doSetMode)
{
m_doSetMode = false;
g_pipe.SetDisplayMode(m_setMode.width, m_setMode.height, m_setMode.refresh);
}
}
void CIndirectDeviceContext::OnUnassignedSwapChain()
{
InterlockedExchange(&m_replugMonitorQueued, 0);
InterlockedExchange(&m_recoverModeUpdateSwapChain, 0);
if (m_replugMonitor)
{
m_replugMonitor = false;
FinishInit(0);
}
}
void CIndirectDeviceContext::OnSwapChainLost()
{
// A mode update normally keeps the swap chain alive. If Windows instead
// reports the existing path disappeared before we see a frame at the new
// size, recover by scheduling the old replug path from the LGMP timer so we
// do not tear down the swap chain from one of its worker threads.
if (!InterlockedCompareExchange(&m_recoverModeUpdateSwapChain, 0, 0))
return;
if (InterlockedExchange(&m_replugMonitorQueued, 1))
return;
DEBUG_WARN("Swap chain was lost after a mode update, falling back to monitor replug");
if (doSetMode)
g_pipe.SetDisplayMode(mode.width, mode.height, mode.refresh);
}
static inline void FillSignalInfo(DISPLAYCONFIG_VIDEO_SIGNAL_INFO & mode, DWORD width, DWORD height, DWORD vsync, bool monitorMode)
@@ -324,13 +427,18 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription(
const IDARG_IN_PARSEMONITORDESCRIPTION* inArgs,
IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs)
{
outArgs->MonitorModeBufferOutputCount = (UINT)m_displayModes.size();
CSettings::DisplayModes modes;
AcquireSRWLockShared(&m_modeLock);
modes = m_displayModes;
ReleaseSRWLockShared(&m_modeLock);
outArgs->MonitorModeBufferOutputCount = (UINT)modes.size();
outArgs->PreferredMonitorModeIdx = 0;
if (inArgs->MonitorModeBufferInputCount < (UINT)m_displayModes.size())
if (inArgs->MonitorModeBufferInputCount < (UINT)modes.size())
return (inArgs->MonitorModeBufferInputCount > 0) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
auto * mode = inArgs->pMonitorModes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
{
mode->Size = sizeof(IDDCX_MONITOR_MODE);
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
@@ -338,7 +446,7 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription(
if (it->preferred)
outArgs->PreferredMonitorModeIdx =
(UINT)std::distance(m_displayModes.cbegin(), it);
(UINT)std::distance(modes.cbegin(), it);
}
return STATUS_SUCCESS;
@@ -348,13 +456,18 @@ NTSTATUS CIndirectDeviceContext::MonitorGetDefaultModes(
const IDARG_IN_GETDEFAULTDESCRIPTIONMODES* inArgs,
IDARG_OUT_GETDEFAULTDESCRIPTIONMODES* outArgs)
{
outArgs->DefaultMonitorModeBufferOutputCount = (UINT)m_displayModes.size();
CSettings::DisplayModes modes;
AcquireSRWLockShared(&m_modeLock);
modes = m_displayModes;
ReleaseSRWLockShared(&m_modeLock);
outArgs->DefaultMonitorModeBufferOutputCount = (UINT)modes.size();
outArgs->PreferredMonitorModeIdx = 0;
if (inArgs->DefaultMonitorModeBufferInputCount < (UINT)m_displayModes.size())
if (inArgs->DefaultMonitorModeBufferInputCount < (UINT)modes.size())
return (inArgs->DefaultMonitorModeBufferInputCount > 0) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
auto* mode = inArgs->pDefaultMonitorModes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
{
mode->Size = sizeof(IDDCX_MONITOR_MODE);
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_DRIVER;
@@ -362,7 +475,7 @@ NTSTATUS CIndirectDeviceContext::MonitorGetDefaultModes(
if (it->preferred)
outArgs->PreferredMonitorModeIdx =
(UINT)std::distance(m_displayModes.cbegin(), it);
(UINT)std::distance(modes.cbegin(), it);
}
return STATUS_SUCCESS;
@@ -372,12 +485,17 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes(
const IDARG_IN_QUERYTARGETMODES* inArgs,
IDARG_OUT_QUERYTARGETMODES* outArgs)
{
outArgs->TargetModeBufferOutputCount = (UINT)m_displayModes.size();
if (inArgs->TargetModeBufferInputCount < (UINT)m_displayModes.size())
CSettings::DisplayModes modes;
AcquireSRWLockShared(&m_modeLock);
modes = m_displayModes;
ReleaseSRWLockShared(&m_modeLock);
outArgs->TargetModeBufferOutputCount = (UINT)modes.size();
if (inArgs->TargetModeBufferInputCount < (UINT)modes.size())
return (inArgs->TargetModeBufferInputCount > 0) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
auto* mode = inArgs->pTargetModes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
{
mode->Size = sizeof(IDDCX_TARGET_MODE);
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, false);
@@ -392,13 +510,18 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription2(
const IDARG_IN_PARSEMONITORDESCRIPTION2* inArgs,
IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs)
{
outArgs->MonitorModeBufferOutputCount = (UINT)m_displayModes.size();
CSettings::DisplayModes modes;
AcquireSRWLockShared(&m_modeLock);
modes = m_displayModes;
ReleaseSRWLockShared(&m_modeLock);
outArgs->MonitorModeBufferOutputCount = (UINT)modes.size();
outArgs->PreferredMonitorModeIdx = 0;
if (inArgs->MonitorModeBufferInputCount < (UINT)m_displayModes.size())
if (inArgs->MonitorModeBufferInputCount < (UINT)modes.size())
return (inArgs->MonitorModeBufferInputCount > 0) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
auto * mode = inArgs->pMonitorModes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
{
ZeroMemory(mode, sizeof(*mode));
mode->Size = sizeof(IDDCX_MONITOR_MODE2);
@@ -408,7 +531,7 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription2(
if (it->preferred)
outArgs->PreferredMonitorModeIdx =
(UINT)std::distance(m_displayModes.cbegin(), it);
(UINT)std::distance(modes.cbegin(), it);
}
return STATUS_SUCCESS;
@@ -418,15 +541,20 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes2(
const IDARG_IN_QUERYTARGETMODES2* inArgs,
IDARG_OUT_QUERYTARGETMODES* outArgs)
{
outArgs->TargetModeBufferOutputCount = (UINT)m_displayModes.size();
if (inArgs->TargetModeBufferInputCount < (UINT)m_displayModes.size())
CSettings::DisplayModes modes;
AcquireSRWLockShared(&m_modeLock);
modes = m_displayModes;
ReleaseSRWLockShared(&m_modeLock);
outArgs->TargetModeBufferOutputCount = (UINT)modes.size();
if (inArgs->TargetModeBufferInputCount < (UINT)modes.size())
return STATUS_SUCCESS;
if (!inArgs->pTargetModes)
return STATUS_INVALID_PARAMETER;
auto* mode = inArgs->pTargetModes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
for (auto it = modes.cbegin(); it != modes.cend(); ++it, ++mode)
{
ZeroMemory(mode, sizeof(*mode));
mode->Size = sizeof(IDDCX_TARGET_MODE2);
@@ -438,106 +566,78 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes2(
}
#endif
bool CIndirectDeviceContext::UpdateMonitorModes()
{
if (!m_monitor)
return false;
#ifdef HAS_IDDCX_110
if (CanUseIddCx110DDIs())
{
IDDCX_TARGET_MODE2* modes = (IDDCX_TARGET_MODE2*)_malloca(
m_displayModes.size() * sizeof(IDDCX_TARGET_MODE2));
if (!modes)
{
DEBUG_WARN("Failed to allocate memory for the mode list");
return false;
}
ZeroMemory(modes, m_displayModes.size() * sizeof(IDDCX_TARGET_MODE2));
auto* mode = modes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
{
mode->Size = sizeof(IDDCX_TARGET_MODE2);
mode->RequiredBandwidth = (UINT64)it->width * it->height * it->refresh * 32;
mode->BitsPerComponent = GetWireBitsPerComponent(CanUseIddCx110DDIs());
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, false);
}
IDARG_IN_UPDATEMODES2 updateModes = {};
updateModes.Reason = IDDCX_UPDATE_REASON_OTHER;
updateModes.TargetModeCount = (UINT)m_displayModes.size();
updateModes.pTargetModes = modes;
NTSTATUS status = IddCxMonitorUpdateModes2(m_monitor, &updateModes);
_freea(modes);
if (!NT_SUCCESS(status))
{
DEBUG_WARN("IddCxMonitorUpdateModes2 Failed (0x%08x)", status);
return false;
}
return true;
}
#endif
IDDCX_TARGET_MODE* modes = (IDDCX_TARGET_MODE*)_malloca(
m_displayModes.size() * sizeof(IDDCX_TARGET_MODE));
if (!modes)
{
DEBUG_WARN("Failed to allocate memory for the mode list");
return false;
}
ZeroMemory(modes, m_displayModes.size() * sizeof(IDDCX_TARGET_MODE));
auto* mode = modes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
{
mode->Size = sizeof(IDDCX_TARGET_MODE);
mode->RequiredBandwidth = (UINT64)it->width * it->height * it->refresh * 32;
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, false);
}
IDARG_IN_UPDATEMODES updateModes = {};
updateModes.Reason = IDDCX_UPDATE_REASON_OTHER;
updateModes.TargetModeCount = (UINT)m_displayModes.size();
updateModes.pTargetModes = modes;
NTSTATUS status = IddCxMonitorUpdateModes(m_monitor, &updateModes);
_freea(modes);
if (!NT_SUCCESS(status))
{
DEBUG_WARN("IddCxMonitorUpdateModes Failed (0x%08x)", status);
return false;
}
return true;
}
void CIndirectDeviceContext::SetResolution(int width, int height)
{
m_setMode.width = width;
m_setMode.height = height;
m_setMode.refresh = g_settings.GetDefaultRefresh();
m_setMode.preferred = true;
g_settings.SetExtraMode(m_setMode);
CSettings::DisplayMode mode = {};
mode.width = width;
mode.height = height;
mode.refresh = g_settings.GetDefaultRefresh();
mode.preferred = true;
// A window resize streams many WINDOWSIZE requests in quick succession.
// Record the latest request and (re)start a timer; the actual mode change and
// replug only happen once the requested resolution has settled (i.e. no new
// request has arrived) for m_resChangeDelayMs. Each new request restarts the
// countdown, coalescing a burst of resizes into a single replug.
AcquireSRWLockExclusive(&m_stateLock);
m_pendingMode = mode;
m_resChangePending = true;
ReleaseSRWLockExclusive(&m_stateLock);
// Create the debounce timer once; WdfTimerStart on an already-queued
// non-periodic timer simply updates its due time, giving us the restart.
if (!m_resChangeTimer)
{
WDF_TIMER_CONFIG config;
WDF_TIMER_CONFIG_INIT(&config,
[](WDFTIMER timer) -> void
{
WDFOBJECT parent = WdfTimerGetParentObject(timer);
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(parent);
wrapper->context->ApplyResolution();
});
config.AutomaticSerialization = FALSE;
WDF_OBJECT_ATTRIBUTES attribs;
WDF_OBJECT_ATTRIBUTES_INIT(&attribs);
attribs.ParentObject = m_wdfDevice;
attribs.ExecutionLevel = WdfExecutionLevelDispatch;
NTSTATUS status = WdfTimerCreate(&config, &attribs, &m_resChangeTimer);
if (!NT_SUCCESS(status))
{
DEBUG_ERROR_HR(status, "Resolution change timer creation failed");
m_resChangeTimer = nullptr;
// Fall back to applying immediately so a resize is not lost.
ApplyResolution();
return;
}
}
WdfTimerStart(m_resChangeTimer, WDF_REL_TIMEOUT_IN_MS(m_resChangeDelayMs));
}
void CIndirectDeviceContext::ApplyResolution()
{
AcquireSRWLockExclusive(&m_stateLock);
if (!m_resChangePending)
{
ReleaseSRWLockExclusive(&m_stateLock);
return;
}
CSettings::DisplayMode mode = m_pendingMode;
m_resChangePending = false;
m_setMode = mode;
m_doSetMode = true;
ReleaseSRWLockExclusive(&m_stateLock);
g_settings.SetExtraMode(mode);
PopulateDefaultModes();
if (UpdateMonitorModes())
{
DEBUG_TRACE("Updated monitor modes without replugging");
m_doSetMode = false;
InterlockedExchange(&m_recoverModeUpdateSwapChain, 1);
g_pipe.SetDisplayMode(m_setMode.width, m_setMode.height, m_setMode.refresh);
return;
}
DEBUG_TRACE("Falling back to monitor replug for mode update");
m_doSetMode = true;
InterlockedExchange(&m_recoverModeUpdateSwapChain, 0);
// IddCxMonitorUpdateModes[2] does not invalidate Windows' cached mode list,
// so the only reliable way to apply a new mode is to depart and re-arrive the
// monitor, forcing Windows to rebuild the topology from the new mode list.
ReplugMonitor();
}
@@ -722,6 +822,23 @@ void CIndirectDeviceContext::DeInitLGMP()
{
m_hasFrame = false;
// The retry timer callback dereferences this context, so make sure it is
// stopped and drained before we tear anything down. Wait for any in-flight
// callback to complete.
if (m_initTimer)
{
WdfTimerStop(m_initTimer, TRUE);
m_initTimer = nullptr;
}
// The resolution debounce timer callback dereferences this context too; stop
// and drain it before tearing anything down.
if (m_resChangeTimer)
{
WdfTimerStop(m_resChangeTimer, TRUE);
m_resChangeTimer = nullptr;
}
if (m_lgmp == nullptr)
return;
@@ -742,10 +859,13 @@ void CIndirectDeviceContext::DeInitLGMP()
void CIndirectDeviceContext::LGMPTimer()
{
if (InterlockedExchange(&m_replugMonitorQueued, 0))
// Rebuild the monitor queued by ReplugMonitor, off the IddCx callback thread.
if (InterlockedExchange(&m_finishInitQueued, 0))
{
m_doSetMode = true;
ReplugMonitor();
FinishInit(0);
AcquireSRWLockExclusive(&m_stateLock);
m_replugMonitor = false;
ReleaseSRWLockExclusive(&m_stateLock);
return;
}
@@ -807,10 +927,6 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
if (!m_lgmp || !m_frameQueue)
return result;
if (InterlockedCompareExchange(&m_recoverModeUpdateSwapChain, 0, 0) &&
srcFormat.width == m_setMode.width && srcFormat.height == m_setMode.height)
InterlockedExchange(&m_recoverModeUpdateSwapChain, 0);
if (m_width != dstFormat.desc.Width ||
m_height != dstFormat.desc.Height ||
m_pitch != pitch ||
@@ -827,15 +943,21 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
// Detect HDR metadata changes that require a format version bump
// so the client knows to re-apply the HDR image description.
if (srcFormat.hdr)
//
// Use dstFormat: post-processing (CHDR16to10Effect) can rotate the gamut
// (BT.709 scRGB -> BT.2020 PQ), so the metadata describing the *emitted*
// frame lives in dstFormat, not srcFormat. Forwarding srcFormat here would
// tag PQ/BT.2020 pixels with the source's BT.709 primaries and mislead
// consumers that derive their colour conversion from these values.
if (dstFormat.hdr)
{
if (!m_lastHDRActive ||
memcmp(m_lastHDRDisplayPrimary, srcFormat.displayPrimary, sizeof(m_lastHDRDisplayPrimary)) != 0 ||
memcmp(m_lastHDRWhitePoint , srcFormat.whitePoint , sizeof(m_lastHDRWhitePoint )) != 0 ||
m_lastHDRMaxDisplayLuminance != srcFormat.maxDisplayLuminance ||
m_lastHDRMinDisplayLuminance != srcFormat.minDisplayLuminance ||
m_lastHDRMaxContentLightLevel != srcFormat.maxContentLightLevel ||
m_lastHDRMaxFrameAverageLightLevel != srcFormat.maxFrameAverageLightLevel)
memcmp(m_lastHDRDisplayPrimary, dstFormat.displayPrimary, sizeof(m_lastHDRDisplayPrimary)) != 0 ||
memcmp(m_lastHDRWhitePoint , dstFormat.whitePoint , sizeof(m_lastHDRWhitePoint )) != 0 ||
m_lastHDRMaxDisplayLuminance != dstFormat.maxDisplayLuminance ||
m_lastHDRMinDisplayLuminance != dstFormat.minDisplayLuminance ||
m_lastHDRMaxContentLightLevel != dstFormat.maxContentLightLevel ||
m_lastHDRMaxFrameAverageLightLevel != dstFormat.maxFrameAverageLightLevel)
{
++m_formatVer;
}
@@ -846,13 +968,13 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
++m_formatVer;
}
m_lastHDRActive = srcFormat.hdr;
memcpy(m_lastHDRDisplayPrimary, srcFormat.displayPrimary, sizeof(m_lastHDRDisplayPrimary));
memcpy(m_lastHDRWhitePoint , srcFormat.whitePoint , sizeof(m_lastHDRWhitePoint ));
m_lastHDRMaxDisplayLuminance = srcFormat.maxDisplayLuminance;
m_lastHDRMinDisplayLuminance = srcFormat.minDisplayLuminance;
m_lastHDRMaxContentLightLevel = srcFormat.maxContentLightLevel;
m_lastHDRMaxFrameAverageLightLevel = srcFormat.maxFrameAverageLightLevel;
m_lastHDRActive = dstFormat.hdr;
memcpy(m_lastHDRDisplayPrimary, dstFormat.displayPrimary, sizeof(m_lastHDRDisplayPrimary));
memcpy(m_lastHDRWhitePoint , dstFormat.whitePoint , sizeof(m_lastHDRWhitePoint ));
m_lastHDRMaxDisplayLuminance = dstFormat.maxDisplayLuminance;
m_lastHDRMinDisplayLuminance = dstFormat.minDisplayLuminance;
m_lastHDRMaxContentLightLevel = dstFormat.maxContentLightLevel;
m_lastHDRMaxFrameAverageLightLevel = dstFormat.maxFrameAverageLightLevel;
if (++m_frameIndex == LGMP_Q_FRAME_LEN)
m_frameIndex = 0;
@@ -893,15 +1015,17 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame
fi->rotation = FRAME_ROT_0;
fi->type = dstFormat.format;
// Populate HDR metadata if the frame is HDR
// Populate HDR metadata if the frame is HDR. Use dstFormat so the primaries
// describe the emitted frame after any gamut conversion in post-processing
// (see the metadata-change detection above).
if (flags & FRAME_FLAG_HDR)
{
memcpy(fi->hdrDisplayPrimary, srcFormat.displayPrimary, sizeof(fi->hdrDisplayPrimary));
memcpy(fi->hdrWhitePoint , srcFormat.whitePoint , sizeof(fi->hdrWhitePoint));
fi->hdrMaxDisplayLuminance = srcFormat.maxDisplayLuminance;
fi->hdrMinDisplayLuminance = srcFormat.minDisplayLuminance;
fi->hdrMaxContentLightLevel = srcFormat.maxContentLightLevel;
fi->hdrMaxFrameAverageLightLevel = srcFormat.maxFrameAverageLightLevel;
memcpy(fi->hdrDisplayPrimary, dstFormat.displayPrimary, sizeof(fi->hdrDisplayPrimary));
memcpy(fi->hdrWhitePoint , dstFormat.whitePoint , sizeof(fi->hdrWhitePoint));
fi->hdrMaxDisplayLuminance = dstFormat.maxDisplayLuminance;
fi->hdrMinDisplayLuminance = dstFormat.minDisplayLuminance;
fi->hdrMaxContentLightLevel = dstFormat.maxContentLightLevel;
fi->hdrMaxFrameAverageLightLevel = dstFormat.maxFrameAverageLightLevel;
}
fi->damageRectsCount = 0;

View File

@@ -65,6 +65,17 @@ private:
IDDCX_MONITOR m_monitor = nullptr;
bool m_replugMonitor = false;
// Guards the adapter/monitor init handshake and the replug state machine
// (m_monitor, m_replugMonitor, m_doSetMode, m_setMode). These are touched
// from the IddCx callback threads and the LGMP timer thread.
SRWLOCK m_stateLock = SRWLOCK_INIT;
// Retry state for InitAdapter. At boot the IVSHMEM device may not have
// enumerated yet; if so we re-attempt from a timer instead of giving up.
WDFTIMER m_initTimer = nullptr;
bool m_ivshmemOpened = false;
volatile LONG m_initInProgress = 0;
CIVSHMEM m_ivshmem;
PLGMPHost m_lgmp = nullptr;
@@ -123,18 +134,37 @@ private:
void QueryIddCxCapabilities();
bool CanUseIddCx110DDIs() const { return m_canProcessFP16; }
void ScheduleInitRetry();
void StopInitRetry();
void DeInitLGMP();
void LGMPTimer();
void ResendCursor() const;
bool UpdateMonitorModes();
// Guards m_displayModes and m_edid. The mode list is rebuilt on the LGMP
// timer thread (SetResolution) while IddCx concurrently enumerates it on its
// own callback threads (ParseMonitorDescription / MonitorQueryTargetModes /
// FinishInit). Never held across an IddCx API call - snapshot then call.
mutable SRWLOCK m_modeLock = SRWLOCK_INIT;
CSettings::DisplayModes m_displayModes;
CEdid m_edid;
CSettings::DisplayMode m_setMode = {};
bool m_doSetMode = false;
volatile LONG m_replugMonitorQueued = 0;
volatile LONG m_recoverModeUpdateSwapChain = 0;
// Debounce for resolution changes. A window resize streams many WINDOWSIZE
// requests in quick succession; rather than replug the monitor for each, we
// (re)start a timer and only apply the last requested resolution once it has
// remained unchanged for m_resChangeDelayMs. Guarded by m_stateLock.
static const ULONG m_resChangeDelayMs = 1000;
WDFTIMER m_resChangeTimer = nullptr;
CSettings::DisplayMode m_pendingMode = {};
bool m_resChangePending = false;
// Set by ReplugMonitor after a departure to rebuild the monitor from the LGMP
// timer, off the IddCx callback thread.
volatile LONG m_finishInitQueued = 0;
public:
CIndirectDeviceContext(_In_ WDFDEVICE wdfDevice) :
@@ -149,9 +179,8 @@ public:
void FinishInit(UINT connectorIndex);
void ReplugMonitor();
void OnMonitorDestroyed(IDDCX_MONITOR monitor);
void OnAssignSwapChain();
void OnUnassignedSwapChain();
void OnSwapChainLost();
NTSTATUS ParseMonitorDescription(
const IDARG_IN_PARSEMONITORDESCRIPTION* inArgs, IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs);
@@ -168,6 +197,7 @@ public:
#endif
void SetResolution(int width, int height);
void ApplyResolution();
size_t GetAlignSize () const { return m_alignSize ; }
size_t GetMaxFrameSize() const { return m_maxFrameSize ; }

View File

@@ -32,50 +32,78 @@ CIndirectMonitorContext::CIndirectMonitorContext(_In_ IDDCX_MONITOR monitor, CIn
CIndirectMonitorContext::~CIndirectMonitorContext()
{
UnassignSwapChain();
m_devContext->OnMonitorDestroyed(m_monitor);
}
void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID renderAdapter, HANDLE newFrameEvent)
{
reInit:
UnassignSwapChain();
m_dx11Device = std::make_shared<CD3D11Device>(renderAdapter);
if (FAILED(m_dx11Device->Init()))
{
WdfObjectDelete(swapChain);
return;
}
// Build everything into locals so the members are never observed
// half-constructed by a concurrent unassign, and so the processor (which
// spawns a worker thread) is created outside the lock.
std::shared_ptr<CD3D11Device> dx11Device;
std::shared_ptr<CD3D12Device> dx12Device;
UINT64 alignSize = CPlatformInfo::GetPageSize();
m_dx12Device = std::make_shared<CD3D12Device>(renderAdapter);
switch (m_dx12Device->Init(m_devContext->GetIVSHMEM(), alignSize))
for (;;)
{
case CD3D12Device::SUCCESS:
break;
case CD3D12Device::FAILURE:
dx11Device = std::make_shared<CD3D11Device>(renderAdapter);
if (FAILED(dx11Device->Init()))
{
WdfObjectDelete(swapChain);
return;
}
case CD3D12Device::RETRY:
m_dx12Device.reset();
m_dx11Device.reset();
goto reInit;
}
if (!m_devContext->SetupLGMP(alignSize))
{
WdfObjectDelete(swapChain);
DEBUG_ERROR("SetupLGMP failed");
return;
UINT64 alignSize = CPlatformInfo::GetPageSize();
dx12Device = std::make_shared<CD3D12Device>(renderAdapter);
CD3D12Device::InitResult r = dx12Device->Init(m_devContext->GetIVSHMEM(), alignSize);
if (r == CD3D12Device::RETRY)
{
dx12Device.reset();
dx11Device.reset();
continue;
}
if (r == CD3D12Device::FAILURE)
{
WdfObjectDelete(swapChain);
return;
}
if (!m_devContext->SetupLGMP(alignSize))
{
WdfObjectDelete(swapChain);
DEBUG_ERROR("SetupLGMP failed");
return;
}
break;
}
m_swapChain.reset(new CSwapChainProcessor(m_monitor, m_devContext, swapChain, m_dx11Device, m_dx12Device, newFrameEvent));
std::unique_ptr<CSwapChainProcessor> processor(new CSwapChainProcessor(
m_monitor, m_devContext, swapChain, dx11Device, dx12Device, newFrameEvent));
AcquireSRWLockExclusive(&m_lock);
m_dx11Device = std::move(dx11Device);
m_dx12Device = std::move(dx12Device);
m_swapChain = std::move(processor);
ReleaseSRWLockExclusive(&m_lock);
}
void CIndirectMonitorContext::UnassignSwapChain()
{
m_swapChain.reset();
m_dx11Device.reset();
m_dx12Device.reset();
// Detach under the lock, then destroy outside it. Destroying the processor
// joins its worker thread, whose teardown (WdfObjectDelete) re-enters this
// method on another thread - holding the lock across that would deadlock.
std::unique_ptr<CSwapChainProcessor> processor;
std::shared_ptr<CD3D11Device> dx11Device;
std::shared_ptr<CD3D12Device> dx12Device;
AcquireSRWLockExclusive(&m_lock);
processor = std::move(m_swapChain);
dx11Device = std::move(m_dx11Device);
dx12Device = std::move(m_dx12Device);
ReleaseSRWLockExclusive(&m_lock);
processor.reset();
dx11Device.reset();
dx12Device.reset();
}

View File

@@ -35,6 +35,10 @@ class CIndirectMonitorContext
private:
IDDCX_MONITOR m_monitor;
// Guards the swap chain and device pointers. Assign and unassign can run
// concurrently (an unassign triggered by the worker's WdfObjectDelete can
// race the next assign), and shared_ptr copy/reset is not thread safe.
SRWLOCK m_lock = SRWLOCK_INIT;
std::shared_ptr<CD3D11Device> m_dx11Device;
std::shared_ptr<CD3D12Device> m_dx12Device;

View File

@@ -222,6 +222,16 @@ void CPipeServer::WriteMsg(const LGPipeMsg & msg)
{
if (!m_connected)
{
// Not connected yet: keep only the latest message of each type. These are
// all latest-state-wins messages, so a burst (e.g. display mode changes
// while resizing) must collapse to the final state rather than replay every
// intermediate value when the helper reconnects.
for (auto & queued : m_queue)
if (queued.type == msg.type)
{
queued = msg;
return;
}
m_queue.push_back(msg);
return;
}

View File

@@ -38,7 +38,9 @@ CSwapChainProcessor::CSwapChainProcessor(IDDCX_MONITOR monitor, CIndirectDeviceC
if (!m_postProcessor.Init(dx12Device))
DEBUG_ERROR("Failed to initialize post processor");
m_terminateEvent.Attach(CreateEvent(nullptr, FALSE, FALSE, nullptr));
// Manual-reset: both worker threads wait on this, so it must stay signalled
// once set or only one thread would ever observe termination.
m_terminateEvent.Attach(CreateEvent(nullptr, TRUE, FALSE, nullptr));
m_thread[0].Attach(CreateThread(nullptr, 0, _SwapChainThread, this, 0, nullptr));
m_cursorDataEvent.Attach(CreateEvent(nullptr, FALSE, FALSE, nullptr));
@@ -53,6 +55,11 @@ CSwapChainProcessor::~CSwapChainProcessor()
if (m_thread[1].Get())
WaitForSingleObject(m_thread[1].Get(), INFINITE);
// Drain in-flight GPU work / completion callbacks before releasing the
// resources they reference. The swap chain was already released in the
// worker epilogue, so this does not hold an IddCx frame.
m_dx12Device->WaitForIdle();
m_postProcessor.Reset();
m_resPool.Reset();
m_fbPool.Reset();
@@ -71,22 +78,26 @@ void CSwapChainProcessor::SwapChainThread()
HANDLE avTaskHandle = AvSetMmThreadCharacteristicsW(L"Distribution", &avTask);
DEBUG_INFO("Start Thread");
SwapChainThreadCore();
WdfObjectDelete((WDFOBJECT)m_hSwapChain);
// Only delete the swap chain if we took ownership of it (SetDevice
// succeeded). If SetDevice failed IddCx still owns and tears it down, so
// deleting it here would double-free the WDF object. Releasing it when we do
// own it hands the acquired frame back to IddCx promptly.
if (SwapChainThreadCore())
WdfObjectDelete((WDFOBJECT)m_hSwapChain);
m_hSwapChain = nullptr;
AvRevertMmThreadCharacteristics(avTaskHandle);
}
void CSwapChainProcessor::SwapChainThreadCore()
bool CSwapChainProcessor::SwapChainThreadCore()
{
ComPtr<IDXGIDevice> dxgiDevice;
HRESULT hr = m_dx11Device->GetDevice().As(&dxgiDevice);
if (FAILED(hr))
{
DEBUG_ERROR_HR(hr, "Failed to get the dxgiDevice");
return;
return false;
}
if (IDD_IS_FUNCTION_AVAILABLE(IddCxSetRealtimeGPUPriority))
@@ -107,12 +118,17 @@ void CSwapChainProcessor::SwapChainThreadCore()
IDARG_IN_SWAPCHAINSETDEVICE setDevice = {};
setDevice.pDevice = dxgiDevice.Get();
// A failure here (commonly DXGI_ERROR_ACCESS_LOST on the first assignment)
// is not recoverable on this handle - IddCx reassigns a fresh swap chain,
// which is what actually succeeds. Bail cleanly and let that happen.
hr = IddCxSwapChainSetDevice(m_hSwapChain, &setDevice);
if (FAILED(hr))
{
DEBUG_ERROR_HR(hr, "IddCxSwapChainSetDevice Failed");
return;
return false;
}
// Past this point SetDevice succeeded: we own the swap chain and are
// responsible for deleting it.
IDARG_IN_SETUP_HWCURSOR c = {};
c.CursorInfo.Size = sizeof(c.CursorInfo);
@@ -125,7 +141,7 @@ void CSwapChainProcessor::SwapChainThreadCore()
if (!NT_SUCCESS(status))
{
DEBUG_ERROR("IddCxMonitorSetupHardwareCursor Failed (0x%08x)", status);
return;
return true;
}
m_lastShapeId = 0;
@@ -145,6 +161,11 @@ void CSwapChainProcessor::SwapChainThreadCore()
UINT dirtyRectCount = 0;
ComPtr<IDXGIResource> surface;
// The surface colour space is the source of truth for the content format.
// Only the buffer2 acquisition path (IddCx 1.10+) reports it; on the legacy
// path HDR is not available, so default to SDR.
DXGI_COLOR_SPACE_TYPE colorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
#ifdef HAS_IDDCX_110
if (m_devContext->CanProcessFP16())
{
@@ -161,6 +182,7 @@ void CSwapChainProcessor::SwapChainThreadCore()
frameNumber = buffer.MetaData.PresentationFrameNumber;
dirtyRectCount = buffer.MetaData.DirtyRectCount;
surface = buffer.MetaData.pSurface;
colorSpace = buffer.MetaData.SurfaceColorSpace;
}
}
else
@@ -200,15 +222,15 @@ void CSwapChainProcessor::SwapChainThreadCore()
if (frameNumber != lastFrameNumber)
{
lastFrameNumber = frameNumber;
SwapChainNewFrame(surface, dirtyRectCount);
SwapChainNewFrame(surface, dirtyRectCount, colorSpace);
// report that all GPU processing for this frame has been queued
hr = IddCxSwapChainFinishedProcessingFrame(m_hSwapChain);
if (FAILED(hr))
{
if (hr == STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY)
m_devContext->OnSwapChainLost();
else
// A lost path is normal (mode change/topology rebuild); Windows
// reassigns a fresh swap chain. Just exit and let it.
if (hr != STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY)
DEBUG_ERROR_HR(hr, "IddCxSwapChainFinishedProcessingFrame Failed");
break;
}
@@ -216,12 +238,10 @@ void CSwapChainProcessor::SwapChainThreadCore()
}
}
else
{
if (hr == STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY)
m_devContext->OnSwapChainLost();
break;
}
}
return true;
}
void CSwapChainProcessor::CompletionFunction(
@@ -313,7 +333,8 @@ static FrameType GetFrameType(DXGI_FORMAT format)
}
}
bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer, unsigned dirtyRectCount)
bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer, unsigned dirtyRectCount,
DXGI_COLOR_SPACE_TYPE colorSpace)
{
ComPtr<ID3D11Texture2D> texture;
HRESULT hr = acquiredBuffer.As(&texture);
@@ -366,57 +387,74 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
srcFormat.height = srcDesc.Height;
srcFormat.format = GetFrameType(srcDesc.Format);
// Only HDR-capable formats can carry HDR content.
// 8-bit formats (BGRA, RGBA) cannot represent HDR,
// even if IsHDRActive() is momentarily stale during mode switches.
if (srcDesc.Format != DXGI_FORMAT_R16G16B16A16_FLOAT &&
srcDesc.Format != DXGI_FORMAT_R10G10B10A2_UNORM)
switch (colorSpace)
{
srcFormat.hdr = false;
srcFormat.hdrPQ = false;
}
else if (srcDesc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT)
{
// FP16 is HDR content (scRGB / linear, not PQ-curve).
// FP16 always carries HDR color data regardless of OS HDR mode,
// but metadata (primaries, luminances) may be unavailable.
srcFormat.hdr = true;
srcFormat.hdrPQ = false;
if (!m_devContext->GetHDRMetadata(srcFormat))
{
// No HDR metadata from the OS; provide reasonable defaults
// so downstream consumers have valid primaries and luminances.
// BT.709/sRGB primaries (in 0.00002 units):
srcFormat.displayPrimary[0][0] = 13250; // Rx
srcFormat.displayPrimary[0][1] = 34500; // Ry
srcFormat.displayPrimary[1][0] = 7500; // Gx
srcFormat.displayPrimary[1][1] = 30000; // Gy
srcFormat.displayPrimary[2][0] = 34000; // Bx
srcFormat.displayPrimary[2][1] = 16000; // By
// D65 white point (in 0.00002 units):
srcFormat.whitePoint[0] = 15635;
srcFormat.whitePoint[1] = 16450;
// 80 cd/m² display, 0.005 cd/m² black (in 0.0001 cd/m² units):
srcFormat.maxDisplayLuminance = 800000;
srcFormat.minDisplayLuminance = 50;
// Content light levels unknown:
srcFormat.maxContentLightLevel = 0;
srcFormat.maxFrameAverageLightLevel = 0;
}
}
else if (m_devContext->CanProcessFP16() && m_devContext->IsHDRActive())
{
// Non-FP16 format (e.g., RGBA10) with OS HDR mode active.
// Windows applies the PQ (ST.2084) transfer function for non-FP16 HDR.
srcFormat.hdr = true;
srcFormat.hdrPQ = true;
case DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020:
case DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020:
// HDR10: BT.2020 primaries with the PQ (ST.2084) transfer function
// already applied to the pixel data.
srcFormat.hdr = true;
srcFormat.hdrPQ = true;
if (!m_devContext->GetHDRMetadata(srcFormat))
{
// HDR is active but the OS has not delivered static metadata yet
// (e.g. a brief window during a mode switch). The pixels are still
// PQ-encoded, so keep the PQ flag and supply BT.2020/PQ defaults
// rather than mislabel the frame as SDR.
// BT.2020 primaries (in 0.00002 units):
srcFormat.displayPrimary[0][0] = 35400; // Rx
srcFormat.displayPrimary[0][1] = 14600; // Ry
srcFormat.displayPrimary[1][0] = 8500; // Gx
srcFormat.displayPrimary[1][1] = 39850; // Gy
srcFormat.displayPrimary[2][0] = 6550; // Bx
srcFormat.displayPrimary[2][1] = 2300; // By
// D65 white point (in 0.00002 units):
srcFormat.whitePoint[0] = 15635;
srcFormat.whitePoint[1] = 16450;
// Mastering luminances follow SMPTE ST 2086 units: max in whole cd/m²,
// min in 0.0001 cd/m². 1000 cd/m² display, 0.0001 cd/m² black:
srcFormat.maxDisplayLuminance = 1000;
srcFormat.minDisplayLuminance = 1;
// Content light levels unknown:
srcFormat.maxContentLightLevel = 0;
srcFormat.maxFrameAverageLightLevel = 0;
}
break;
// Load HDR metadata; if none is available the frame is not HDR.
if (!m_devContext->GetHDRMetadata(srcFormat))
{
case DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709:
// scRGB: linear (FP16) content with BT.709 primaries. HDR, but the PQ
// curve has not been applied.
srcFormat.hdr = true;
srcFormat.hdrPQ = false;
if (!m_devContext->GetHDRMetadata(srcFormat))
{
// No HDR metadata from the OS; provide reasonable defaults
// so downstream consumers have valid primaries and luminances.
// BT.709/sRGB primaries (in 0.00002 units):
srcFormat.displayPrimary[0][0] = 13250; // Rx
srcFormat.displayPrimary[0][1] = 34500; // Ry
srcFormat.displayPrimary[1][0] = 7500; // Gx
srcFormat.displayPrimary[1][1] = 30000; // Gy
srcFormat.displayPrimary[2][0] = 34000; // Bx
srcFormat.displayPrimary[2][1] = 16000; // By
// D65 white point (in 0.00002 units):
srcFormat.whitePoint[0] = 15635;
srcFormat.whitePoint[1] = 16450;
// Mastering luminances follow SMPTE ST 2086 units: max in whole cd/m²,
// min in 0.0001 cd/m². 80 cd/m² display, 0.005 cd/m² black:
srcFormat.maxDisplayLuminance = 80;
srcFormat.minDisplayLuminance = 50;
// Content light levels unknown:
srcFormat.maxContentLightLevel = 0;
srcFormat.maxFrameAverageLightLevel = 0;
}
break;
default:
// Everything else (e.g. RGB_FULL_G22_NONE_P709) is SDR.
srcFormat.hdr = false;
srcFormat.hdrPQ = false;
}
break;
}
bool postProcessFormatChanged = false;
@@ -583,7 +621,6 @@ bool CSwapChainProcessor::QueryHWCursor()
// this occurs if the display went away (ie, screen blanking or disabled)
if (status == STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY)
{
m_devContext->OnSwapChainLost();
SetEvent(m_terminateEvent.Get());
return false;
}

View File

@@ -62,7 +62,7 @@ private:
static DWORD CALLBACK _SwapChainThread(LPVOID arg);
void SwapChainThread();
void SwapChainThreadCore();
bool SwapChainThreadCore();
static DWORD CALLBACK _CursorThread(LPVOID arg);
bool QueryHWCursor();
@@ -70,7 +70,8 @@ private:
static void CompletionFunction(
CD3D12CommandQueue * queue, bool result, void * param1, void * param2);
bool SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer, unsigned dirtyRectCount);
bool SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer, unsigned dirtyRectCount,
DXGI_COLOR_SPACE_TYPE colorSpace);
public:
CSwapChainProcessor(IDDCX_MONITOR monitor, CIndirectDeviceContext * devContext, IDDCX_SWAPCHAIN hSwapChain,

View File

@@ -199,7 +199,6 @@ NTSTATUS LGIddMonitorUnassignSwapChain(IDDCX_MONITOR monitor)
{
auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
wrapper->context->UnassignSwapChain();
wrapper->context->GetDeviceContext()->OnUnassignedSwapChain();
return STATUS_SUCCESS;
}
@@ -267,14 +266,16 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
return status;
/*
* Keep the WDF device cached so callbacks that do not provide an adapter or
* monitor context can still reach the device context on down-level IddCx.
* Construct the device context and cache the WDF device BEFORE calling
* IddCxDeviceInitialize. IddCxDeviceInitialize arms the IddCx callbacks, and
* callbacks that resolve the context via l_wdfDevice (down-level IddCx that
* provides no adapter/monitor context) must never observe a null context.
*/
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device);
wrapper->context = new CIndirectDeviceContext(device);
l_wdfDevice = device;
status = IddCxDeviceInitialize(device);
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(device);
wrapper->context = new CIndirectDeviceContext(device);
return status;
}

View File

@@ -49,8 +49,17 @@ bool CHDR16to10Effect::Init(const ComPtr<ID3D12Device3>& device)
"void main(uint3 dt : SV_DispatchThreadID)\n"
"{\n"
" float3 linearValue = src[dt.xy].rgb * ReferenceWhiteNits;\n"
" // scRGB uses BT.709 primaries whereas HDR10/PQ output uses BT.2020.\n"
" // Rotate the gamut in linear light (BT.2087) BEFORE applying the PQ\n"
" // curve, otherwise the BT.709 values are later reinterpreted as BT.2020\n"
" // and saturated colours (most visibly red) are pushed outside their\n"
" // intended gamut.\n"
" float3 rec2020 = float3(\n"
" dot(linearValue, float3(0.6274039, 0.3292830, 0.0433131)),\n"
" dot(linearValue, float3(0.0690973, 0.9195404, 0.0113623)),\n"
" dot(linearValue, float3(0.0163914, 0.0880133, 0.8955953)));\n"
" // scRGB to PQ (ST.2084)\n"
" float3 Y = linearValue / 10000.0;\n"
" float3 Y = rec2020 / 10000.0;\n"
" float3 Ym1 = pow(max(Y, 0.0), PQ_m1);\n"
" float3 pq = pow((PQ_c1 + PQ_c2 * Ym1) / (1.0 + PQ_c3 * Ym1), PQ_m2);\n"
" dst[dt.xy] = float4(pq, src[dt.xy].a);\n"
@@ -116,7 +125,16 @@ PostProcessStatus CHDR16to10Effect::SetFormat(
// Explicitly propagate HDR static metadata so it survives post-processing.
// Do not rely on the caller's copy semantics in CPostProcessor::Configure().
memcpy(dst.displayPrimary, src.displayPrimary, sizeof(dst.displayPrimary));
// The shader rotates the gamut from BT.709 to BT.2020, so advertise BT.2020
// mastering primaries here rather than forwarding the source's BT.709 set
// (in 0.00002 units) - otherwise consumers see PQ/BT.2020 content tagged
// with BT.709 primaries.
dst.displayPrimary[0][0] = 35400; // Rx
dst.displayPrimary[0][1] = 14600; // Ry
dst.displayPrimary[1][0] = 8500; // Gx
dst.displayPrimary[1][1] = 39850; // Gy
dst.displayPrimary[2][0] = 6550; // Bx
dst.displayPrimary[2][1] = 2300; // By
memcpy(dst.whitePoint , src.whitePoint , sizeof(dst.whitePoint ));
dst.maxDisplayLuminance = src.maxDisplayLuminance;
dst.minDisplayLuminance = src.minDisplayLuminance;

View File

@@ -18,8 +18,8 @@ class CHDR16to10Effect : public CComputeEffect
private:
struct Consts
{
float ReferenceWhiteNits; // scRGB reference white in nits (BT.2408 recommends 203)
} m_consts = { 203.0f };
float ReferenceWhiteNits; // scRGB reference white in nits (typically 80)
} m_consts = { 80.0f };
ComPtr<ID3D12Resource> m_constBuffer;
public:

View File

@@ -77,6 +77,7 @@ endfunction()
build_effects(
effect
effect/rgb24.effect
effect/hdrpq.effect
)
add_definitions(-D ATOMIC_LOCKING)

52
obs/effect/hdrpq.effect Normal file
View File

@@ -0,0 +1,52 @@
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float2 outputSize;
uniform float3 colorMatrix0;
uniform float3 colorMatrix1;
uniform float3 colorMatrix2;
uniform float scale;
struct VertData
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertData VSDefault(VertData vert_in)
{
VertData vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
float4 PSHDRPQ(VertData vert_in) : TARGET
{
uvec2 outputPos = uvec2(vert_in.uv * outputSize);
vec4 pixel = texelFetch(image, ivec2(outputPos), 0);
/* SMPTE ST.2084 (PQ) EOTF: recover normalised linear light where 1.0
* corresponds to 10000 cd/m² */
vec3 e = pow(max(pixel.rgb, 0.0), vec3(1.0 / 78.84375));
vec3 num = max(e - 0.8359375, 0.0);
vec3 den = 18.8515625 - 18.6875 * e;
vec3 lin = pow(num / den, vec3(1.0 / 0.1593017578125));
/* convert from the source display primaries to BT.709 in linear light */
vec3 rgb709 = vec3(
dot(colorMatrix0, lin),
dot(colorMatrix1, lin),
dot(colorMatrix2, lin));
/* scale to the scRGB reference white convention (1.0 = 80 cd/m²) */
return float4(rgb709 * scale, pixel.a);
}
technique Draw
{
pass
{
vertex_shader = VSDefault(vert_in);
pixel_shader = PSHDRPQ(vert_in);
}
}

175
obs/lg.c
View File

@@ -38,6 +38,12 @@
#include <GL/gl.h>
#include "rgb24.effect.h"
#include "hdrpq.effect.h"
/* scRGB reference white in cd/m² (OBS GS_CS_709_SCRGB is defined as
* 1.0 = 80 cd/m²). PQ encodes an absolute 0..10000 cd/m² range, so linear
* PQ output is scaled by 10000 / 80 to reach the scRGB convention. */
#define LG_SCRGB_REFERENCE_WHITE 80.0f
/**
* the following comes from drm_fourcc.h and is included here to avoid the
@@ -97,6 +103,9 @@ typedef struct
bool hideMouse;
bool hdr;
bool hdrPQ;
struct vec3 colorMatrix[3]; // source primaries -> BT.709 (linear)
float hdrScale; // scRGB reference white scaling
#if LIBOBS_API_MAJOR_VER >= 27
bool dmabuf;
bool dmabufTested;
@@ -127,6 +136,12 @@ typedef struct
gs_eparam_t * image;
gs_eparam_t * outputSize;
gs_eparam_t * swap;
gs_effect_t * hdrEffect;
gs_eparam_t * hdrImage;
gs_eparam_t * hdrOutputSize;
gs_eparam_t * hdrColorMatrix[3];
gs_eparam_t * hdrScaleParam;
}
LGPlugin;
@@ -163,6 +178,30 @@ static void * lgCreate(obs_data_t * settings, obs_source_t * context)
this->unpackEffect, "outputSize");
this->swap = gs_effect_get_param_by_name(
this->unpackEffect, "swap" );
this->hdrEffect = gs_effect_create(b_effect_hdrpq_effect, "hdrpq", &error);
if (!this->hdrEffect)
{
blog(LOG_ERROR, "%s", error);
bfree(error);
gs_effect_destroy(this->unpackEffect);
bfree(this);
obs_leave_graphics();
return NULL;
}
this->hdrImage = gs_effect_get_param_by_name(
this->hdrEffect, "image" );
this->hdrOutputSize = gs_effect_get_param_by_name(
this->hdrEffect, "outputSize" );
this->hdrColorMatrix[0] = gs_effect_get_param_by_name(
this->hdrEffect, "colorMatrix0");
this->hdrColorMatrix[1] = gs_effect_get_param_by_name(
this->hdrEffect, "colorMatrix1");
this->hdrColorMatrix[2] = gs_effect_get_param_by_name(
this->hdrEffect, "colorMatrix2");
this->hdrScaleParam = gs_effect_get_param_by_name(
this->hdrEffect, "scale" );
obs_leave_graphics();
os_sem_init (&this->frameSem , 0);
@@ -274,6 +313,7 @@ static void lgDestroy(void * data)
obs_enter_graphics();
gs_effect_destroy(this->unpackEffect);
gs_effect_destroy(this->hdrEffect);
obs_leave_graphics();
bfree(this);
@@ -587,6 +627,121 @@ static DMAFrameInfo * dmabufOpenDMAFrameInfo(LGPlugin * this, LGMPMessage * msg,
}
#endif
/* chromaticity coordinates are transported in SMPTE ST 2086 units of
* 0.00002 */
#define LG_ST2086_UNIT 0.00002
static bool mat3Inverse(const double m[9], double out[9])
{
const double det =
m[0] * (m[4] * m[8] - m[5] * m[7]) -
m[1] * (m[3] * m[8] - m[5] * m[6]) +
m[2] * (m[3] * m[7] - m[4] * m[6]);
if (det == 0.0)
return false;
const double inv = 1.0 / det;
out[0] = (m[4] * m[8] - m[5] * m[7]) * inv;
out[1] = (m[2] * m[7] - m[1] * m[8]) * inv;
out[2] = (m[1] * m[5] - m[2] * m[4]) * inv;
out[3] = (m[5] * m[6] - m[3] * m[8]) * inv;
out[4] = (m[0] * m[8] - m[2] * m[6]) * inv;
out[5] = (m[2] * m[3] - m[0] * m[5]) * inv;
out[6] = (m[3] * m[7] - m[4] * m[6]) * inv;
out[7] = (m[1] * m[6] - m[0] * m[7]) * inv;
out[8] = (m[0] * m[4] - m[1] * m[3]) * inv;
return true;
}
static void mat3Mul(const double a[9], const double b[9], double out[9])
{
for (int r = 0; r < 3; ++r)
for (int c = 0; c < 3; ++c)
out[r * 3 + c] =
a[r * 3 + 0] * b[0 * 3 + c] +
a[r * 3 + 1] * b[1 * 3 + c] +
a[r * 3 + 2] * b[2 * 3 + c];
}
/* build the linear RGB -> CIE XYZ matrix for a set of primaries and white
* point (Bruce Lindbloom's method) */
static bool primariesToXYZ(double xr, double yr, double xg, double yg,
double xb, double yb, double xw, double yw, double out[9])
{
if (yr == 0.0 || yg == 0.0 || yb == 0.0 || yw == 0.0)
return false;
const double Xr = xr / yr, Yr = 1.0, Zr = (1.0 - xr - yr) / yr;
const double Xg = xg / yg, Yg = 1.0, Zg = (1.0 - xg - yg) / yg;
const double Xb = xb / yb, Yb = 1.0, Zb = (1.0 - xb - yb) / yb;
const double P[9] =
{
Xr, Xg, Xb,
Yr, Yg, Yb,
Zr, Zg, Zb
};
double Pinv[9];
if (!mat3Inverse(P, Pinv))
return false;
const double Xw = xw / yw, Yw = 1.0, Zw = (1.0 - xw - yw) / yw;
const double Sr = Pinv[0] * Xw + Pinv[1] * Yw + Pinv[2] * Zw;
const double Sg = Pinv[3] * Xw + Pinv[4] * Yw + Pinv[5] * Zw;
const double Sb = Pinv[6] * Xw + Pinv[7] * Yw + Pinv[8] * Zw;
out[0] = Sr * Xr; out[1] = Sg * Xg; out[2] = Sb * Xb;
out[3] = Sr * Yr; out[4] = Sg * Yg; out[5] = Sb * Yb;
out[6] = Sr * Zr; out[7] = Sg * Zg; out[8] = Sb * Zb;
return true;
}
/* compute the linear-light matrix that converts the frame's source display
* primaries to BT.709. Falls back to identity (assume BT.709) if the metadata
* is missing or degenerate. */
static void lgComputeColorMatrix(LGPlugin * this, const KVMFRFrame * frame)
{
static const double bt709[9] =
{
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0
};
const double * result = bt709;
double src[9], dst709[9], dst709inv[9], conv[9];
const double xr = frame->hdrDisplayPrimary[0][0] * LG_ST2086_UNIT;
const double yr = frame->hdrDisplayPrimary[0][1] * LG_ST2086_UNIT;
const double xg = frame->hdrDisplayPrimary[1][0] * LG_ST2086_UNIT;
const double yg = frame->hdrDisplayPrimary[1][1] * LG_ST2086_UNIT;
const double xb = frame->hdrDisplayPrimary[2][0] * LG_ST2086_UNIT;
const double yb = frame->hdrDisplayPrimary[2][1] * LG_ST2086_UNIT;
const double xw = frame->hdrWhitePoint[0] * LG_ST2086_UNIT;
const double yw = frame->hdrWhitePoint[1] * LG_ST2086_UNIT;
/* BT.709 / D65 target */
if (primariesToXYZ(xr, yr, xg, yg, xb, yb, xw, yw, src) &&
primariesToXYZ(0.640, 0.330, 0.300, 0.600, 0.150, 0.060,
0.3127, 0.3290, dst709) &&
mat3Inverse(dst709, dst709inv))
{
mat3Mul(dst709inv, src, conv);
result = conv;
}
else
printf("HDR metadata missing or invalid, assuming BT.709 primaries\n");
for (int r = 0; r < 3; ++r)
vec3_set(&this->colorMatrix[r],
(float)result[r * 3 + 0],
(float)result[r * 3 + 1],
(float)result[r * 3 + 2]);
this->hdrScale = 10000.0f / LG_SCRGB_REFERENCE_WHITE;
}
static void lgFormatInit(LGPlugin * this, const KVMFRFrame * frame,
LGMPMessage * msg)
{
@@ -621,6 +776,10 @@ static void lgFormatInit(LGPlugin * this, const KVMFRFrame * frame,
this->dataWidth = frame->dataWidth;
this->unpack = false;
this->hdr = frame->flags & FRAME_FLAG_HDR;
this->hdrPQ = frame->flags & FRAME_FLAG_HDR_PQ;
if (this->hdr && this->hdrPQ)
lgComputeColorMatrix(this, frame);
this->bpp = 4;
switch(this->type)
@@ -936,6 +1095,9 @@ static void lgVideoRender(void * data, gs_effect_t * effect)
if (!texture)
return;
const bool hdrDecode =
this->type == FRAME_TYPE_RGBA10 && this->hdr && this->hdrPQ;
if (this->type == FRAME_TYPE_RGB_24 || this->type == FRAME_TYPE_BGR_32)
{
effect = this->unpackEffect;
@@ -945,6 +1107,19 @@ static void lgVideoRender(void * data, gs_effect_t * effect)
gs_effect_set_vec2(this->outputSize, &outputSize);
gs_effect_set_int(this->swap, this->type == FRAME_TYPE_RGB_24 ? 1 : 0);
}
else if (hdrDecode)
{
/* decode the PQ (ST.2084) encoded frame to linear scRGB and remap the
* source primaries to BT.709 so OBS receives valid GS_CS_709_SCRGB data */
effect = this->hdrEffect;
gs_effect_set_texture(this->hdrImage, texture);
struct vec2 outputSize;
vec2_set(&outputSize, this->frameWidth, this->frameHeight);
gs_effect_set_vec2(this->hdrOutputSize, &outputSize);
for (int i = 0; i < 3; ++i)
gs_effect_set_vec3(this->hdrColorMatrix[i], &this->colorMatrix[i]);
gs_effect_set_float(this->hdrScaleParam, this->hdrScale);
}
else
{
effect = obs_get_base_effect(OBS_EFFECT_OPAQUE);

View File

@@ -14,6 +14,10 @@ function(build_resources)
set(LG_RESOURCES_INCS "${LG_RESOURCES_INCS}" PARENT_SCOPE)
endfunction()
set(RESOURCES_SOURCES
icondata.c
)
build_resources(
lg-logo.svg
status/spice.svg
@@ -22,5 +26,5 @@ build_resources(
no-input-cursor/32.xcur
)
add_library(lg_resources STATIC ${LG_RESOURCES_OBJS})
add_library(lg_resources STATIC ${RESOURCES_SOURCES} ${LG_RESOURCES_OBJS})
set_target_properties(lg_resources PROPERTIES LINKER_LANGUAGE C)

539
resources/icondata.c Normal file
View File

@@ -0,0 +1,539 @@
/**
* Looking Glass
* Copyright © 2017-2026 The Looking Glass Authors
* https://looking-glass.io
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* 64x64 Looking Glass icon represented as an array of 32-bit packed CARDINAL
ARGB with high byte being A, low byte being B. The first two cardinals are
width, height. Data is in rows, left to right and top to bottom */
const unsigned long icondata[] = {
0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x068150ab, 0x4e8554b0, 0xaa905cbc,
0xf0905cbd, 0xff9560c2, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9660c3, 0xf0905cbd, 0xaa905cbc, 0x4e8554b0, 0x068150ab, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1c8050aa, 0xa88e5bba, 0xf89660c3, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xf89660c3, 0xa88e5bba, 0x1c8050aa,
0x00000000, 0x00000000, 0x00000000, 0x1c8050aa, 0xca915dbd, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff945fc1, 0xff8654b1, 0xff794aa2, 0xff74469d, 0xff73469c, 0xff73469c, 0xff73469c, 0xff73469c,
0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff74469d, 0xff74469d,
0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d,
0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d,
0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff73469d, 0xff73469d,
0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff73469c, 0xff73469c, 0xff73469c, 0xff73469c,
0xff73469d, 0xff794aa2, 0xff8654b1, 0xff945fc1, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xca915dbd,
0x1c8050aa, 0x00000000, 0x068150ab, 0xa88e5bba, 0xff9761c4, 0xff9761c4, 0xff9560c2, 0xff794aa3,
0xff4d2575, 0xff3a0c64, 0xff360661, 0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461,
0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460,
0xff350460, 0xff360661, 0xff3a0c64, 0xff4d2575, 0xff794aa3, 0xff9560c2, 0xff9761c4, 0xff9761c4,
0xa88e5bba, 0x068150ab, 0x4e8554b0, 0xf89660c3, 0xff9761c4, 0xff9560c2, 0xff64398d, 0xff380a62,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff360461,
0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463,
0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463,
0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360461, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff380a62, 0xff64398d, 0xff9560c2, 0xff9761c4,
0xf89660c3, 0x4e8554b0, 0xaa905cbc, 0xff9761c4, 0xff9761c4, 0xff794aa3, 0xff380a62, 0xff350460,
0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463,
0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff3b1365, 0xff422469,
0xff482e6c, 0xff4a316d, 0xff4a326d, 0xff482e6c, 0xff422469, 0xff3b1265, 0xff370463, 0xff370463,
0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff360461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff380a62, 0xff794aa3, 0xff9761c4,
0xff9761c4, 0xaa905cbc, 0xf0905cbd, 0xff9761c4, 0xff945fc1, 0xff4d2575, 0xff350460, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff360463, 0xff370463, 0xff370463,
0xff370463, 0xff370463, 0xff380664, 0xff412269, 0xff685982, 0xffa19aad, 0xffc2bdc9, 0xffd6d3db,
0xffdedbe2, 0xffdedae3, 0xffdedbe3, 0xffdddae2, 0xffd5d2da, 0xffc1bcc9, 0xff9f97ac, 0xff695a82,
0xff412269, 0xff370664, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463,
0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff4d2575, 0xff945fc1,
0xff9761c4, 0xf0905cbd, 0xff9560c2, 0xff9761c4, 0xff8654b1, 0xff3a0c64, 0xff350461, 0xff350461,
0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360463, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff370464,
0xff380664, 0xff4a316e, 0xff9a91a8, 0xffd2ced7, 0xffdfdce3, 0xffc2bfca, 0xff9d96ab, 0xff786c8d,
0xff5f4d7c, 0xff543d75, 0xff533c74, 0xff5e4b7b, 0xff796d8e, 0xff9e97ab, 0xffc2beca, 0xffdfdbe3,
0xffd2ced7, 0xff968ea5, 0xff482f6d, 0xff380664, 0xff370464, 0xff370463, 0xff370463, 0xff370463,
0xff370463, 0xff360463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff3a0c64, 0xff8654b1,
0xff9761c4, 0xff9560c2, 0xff9761c4, 0xff9761c4, 0xff794aa3, 0xff360662, 0xff350461, 0xff350461,
0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463,
0xff370463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff3f1d68,
0xff8c839d, 0xffdbd8df, 0xffd2ced8, 0xff8e859f, 0xff4c346f, 0xff3b1467, 0xff380465, 0xff380465,
0xff380465, 0xff380565, 0xff380565, 0xff380465, 0xff380465, 0xff380465, 0xff3b1367, 0xff4c3470,
0xff8f86a0, 0xffd1cdd7, 0xffd9d5de, 0xff8c839d, 0xff3f1d68, 0xff370464, 0xff370464, 0xff370464,
0xff370464, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff350461, 0xff360662, 0xff794aa3,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff350461, 0xff360461, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370564, 0xff533f74, 0xffc0bbc8,
0xffdbd8e0, 0xff8a809b, 0xff43256b, 0xff380565, 0xff380665, 0xff42236a, 0xff5a4678, 0xff867c99,
0xffa39db0, 0xffada6b8, 0xffada6b8, 0xffa49db0, 0xff867b99, 0xff584377, 0xff43236a, 0xff380665,
0xff380565, 0xff44256b, 0xff897f9b, 0xffdad7df, 0xffc0bbc8, 0xff523d73, 0xff370564, 0xff370464,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469d, 0xff360461, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370665, 0xff6a5c83, 0xffd6d3db, 0xffbfbac7,
0xff523c74, 0xff380665, 0xff3a0c66, 0xff574377, 0xffa19aae, 0xffd3cfd9, 0xffe2dfe6, 0xffd1ced7,
0xffbfbac7, 0xffb4adbe, 0xffb3acbe, 0xffbfbbc8, 0xffd1cdd7, 0xffe1dee5, 0xffd3cfd9, 0xff9f97ad,
0xff553f76, 0xff3a0b66, 0xff380665, 0xff533c74, 0xffbeb9c7, 0xffd6d3db, 0xff665781, 0xff370665,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff370463,
0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff73469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380565, 0xff6b5d84, 0xffdddbe2, 0xffa7a0b3, 0xff42226b,
0xff380566, 0xff462a6d, 0xffa49db1, 0xffe1dee5, 0xffc7c4cf, 0xff887e9b, 0xff503a73, 0xff41206b,
0xff3b0e67, 0xff390867, 0xff390867, 0xff3b0f67, 0xff411f6a, 0xff513973, 0xff877d9a, 0xffc6c1cd,
0xffdedbe3, 0xffa29aaf, 0xff472b6d, 0xff380566, 0xff42226b, 0xffa69fb2, 0xffd9d6df, 0xff675782,
0xff380565, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463,
0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360462,
0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff380465, 0xff574377, 0xffd9d6dd, 0xffa69fb3, 0xff3e1969, 0xff390666,
0xff645480, 0xffcfcbd6, 0xffcfccd6, 0xff776a8e, 0xff3f1b6a, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff3e196a,
0xff76698d, 0xffcfcbd5, 0xffcfcbd6, 0xff645380, 0xff380666, 0xff3d1769, 0xffa39bb0, 0xffd7d4dd,
0xff584377, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370464,
0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360463,
0xff370463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370465,
0xff380465, 0xff380465, 0xff43236b, 0xffc8c4cf, 0xffbab5c3, 0xff411f6a, 0xff390766, 0xff766b8c,
0xffdfdce3, 0xffada6b8, 0xff472b6e, 0xff390567, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390567, 0xff47296e, 0xffaba5b7, 0xffdddae1, 0xff72648a, 0xff390666, 0xff411f6a, 0xffbab5c3,
0xffc7c3ce, 0xff43246b, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464,
0xff370464, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465,
0xff380465, 0xff390866, 0xff968ea6, 0xffd7d4dc, 0xff4d3471, 0xff380566, 0xff6b5d85, 0xffe0dee4,
0xff9d96ab, 0xff3f186a, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff3e166a, 0xff988ea8, 0xffdddae2, 0xff6a5b84, 0xff380566, 0xff4c3371,
0xffd6d2db, 0xff978ea6, 0xff390966, 0xff380465, 0xff380465, 0xff380465, 0xff370465, 0xff370464,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff360463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465,
0xff380466, 0xff513a73, 0xffdedce2, 0xff7e7393, 0xff390567, 0xff4c3271, 0xffd5d1da, 0xffa8a1b4,
0xff3e1669, 0xff390467, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390467, 0xff3e1469, 0xffa7a0b4, 0xffd3cfd9, 0xff4c3271, 0xff390567,
0xff7e7293, 0xffdddae2, 0xff513a73, 0xff380466, 0xff380465, 0xff380465, 0xff380465, 0xff370465,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff370463, 0xff370463,
0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465, 0xff380466,
0xff390a67, 0xffa8a2b4, 0xffc7c3ce, 0xff401d6a, 0xff3c1068, 0xffada7b9, 0xffc9c5d1, 0xff45266d,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff45256e, 0xffc9c5d1, 0xffaea8ba, 0xff3c1169,
0xff3f1b6a, 0xffc5c0cd, 0xffa7a1b3, 0xff390a67, 0xff380466, 0xff380465, 0xff380465, 0xff380465,
0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465, 0xff380466, 0xff380466,
0xff4a2f6f, 0xffdcd9e1, 0xff7b6e90, 0xff390467, 0xff645480, 0xffe2e0e6, 0xff6a5b85, 0xff390468,
0xff390468, 0xff390468, 0xff3a0468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0468, 0xff390468, 0xff390468, 0xff390468, 0xff685784, 0xffe0dde5, 0xff645280,
0xff390467, 0xff7a6d90, 0xffdcd9e1, 0xff492e6f, 0xff380466, 0xff380466, 0xff380465, 0xff380465,
0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380466, 0xff380466, 0xff380466,
0xff827896, 0xffd6d3db, 0xff45276d, 0xff3b0c68, 0xffb3adbd, 0xffb9b3c2, 0xff3c116a, 0xff390468,
0xff3a0468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0468, 0xff390468, 0xff3c116a, 0xffb7b2c1, 0xffb2abbc,
0xff3b0c68, 0xff45276d, 0xffd6d2dc, 0xff827896, 0xff380466, 0xff380466, 0xff380466, 0xff380465,
0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465, 0xff380466, 0xff380466, 0xff390967,
0xffb4aebe, 0xffb0aabb, 0xff3a0767, 0xff4a2f70, 0xffdedbe2, 0xff73658c, 0xff390468, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3b046a, 0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff73658c, 0xffdcd9e1,
0xff4a2f70, 0xff3a0767, 0xffafa8ba, 0xffb5afbf, 0xff3a0a67, 0xff380466, 0xff380466, 0xff380465,
0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff3d1667, 0xff7a6e8f, 0xff8e859e, 0xff4b3270, 0xff380466, 0xff42226c,
0xffd4d0d9, 0xff807594, 0xff390467, 0xff74678c, 0xffdbd8e0, 0xff472a6f, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff46286f, 0xffd9d6de,
0xff77698e, 0xff390467, 0xff827696, 0xffd3cfd9, 0xff42226b, 0xff380466, 0xff4c3370, 0xff8d849e,
0xff7a6f8f, 0xff3d1567, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff928aa2, 0xffe1dee5, 0xffd2ced8, 0xffc5c1cd, 0xff401d6a, 0xff4b3170,
0xffdfdce4, 0xff5c477b, 0xff390568, 0xffa49eb1, 0xffbfbac8, 0xff3c106a, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3c0f6a, 0xffbeb9c7,
0xffa49db2, 0xff390468, 0xff5b467a, 0xffdfdce4, 0xff4b3170, 0xff401d6a, 0xffc6c1cd, 0xffd3cfd9,
0xffdfdde3, 0xff9289a2, 0xff380565, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff390a66, 0xffbab5c4, 0xffaaa4b6, 0xff685883, 0xffe0dce4, 0xff4a3070, 0xff564077,
0xffe2dee6, 0xff4a2f70, 0xff3b0c69, 0xffbcb7c5, 0xffa8a2b5, 0xff3a0569, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0569, 0xffa7a0b4,
0xffbbb6c4, 0xff3b0c69, 0xff4a2f70, 0xffe2dfe6, 0xff564077, 0xff4a3070, 0xffdfdce4, 0xff695884,
0xffaaa3b6, 0xffbbb5c4, 0xff3a0a66, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff867b98, 0xffe2dfe6, 0xffe1dee5, 0xffb9b4c2, 0xff3e1869, 0xff624d81,
0xffdcd8e1, 0xff47296e, 0xff3d126a, 0xffc5c1cd, 0xff978ea7, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046c,
0xff3b046c, 0xff3c046c, 0xff3c046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff988fa8,
0xffc5c0cc, 0xff3c126a, 0xff47296e, 0xffdcd9e1, 0xff614c80, 0xff3e1869, 0xffb9b3c2, 0xffe0dde4,
0xffe3e1e7, 0xff857b97, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff3a0d66, 0xff9389a3, 0xffcdc8d4, 0xff45286d, 0xff380467, 0xff675384,
0xffdbd8e0, 0xff46296e, 0xff3d136a, 0xffc6c1ce, 0xff948aa5, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046c,
0xff3b046c, 0xff3c046c, 0xff3c046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff9489a5,
0xffc6c1ce, 0xff3d136a, 0xff46286e, 0xffdbd8e0, 0xff675384, 0xff380467, 0xff45286d, 0xffcdc7d4,
0xff948aa4, 0xff3a0c66, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff380465, 0xff867d98, 0xffd1ced7, 0xff41206a, 0xff380466, 0xff5a437a,
0xffe0dce4, 0xff482c6f, 0xff3c0f69, 0xffc2bdca, 0xffa199af, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046c,
0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xffa098ae,
0xffc1bdc9, 0xff3c0f69, 0xff482c6f, 0xffdfdce4, 0xff5b447b, 0xff380466, 0xff411f6a, 0xffd1cdd7,
0xff867d98, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff380465, 0xff716289, 0xffd9d6de, 0xff45276c, 0xff380466, 0xff4f3773,
0xffe2dee6, 0xff523a75, 0xff3a0668, 0xffada7b9, 0xffb6b0c0, 0xff3b0a69, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3b0a69, 0xffb6b0c0,
0xffaea8ba, 0xff3a0668, 0xff523b75, 0xffe3e0e7, 0xff4f3772, 0xff380466, 0xff45286c, 0xffdad7df,
0xff716189, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff380465, 0xff523c73, 0xffe2e0e6, 0xff4d3571, 0xff380466, 0xff46296d,
0xffdad7df, 0xff706189, 0xff390467, 0xff8c829e, 0xffd1cdd7, 0xff42206c, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff42206c, 0xffd2ced8,
0xff8b819d, 0xff390467, 0xff716289, 0xffdad7df, 0xff46296d, 0xff380466, 0xff4e3572, 0xffe2dfe6,
0xff523c74, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff380465, 0xff472b6d, 0xffdcd9e0, 0xff6a5b84, 0xff380466, 0xff3c1468,
0xffc2beca, 0xff9f98ad, 0xff390467, 0xff533c76, 0xffe1dee6, 0xff5c487c, 0xff390468, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3b046a, 0xff3b046a, 0xff3b046a, 0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff5c497c, 0xffe2dfe7,
0xff543e77, 0xff390467, 0xffa19aaf, 0xffc2beca, 0xff3c1368, 0xff380466, 0xff6c5d86, 0xffdcd9e1,
0xff472c6d, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370464, 0xff380465, 0xff3d1567, 0xffc4bfcb, 0xff9c95ab, 0xff380466, 0xff380466,
0xff968da6, 0xffc9c4d0, 0xff3f1a6a, 0xff3f186a, 0xffc5c0cd, 0xffa199af, 0xff3a0668, 0xff390468,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff3a0768, 0xffa199af, 0xffc6c1cd,
0xff3e176a, 0xff3f196a, 0xffc8c4d0, 0xff978fa6, 0xff380466, 0xff380466, 0xff9e97ac, 0xffc4c0cc,
0xff3d1567, 0xff380465, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff9b92a9, 0xffc5c1cd, 0xff3d1669, 0xff380466,
0xff5a4779, 0xffe0dde5, 0xff5e4b7d, 0xff390467, 0xff827796, 0xffdbd9e0, 0xff4d3473, 0xff390468,
0xff390468, 0xff3a0468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0468, 0xff390468, 0xff390468, 0xff4e3573, 0xffdbd8e0, 0xff837897,
0xff390467, 0xff5f4d7d, 0xffe2e0e6, 0xff594679, 0xff380466, 0xff3d1668, 0xffc5c0cc, 0xff9d95ab,
0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff370463, 0xff370463,
0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff604f7d, 0xffe1dee5, 0xff574277, 0xff380466,
0xff3d1568, 0xffc1bcc9, 0xffada7b9, 0xff3b0c68, 0xff43226c, 0xffcbc7d2, 0xffa9a2b5, 0xff3c0f69,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff3c1069, 0xffaba5b7, 0xffccc8d2, 0xff43226c,
0xff3b0c68, 0xffaea8b9, 0xffc1bcc9, 0xff3d1568, 0xff380466, 0xff564276, 0xffe2dfe5, 0xff5f4d7c,
0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff370463, 0xff370463,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff3e1a68, 0xffc8c4cf, 0xff9e97ac, 0xff390766,
0xff380466, 0xff6e5f87, 0xffdfdce4, 0xff5b497a, 0xff390467, 0xff6b5b85, 0xffe0dde4, 0xff7b6f91,
0xff390668, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390668, 0xff7c7091, 0xffe0dde4, 0xff6b5b85, 0xff390467,
0xff5c4a7b, 0xffe1dee5, 0xff6f6288, 0xff380466, 0xff390666, 0xff9f97ac, 0xffc9c4d0, 0xff3e1a68,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff360463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370564, 0xff857b98, 0xffd8d6dd, 0xff4a2f6e,
0xff380465, 0xff3d1668, 0xffb9b3c3, 0xffbcb7c5, 0xff3f1a69, 0xff390a67, 0xff9289a3, 0xffddd9e1,
0xff695a84, 0xff390667, 0xff390467, 0xff390467, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390467, 0xff390467, 0xff390667, 0xff6d5e86, 0xffdddae1, 0xff948ca4, 0xff390a67, 0xff3e1969,
0xffbdb8c6, 0xffbab4c3, 0xff3d1668, 0xff380465, 0xff4a2f6e, 0xffd9d7de, 0xff887e99, 0xff370564,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360463, 0xff360463,
0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff42236a, 0xffcecad5, 0xff9991a8,
0xff390765, 0xff380465, 0xff574377, 0xffdcd8e1, 0xff9086a1, 0xff3a0a67, 0xff3d1669, 0xffa29baf,
0xffdcd9e1, 0xff776a8e, 0xff3b0b68, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff3b0b68, 0xff776b8e, 0xffdddae2, 0xffa49db2, 0xff3e1769, 0xff390a67, 0xff8e859f,
0xffdddae1, 0xff584477, 0xff380465, 0xff390865, 0xff9b94a9, 0xffcfccd5, 0xff42246a, 0xff370464,
0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360463,
0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370564, 0xff807493, 0xffdddae2,
0xff5b4979, 0xff380465, 0xff390765, 0xff807594, 0xffe0dde5, 0xff75698c, 0xff380666, 0xff3e1869,
0xff9991a8, 0xffe1dfe5, 0xff9f97ad, 0xff472b6e, 0xff390567, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390567,
0xff472b6e, 0xff9e96ac, 0xffe1dfe5, 0xff9990a8, 0xff3e1869, 0xff390666, 0xff776b8e, 0xffe0dde4,
0xff7f7593, 0xff390665, 0xff380465, 0xff594578, 0xffdfdce3, 0xff807594, 0xff370564, 0xff370464,
0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360462,
0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370464, 0xff3d1867, 0xffb9b4c2,
0xffbfbac7, 0xff402069, 0xff370465, 0xff3a0e66, 0xff9992a7, 0xffdddbe1, 0xff726489, 0xff390866,
0xff3a0d67, 0xff766a8d, 0xffd3cfd9, 0xffd5d2db, 0xff8f86a0, 0xff4d3471, 0xff3c1268, 0xff380466,
0xff380466, 0xff380467, 0xff380467, 0xff380466, 0xff380466, 0xff3b1168, 0xff4c3471, 0xff8f86a0,
0xffd4d1da, 0xffd3d0d9, 0xff766a8d, 0xff3a0d67, 0xff390966, 0xff75688c, 0xffdfdde4, 0xff9a92a8,
0xff3a0d66, 0xff370465, 0xff412069, 0xffc0bbc8, 0xffb9b4c2, 0xff3d1867, 0xff370464, 0xff370463,
0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360461, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff533e74,
0xffd9d6de, 0xff9e97ac, 0xff3a0f65, 0xff370465, 0xff3c1567, 0xff9a94a8, 0xffdfdde4, 0xff8b829c,
0xff3d1668, 0xff380565, 0xff472b6d, 0xff938ba3, 0xffd1ced8, 0xffdedbe3, 0xffc1bcc9, 0xff9f98ad,
0xff7f7394, 0xff695685, 0xff695785, 0xff817695, 0xff9e97ac, 0xffbfbac8, 0xffe0dee4, 0xffd2ced8,
0xff9188a1, 0xff472a6d, 0xff380565, 0xff3d1567, 0xff8a819b, 0xffe1dfe5, 0xff9c95aa, 0xff3c1567,
0xff370465, 0xff3a1066, 0xffa099ad, 0xffd8d6dd, 0xff533e73, 0xff370464, 0xff370463, 0xff370463,
0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469d, 0xff350461, 0xff360461, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370563,
0xff726489, 0xffe1dfe5, 0xff89809b, 0xff390c65, 0xff370464, 0xff3a1066, 0xff867b98, 0xffdedce3,
0xffb2adbd, 0xff523c73, 0xff390865, 0xff380565, 0xff43236a, 0xff6a5b84, 0xffa49db0, 0xffc2bdca,
0xffd5d2da, 0xffdad7df, 0xffdad7df, 0xffd4d2da, 0xffc3bfca, 0xffa39cb0, 0xff6c5d85, 0xff42236a,
0xff380565, 0xff390966, 0xff533d74, 0xffb4aebd, 0xffdedce2, 0xff867c98, 0xff3a1166, 0xff370464,
0xff390b65, 0xff887e99, 0xffe1dee5, 0xff716487, 0xff370563, 0xff370463, 0xff370463, 0xff360463,
0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff73469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469d, 0xff350461, 0xff350461, 0xff360461,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463,
0xff380a64, 0xff867c98, 0xffe1dfe5, 0xff897f9a, 0xff390e65, 0xff370464, 0xff380764, 0xff5f4d7b,
0xffc3beca, 0xffddd9e1, 0xffa098ad, 0xff4f3872, 0xff3a0e66, 0xff380465, 0xff380565, 0xff3b1167,
0xff42236a, 0xff45286c, 0xff45286c, 0xff42236a, 0xff3b1267, 0xff380565, 0xff380465, 0xff3a0f66,
0xff4f3872, 0xffa19aae, 0xffdedce2, 0xffc4bfcb, 0xff5f4d7b, 0xff380764, 0xff370464, 0xff390c65,
0xff867d99, 0xffe0dde3, 0xff847a95, 0xff380964, 0xff370463, 0xff360463, 0xff360463, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff350461, 0xff73469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469c, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463,
0xff360463, 0xff380a64, 0xff867c98, 0xffe0dee4, 0xff9991a7, 0xff3e1c67, 0xff370464, 0xff370464,
0xff3f1d68, 0xff807494, 0xffcecad4, 0xffdfdce3, 0xffb8b2c1, 0xff867d98, 0xff543f74, 0xff45296b,
0xff3f1d68, 0xff3c1467, 0xff3c1467, 0xff3f1b68, 0xff45296b, 0xff554075, 0xff877d99, 0xffb9b4c2,
0xffdfdce3, 0xffcdc8d3, 0xff7f7492, 0xff3f1d68, 0xff370464, 0xff370464, 0xff3f1d67, 0xff9a92a8,
0xffe1dfe5, 0xff847a95, 0xff380964, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff73469c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469c, 0xff350460, 0xff350460, 0xff350461,
0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff380a63, 0xff74678a, 0xffdad7df, 0xffb8b2c1, 0xff513a71, 0xff370663,
0xff370463, 0xff370564, 0xff402068, 0xff6b5b84, 0xffada7b8, 0xffd0cdd6, 0xffe1dee5, 0xffdbd8e0,
0xffcfcad5, 0xffc7c2ce, 0xffc7c3ce, 0xffcdc9d4, 0xffdcd9e0, 0xffe3e0e6, 0xffd2ced7, 0xffaea8b9,
0xff6b5c84, 0xff401f68, 0xff370464, 0xff370463, 0xff370663, 0xff513b72, 0xffbab5c2, 0xffdad8df,
0xff766a8c, 0xff370a63, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff73469c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469c, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360562, 0xff594677, 0xffc1bcc9, 0xffdad7df, 0xff897f9a,
0xff432569, 0xff370563, 0xff370463, 0xff370463, 0xff380764, 0xff412168, 0xff4d376f, 0xff6b5c84,
0xff8a819b, 0xff9288a2, 0xff9288a2, 0xff89809a, 0xff6b5b84, 0xff4d376f, 0xff412168, 0xff380763,
0xff370463, 0xff370463, 0xff370563, 0xff44276a, 0xff8c829c, 0xffdbd8df, 0xffc1bdc9, 0xff5a4877,
0xff360562, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff360461,
0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff73469c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff360461,
0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff3e1d66, 0xff8c839c, 0xffd8d4dd,
0xffd1ced7, 0xff897e9a, 0xff482f6c, 0xff380b64, 0xff360463, 0xff360463, 0xff370463, 0xff370463,
0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463,
0xff380b64, 0xff49306d, 0xff8a819b, 0xffd4d1d9, 0xffd9d6de, 0xff8e859d, 0xff3e1e66, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035f, 0xff34035f, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff360461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff370662, 0xff482f6c,
0xff988fa6, 0xffd4d1d9, 0xffddd9e1, 0xffb3adbd, 0xff837a96, 0xff513c71, 0xff432769, 0xff3b1565,
0xff380c63, 0xff370863, 0xff370863, 0xff380d64, 0xff3b1565, 0xff432769, 0xff503b70, 0xff827894,
0xffb4aebd, 0xffdddae1, 0xffd6d3db, 0xff978fa5, 0xff482f6b, 0xff370662, 0xff360462, 0xff360462,
0xff360461, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff34035f, 0xff34035f, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360461,
0xff370662, 0xff422568, 0xff74688a, 0xffb1abbb, 0xffd3d0d9, 0xffe2dfe6, 0xffd9d6de, 0xffc7c4ce,
0xffbcb7c4, 0xffb3adbd, 0xffb3adbd, 0xffbdb8c5, 0xffc7c4ce, 0xffd9d7de, 0xffe2dfe6, 0xffd3d0d8,
0xffb1acbb, 0xff75698a, 0xff422668, 0xff370762, 0xff360461, 0xff360461, 0xff360461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035e, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff35045f, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff370862, 0xff402367, 0xff503a70, 0xff736588, 0xff948ca3,
0xffa7a1b1, 0xffd2ced7, 0xffd2ced7, 0xffa7a2b1, 0xff978ea4, 0xff75688a, 0xff503b70, 0xff402266,
0xff360762, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff35045f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff35045f, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff360661, 0xffaea8b8, 0xffaea8b8, 0xff360661, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff35045f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e, 0xff34035e, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff35045f, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff360661, 0xffaea8b8, 0xffaea8b8, 0xff360661, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff35045f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff33035d, 0xff33035d, 0xff33035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff35045f, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff360660, 0xffaea8b8, 0xffaea8b8, 0xff360660, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff35045f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff33035e, 0xff33035d, 0xff33035d, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff35035f, 0xff35045f, 0xff35045f, 0xff350460, 0xff350460,
0xff350560, 0xffaea8b8, 0xffaea8b8, 0xff350560, 0xff350460, 0xff350460, 0xff35045f, 0xff35045f,
0xff35035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff33035e, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459b, 0xff33035c, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff35055f, 0xffaea8b8, 0xffaea8b8, 0xff35055f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff33035e, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c, 0xff73459b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459b, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f,
0xff35055f, 0xffaea8b8, 0xffaea8b8, 0xff35055f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff73459b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459b, 0xff32035b, 0xff32035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff35055e, 0xffaea8b8, 0xffaea8b8, 0xff35055e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff33035e, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff32035c, 0xff32035b, 0xff73459b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035c, 0xff32035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff3f2363, 0xff746887, 0xff958fa2, 0xff9892a3, 0xff9892a3, 0xff9892a3,
0xff9892a3, 0xffc9c6d0, 0xffc9c6d0, 0xff9892a3, 0xff9892a3, 0xff9892a3, 0xff9892a3, 0xff9690a2,
0xff766b8a, 0xff402464, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff32035c, 0xff32035c, 0xff32035b, 0xff32035b, 0xff32035b, 0xff73469b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff784aa1, 0xff33055c, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035c, 0xff32035c, 0xff32035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff4a346a, 0xffc8c5cf, 0xffd9d6dd, 0xffc6c2cc, 0xffc4c0ca, 0xffc4c0ca, 0xffc4c0ca,
0xffc4c0ca, 0xffc5c1cb, 0xffc5c1cb, 0xffc4c0ca, 0xffc4c0ca, 0xffc4c0ca, 0xffc4c0ca, 0xffc5c1cb,
0xffdad7de, 0xffc8c4ce, 0xff4b356a, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff32035c, 0xff32035c,
0xff32035c, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff33055c, 0xff784aa1,
0xff9761c4, 0xff9761c4, 0xff9560c2, 0xff9761c4, 0xff8654b0, 0xff370c5e, 0xff32035a, 0xff32035a,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035c,
0xff32035c, 0xff32035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff350a5d, 0xffada8b6, 0xffc9c6cf, 0xff4e3b6c, 0xff402363, 0xff3f2263, 0xff3f2263, 0xff3f2263,
0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2363,
0xff4f3b6c, 0xffc9c6cf, 0xffaca6b6, 0xff350a5d, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff32035c, 0xff32035c, 0xff32035c, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035a, 0xff32035a, 0xff370c5e, 0xff8654b0,
0xff9761c4, 0xff9560c2, 0xf0905cbc, 0xff9761c4, 0xff945fc1, 0xff4b2471, 0xff31035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035c, 0xff32035c, 0xff32035c, 0xff32035c,
0xff3e2262, 0xffd4d2d8, 0xffdad7df, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2,
0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2,
0xffccc8d2, 0xffdbd7df, 0xffd4d2d8, 0xff3d2262, 0xff32035c, 0xff32035c, 0xff32035c, 0xff32035c,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff31035a, 0xff4b2471, 0xff945fc1,
0xff9761c4, 0xf0905cbc, 0xaa905cbc, 0xff9761c4, 0xff9761c4, 0xff784aa1, 0xff34095c, 0xff31035a,
0xff31035a, 0xff31035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff35105d, 0xff796f8a, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299,
0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299,
0xff8a8299, 0xff8a8299, 0xff796f8a, 0xff35105d, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff34095c, 0xff784aa1, 0xff9761c4,
0xff9761c4, 0xaa905cbc, 0x4e8554af, 0xf89660c3, 0xff9761c4, 0xff9560c2, 0xff63398a, 0xff34095c,
0xff310359, 0xff310359, 0xff31035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff31035a, 0xff31035a,
0xff31035a, 0xff31035a, 0xff310359, 0xff310359, 0xff34095c, 0xff63398a, 0xff9560c2, 0xff9761c4,
0xf89660c3, 0x4e8554af, 0x068150ab, 0xa88e5bba, 0xff9761c4, 0xff9761c4, 0xff9560c2, 0xff784aa1,
0xff4b2471, 0xff360c5d, 0xff32055a, 0xff310359, 0xff310359, 0xff310359, 0xff31035a, 0xff31035a,
0xff31035a, 0xff31035a, 0xff31035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff310359, 0xff310359,
0xff310359, 0xff32055a, 0xff360c5d, 0xff4b2471, 0xff784aa1, 0xff9560c2, 0xff9761c4, 0xff9761c4,
0xa88e5bba, 0x068150ab, 0x00000000, 0x1c7f50a9, 0xca915dbd, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff945fc1, 0xff8654b0, 0xff784aa1, 0xff73469b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73469b, 0xff784aa1, 0xff8654b0, 0xff945fc1, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xca915dbd,
0x1c7f50a9, 0x00000000, 0x00000000, 0x00000000, 0x1c7f50a9, 0xa88e5bba, 0xf89660c3, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xf89660c3, 0xa88e5bba, 0x1c7f50a9,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x068150aa, 0x4e8554af, 0xaa905cbc,
0xf0905cbc, 0xff9560c2, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9660c3, 0xf0905cbc, 0xaa905cbc, 0x4e8554af, 0x068150aa, 0x00000000,
0x00000000, 0x00000000
};
const unsigned icondataSize = sizeof(icondata);

View File

@@ -18,522 +18,5 @@
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* 64x64 Looking Glass icon represented as an array of 32-bit packed CARDINAL
ARGB with high byte being A, low byte being B. The first two cardinals are
width, height. Data is in rows, left to right and top to bottom */
const unsigned long icondata[] = {
0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x068150ab, 0x4e8554b0, 0xaa905cbc,
0xf0905cbd, 0xff9560c2, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9660c3, 0xf0905cbd, 0xaa905cbc, 0x4e8554b0, 0x068150ab, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1c8050aa, 0xa88e5bba, 0xf89660c3, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xf89660c3, 0xa88e5bba, 0x1c8050aa,
0x00000000, 0x00000000, 0x00000000, 0x1c8050aa, 0xca915dbd, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff945fc1, 0xff8654b1, 0xff794aa2, 0xff74469d, 0xff73469c, 0xff73469c, 0xff73469c, 0xff73469c,
0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff74469d, 0xff74469d,
0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d,
0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d,
0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff74469d, 0xff73469d, 0xff73469d,
0xff73469d, 0xff73469d, 0xff73469d, 0xff73469d, 0xff73469c, 0xff73469c, 0xff73469c, 0xff73469c,
0xff73469d, 0xff794aa2, 0xff8654b1, 0xff945fc1, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xca915dbd,
0x1c8050aa, 0x00000000, 0x068150ab, 0xa88e5bba, 0xff9761c4, 0xff9761c4, 0xff9560c2, 0xff794aa3,
0xff4d2575, 0xff3a0c64, 0xff360661, 0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461,
0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460,
0xff350460, 0xff360661, 0xff3a0c64, 0xff4d2575, 0xff794aa3, 0xff9560c2, 0xff9761c4, 0xff9761c4,
0xa88e5bba, 0x068150ab, 0x4e8554b0, 0xf89660c3, 0xff9761c4, 0xff9560c2, 0xff64398d, 0xff380a62,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff360461,
0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463,
0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360463,
0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360461, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff380a62, 0xff64398d, 0xff9560c2, 0xff9761c4,
0xf89660c3, 0x4e8554b0, 0xaa905cbc, 0xff9761c4, 0xff9761c4, 0xff794aa3, 0xff380a62, 0xff350460,
0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463,
0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff3b1365, 0xff422469,
0xff482e6c, 0xff4a316d, 0xff4a326d, 0xff482e6c, 0xff422469, 0xff3b1265, 0xff370463, 0xff370463,
0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360463, 0xff360463, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff360461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff380a62, 0xff794aa3, 0xff9761c4,
0xff9761c4, 0xaa905cbc, 0xf0905cbd, 0xff9761c4, 0xff945fc1, 0xff4d2575, 0xff350460, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff360463, 0xff370463, 0xff370463,
0xff370463, 0xff370463, 0xff380664, 0xff412269, 0xff685982, 0xffa19aad, 0xffc2bdc9, 0xffd6d3db,
0xffdedbe2, 0xffdedae3, 0xffdedbe3, 0xffdddae2, 0xffd5d2da, 0xffc1bcc9, 0xff9f97ac, 0xff695a82,
0xff412269, 0xff370664, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463,
0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff4d2575, 0xff945fc1,
0xff9761c4, 0xf0905cbd, 0xff9560c2, 0xff9761c4, 0xff8654b1, 0xff3a0c64, 0xff350461, 0xff350461,
0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360463, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff370464,
0xff380664, 0xff4a316e, 0xff9a91a8, 0xffd2ced7, 0xffdfdce3, 0xffc2bfca, 0xff9d96ab, 0xff786c8d,
0xff5f4d7c, 0xff543d75, 0xff533c74, 0xff5e4b7b, 0xff796d8e, 0xff9e97ab, 0xffc2beca, 0xffdfdbe3,
0xffd2ced7, 0xff968ea5, 0xff482f6d, 0xff380664, 0xff370464, 0xff370463, 0xff370463, 0xff370463,
0xff370463, 0xff360463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff3a0c64, 0xff8654b1,
0xff9761c4, 0xff9560c2, 0xff9761c4, 0xff9761c4, 0xff794aa3, 0xff360662, 0xff350461, 0xff350461,
0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463,
0xff370463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff3f1d68,
0xff8c839d, 0xffdbd8df, 0xffd2ced8, 0xff8e859f, 0xff4c346f, 0xff3b1467, 0xff380465, 0xff380465,
0xff380465, 0xff380565, 0xff380565, 0xff380465, 0xff380465, 0xff380465, 0xff3b1367, 0xff4c3470,
0xff8f86a0, 0xffd1cdd7, 0xffd9d5de, 0xff8c839d, 0xff3f1d68, 0xff370464, 0xff370464, 0xff370464,
0xff370464, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff350461, 0xff360662, 0xff794aa3,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff350461, 0xff360461, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370564, 0xff533f74, 0xffc0bbc8,
0xffdbd8e0, 0xff8a809b, 0xff43256b, 0xff380565, 0xff380665, 0xff42236a, 0xff5a4678, 0xff867c99,
0xffa39db0, 0xffada6b8, 0xffada6b8, 0xffa49db0, 0xff867b99, 0xff584377, 0xff43236a, 0xff380665,
0xff380565, 0xff44256b, 0xff897f9b, 0xffdad7df, 0xffc0bbc8, 0xff523d73, 0xff370564, 0xff370464,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469d, 0xff360461, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370665, 0xff6a5c83, 0xffd6d3db, 0xffbfbac7,
0xff523c74, 0xff380665, 0xff3a0c66, 0xff574377, 0xffa19aae, 0xffd3cfd9, 0xffe2dfe6, 0xffd1ced7,
0xffbfbac7, 0xffb4adbe, 0xffb3acbe, 0xffbfbbc8, 0xffd1cdd7, 0xffe1dee5, 0xffd3cfd9, 0xff9f97ad,
0xff553f76, 0xff3a0b66, 0xff380665, 0xff533c74, 0xffbeb9c7, 0xffd6d3db, 0xff665781, 0xff370665,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff370463,
0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff73469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380565, 0xff6b5d84, 0xffdddbe2, 0xffa7a0b3, 0xff42226b,
0xff380566, 0xff462a6d, 0xffa49db1, 0xffe1dee5, 0xffc7c4cf, 0xff887e9b, 0xff503a73, 0xff41206b,
0xff3b0e67, 0xff390867, 0xff390867, 0xff3b0f67, 0xff411f6a, 0xff513973, 0xff877d9a, 0xffc6c1cd,
0xffdedbe3, 0xffa29aaf, 0xff472b6d, 0xff380566, 0xff42226b, 0xffa69fb2, 0xffd9d6df, 0xff675782,
0xff380565, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463,
0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360462,
0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff380465, 0xff574377, 0xffd9d6dd, 0xffa69fb3, 0xff3e1969, 0xff390666,
0xff645480, 0xffcfcbd6, 0xffcfccd6, 0xff776a8e, 0xff3f1b6a, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff3e196a,
0xff76698d, 0xffcfcbd5, 0xffcfcbd6, 0xff645380, 0xff380666, 0xff3d1769, 0xffa39bb0, 0xffd7d4dd,
0xff584377, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370464,
0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360463,
0xff370463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370465,
0xff380465, 0xff380465, 0xff43236b, 0xffc8c4cf, 0xffbab5c3, 0xff411f6a, 0xff390766, 0xff766b8c,
0xffdfdce3, 0xffada6b8, 0xff472b6e, 0xff390567, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390567, 0xff47296e, 0xffaba5b7, 0xffdddae1, 0xff72648a, 0xff390666, 0xff411f6a, 0xffbab5c3,
0xffc7c3ce, 0xff43246b, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464,
0xff370464, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465,
0xff380465, 0xff390866, 0xff968ea6, 0xffd7d4dc, 0xff4d3471, 0xff380566, 0xff6b5d85, 0xffe0dee4,
0xff9d96ab, 0xff3f186a, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff3e166a, 0xff988ea8, 0xffdddae2, 0xff6a5b84, 0xff380566, 0xff4c3371,
0xffd6d2db, 0xff978ea6, 0xff390966, 0xff380465, 0xff380465, 0xff380465, 0xff370465, 0xff370464,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff360463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465,
0xff380466, 0xff513a73, 0xffdedce2, 0xff7e7393, 0xff390567, 0xff4c3271, 0xffd5d1da, 0xffa8a1b4,
0xff3e1669, 0xff390467, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390467, 0xff3e1469, 0xffa7a0b4, 0xffd3cfd9, 0xff4c3271, 0xff390567,
0xff7e7293, 0xffdddae2, 0xff513a73, 0xff380466, 0xff380465, 0xff380465, 0xff380465, 0xff370465,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff370463, 0xff370463,
0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465, 0xff380466,
0xff390a67, 0xffa8a2b4, 0xffc7c3ce, 0xff401d6a, 0xff3c1068, 0xffada7b9, 0xffc9c5d1, 0xff45266d,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff45256e, 0xffc9c5d1, 0xffaea8ba, 0xff3c1169,
0xff3f1b6a, 0xffc5c0cd, 0xffa7a1b3, 0xff390a67, 0xff380466, 0xff380465, 0xff380465, 0xff380465,
0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465, 0xff380466, 0xff380466,
0xff4a2f6f, 0xffdcd9e1, 0xff7b6e90, 0xff390467, 0xff645480, 0xffe2e0e6, 0xff6a5b85, 0xff390468,
0xff390468, 0xff390468, 0xff3a0468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0468, 0xff390468, 0xff390468, 0xff390468, 0xff685784, 0xffe0dde5, 0xff645280,
0xff390467, 0xff7a6d90, 0xffdcd9e1, 0xff492e6f, 0xff380466, 0xff380466, 0xff380465, 0xff380465,
0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380466, 0xff380466, 0xff380466,
0xff827896, 0xffd6d3db, 0xff45276d, 0xff3b0c68, 0xffb3adbd, 0xffb9b3c2, 0xff3c116a, 0xff390468,
0xff3a0468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0468, 0xff390468, 0xff3c116a, 0xffb7b2c1, 0xffb2abbc,
0xff3b0c68, 0xff45276d, 0xffd6d2dc, 0xff827896, 0xff380466, 0xff380466, 0xff380466, 0xff380465,
0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff380465, 0xff380465, 0xff380465, 0xff380466, 0xff380466, 0xff390967,
0xffb4aebe, 0xffb0aabb, 0xff3a0767, 0xff4a2f70, 0xffdedbe2, 0xff73658c, 0xff390468, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3b046a, 0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff73658c, 0xffdcd9e1,
0xff4a2f70, 0xff3a0767, 0xffafa8ba, 0xffb5afbf, 0xff3a0a67, 0xff380466, 0xff380466, 0xff380465,
0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff3d1667, 0xff7a6e8f, 0xff8e859e, 0xff4b3270, 0xff380466, 0xff42226c,
0xffd4d0d9, 0xff807594, 0xff390467, 0xff74678c, 0xffdbd8e0, 0xff472a6f, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff46286f, 0xffd9d6de,
0xff77698e, 0xff390467, 0xff827696, 0xffd3cfd9, 0xff42226b, 0xff380466, 0xff4c3370, 0xff8d849e,
0xff7a6f8f, 0xff3d1567, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff928aa2, 0xffe1dee5, 0xffd2ced8, 0xffc5c1cd, 0xff401d6a, 0xff4b3170,
0xffdfdce4, 0xff5c477b, 0xff390568, 0xffa49eb1, 0xffbfbac8, 0xff3c106a, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3c0f6a, 0xffbeb9c7,
0xffa49db2, 0xff390468, 0xff5b467a, 0xffdfdce4, 0xff4b3170, 0xff401d6a, 0xffc6c1cd, 0xffd3cfd9,
0xffdfdde3, 0xff9289a2, 0xff380565, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff390a66, 0xffbab5c4, 0xffaaa4b6, 0xff685883, 0xffe0dce4, 0xff4a3070, 0xff564077,
0xffe2dee6, 0xff4a2f70, 0xff3b0c69, 0xffbcb7c5, 0xffa8a2b5, 0xff3a0569, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0569, 0xffa7a0b4,
0xffbbb6c4, 0xff3b0c69, 0xff4a2f70, 0xffe2dfe6, 0xff564077, 0xff4a3070, 0xffdfdce4, 0xff695884,
0xffaaa3b6, 0xffbbb5c4, 0xff3a0a66, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff867b98, 0xffe2dfe6, 0xffe1dee5, 0xffb9b4c2, 0xff3e1869, 0xff624d81,
0xffdcd8e1, 0xff47296e, 0xff3d126a, 0xffc5c1cd, 0xff978ea7, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046c,
0xff3b046c, 0xff3c046c, 0xff3c046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff988fa8,
0xffc5c0cc, 0xff3c126a, 0xff47296e, 0xffdcd9e1, 0xff614c80, 0xff3e1869, 0xffb9b3c2, 0xffe0dde4,
0xffe3e1e7, 0xff857b97, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff3a0d66, 0xff9389a3, 0xffcdc8d4, 0xff45286d, 0xff380467, 0xff675384,
0xffdbd8e0, 0xff46296e, 0xff3d136a, 0xffc6c1ce, 0xff948aa5, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046c,
0xff3b046c, 0xff3c046c, 0xff3c046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff9489a5,
0xffc6c1ce, 0xff3d136a, 0xff46286e, 0xffdbd8e0, 0xff675384, 0xff380467, 0xff45286d, 0xffcdc7d4,
0xff948aa4, 0xff3a0c66, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff380465, 0xff867d98, 0xffd1ced7, 0xff41206a, 0xff380466, 0xff5a437a,
0xffe0dce4, 0xff482c6f, 0xff3c0f69, 0xffc2bdca, 0xffa199af, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046c,
0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046c, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xffa098ae,
0xffc1bdc9, 0xff3c0f69, 0xff482c6f, 0xffdfdce4, 0xff5b447b, 0xff380466, 0xff411f6a, 0xffd1cdd7,
0xff867d98, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370464, 0xff370464, 0xff370464,
0xff370465, 0xff380465, 0xff380465, 0xff716289, 0xffd9d6de, 0xff45276c, 0xff380466, 0xff4f3773,
0xffe2dee6, 0xff523a75, 0xff3a0668, 0xffada7b9, 0xffb6b0c0, 0xff3b0a69, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3b0a69, 0xffb6b0c0,
0xffaea8ba, 0xff3a0668, 0xff523b75, 0xffe3e0e7, 0xff4f3772, 0xff380466, 0xff45286c, 0xffdad7df,
0xff716189, 0xff380465, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff380465, 0xff523c73, 0xffe2e0e6, 0xff4d3571, 0xff380466, 0xff46296d,
0xffdad7df, 0xff706189, 0xff390467, 0xff8c829e, 0xffd1cdd7, 0xff42206c, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3b046a, 0xff3b046b, 0xff3b046b,
0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046b, 0xff3b046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff42206c, 0xffd2ced8,
0xff8b819d, 0xff390467, 0xff716289, 0xffdad7df, 0xff46296d, 0xff380466, 0xff4e3572, 0xffe2dfe6,
0xff523c74, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370465, 0xff380465, 0xff472b6d, 0xffdcd9e0, 0xff6a5b84, 0xff380466, 0xff3c1468,
0xffc2beca, 0xff9f98ad, 0xff390467, 0xff533c76, 0xffe1dee6, 0xff5c487c, 0xff390468, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3b046a, 0xff3b046a, 0xff3b046a, 0xff3b046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff5c497c, 0xffe2dfe7,
0xff543e77, 0xff390467, 0xffa19aaf, 0xffc2beca, 0xff3c1368, 0xff380466, 0xff6c5d86, 0xffdcd9e1,
0xff472c6d, 0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370464, 0xff370464,
0xff370464, 0xff370464, 0xff380465, 0xff3d1567, 0xffc4bfcb, 0xff9c95ab, 0xff380466, 0xff380466,
0xff968da6, 0xffc9c4d0, 0xff3f1a6a, 0xff3f186a, 0xffc5c0cd, 0xffa199af, 0xff3a0668, 0xff390468,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a046a, 0xff3a046a, 0xff3a046a,
0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a046a, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff3a0768, 0xffa199af, 0xffc6c1cd,
0xff3e176a, 0xff3f196a, 0xffc8c4d0, 0xff978fa6, 0xff380466, 0xff380466, 0xff9e97ac, 0xffc4c0cc,
0xff3d1567, 0xff380465, 0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff370463, 0xff370463, 0xff370464,
0xff370464, 0xff370464, 0xff370465, 0xff380465, 0xff9b92a9, 0xffc5c1cd, 0xff3d1669, 0xff380466,
0xff5a4779, 0xffe0dde5, 0xff5e4b7d, 0xff390467, 0xff827796, 0xffdbd9e0, 0xff4d3473, 0xff390468,
0xff390468, 0xff3a0468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0468, 0xff390468, 0xff390468, 0xff4e3573, 0xffdbd8e0, 0xff837897,
0xff390467, 0xff5f4d7d, 0xffe2e0e6, 0xff594679, 0xff380466, 0xff3d1668, 0xffc5c0cc, 0xff9d95ab,
0xff380465, 0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff370463, 0xff370463,
0xff370464, 0xff370464, 0xff370464, 0xff370465, 0xff604f7d, 0xffe1dee5, 0xff574277, 0xff380466,
0xff3d1568, 0xffc1bcc9, 0xffada7b9, 0xff3b0c68, 0xff43226c, 0xffcbc7d2, 0xffa9a2b5, 0xff3c0f69,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469, 0xff3a0469,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff3c1069, 0xffaba5b7, 0xffccc8d2, 0xff43226c,
0xff3b0c68, 0xffaea8b9, 0xffc1bcc9, 0xff3d1568, 0xff380466, 0xff564276, 0xffe2dfe5, 0xff5f4d7c,
0xff370465, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff370463, 0xff370463,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff3e1a68, 0xffc8c4cf, 0xff9e97ac, 0xff390766,
0xff380466, 0xff6e5f87, 0xffdfdce4, 0xff5b497a, 0xff390467, 0xff6b5b85, 0xffe0dde4, 0xff7b6f91,
0xff390668, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff3a0469, 0xff3a0469, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390668, 0xff7c7091, 0xffe0dde4, 0xff6b5b85, 0xff390467,
0xff5c4a7b, 0xffe1dee5, 0xff6f6288, 0xff380466, 0xff390666, 0xff9f97ac, 0xffc9c4d0, 0xff3e1a68,
0xff370464, 0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360463, 0xff360463, 0xff370463,
0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff370564, 0xff857b98, 0xffd8d6dd, 0xff4a2f6e,
0xff380465, 0xff3d1668, 0xffb9b3c3, 0xffbcb7c5, 0xff3f1a69, 0xff390a67, 0xff9289a3, 0xffddd9e1,
0xff695a84, 0xff390667, 0xff390467, 0xff390467, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468, 0xff390468,
0xff390467, 0xff390467, 0xff390667, 0xff6d5e86, 0xffdddae1, 0xff948ca4, 0xff390a67, 0xff3e1969,
0xffbdb8c6, 0xffbab4c3, 0xff3d1668, 0xff380465, 0xff4a2f6e, 0xffd9d7de, 0xff887e99, 0xff370564,
0xff370464, 0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360463, 0xff360463,
0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370464, 0xff42236a, 0xffcecad5, 0xff9991a8,
0xff390765, 0xff380465, 0xff574377, 0xffdcd8e1, 0xff9086a1, 0xff3a0a67, 0xff3d1669, 0xffa29baf,
0xffdcd9e1, 0xff776a8e, 0xff3b0b68, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff3b0b68, 0xff776b8e, 0xffdddae2, 0xffa49db2, 0xff3e1769, 0xff390a67, 0xff8e859f,
0xffdddae1, 0xff584477, 0xff380465, 0xff390865, 0xff9b94a9, 0xffcfccd5, 0xff42246a, 0xff370464,
0xff370464, 0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360463,
0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff370464, 0xff370564, 0xff807493, 0xffdddae2,
0xff5b4979, 0xff380465, 0xff390765, 0xff807594, 0xffe0dde5, 0xff75698c, 0xff380666, 0xff3e1869,
0xff9991a8, 0xffe1dfe5, 0xff9f97ad, 0xff472b6e, 0xff390567, 0xff390467, 0xff390467, 0xff390467,
0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390467, 0xff390567,
0xff472b6e, 0xff9e96ac, 0xffe1dfe5, 0xff9990a8, 0xff3e1869, 0xff390666, 0xff776b8e, 0xffe0dde4,
0xff7f7593, 0xff390665, 0xff380465, 0xff594578, 0xffdfdce3, 0xff807594, 0xff370564, 0xff370464,
0xff370464, 0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360462, 0xff360462, 0xff360462,
0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370463, 0xff370464, 0xff3d1867, 0xffb9b4c2,
0xffbfbac7, 0xff402069, 0xff370465, 0xff3a0e66, 0xff9992a7, 0xffdddbe1, 0xff726489, 0xff390866,
0xff3a0d67, 0xff766a8d, 0xffd3cfd9, 0xffd5d2db, 0xff8f86a0, 0xff4d3471, 0xff3c1268, 0xff380466,
0xff380466, 0xff380467, 0xff380467, 0xff380466, 0xff380466, 0xff3b1168, 0xff4c3471, 0xff8f86a0,
0xffd4d1da, 0xffd3d0d9, 0xff766a8d, 0xff3a0d67, 0xff390966, 0xff75688c, 0xffdfdde4, 0xff9a92a8,
0xff3a0d66, 0xff370465, 0xff412069, 0xffc0bbc8, 0xffb9b4c2, 0xff3d1867, 0xff370464, 0xff370463,
0xff370463, 0xff370463, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff74469d, 0xff360461, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370464, 0xff533e74,
0xffd9d6de, 0xff9e97ac, 0xff3a0f65, 0xff370465, 0xff3c1567, 0xff9a94a8, 0xffdfdde4, 0xff8b829c,
0xff3d1668, 0xff380565, 0xff472b6d, 0xff938ba3, 0xffd1ced8, 0xffdedbe3, 0xffc1bcc9, 0xff9f98ad,
0xff7f7394, 0xff695685, 0xff695785, 0xff817695, 0xff9e97ac, 0xffbfbac8, 0xffe0dee4, 0xffd2ced8,
0xff9188a1, 0xff472a6d, 0xff380565, 0xff3d1567, 0xff8a819b, 0xffe1dfe5, 0xff9c95aa, 0xff3c1567,
0xff370465, 0xff3a1066, 0xffa099ad, 0xffd8d6dd, 0xff533e73, 0xff370464, 0xff370463, 0xff370463,
0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff74469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469d, 0xff350461, 0xff360461, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463, 0xff370463, 0xff370563,
0xff726489, 0xffe1dfe5, 0xff89809b, 0xff390c65, 0xff370464, 0xff3a1066, 0xff867b98, 0xffdedce3,
0xffb2adbd, 0xff523c73, 0xff390865, 0xff380565, 0xff43236a, 0xff6a5b84, 0xffa49db0, 0xffc2bdca,
0xffd5d2da, 0xffdad7df, 0xffdad7df, 0xffd4d2da, 0xffc3bfca, 0xffa39cb0, 0xff6c5d85, 0xff42236a,
0xff380565, 0xff390966, 0xff533d74, 0xffb4aebd, 0xffdedce2, 0xff867c98, 0xff3a1166, 0xff370464,
0xff390b65, 0xff887e99, 0xffe1dee5, 0xff716487, 0xff370563, 0xff370463, 0xff370463, 0xff360463,
0xff360463, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff73469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469d, 0xff350461, 0xff350461, 0xff360461,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463, 0xff360463, 0xff370463,
0xff380a64, 0xff867c98, 0xffe1dfe5, 0xff897f9a, 0xff390e65, 0xff370464, 0xff380764, 0xff5f4d7b,
0xffc3beca, 0xffddd9e1, 0xffa098ad, 0xff4f3872, 0xff3a0e66, 0xff380465, 0xff380565, 0xff3b1167,
0xff42236a, 0xff45286c, 0xff45286c, 0xff42236a, 0xff3b1267, 0xff380565, 0xff380465, 0xff3a0f66,
0xff4f3872, 0xffa19aae, 0xffdedce2, 0xffc4bfcb, 0xff5f4d7b, 0xff380764, 0xff370464, 0xff390c65,
0xff867d99, 0xffe0dde3, 0xff847a95, 0xff380964, 0xff370463, 0xff360463, 0xff360463, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff350461, 0xff73469d,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469c, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360463,
0xff360463, 0xff380a64, 0xff867c98, 0xffe0dee4, 0xff9991a7, 0xff3e1c67, 0xff370464, 0xff370464,
0xff3f1d68, 0xff807494, 0xffcecad4, 0xffdfdce3, 0xffb8b2c1, 0xff867d98, 0xff543f74, 0xff45296b,
0xff3f1d68, 0xff3c1467, 0xff3c1467, 0xff3f1b68, 0xff45296b, 0xff554075, 0xff877d99, 0xffb9b4c2,
0xffdfdce3, 0xffcdc8d3, 0xff7f7492, 0xff3f1d68, 0xff370464, 0xff370464, 0xff3f1d67, 0xff9a92a8,
0xffe1dfe5, 0xff847a95, 0xff380964, 0xff360463, 0xff360463, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff73469c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469c, 0xff350460, 0xff350460, 0xff350461,
0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff380a63, 0xff74678a, 0xffdad7df, 0xffb8b2c1, 0xff513a71, 0xff370663,
0xff370463, 0xff370564, 0xff402068, 0xff6b5b84, 0xffada7b8, 0xffd0cdd6, 0xffe1dee5, 0xffdbd8e0,
0xffcfcad5, 0xffc7c2ce, 0xffc7c3ce, 0xffcdc9d4, 0xffdcd9e0, 0xffe3e0e6, 0xffd2ced7, 0xffaea8b9,
0xff6b5c84, 0xff401f68, 0xff370464, 0xff370463, 0xff370663, 0xff513b72, 0xffbab5c2, 0xffdad8df,
0xff766a8c, 0xff370a63, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462,
0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff73469c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469c, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360462, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360562, 0xff594677, 0xffc1bcc9, 0xffdad7df, 0xff897f9a,
0xff432569, 0xff370563, 0xff370463, 0xff370463, 0xff380764, 0xff412168, 0xff4d376f, 0xff6b5c84,
0xff8a819b, 0xff9288a2, 0xff9288a2, 0xff89809a, 0xff6b5b84, 0xff4d376f, 0xff412168, 0xff380763,
0xff370463, 0xff370463, 0xff370563, 0xff44276a, 0xff8c829c, 0xffdbd8df, 0xffc1bdc9, 0xff5a4877,
0xff360562, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff360461,
0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff73469c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff360461,
0xff360461, 0xff360462, 0xff360462, 0xff360462, 0xff360462, 0xff3e1d66, 0xff8c839c, 0xffd8d4dd,
0xffd1ced7, 0xff897e9a, 0xff482f6c, 0xff380b64, 0xff360463, 0xff360463, 0xff370463, 0xff370463,
0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff370463, 0xff360463, 0xff360463,
0xff380b64, 0xff49306d, 0xff8a819b, 0xffd4d1d9, 0xffd9d6de, 0xff8e859d, 0xff3e1e66, 0xff360462,
0xff360462, 0xff360462, 0xff360462, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035f, 0xff34035f, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff360461, 0xff360461, 0xff360461, 0xff360462, 0xff360462, 0xff370662, 0xff482f6c,
0xff988fa6, 0xffd4d1d9, 0xffddd9e1, 0xffb3adbd, 0xff837a96, 0xff513c71, 0xff432769, 0xff3b1565,
0xff380c63, 0xff370863, 0xff370863, 0xff380d64, 0xff3b1565, 0xff432769, 0xff503b70, 0xff827894,
0xffb4aebd, 0xffdddae1, 0xffd6d3db, 0xff978fa5, 0xff482f6b, 0xff370662, 0xff360462, 0xff360462,
0xff360461, 0xff360461, 0xff360461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff34035f, 0xff34035f, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff360461, 0xff360461, 0xff360461,
0xff370662, 0xff422568, 0xff74688a, 0xffb1abbb, 0xffd3d0d9, 0xffe2dfe6, 0xffd9d6de, 0xffc7c4ce,
0xffbcb7c4, 0xffb3adbd, 0xffb3adbd, 0xffbdb8c5, 0xffc7c4ce, 0xffd9d7de, 0xffe2dfe6, 0xffd3d0d8,
0xffb1acbb, 0xff75698a, 0xff422668, 0xff370762, 0xff360461, 0xff360461, 0xff360461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035e, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff35045f, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff370862, 0xff402367, 0xff503a70, 0xff736588, 0xff948ca3,
0xffa7a1b1, 0xffd2ced7, 0xffd2ced7, 0xffa7a2b1, 0xff978ea4, 0xff75688a, 0xff503b70, 0xff402266,
0xff360762, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff35045f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff35045f, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff360661, 0xffaea8b8, 0xffaea8b8, 0xff360661, 0xff350461, 0xff350461, 0xff350461, 0xff350461,
0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350461, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff35045f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e, 0xff34035e, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff35045f, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff360661, 0xffaea8b8, 0xffaea8b8, 0xff360661, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff35045f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff33035d, 0xff33035d, 0xff33035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff35045f, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff360660, 0xffaea8b8, 0xffaea8b8, 0xff360660, 0xff350460, 0xff350460, 0xff350460, 0xff350460,
0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff350460, 0xff35045f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff33035e, 0xff33035d, 0xff33035d, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459c, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff35035f, 0xff35045f, 0xff35045f, 0xff350460, 0xff350460,
0xff350560, 0xffaea8b8, 0xffaea8b8, 0xff350560, 0xff350460, 0xff350460, 0xff35045f, 0xff35045f,
0xff35035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff33035e, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff73459c,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459b, 0xff33035c, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff35055f, 0xffaea8b8, 0xffaea8b8, 0xff35055f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f,
0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035f, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff33035e, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c, 0xff73459b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459b, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035f, 0xff34035f,
0xff35055f, 0xffaea8b8, 0xffaea8b8, 0xff35055f, 0xff34035f, 0xff34035f, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff73459b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73459b, 0xff32035b, 0xff32035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff35055e, 0xffaea8b8, 0xffaea8b8, 0xff35055e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e,
0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff34035e, 0xff33035e, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff32035c, 0xff32035b, 0xff73459b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff73469b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035c, 0xff32035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff3f2363, 0xff746887, 0xff958fa2, 0xff9892a3, 0xff9892a3, 0xff9892a3,
0xff9892a3, 0xffc9c6d0, 0xffc9c6d0, 0xff9892a3, 0xff9892a3, 0xff9892a3, 0xff9892a3, 0xff9690a2,
0xff766b8a, 0xff402464, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff32035c, 0xff32035c, 0xff32035b, 0xff32035b, 0xff32035b, 0xff73469b,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff784aa1, 0xff33055c, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035c, 0xff32035c, 0xff32035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035d, 0xff33035d, 0xff33035d,
0xff33035d, 0xff4a346a, 0xffc8c5cf, 0xffd9d6dd, 0xffc6c2cc, 0xffc4c0ca, 0xffc4c0ca, 0xffc4c0ca,
0xffc4c0ca, 0xffc5c1cb, 0xffc5c1cb, 0xffc4c0ca, 0xffc4c0ca, 0xffc4c0ca, 0xffc4c0ca, 0xffc5c1cb,
0xffdad7de, 0xffc8c4ce, 0xff4b356a, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035d, 0xff33035c,
0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff32035c, 0xff32035c,
0xff32035c, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff33055c, 0xff784aa1,
0xff9761c4, 0xff9761c4, 0xff9560c2, 0xff9761c4, 0xff8654b0, 0xff370c5e, 0xff32035a, 0xff32035a,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035c,
0xff32035c, 0xff32035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff350a5d, 0xffada8b6, 0xffc9c6cf, 0xff4e3b6c, 0xff402363, 0xff3f2263, 0xff3f2263, 0xff3f2263,
0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2263, 0xff3f2363,
0xff4f3b6c, 0xffc9c6cf, 0xffaca6b6, 0xff350a5d, 0xff33035c, 0xff33035c, 0xff33035c, 0xff33035c,
0xff33035c, 0xff33035c, 0xff32035c, 0xff32035c, 0xff32035c, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035a, 0xff32035a, 0xff370c5e, 0xff8654b0,
0xff9761c4, 0xff9560c2, 0xf0905cbc, 0xff9761c4, 0xff945fc1, 0xff4b2471, 0xff31035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035c, 0xff32035c, 0xff32035c, 0xff32035c,
0xff3e2262, 0xffd4d2d8, 0xffdad7df, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2,
0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2, 0xffccc8d2,
0xffccc8d2, 0xffdbd7df, 0xffd4d2d8, 0xff3d2262, 0xff32035c, 0xff32035c, 0xff32035c, 0xff32035c,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff31035a, 0xff4b2471, 0xff945fc1,
0xff9761c4, 0xf0905cbc, 0xaa905cbc, 0xff9761c4, 0xff9761c4, 0xff784aa1, 0xff34095c, 0xff31035a,
0xff31035a, 0xff31035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff35105d, 0xff796f8a, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299,
0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299, 0xff8a8299,
0xff8a8299, 0xff8a8299, 0xff796f8a, 0xff35105d, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff34095c, 0xff784aa1, 0xff9761c4,
0xff9761c4, 0xaa905cbc, 0x4e8554af, 0xf89660c3, 0xff9761c4, 0xff9560c2, 0xff63398a, 0xff34095c,
0xff310359, 0xff310359, 0xff31035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff31035a, 0xff31035a,
0xff31035a, 0xff31035a, 0xff310359, 0xff310359, 0xff34095c, 0xff63398a, 0xff9560c2, 0xff9761c4,
0xf89660c3, 0x4e8554af, 0x068150ab, 0xa88e5bba, 0xff9761c4, 0xff9761c4, 0xff9560c2, 0xff784aa1,
0xff4b2471, 0xff360c5d, 0xff32055a, 0xff310359, 0xff310359, 0xff310359, 0xff31035a, 0xff31035a,
0xff31035a, 0xff31035a, 0xff31035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035b, 0xff32035b, 0xff32035b,
0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035b, 0xff32035a,
0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a, 0xff32035a,
0xff32035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff31035a, 0xff310359, 0xff310359,
0xff310359, 0xff32055a, 0xff360c5d, 0xff4b2471, 0xff784aa1, 0xff9560c2, 0xff9761c4, 0xff9761c4,
0xa88e5bba, 0x068150ab, 0x00000000, 0x1c7f50a9, 0xca915dbd, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff945fc1, 0xff8654b0, 0xff784aa1, 0xff73469b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b, 0xff73459b,
0xff73469b, 0xff784aa1, 0xff8654b0, 0xff945fc1, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xca915dbd,
0x1c7f50a9, 0x00000000, 0x00000000, 0x00000000, 0x1c7f50a9, 0xa88e5bba, 0xf89660c3, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xf89660c3, 0xa88e5bba, 0x1c7f50a9,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x068150aa, 0x4e8554af, 0xaa905cbc,
0xf0905cbc, 0xff9560c2, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4, 0xff9761c4,
0xff9761c4, 0xff9761c4, 0xff9660c3, 0xf0905cbc, 0xaa905cbc, 0x4e8554af, 0x068150aa, 0x00000000,
0x00000000, 0x00000000
};
extern const unsigned long icondata[];
extern const unsigned icondataSize;