//========================================================================
//
// UnicodeTypeTable.cc
//
// Copyright 2004 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2006, 2007 Ed Catmur <ed@catmur.co.uk>
// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2008, 2016 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2012 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2016 Khaled Hosny <khaledhosny@eglug.org>
// Copyright (C) 2019 Adriaan de Groot <groot@kde.org>
// Copyright (C) 2020 Alex Henrie <alexhenrie24@gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <cstdlib>
#include "CharTypes.h"
#include "UnicodeTypeTable.h"
#include "goo/gmem.h"

struct UnicodeMapTableEntry
{
    const char *vector;
    const char type;
};

struct UnicodeCaseTableVector
{
    Unicode codes[256];
};

static const UnicodeMapTableEntry typeTable[256] = {
    { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN###NNNNN################NNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN#N####NNNNLNNNNN####NLNNN#"
      "LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL",
      'X' },
    { nullptr, 'L' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLNNNNNNNNNNNNNNLLNNNNNNNNNNNNNNLLLLLNNN"
      "NNNNNNLNNNNNNNNNNNNNNNNN",
      'X' },
    { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLNNNNNNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLNLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNRNRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"
      "RRRRRRRRRRRRRRRRRRRRRRRR",
      'X' },
    { "RRRR#########RNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNN####################"
      "RRRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNRNNNNNNNRRNNNNNNNRR##########RRRRRR",
      'X' },
    { "RRRRRRRRRRRRRRNNRNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNNNNNNNNNNNNNNNNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNNNNNNNNNNRNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN"
      "NNNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { nullptr, 'N' },
    { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLNNNNLLLLLLLLLLLLLNNLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNLLLLLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLL"
      "LLLLLLLLLL##LLLLLLLNNNNN",
      'X' },
    { "NNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLNNNNNNNNLLLLNLLLLLLLLLLLLLLLLLLLLNNLLLL"
      "LLLLLLLL##NNNNNNNNNNNNNN",
      'X' },
    { "NNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLNLNNNLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLNNNNNN#NLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLNNNNNLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNN#####"
      "LLLLLLLNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLNNNNNNNNNLLLLLLLLLLNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNLNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNLNNNNNLNNLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLNNNNNNLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNLLLLLLLLNLLNNNNNNNNNNNLLLLLLL#"
      "LNLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { "NNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLNNNNNLLLLLLNLLLLLLNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN"
      "NNNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLNNNLLLLLLLLLLLNNNLLLLLLLLLLLLNNNNLLLLLLLL"
      "LLLLLNNNLLLLLLLLLLLLLNNN",
      'X' },
    { "NNNNNNNNNNNNNNLRNNNNNNNNNNNNNNNNNNNNNNNNNNLRNLRN#####NNNNNNNNNNNNNNN#NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN#L##########NNNL############NNN###################################"
      "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { "NNLNNNNLNNLLLLLLLLLLNLNNNLLLLLNNNNNNLNLNLNLLLL#"
      "LLLNLLLLLLLNNLLLLNNNNNLLLLLNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { "NNNNNNNNNNNNNNNNNN##"
      "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN"
      "NNNN",
      'X' },
    { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN"
      "NNNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN####################"
      "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { nullptr, 'L' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { nullptr, 'N' },
    { "NNNNNLLLNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLNNNNNNNLLLLLNNLLLLLNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLNLLLL",
      'X' },
    { nullptr, 'L' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLN",
      'X' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN"
      "NNNNNNNNNNNNNNNNNNNNNNNN",
      'X' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"
      "LLLLLLLLLLLLLLLLLLLLLLLL",
      'X' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { nullptr, 'L' },
    { "LLLLLLLLLLLLLLLLLLLLLLLLRRRRRRNRRRRRRRRRR#"
      "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR",
      'X' },
    { nullptr, 'R' },
    { "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR"
      "RRRRRRRRRRRRRRRRRRRRRNNN",
      'X' },
    { "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN#N#NN#NNNNNNNNN#NN##NNNNN##"
      "NRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRNNN",
      'X' },
    { "NNN###NNNNN################NNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL#####NNN##"
      "NNNNNNNNNNNNNNNNNNNNNNNLL",
      'X' }
};

static const UnicodeCaseTableVector caseTable00 = {
    { 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c,
      0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039,
      0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076,
      0x0077, 0x0078, 0x0079, 0x007a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073,
      0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090,
      0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad,
      0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x03bc, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea,
      0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00d7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
      0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff }
};
static const UnicodeCaseTableVector caseTable01 = {
    { 0x0101, 0x0101, 0x0103, 0x0103, 0x0105, 0x0105, 0x0107, 0x0107, 0x0109, 0x0109, 0x010b, 0x010b, 0x010d, 0x010d, 0x010f, 0x010f, 0x0111, 0x0111, 0x0113, 0x0113, 0x0115, 0x0115, 0x0117, 0x0117, 0x0119, 0x0119, 0x011b, 0x011b, 0x011d,
      0x011d, 0x011f, 0x011f, 0x0121, 0x0121, 0x0123, 0x0123, 0x0125, 0x0125, 0x0127, 0x0127, 0x0129, 0x0129, 0x012b, 0x012b, 0x012d, 0x012d, 0x012f, 0x012f, 0x0130, 0x0131, 0x0133, 0x0133, 0x0135, 0x0135, 0x0137, 0x0137, 0x0138, 0x013a,
      0x013a, 0x013c, 0x013c, 0x013e, 0x013e, 0x0140, 0x0140, 0x0142, 0x0142, 0x0144, 0x0144, 0x0146, 0x0146, 0x0148, 0x0148, 0x0149, 0x014b, 0x014b, 0x014d, 0x014d, 0x014f, 0x014f, 0x0151, 0x0151, 0x0153, 0x0153, 0x0155, 0x0155, 0x0157,
      0x0157, 0x0159, 0x0159, 0x015b, 0x015b, 0x015d, 0x015d, 0x015f, 0x015f, 0x0161, 0x0161, 0x0163, 0x0163, 0x0165, 0x0165, 0x0167, 0x0167, 0x0169, 0x0169, 0x016b, 0x016b, 0x016d, 0x016d, 0x016f, 0x016f, 0x0171, 0x0171, 0x0173, 0x0173,
      0x0175, 0x0175, 0x0177, 0x0177, 0x00ff, 0x017a, 0x017a, 0x017c, 0x017c, 0x017e, 0x017e, 0x0073, 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, 0x0188, 0x0256, 0x0257, 0x018c, 0x018c, 0x018d, 0x01dd, 0x0259, 0x025b,
      0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, 0x0199, 0x0199, 0x019a, 0x019b, 0x026f, 0x0272, 0x019e, 0x0275, 0x01a1, 0x01a1, 0x01a3, 0x01a3, 0x01a5, 0x01a5, 0x0280, 0x01a8, 0x01a8, 0x0283, 0x01aa, 0x01ab, 0x01ad, 0x01ad,
      0x0288, 0x01b0, 0x01b0, 0x028a, 0x028b, 0x01b4, 0x01b4, 0x01b6, 0x01b6, 0x0292, 0x01b9, 0x01b9, 0x01ba, 0x01bb, 0x01bd, 0x01bd, 0x01be, 0x01bf, 0x01c0, 0x01c1, 0x01c2, 0x01c3, 0x01c6, 0x01c6, 0x01c6, 0x01c9, 0x01c9, 0x01c9, 0x01cc,
      0x01cc, 0x01cc, 0x01ce, 0x01ce, 0x01d0, 0x01d0, 0x01d2, 0x01d2, 0x01d4, 0x01d4, 0x01d6, 0x01d6, 0x01d8, 0x01d8, 0x01da, 0x01da, 0x01dc, 0x01dc, 0x01dd, 0x01df, 0x01df, 0x01e1, 0x01e1, 0x01e3, 0x01e3, 0x01e5, 0x01e5, 0x01e7, 0x01e7,
      0x01e9, 0x01e9, 0x01eb, 0x01eb, 0x01ed, 0x01ed, 0x01ef, 0x01ef, 0x01f0, 0x01f3, 0x01f3, 0x01f3, 0x01f5, 0x01f5, 0x0195, 0x01bf, 0x01f9, 0x01f9, 0x01fb, 0x01fb, 0x01fd, 0x01fd, 0x01ff, 0x01ff }
};
static const UnicodeCaseTableVector caseTable02 = {
    { 0x0201, 0x0201, 0x0203, 0x0203, 0x0205, 0x0205, 0x0207, 0x0207, 0x0209, 0x0209, 0x020b, 0x020b, 0x020d, 0x020d, 0x020f, 0x020f, 0x0211, 0x0211, 0x0213, 0x0213, 0x0215, 0x0215, 0x0217, 0x0217, 0x0219, 0x0219, 0x021b, 0x021b, 0x021d,
      0x021d, 0x021f, 0x021f, 0x019e, 0x0221, 0x0223, 0x0223, 0x0225, 0x0225, 0x0227, 0x0227, 0x0229, 0x0229, 0x022b, 0x022b, 0x022d, 0x022d, 0x022f, 0x022f, 0x0231, 0x0231, 0x0233, 0x0233, 0x0234, 0x0235, 0x0236, 0x0237, 0x0238, 0x0239,
      0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f, 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f, 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256,
      0x0257, 0x0258, 0x0259, 0x025a, 0x025b, 0x025c, 0x025d, 0x025e, 0x025f, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266, 0x0267, 0x0268, 0x0269, 0x026a, 0x026b, 0x026c, 0x026d, 0x026e, 0x026f, 0x0270, 0x0271, 0x0272, 0x0273,
      0x0274, 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x027a, 0x027b, 0x027c, 0x027d, 0x027e, 0x027f, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x028a, 0x028b, 0x028c, 0x028d, 0x028e, 0x028f, 0x0290,
      0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 0x0298, 0x0299, 0x029a, 0x029b, 0x029c, 0x029d, 0x029e, 0x029f, 0x02a0, 0x02a1, 0x02a2, 0x02a3, 0x02a4, 0x02a5, 0x02a6, 0x02a7, 0x02a8, 0x02a9, 0x02aa, 0x02ab, 0x02ac, 0x02ad,
      0x02ae, 0x02af, 0x02b0, 0x02b1, 0x02b2, 0x02b3, 0x02b4, 0x02b5, 0x02b6, 0x02b7, 0x02b8, 0x02b9, 0x02ba, 0x02bb, 0x02bc, 0x02bd, 0x02be, 0x02bf, 0x02c0, 0x02c1, 0x02c2, 0x02c3, 0x02c4, 0x02c5, 0x02c6, 0x02c7, 0x02c8, 0x02c9, 0x02ca,
      0x02cb, 0x02cc, 0x02cd, 0x02ce, 0x02cf, 0x02d0, 0x02d1, 0x02d2, 0x02d3, 0x02d4, 0x02d5, 0x02d6, 0x02d7, 0x02d8, 0x02d9, 0x02da, 0x02db, 0x02dc, 0x02dd, 0x02de, 0x02df, 0x02e0, 0x02e1, 0x02e2, 0x02e3, 0x02e4, 0x02e5, 0x02e6, 0x02e7,
      0x02e8, 0x02e9, 0x02ea, 0x02eb, 0x02ec, 0x02ed, 0x02ee, 0x02ef, 0x02f0, 0x02f1, 0x02f2, 0x02f3, 0x02f4, 0x02f5, 0x02f6, 0x02f7, 0x02f8, 0x02f9, 0x02fa, 0x02fb, 0x02fc, 0x02fd, 0x02fe, 0x02ff }
};
static const UnicodeCaseTableVector caseTable03 = {
    { 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a, 0x030b, 0x030c, 0x030d, 0x030e, 0x030f, 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317, 0x0318, 0x0319, 0x031a, 0x031b, 0x031c,
      0x031d, 0x031e, 0x031f, 0x0320, 0x0321, 0x0322, 0x0323, 0x0324, 0x0325, 0x0326, 0x0327, 0x0328, 0x0329, 0x032a, 0x032b, 0x032c, 0x032d, 0x032e, 0x032f, 0x0330, 0x0331, 0x0332, 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339,
      0x033a, 0x033b, 0x033c, 0x033d, 0x033e, 0x033f, 0x0340, 0x0341, 0x0342, 0x0343, 0x0344, 0x03b9, 0x0346, 0x0347, 0x0348, 0x0349, 0x034a, 0x034b, 0x034c, 0x034d, 0x034e, 0x034f, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356,
      0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035c, 0x035d, 0x035e, 0x035f, 0x0360, 0x0361, 0x0362, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f, 0x0370, 0x0371, 0x0372, 0x0373,
      0x0374, 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x037a, 0x037b, 0x037c, 0x037d, 0x037e, 0x037f, 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x03ac, 0x0387, 0x03ad, 0x03ae, 0x03af, 0x038b, 0x03cc, 0x038d, 0x03cd, 0x03ce, 0x0390,
      0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03a2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03ac, 0x03ad,
      0x03ae, 0x03af, 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca,
      0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x03cf, 0x03b2, 0x03b8, 0x03d2, 0x03d3, 0x03d4, 0x03c6, 0x03c0, 0x03d7, 0x03d9, 0x03d9, 0x03db, 0x03db, 0x03dd, 0x03dd, 0x03df, 0x03df, 0x03e1, 0x03e1, 0x03e3, 0x03e3, 0x03e5, 0x03e5, 0x03e7, 0x03e7,
      0x03e9, 0x03e9, 0x03eb, 0x03eb, 0x03ed, 0x03ed, 0x03ef, 0x03ef, 0x03ba, 0x03c1, 0x03f2, 0x03f3, 0x03b8, 0x03b5, 0x03f6, 0x03f8, 0x03f8, 0x03f2, 0x03fb, 0x03fb, 0x03fc, 0x03fd, 0x03fe, 0x03ff }
};
static const UnicodeCaseTableVector caseTable04 = {
    { 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c,
      0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439,
      0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456,
      0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 0x0461, 0x0461, 0x0463, 0x0463, 0x0465, 0x0465, 0x0467, 0x0467, 0x0469, 0x0469, 0x046b, 0x046b, 0x046d, 0x046d, 0x046f, 0x046f, 0x0471, 0x0471, 0x0473, 0x0473,
      0x0475, 0x0475, 0x0477, 0x0477, 0x0479, 0x0479, 0x047b, 0x047b, 0x047d, 0x047d, 0x047f, 0x047f, 0x0481, 0x0481, 0x0482, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x048b, 0x048b, 0x048d, 0x048d, 0x048f, 0x048f, 0x0491,
      0x0491, 0x0493, 0x0493, 0x0495, 0x0495, 0x0497, 0x0497, 0x0499, 0x0499, 0x049b, 0x049b, 0x049d, 0x049d, 0x049f, 0x049f, 0x04a1, 0x04a1, 0x04a3, 0x04a3, 0x04a5, 0x04a5, 0x04a7, 0x04a7, 0x04a9, 0x04a9, 0x04ab, 0x04ab, 0x04ad, 0x04ad,
      0x04af, 0x04af, 0x04b1, 0x04b1, 0x04b3, 0x04b3, 0x04b5, 0x04b5, 0x04b7, 0x04b7, 0x04b9, 0x04b9, 0x04bb, 0x04bb, 0x04bd, 0x04bd, 0x04bf, 0x04bf, 0x04c0, 0x04c2, 0x04c2, 0x04c4, 0x04c4, 0x04c6, 0x04c6, 0x04c8, 0x04c8, 0x04ca, 0x04ca,
      0x04cc, 0x04cc, 0x04ce, 0x04ce, 0x04cf, 0x04d1, 0x04d1, 0x04d3, 0x04d3, 0x04d5, 0x04d5, 0x04d7, 0x04d7, 0x04d9, 0x04d9, 0x04db, 0x04db, 0x04dd, 0x04dd, 0x04df, 0x04df, 0x04e1, 0x04e1, 0x04e3, 0x04e3, 0x04e5, 0x04e5, 0x04e7, 0x04e7,
      0x04e9, 0x04e9, 0x04eb, 0x04eb, 0x04ed, 0x04ed, 0x04ef, 0x04ef, 0x04f1, 0x04f1, 0x04f3, 0x04f3, 0x04f5, 0x04f5, 0x04f6, 0x04f7, 0x04f9, 0x04f9, 0x04fa, 0x04fb, 0x04fc, 0x04fd, 0x04fe, 0x04ff }
};
static const UnicodeCaseTableVector caseTable05 = {
    { 0x0501, 0x0501, 0x0503, 0x0503, 0x0505, 0x0505, 0x0507, 0x0507, 0x0509, 0x0509, 0x050b, 0x050b, 0x050d, 0x050d, 0x050f, 0x050f, 0x0510, 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, 0x0518, 0x0519, 0x051a, 0x051b, 0x051c,
      0x051d, 0x051e, 0x051f, 0x0520, 0x0521, 0x0522, 0x0523, 0x0524, 0x0525, 0x0526, 0x0527, 0x0528, 0x0529, 0x052a, 0x052b, 0x052c, 0x052d, 0x052e, 0x052f, 0x0530, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569,
      0x056a, 0x056b, 0x056c, 0x056d, 0x056e, 0x056f, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586,
      0x0557, 0x0558, 0x0559, 0x055a, 0x055b, 0x055c, 0x055d, 0x055e, 0x055f, 0x0560, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, 0x0566, 0x0567, 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, 0x056f, 0x0570, 0x0571, 0x0572, 0x0573,
      0x0574, 0x0575, 0x0576, 0x0577, 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 0x0580, 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0587, 0x0588, 0x0589, 0x058a, 0x058b, 0x058c, 0x058d, 0x058e, 0x058f, 0x0590,
      0x0591, 0x0592, 0x0593, 0x0594, 0x0595, 0x0596, 0x0597, 0x0598, 0x0599, 0x059a, 0x059b, 0x059c, 0x059d, 0x059e, 0x059f, 0x05a0, 0x05a1, 0x05a2, 0x05a3, 0x05a4, 0x05a5, 0x05a6, 0x05a7, 0x05a8, 0x05a9, 0x05aa, 0x05ab, 0x05ac, 0x05ad,
      0x05ae, 0x05af, 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, 0x05b8, 0x05b9, 0x05ba, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05c4, 0x05c5, 0x05c6, 0x05c7, 0x05c8, 0x05c9, 0x05ca,
      0x05cb, 0x05cc, 0x05cd, 0x05ce, 0x05cf, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
      0x05e8, 0x05e9, 0x05ea, 0x05eb, 0x05ec, 0x05ed, 0x05ee, 0x05ef, 0x05f0, 0x05f1, 0x05f2, 0x05f3, 0x05f4, 0x05f5, 0x05f6, 0x05f7, 0x05f8, 0x05f9, 0x05fa, 0x05fb, 0x05fc, 0x05fd, 0x05fe, 0x05ff }
};
static const UnicodeCaseTableVector caseTable1e = {
    { 0x1e01, 0x1e01, 0x1e03, 0x1e03, 0x1e05, 0x1e05, 0x1e07, 0x1e07, 0x1e09, 0x1e09, 0x1e0b, 0x1e0b, 0x1e0d, 0x1e0d, 0x1e0f, 0x1e0f, 0x1e11, 0x1e11, 0x1e13, 0x1e13, 0x1e15, 0x1e15, 0x1e17, 0x1e17, 0x1e19, 0x1e19, 0x1e1b, 0x1e1b, 0x1e1d,
      0x1e1d, 0x1e1f, 0x1e1f, 0x1e21, 0x1e21, 0x1e23, 0x1e23, 0x1e25, 0x1e25, 0x1e27, 0x1e27, 0x1e29, 0x1e29, 0x1e2b, 0x1e2b, 0x1e2d, 0x1e2d, 0x1e2f, 0x1e2f, 0x1e31, 0x1e31, 0x1e33, 0x1e33, 0x1e35, 0x1e35, 0x1e37, 0x1e37, 0x1e39, 0x1e39,
      0x1e3b, 0x1e3b, 0x1e3d, 0x1e3d, 0x1e3f, 0x1e3f, 0x1e41, 0x1e41, 0x1e43, 0x1e43, 0x1e45, 0x1e45, 0x1e47, 0x1e47, 0x1e49, 0x1e49, 0x1e4b, 0x1e4b, 0x1e4d, 0x1e4d, 0x1e4f, 0x1e4f, 0x1e51, 0x1e51, 0x1e53, 0x1e53, 0x1e55, 0x1e55, 0x1e57,
      0x1e57, 0x1e59, 0x1e59, 0x1e5b, 0x1e5b, 0x1e5d, 0x1e5d, 0x1e5f, 0x1e5f, 0x1e61, 0x1e61, 0x1e63, 0x1e63, 0x1e65, 0x1e65, 0x1e67, 0x1e67, 0x1e69, 0x1e69, 0x1e6b, 0x1e6b, 0x1e6d, 0x1e6d, 0x1e6f, 0x1e6f, 0x1e71, 0x1e71, 0x1e73, 0x1e73,
      0x1e75, 0x1e75, 0x1e77, 0x1e77, 0x1e79, 0x1e79, 0x1e7b, 0x1e7b, 0x1e7d, 0x1e7d, 0x1e7f, 0x1e7f, 0x1e81, 0x1e81, 0x1e83, 0x1e83, 0x1e85, 0x1e85, 0x1e87, 0x1e87, 0x1e89, 0x1e89, 0x1e8b, 0x1e8b, 0x1e8d, 0x1e8d, 0x1e8f, 0x1e8f, 0x1e91,
      0x1e91, 0x1e93, 0x1e93, 0x1e95, 0x1e95, 0x1e96, 0x1e97, 0x1e98, 0x1e99, 0x1e9a, 0x1e61, 0x1e9c, 0x1e9d, 0x1e9e, 0x1e9f, 0x1ea1, 0x1ea1, 0x1ea3, 0x1ea3, 0x1ea5, 0x1ea5, 0x1ea7, 0x1ea7, 0x1ea9, 0x1ea9, 0x1eab, 0x1eab, 0x1ead, 0x1ead,
      0x1eaf, 0x1eaf, 0x1eb1, 0x1eb1, 0x1eb3, 0x1eb3, 0x1eb5, 0x1eb5, 0x1eb7, 0x1eb7, 0x1eb9, 0x1eb9, 0x1ebb, 0x1ebb, 0x1ebd, 0x1ebd, 0x1ebf, 0x1ebf, 0x1ec1, 0x1ec1, 0x1ec3, 0x1ec3, 0x1ec5, 0x1ec5, 0x1ec7, 0x1ec7, 0x1ec9, 0x1ec9, 0x1ecb,
      0x1ecb, 0x1ecd, 0x1ecd, 0x1ecf, 0x1ecf, 0x1ed1, 0x1ed1, 0x1ed3, 0x1ed3, 0x1ed5, 0x1ed5, 0x1ed7, 0x1ed7, 0x1ed9, 0x1ed9, 0x1edb, 0x1edb, 0x1edd, 0x1edd, 0x1edf, 0x1edf, 0x1ee1, 0x1ee1, 0x1ee3, 0x1ee3, 0x1ee5, 0x1ee5, 0x1ee7, 0x1ee7,
      0x1ee9, 0x1ee9, 0x1eeb, 0x1eeb, 0x1eed, 0x1eed, 0x1eef, 0x1eef, 0x1ef1, 0x1ef1, 0x1ef3, 0x1ef3, 0x1ef5, 0x1ef5, 0x1ef7, 0x1ef7, 0x1ef9, 0x1ef9, 0x1efa, 0x1efb, 0x1efc, 0x1efd, 0x1efe, 0x1eff }
};
static const UnicodeCaseTableVector caseTable1f = {
    { 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0x1f16, 0x1f17, 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14,
      0x1f15, 0x1f1e, 0x1f1f, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, 0x1f30, 0x1f31,
      0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37, 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x1f46, 0x1f47, 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x1f4e, 0x1f4f, 0x1f50, 0x1f51, 0x1f52, 0x1f53, 0x1f54, 0x1f55, 0x1f56,
      0x1f57, 0x1f58, 0x1f51, 0x1f5a, 0x1f53, 0x1f5c, 0x1f55, 0x1f5e, 0x1f57, 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1f70, 0x1f71, 0x1f72, 0x1f73,
      0x1f74, 0x1f75, 0x1f76, 0x1f77, 0x1f78, 0x1f79, 0x1f7a, 0x1f7b, 0x1f7c, 0x1f7d, 0x1f7e, 0x1f7f, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, 0x1f90,
      0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5,
      0x1fa6, 0x1fa7, 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0x1fbd, 0x03b9, 0x1fbf, 0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, 0x1fc4, 0x1fc5, 0x1fc6, 0x1fc7, 0x1f72, 0x1f73, 0x1f74,
      0x1f75, 0x1fc3, 0x1fcd, 0x1fce, 0x1fcf, 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5, 0x1fd6, 0x1fd7, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fdc, 0x1fdd, 0x1fde, 0x1fdf, 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5, 0x1fe6, 0x1fe7,
      0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1, 0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0x1ffd, 0x1ffe, 0x1fff }
};
static const UnicodeCaseTableVector caseTable21 = {
    { 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105, 0x2106, 0x2107, 0x2108, 0x2109, 0x210a, 0x210b, 0x210c, 0x210d, 0x210e, 0x210f, 0x2110, 0x2111, 0x2112, 0x2113, 0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x211a, 0x211b, 0x211c,
      0x211d, 0x211e, 0x211f, 0x2120, 0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x03c9, 0x2127, 0x2128, 0x2129, 0x006b, 0x00e5, 0x212c, 0x212d, 0x212e, 0x212f, 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139,
      0x213a, 0x213b, 0x213c, 0x213d, 0x213e, 0x213f, 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145, 0x2146, 0x2147, 0x2148, 0x2149, 0x214a, 0x214b, 0x214c, 0x214d, 0x214e, 0x214f, 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, 0x2155, 0x2156,
      0x2157, 0x2158, 0x2159, 0x215a, 0x215b, 0x215c, 0x215d, 0x215e, 0x215f, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f, 0x2170, 0x2171, 0x2172, 0x2173,
      0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f, 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185, 0x2186, 0x2187, 0x2188, 0x2189, 0x218a, 0x218b, 0x218c, 0x218d, 0x218e, 0x218f, 0x2190,
      0x2191, 0x2192, 0x2193, 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x219a, 0x219b, 0x219c, 0x219d, 0x219e, 0x219f, 0x21a0, 0x21a1, 0x21a2, 0x21a3, 0x21a4, 0x21a5, 0x21a6, 0x21a7, 0x21a8, 0x21a9, 0x21aa, 0x21ab, 0x21ac, 0x21ad,
      0x21ae, 0x21af, 0x21b0, 0x21b1, 0x21b2, 0x21b3, 0x21b4, 0x21b5, 0x21b6, 0x21b7, 0x21b8, 0x21b9, 0x21ba, 0x21bb, 0x21bc, 0x21bd, 0x21be, 0x21bf, 0x21c0, 0x21c1, 0x21c2, 0x21c3, 0x21c4, 0x21c5, 0x21c6, 0x21c7, 0x21c8, 0x21c9, 0x21ca,
      0x21cb, 0x21cc, 0x21cd, 0x21ce, 0x21cf, 0x21d0, 0x21d1, 0x21d2, 0x21d3, 0x21d4, 0x21d5, 0x21d6, 0x21d7, 0x21d8, 0x21d9, 0x21da, 0x21db, 0x21dc, 0x21dd, 0x21de, 0x21df, 0x21e0, 0x21e1, 0x21e2, 0x21e3, 0x21e4, 0x21e5, 0x21e6, 0x21e7,
      0x21e8, 0x21e9, 0x21ea, 0x21eb, 0x21ec, 0x21ed, 0x21ee, 0x21ef, 0x21f0, 0x21f1, 0x21f2, 0x21f3, 0x21f4, 0x21f5, 0x21f6, 0x21f7, 0x21f8, 0x21f9, 0x21fa, 0x21fb, 0x21fc, 0x21fd, 0x21fe, 0x21ff }
};
static const UnicodeCaseTableVector caseTable24 = {
    { 0x2400, 0x2401, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407, 0x2408, 0x2409, 0x240a, 0x240b, 0x240c, 0x240d, 0x240e, 0x240f, 0x2410, 0x2411, 0x2412, 0x2413, 0x2414, 0x2415, 0x2416, 0x2417, 0x2418, 0x2419, 0x241a, 0x241b, 0x241c,
      0x241d, 0x241e, 0x241f, 0x2420, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439,
      0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456,
      0x2457, 0x2458, 0x2459, 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472, 0x2473,
      0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x247f, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, 0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d, 0x248e, 0x248f, 0x2490,
      0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, 0x2498, 0x2499, 0x249a, 0x249b, 0x249c, 0x249d, 0x249e, 0x249f, 0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5, 0x24a6, 0x24a7, 0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad,
      0x24ae, 0x24af, 0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5, 0x24d0, 0x24d1, 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, 0x24e2, 0x24e3, 0x24e4,
      0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, 0x24d0, 0x24d1, 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7,
      0x24e8, 0x24e9, 0x24ea, 0x24eb, 0x24ec, 0x24ed, 0x24ee, 0x24ef, 0x24f0, 0x24f1, 0x24f2, 0x24f3, 0x24f4, 0x24f5, 0x24f6, 0x24f7, 0x24f8, 0x24f9, 0x24fa, 0x24fb, 0x24fc, 0x24fd, 0x24fe, 0x24ff }
};
static const UnicodeCaseTableVector caseTableff = {
    { 0xff00, 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07, 0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10, 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0xff1a, 0xff1b, 0xff1c,
      0xff1d, 0xff1e, 0xff1f, 0xff20, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, 0xff59,
      0xff5a, 0xff3b, 0xff3c, 0xff3d, 0xff3e, 0xff3f, 0xff40, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56,
      0xff57, 0xff58, 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xff5e, 0xff5f, 0xff60, 0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67, 0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, 0xff70, 0xff71, 0xff72, 0xff73,
      0xff74, 0xff75, 0xff76, 0xff77, 0xff78, 0xff79, 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f, 0xff80, 0xff81, 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87, 0xff88, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f, 0xff90,
      0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97, 0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f, 0xffa0, 0xffa1, 0xffa2, 0xffa3, 0xffa4, 0xffa5, 0xffa6, 0xffa7, 0xffa8, 0xffa9, 0xffaa, 0xffab, 0xffac, 0xffad,
      0xffae, 0xffaf, 0xffb0, 0xffb1, 0xffb2, 0xffb3, 0xffb4, 0xffb5, 0xffb6, 0xffb7, 0xffb8, 0xffb9, 0xffba, 0xffbb, 0xffbc, 0xffbd, 0xffbe, 0xffbf, 0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc4, 0xffc5, 0xffc6, 0xffc7, 0xffc8, 0xffc9, 0xffca,
      0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf, 0xffd0, 0xffd1, 0xffd2, 0xffd3, 0xffd4, 0xffd5, 0xffd6, 0xffd7, 0xffd8, 0xffd9, 0xffda, 0xffdb, 0xffdc, 0xffdd, 0xffde, 0xffdf, 0xffe0, 0xffe1, 0xffe2, 0xffe3, 0xffe4, 0xffe5, 0xffe6, 0xffe7,
      0xffe8, 0xffe9, 0xffea, 0xffeb, 0xffec, 0xffed, 0xffee, 0xffef, 0xfff0, 0xfff1, 0xfff2, 0xfff3, 0xfff4, 0xfff5, 0xfff6, 0xfff7, 0xfff8, 0xfff9, 0xfffa, 0xfffb, 0xfffc, 0xfffd, 0xfffe, 0xffff }
};
static const UnicodeCaseTableVector caseTable104 = { {
        0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417,
        0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407,
        0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f,
        0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, 0x10450, 0x10451, 0x10452, 0x10453, 0x10454, 0x10455, 0x10456, 0x10457, 0x10458, 0x10459, 0x1045a, 0x1045b, 0x1045c, 0x1045d, 0x1045e, 0x1045f,
        0x10460, 0x10461, 0x10462, 0x10463, 0x10464, 0x10465, 0x10466, 0x10467, 0x10468, 0x10469, 0x1046a, 0x1046b, 0x1046c, 0x1046d, 0x1046e, 0x1046f, 0x10470, 0x10471, 0x10472, 0x10473, 0x10474, 0x10475, 0x10476, 0x10477,
        0x10478, 0x10479, 0x1047a, 0x1047b, 0x1047c, 0x1047d, 0x1047e, 0x1047f, 0x10480, 0x10481, 0x10482, 0x10483, 0x10484, 0x10485, 0x10486, 0x10487, 0x10488, 0x10489, 0x1048a, 0x1048b, 0x1048c, 0x1048d, 0x1048e, 0x1048f,
        0x10490, 0x10491, 0x10492, 0x10493, 0x10494, 0x10495, 0x10496, 0x10497, 0x10498, 0x10499, 0x1049a, 0x1049b, 0x1049c, 0x1049d, 0x1049e, 0x1049f, 0x104a0, 0x104a1, 0x104a2, 0x104a3, 0x104a4, 0x104a5, 0x104a6, 0x104a7,
        0x104a8, 0x104a9, 0x104aa, 0x104ab, 0x104ac, 0x104ad, 0x104ae, 0x104af, 0x104b0, 0x104b1, 0x104b2, 0x104b3, 0x104b4, 0x104b5, 0x104b6, 0x104b7, 0x104b8, 0x104b9, 0x104ba, 0x104bb, 0x104bc, 0x104bd, 0x104be, 0x104bf,
        0x104c0, 0x104c1, 0x104c2, 0x104c3, 0x104c4, 0x104c5, 0x104c6, 0x104c7, 0x104c8, 0x104c9, 0x104ca, 0x104cb, 0x104cc, 0x104cd, 0x104ce, 0x104cf, 0x104d0, 0x104d1, 0x104d2, 0x104d3, 0x104d4, 0x104d5, 0x104d6, 0x104d7,
        0x104b0, 0x104b1, 0x104b2, 0x104b3, 0x104b4, 0x104b5, 0x104b6, 0x104b7, 0x104b8, 0x104b9, 0x104ba, 0x104bb, 0x104bc, 0x104bd, 0x104be, 0x104bf, 0x104c0, 0x104c1, 0x104c2, 0x104c3, 0x104c4, 0x104c5, 0x104c6, 0x104c7,
        0x104c8, 0x104c9, 0x104ca, 0x104cb, 0x104cc, 0x104cd, 0x104ce, 0x104cf, 0x104d0, 0x104d1, 0x104d2, 0x104d3, 0x104fc, 0x104fd, 0x104fe, 0x104ff,
} };
static const UnicodeCaseTableVector caseTable10c = { {
        0x10c00, 0x10c01, 0x10c02, 0x10c03, 0x10c04, 0x10c05, 0x10c06, 0x10c07, 0x10c08, 0x10c09, 0x10c0a, 0x10c0b, 0x10c0c, 0x10c0d, 0x10c0e, 0x10c0f, 0x10c10, 0x10c11, 0x10c12, 0x10c13, 0x10c14, 0x10c15, 0x10c16, 0x10c17, 0x10c18,
        0x10c19, 0x10c1a, 0x10c1b, 0x10c1c, 0x10c1d, 0x10c1e, 0x10c1f, 0x10c20, 0x10c21, 0x10c22, 0x10c23, 0x10c24, 0x10c25, 0x10c26, 0x10c27, 0x10c28, 0x10c29, 0x10c2a, 0x10c2b, 0x10c2c, 0x10c2d, 0x10c2e, 0x10c2f, 0x10c30, 0x10c31,
        0x10c32, 0x10c33, 0x10c34, 0x10c35, 0x10c36, 0x10c37, 0x10c38, 0x10c39, 0x10c3a, 0x10c3b, 0x10c3c, 0x10c3d, 0x10c3e, 0x10c3f, 0x10c40, 0x10c41, 0x10c42, 0x10c43, 0x10c44, 0x10c45, 0x10c46, 0x10c47, 0x10c48, 0x10c49, 0x10c4a,
        0x10c4b, 0x10c4c, 0x10c4d, 0x10c4e, 0x10c4f, 0x10c50, 0x10c51, 0x10c52, 0x10c53, 0x10c54, 0x10c55, 0x10c56, 0x10c57, 0x10c58, 0x10c59, 0x10c5a, 0x10c5b, 0x10c5c, 0x10c5d, 0x10c5e, 0x10c5f, 0x10c60, 0x10c61, 0x10c62, 0x10c63,
        0x10c64, 0x10c65, 0x10c66, 0x10c67, 0x10c68, 0x10c69, 0x10c6a, 0x10c6b, 0x10c6c, 0x10c6d, 0x10c6e, 0x10c6f, 0x10c70, 0x10c71, 0x10c72, 0x10c73, 0x10c74, 0x10c75, 0x10c76, 0x10c77, 0x10c78, 0x10c79, 0x10c7a, 0x10c7b, 0x10c7c,
        0x10c7d, 0x10c7e, 0x10c7f, 0x10c80, 0x10c81, 0x10c82, 0x10c83, 0x10c84, 0x10c85, 0x10c86, 0x10c87, 0x10c88, 0x10c89, 0x10c8a, 0x10c8b, 0x10c8c, 0x10c8d, 0x10c8e, 0x10c8f, 0x10c90, 0x10c91, 0x10c92, 0x10c93, 0x10c94, 0x10c95,
        0x10c96, 0x10c97, 0x10c98, 0x10c99, 0x10c9a, 0x10c9b, 0x10c9c, 0x10c9d, 0x10c9e, 0x10c9f, 0x10ca0, 0x10ca1, 0x10ca2, 0x10ca3, 0x10ca4, 0x10ca5, 0x10ca6, 0x10ca7, 0x10ca8, 0x10ca9, 0x10caa, 0x10cab, 0x10cac, 0x10cad, 0x10cae,
        0x10caf, 0x10cb0, 0x10cb1, 0x10cb2, 0x10cb3, 0x10cb4, 0x10cb5, 0x10cb6, 0x10cb7, 0x10cb8, 0x10cb9, 0x10cba, 0x10cbb, 0x10cbc, 0x10cbd, 0x10cbe, 0x10cbf, 0x10c80, 0x10c81, 0x10c82, 0x10c83, 0x10c84, 0x10c85, 0x10c86, 0x10c87,
        0x10c88, 0x10c89, 0x10c8a, 0x10c8b, 0x10c8c, 0x10c8d, 0x10c8e, 0x10c8f, 0x10c90, 0x10c91, 0x10c92, 0x10c93, 0x10c94, 0x10c95, 0x10c96, 0x10c97, 0x10c98, 0x10c99, 0x10c9a, 0x10c9b, 0x10c9c, 0x10c9d, 0x10c9e, 0x10c9f, 0x10ca0,
        0x10ca1, 0x10ca2, 0x10ca3, 0x10ca4, 0x10ca5, 0x10ca6, 0x10ca7, 0x10ca8, 0x10ca9, 0x10caa, 0x10cab, 0x10cac, 0x10cad, 0x10cae, 0x10caf, 0x10cb0, 0x10cb1, 0x10cb2, 0x10cf3, 0x10cf4, 0x10cf5, 0x10cf6, 0x10cf7,
} };
static const UnicodeCaseTableVector caseTable118 = { {
        0x11800, 0x11801, 0x11802, 0x11803, 0x11804, 0x11805, 0x11806, 0x11807, 0x11808, 0x11809, 0x1180a, 0x1180b, 0x1180c, 0x1180d, 0x1180e, 0x1180f, 0x11810, 0x11811, 0x11812, 0x11813, 0x11814, 0x11815, 0x11816, 0x11817, 0x11818,
        0x11819, 0x1181a, 0x1181b, 0x1181c, 0x1181d, 0x1181e, 0x1181f, 0x11820, 0x11821, 0x11822, 0x11823, 0x11824, 0x11825, 0x11826, 0x11827, 0x11828, 0x11829, 0x1182a, 0x1182b, 0x1182c, 0x1182d, 0x1182e, 0x1182f, 0x11830, 0x11831,
        0x11832, 0x11833, 0x11834, 0x11835, 0x11836, 0x11837, 0x11838, 0x11839, 0x1183a, 0x1183b, 0x1183c, 0x1183d, 0x1183e, 0x1183f, 0x11840, 0x11841, 0x11842, 0x11843, 0x11844, 0x11845, 0x11846, 0x11847, 0x11848, 0x11849, 0x1184a,
        0x1184b, 0x1184c, 0x1184d, 0x1184e, 0x1184f, 0x11850, 0x11851, 0x11852, 0x11853, 0x11854, 0x11855, 0x11856, 0x11857, 0x11858, 0x11859, 0x1185a, 0x1185b, 0x1185c, 0x1185d, 0x1185e, 0x1185f, 0x11860, 0x11861, 0x11862, 0x11863,
        0x11864, 0x11865, 0x11866, 0x11867, 0x11868, 0x11869, 0x1186a, 0x1186b, 0x1186c, 0x1186d, 0x1186e, 0x1186f, 0x11870, 0x11871, 0x11872, 0x11873, 0x11874, 0x11875, 0x11876, 0x11877, 0x11878, 0x11879, 0x1187a, 0x1187b, 0x1187c,
        0x1187d, 0x1187e, 0x1187f, 0x11880, 0x11881, 0x11882, 0x11883, 0x11884, 0x11885, 0x11886, 0x11887, 0x11888, 0x11889, 0x1188a, 0x1188b, 0x1188c, 0x1188d, 0x1188e, 0x1188f, 0x11890, 0x11891, 0x11892, 0x11893, 0x11894, 0x11895,
        0x11896, 0x11897, 0x11898, 0x11899, 0x1189a, 0x1189b, 0x1189c, 0x1189d, 0x1189e, 0x1189f, 0x118a0, 0x118a1, 0x118a2, 0x118a3, 0x118a4, 0x118a5, 0x118a6, 0x118a7, 0x118a8, 0x118a9, 0x118aa, 0x118ab, 0x118ac, 0x118ad, 0x118ae,
        0x118af, 0x118b0, 0x118b1, 0x118b2, 0x118b3, 0x118b4, 0x118b5, 0x118b6, 0x118b7, 0x118b8, 0x118b9, 0x118ba, 0x118bb, 0x118bc, 0x118bd, 0x118be, 0x118bf, 0x118a0, 0x118a1, 0x118a2, 0x118a3, 0x118a4, 0x118a5, 0x118a6, 0x118a7,
        0x118a8, 0x118a9, 0x118aa, 0x118ab, 0x118ac, 0x118ad, 0x118ae, 0x118af, 0x118b0, 0x118b1, 0x118b2, 0x118b3, 0x118b4, 0x118b5, 0x118b6, 0x118b7, 0x118b8, 0x118b9, 0x118ba, 0x118bb, 0x118bc, 0x118bd, 0x118be, 0x118bf, 0x118e0,
        0x118e1, 0x118e2, 0x118e3, 0x118e4, 0x118e5, 0x118e6, 0x118e7, 0x118e8, 0x118e9, 0x118ea, 0x118eb, 0x118ec, 0x118ed, 0x118ee, 0x118ef, 0x118f0, 0x118f1, 0x118f2, 0x118f3, 0x118f4, 0x118f5, 0x118f6, 0x118f7,
} };
static const UnicodeCaseTableVector caseTable16e = { {
        0x16e00, 0x16e01, 0x16e02, 0x16e03, 0x16e04, 0x16e05, 0x16e06, 0x16e07, 0x16e08, 0x16e09, 0x16e0a, 0x16e0b, 0x16e0c, 0x16e0d, 0x16e0e, 0x16e0f, 0x16e10, 0x16e11, 0x16e12, 0x16e13, 0x16e14, 0x16e15, 0x16e16, 0x16e17, 0x16e18,
        0x16e19, 0x16e1a, 0x16e1b, 0x16e1c, 0x16e1d, 0x16e1e, 0x16e1f, 0x16e20, 0x16e21, 0x16e22, 0x16e23, 0x16e24, 0x16e25, 0x16e26, 0x16e27, 0x16e28, 0x16e29, 0x16e2a, 0x16e2b, 0x16e2c, 0x16e2d, 0x16e2e, 0x16e2f, 0x16e30, 0x16e31,
        0x16e32, 0x16e33, 0x16e34, 0x16e35, 0x16e36, 0x16e37, 0x16e38, 0x16e39, 0x16e3a, 0x16e3b, 0x16e3c, 0x16e3d, 0x16e3e, 0x16e3f, 0x16e40, 0x16e41, 0x16e42, 0x16e43, 0x16e44, 0x16e45, 0x16e46, 0x16e47, 0x16e48, 0x16e49, 0x16e4a,
        0x16e4b, 0x16e4c, 0x16e4d, 0x16e4e, 0x16e4f, 0x16e50, 0x16e51, 0x16e52, 0x16e53, 0x16e54, 0x16e55, 0x16e56, 0x16e57, 0x16e58, 0x16e59, 0x16e5a, 0x16e5b, 0x16e5c, 0x16e5d, 0x16e5e, 0x16e5f, 0x16e40, 0x16e41, 0x16e42, 0x16e43,
        0x16e44, 0x16e45, 0x16e46, 0x16e47, 0x16e48, 0x16e49, 0x16e4a, 0x16e4b, 0x16e4c, 0x16e4d, 0x16e4e, 0x16e4f, 0x16e50, 0x16e51, 0x16e52, 0x16e53, 0x16e54, 0x16e55, 0x16e56, 0x16e57, 0x16e58, 0x16e59, 0x16e5a, 0x16e5b, 0x16e5c,
        0x16e5d, 0x16e5e, 0x16e5f, 0x16e80, 0x16e81, 0x16e82, 0x16e83, 0x16e84, 0x16e85, 0x16e86, 0x16e87, 0x16e88, 0x16e89, 0x16e8a, 0x16e8b, 0x16e8c, 0x16e8d, 0x16e8e, 0x16e8f, 0x16e90, 0x16e91, 0x16e92, 0x16e93, 0x16e94, 0x16e95,
        0x16e96, 0x16e97, 0x16e98, 0x16e99, 0x16e9a, 0x16e9b, 0x16e9c, 0x16e9d, 0x16e9e, 0x16e9f, 0x16ea0, 0x16ea1, 0x16ea2, 0x16ea3, 0x16ea4, 0x16ea5, 0x16ea6, 0x16ea7, 0x16ea8, 0x16ea9, 0x16eaa, 0x16eab, 0x16eac, 0x16ead, 0x16eae,
        0x16eaf, 0x16eb0, 0x16eb1, 0x16eb2, 0x16eb3, 0x16eb4, 0x16eb5, 0x16eb6, 0x16eb7, 0x16eb8, 0x16eb9, 0x16eba, 0x16ebb, 0x16ebc, 0x16ebd, 0x16ebe, 0x16ebf, 0x16ec0, 0x16ec1, 0x16ec2, 0x16ec3, 0x16ec4, 0x16ec5, 0x16ec6, 0x16ec7,
        0x16ec8, 0x16ec9, 0x16eca, 0x16ecb, 0x16ecc, 0x16ecd, 0x16ece, 0x16ecf, 0x16ed0, 0x16ed1, 0x16ed2, 0x16ed3, 0x16ed4, 0x16ed5, 0x16ed6, 0x16ed7, 0x16ed8, 0x16ed9, 0x16eda, 0x16edb, 0x16edc, 0x16edd, 0x16ede, 0x16edf, 0x16ee0,
        0x16ee1, 0x16ee2, 0x16ee3, 0x16ee4, 0x16ee5, 0x16ee6, 0x16ee7, 0x16ee8, 0x16ee9, 0x16eea, 0x16eeb, 0x16eec, 0x16eed, 0x16eee, 0x16eef, 0x16ef0, 0x16ef1, 0x16ef2, 0x16ef3, 0x16ef4, 0x16ef5, 0x16ef6, 0x16ef7,
} };
static const UnicodeCaseTableVector caseTable1e9 = { {
        0x1e900, 0x1e901, 0x1e902, 0x1e903, 0x1e904, 0x1e905, 0x1e906, 0x1e907, 0x1e908, 0x1e909, 0x1e90a, 0x1e90b, 0x1e90c, 0x1e90d, 0x1e90e, 0x1e90f, 0x1e910, 0x1e911, 0x1e912, 0x1e913, 0x1e914, 0x1e915, 0x1e916, 0x1e917, 0x1e918,
        0x1e919, 0x1e91a, 0x1e91b, 0x1e91c, 0x1e91d, 0x1e91e, 0x1e91f, 0x1e920, 0x1e921, 0x1e900, 0x1e901, 0x1e902, 0x1e903, 0x1e904, 0x1e905, 0x1e906, 0x1e907, 0x1e908, 0x1e909, 0x1e90a, 0x1e90b, 0x1e90c, 0x1e90d, 0x1e90e, 0x1e90f,
        0x1e910, 0x1e911, 0x1e912, 0x1e913, 0x1e914, 0x1e915, 0x1e916, 0x1e917, 0x1e918, 0x1e919, 0x1e91a, 0x1e91b, 0x1e91c, 0x1e91d, 0x1e91e, 0x1e91f, 0x1e920, 0x1e921, 0x1e944, 0x1e945, 0x1e946, 0x1e947, 0x1e948, 0x1e949, 0x1e94a,
        0x1e94b, 0x1e94c, 0x1e94d, 0x1e94e, 0x1e94f, 0x1e950, 0x1e951, 0x1e952, 0x1e953, 0x1e954, 0x1e955, 0x1e956, 0x1e957, 0x1e958, 0x1e959, 0x1e95a, 0x1e95b, 0x1e95c, 0x1e95d, 0x1e95e, 0x1e95f, 0x1e960, 0x1e961, 0x1e962, 0x1e963,
        0x1e964, 0x1e965, 0x1e966, 0x1e967, 0x1e968, 0x1e969, 0x1e96a, 0x1e96b, 0x1e96c, 0x1e96d, 0x1e96e, 0x1e96f, 0x1e970, 0x1e971, 0x1e972, 0x1e973, 0x1e974, 0x1e975, 0x1e976, 0x1e977, 0x1e978, 0x1e979, 0x1e97a, 0x1e97b, 0x1e97c,
        0x1e97d, 0x1e97e, 0x1e97f, 0x1e980, 0x1e981, 0x1e982, 0x1e983, 0x1e984, 0x1e985, 0x1e986, 0x1e987, 0x1e988, 0x1e989, 0x1e98a, 0x1e98b, 0x1e98c, 0x1e98d, 0x1e98e, 0x1e98f, 0x1e990, 0x1e991, 0x1e992, 0x1e993, 0x1e994, 0x1e995,
        0x1e996, 0x1e997, 0x1e998, 0x1e999, 0x1e99a, 0x1e99b, 0x1e99c, 0x1e99d, 0x1e99e, 0x1e99f, 0x1e9a0, 0x1e9a1, 0x1e9a2, 0x1e9a3, 0x1e9a4, 0x1e9a5, 0x1e9a6, 0x1e9a7, 0x1e9a8, 0x1e9a9, 0x1e9aa, 0x1e9ab, 0x1e9ac, 0x1e9ad, 0x1e9ae,
        0x1e9af, 0x1e9b0, 0x1e9b1, 0x1e9b2, 0x1e9b3, 0x1e9b4, 0x1e9b5, 0x1e9b6, 0x1e9b7, 0x1e9b8, 0x1e9b9, 0x1e9ba, 0x1e9bb, 0x1e9bc, 0x1e9bd, 0x1e9be, 0x1e9bf, 0x1e9c0, 0x1e9c1, 0x1e9c2, 0x1e9c3, 0x1e9c4, 0x1e9c5, 0x1e9c6, 0x1e9c7,
        0x1e9c8, 0x1e9c9, 0x1e9ca, 0x1e9cb, 0x1e9cc, 0x1e9cd, 0x1e9ce, 0x1e9cf, 0x1e9d0, 0x1e9d1, 0x1e9d2, 0x1e9d3, 0x1e9d4, 0x1e9d5, 0x1e9d6, 0x1e9d7, 0x1e9d8, 0x1e9d9, 0x1e9da, 0x1e9db, 0x1e9dc, 0x1e9dd, 0x1e9de, 0x1e9df, 0x1e9e0,
        0x1e9e1, 0x1e9e2, 0x1e9e3, 0x1e9e4, 0x1e9e5, 0x1e9e6, 0x1e9e7, 0x1e9e8, 0x1e9e9, 0x1e9ea, 0x1e9eb, 0x1e9ec, 0x1e9ed, 0x1e9ee, 0x1e9ef, 0x1e9f0, 0x1e9f1, 0x1e9f2, 0x1e9f3, 0x1e9f4, 0x1e9f5, 0x1e9f6, 0x1e9f7,
} };
static const UnicodeCaseTableVector *caseTable[] = {
    &caseTable00, &caseTable01, &caseTable02,  &caseTable03, &caseTable04, &caseTable05,  nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, &caseTable1e, &caseTable1f, nullptr,       &caseTable21,  nullptr, nullptr, &caseTable24, nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, &caseTableff, nullptr, nullptr, nullptr,      nullptr,      &caseTable104, nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      &caseTable10c, nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       &caseTable118, nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      &caseTable16e, nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       nullptr,       nullptr, nullptr, nullptr,      nullptr,
    nullptr,      nullptr,      nullptr,       nullptr,      nullptr,      nullptr,       nullptr, nullptr, nullptr,      nullptr, nullptr, nullptr,      nullptr,      nullptr,       &caseTable1e9,
};

static inline char getType(Unicode c)
{
    int i;
    char type;

    if (c > 0xffff) {
        type = 'X';
    } else {
        i = (c >> 8) & 0xff;
        if ((type = typeTable[i].type) == 'X') {
            type = typeTable[i].vector[c & 0xff];
        }
    }
    return type;
}

bool unicodeTypeL(Unicode c)
{
    return getType(c) == 'L';
}

bool unicodeTypeR(Unicode c)
{
    return getType(c) == 'R';
}

bool unicodeTypeNum(Unicode c)
{
    return getType(c) == '#';
}

bool unicodeTypeAlphaNum(Unicode c)
{
    char t;

    t = getType(c);
    return t == 'L' || t == 'R' || t == '#';
}

#define UNICODE_ALPHABETIC_PRESENTATION_BLOCK_BEGIN 0xFB00
#define UNICODE_ALPHABETIC_PRESENTATION_BLOCK_END 0xFB4F

bool unicodeIsAlphabeticPresentationForm(Unicode c)
{
    return c >= UNICODE_ALPHABETIC_PRESENTATION_BLOCK_BEGIN && c <= UNICODE_ALPHABETIC_PRESENTATION_BLOCK_END;
}

Unicode unicodeToUpper(Unicode c)
{
    size_t i = (c >> 8);
    if (i < sizeof(caseTable) / sizeof(caseTable[0]) && caseTable[i]) {
        return caseTable[i]->codes[c & 0xff];
    }
    return c;
}

#define UNICODE_LAST_CHAR 0x10FFFF
#define UNICODE_MAX_TABLE_INDEX (UNICODE_LAST_CHAR / 256 + 1)
// large empty block between U+2FA1D and U+E0001
#define UNICODE_LAST_CHAR_PART1 0x2FAFF
#define UNICODE_LAST_PAGE_PART1 (UNICODE_LAST_CHAR_PART1 / 256)
#define UNICODE_PART2_START 0xE0000

#include "UnicodeCClassTables.h"
#include "UnicodeCompTables.h"
#include "UnicodeDecompTables.h"

#define CC_PART1(Page, Char) ((combining_class_table_part1[Page] >= UNICODE_MAX_TABLE_INDEX) ? (combining_class_table_part1[Page] - UNICODE_MAX_TABLE_INDEX) : (cclass_data[combining_class_table_part1[Page]][Char]))

#define CC_PART2(Page, Char) ((combining_class_table_part2[Page] >= UNICODE_MAX_TABLE_INDEX) ? (combining_class_table_part2[Page] - UNICODE_MAX_TABLE_INDEX) : (cclass_data[combining_class_table_part2[Page]][Char]))

#define COMBINING_CLASS(u) (((u) <= UNICODE_LAST_CHAR_PART1) ? CC_PART1((u) / 256, (u) % 256) : (((u) >= UNICODE_PART2_START && (u) <= UNICODE_LAST_CHAR) ? CC_PART2(((u)-UNICODE_PART2_START) / 256, (u) % 256) : 0))

// Write the compatibility decomposition of @u into @buf, returning the number
// of characters written. @buf may be NULL, in which case the length of the
// decomposition is returned but nothing is written. If @u is its own
// decomposition, write @u into @buf and return 1.
// If reverseRTL is true, then decompositions of RTL characters will be output
// in reverse order.
static int decomp_compat(Unicode u, Unicode *buf, bool reverseRTL = false)
{
    // decomposition tables stored as lists {character, decomp_length, offset}
    // so we do a binary search
    int start = 0, end = DECOMP_TABLE_LENGTH;
    if (u >= decomp_table[start].character && u <= decomp_table[end - 1].character) {
        while (true) {
            int midpoint = (start + end) / 2;
            if (u == decomp_table[midpoint].character) {
                int offset = decomp_table[midpoint].offset;
                if (offset == -1) {
                    break;
                } else {
                    int length = decomp_table[midpoint].length, i;
                    if (buf) {
                        for (i = 0; i < length; ++i) {
                            if (unicodeTypeR(u) && reverseRTL) {
                                buf[i] = decomp_expansion[offset + length - i - 1];
                            } else {
                                buf[i] = decomp_expansion[offset + i];
                            }
                        }
                    }
                    return length;
                }
            } else if (midpoint == start) {
                break;
            } else if (u > decomp_table[midpoint].character) {
                start = midpoint;
            } else {
                end = midpoint;
            }
        }
    }
    if (buf) {
        *buf = u;
    }
    return 1;
}

#define CI(Page, Char) ((compose_table[Page] >= UNICODE_MAX_TABLE_INDEX) ? (compose_table[Page] - UNICODE_MAX_TABLE_INDEX) : (compose_data[compose_table[Page]][Char]))

#define COMPOSE_INDEX(u) ((((u) / 256) > (COMPOSE_TABLE_LAST)) ? 0 : CI((u) / 256, (u) % 256))

// If @add combines with @base, write the combination to @out and return
// true. Otherwise return false.
static bool combine(Unicode base, Unicode add, Unicode *out)
{
    unsigned short idx_base, idx_add;

    idx_base = COMPOSE_INDEX(base);
    if (idx_base >= COMPOSE_FIRST_SINGLE_START && idx_base < COMPOSE_SECOND_START) {
        if (compose_first_single[idx_base - COMPOSE_FIRST_SINGLE_START][0] == add) {
            *out = compose_first_single[idx_base - COMPOSE_FIRST_SINGLE_START][1];
            return true;
        } else {
            return false;
        }
    }

    idx_add = COMPOSE_INDEX(add);
    if (idx_add >= COMPOSE_SECOND_SINGLE_START) {
        if (compose_second_single[idx_add - COMPOSE_SECOND_SINGLE_START][0] == base) {
            *out = compose_second_single[idx_add - COMPOSE_SECOND_SINGLE_START][1];
            return true;
        } else {
            return false;
        }
    }

    if (idx_base >= COMPOSE_FIRST_START && idx_base < COMPOSE_FIRST_SINGLE_START && idx_add >= COMPOSE_SECOND_START && idx_add < COMPOSE_SECOND_SINGLE_START) {
        Unicode o = compose_array[idx_base - COMPOSE_FIRST_START][idx_add - COMPOSE_SECOND_START];
        if (o) {
            *out = o;
            return true;
        }
    }

    return false;
}

#define HANGUL_S_BASE 0xAC00
#define HANGUL_L_BASE 0x1100
#define HANGUL_V_BASE 0x1161
#define HANGUL_T_BASE 0x11A7
#define HANGUL_L_COUNT 19
#define HANGUL_V_COUNT 21
#define HANGUL_T_COUNT 28
#define HANGUL_S_COUNT (HANGUL_L_COUNT * HANGUL_V_COUNT * HANGUL_T_COUNT)
#define HANGUL_N_COUNT (HANGUL_V_COUNT * HANGUL_T_COUNT)
#define HANGUL_IS_L(u) (((u) >= HANGUL_L_BASE) && ((u) < HANGUL_L_BASE + HANGUL_L_COUNT))
#define HANGUL_IS_V(u) (((u) >= HANGUL_V_BASE) && ((u) < HANGUL_V_BASE + HANGUL_V_COUNT))
#define HANGUL_IS_T(u) (((u) >= HANGUL_T_BASE) && ((u) < HANGUL_T_BASE + HANGUL_T_COUNT))
#define HANGUL_IS_SYLLABLE(u) (((u) >= HANGUL_S_BASE) && ((u) < HANGUL_S_BASE + HANGUL_S_COUNT))
#define HANGUL_SYLLABLE_IS_LV(u) (((u)-HANGUL_S_BASE) % HANGUL_T_COUNT == 0)
#define IS_HANGUL(u) (HANGUL_IS_L(u) || HANGUL_IS_V(u) || HANGUL_IS_T(u) || HANGUL_IS_SYLLABLE(u))
#define HANGUL_COMPOSE_L_V(l, v) (HANGUL_S_BASE + (HANGUL_T_COUNT * (((v)-HANGUL_V_BASE) + (HANGUL_V_COUNT * ((l)-HANGUL_L_BASE)))))
#define HANGUL_COMPOSE_LV_T(lv, t) ((lv) + ((t)-HANGUL_T_BASE))

// Converts Unicode string @in of length @len to its normalization in form
// NFKC (compatibility decomposition + canonical composition). The length of
// the resulting Unicode string is returned in @out_len. If non-NULL, @indices
// is assigned the location of a newly-allocated array of length @out_len + 1,
// for each character in the normalized string giving the index in @in of the
// corresponding unnormalized character. @indices is not guaranteed monotone or
// onto.
Unicode *unicodeNormalizeNFKC(const Unicode *in, int len, int *out_len, int **indices)
{
    return unicodeNormalizeNFKC(in, len, out_len, indices, false);
}

Unicode *unicodeNormalizeNFKC(const Unicode *in, int len, int *out_len, int **indices, bool reverseRTL)
{
    Unicode *out;
    int i, o, *classes, *idx = nullptr;

    for (i = 0, o = 0; i < len; ++i) {
        if (HANGUL_IS_L(in[i]) || HANGUL_IS_SYLLABLE(in[i])) {
            o += 1;
        } else {
            o += decomp_compat(in[i], nullptr);
        }
    }

    out = (Unicode *)gmallocn(o, sizeof(Unicode));
    classes = (int *)gmallocn(o, sizeof(int));
    if (indices) {
        idx = (int *)gmallocn(o + 1, sizeof(int));
    }

    for (i = 0, o = 0; i < len;) {
        Unicode u = in[i];
        if (IS_HANGUL(u)) {
            if (HANGUL_IS_L(u)) {
                Unicode l = u;
                if (i + 1 < len && HANGUL_IS_V(in[i + 1])) {
                    Unicode lv = HANGUL_COMPOSE_L_V(l, in[++i]);
                    if (i + 1 < len && HANGUL_IS_T(in[i + 1])) {
                        out[o] = HANGUL_COMPOSE_LV_T(lv, in[++i]);
                    } else {
                        out[o] = lv;
                    }
                } else {
                    out[o] = l;
                }
            } else if (HANGUL_SYLLABLE_IS_LV(u)) {
                Unicode lv = u;
                if (i + 1 < len && HANGUL_IS_T(in[i + 1])) {
                    out[o] = HANGUL_COMPOSE_LV_T(lv, in[++i]);
                } else {
                    out[o] = lv;
                }
            } else {
                out[o] = u;
            }
            if (indices) {
                idx[o] = i;
            }
            ++i;
            ++o;
        } else {
            int j, p, q, r, s, dlen;
            // write compatibility decompositions into out (we have enough space)
            // chomp in until a starter is reached
            for (j = i, p = o; j < len; ++j) {
                u = in[j];
                if (j != i && COMBINING_CLASS(u) == 0) {
                    break;
                }
                dlen = decomp_compat(u, out + p, reverseRTL);
                for (q = p; q < p + dlen; ++q) {
                    classes[q] = COMBINING_CLASS(out[q]);
                    if (indices) {
                        idx[q] = j;
                    }
                }
                p += dlen;
            }
            // put out[o, p) in canonical ordering
            for (q = o + 1; q < p; ++q) {
                for (r = q; r > o + 1; --r) { // FIXME worth using a better sort?
                    int swap;
                    if (classes[r] >= classes[r - 1]) {
                        break;
                    }
                    u = out[r];
                    out[r] = out[r - 1];
                    out[r - 1] = u;
                    swap = classes[r];
                    classes[r] = classes[r - 1];
                    classes[r - 1] = swap;
                    if (indices) {
                        swap = idx[r];
                        idx[r] = idx[r - 1];
                        idx[r - 1] = swap;
                    }
                }
            }
            // canonical compose out[o, p)
            for (q = o + 1; q < p; ++q) {
                if (!combine(out[o], out[q], &out[o])) {
                    break;
                }
            }
            // move out[q, p) back to [o+1, ?)
            if (q != o + 1) {
                for (r = q, s = o + 1; r < p; ++r, ++s) {
                    out[s] = out[r];
                    if (indices) {
                        idx[s] = idx[r];
                    }
                }
            } else {
                s = p;
            }
            i = j;
            o = s;
        }
    }

    *out_len = o;
    gfree(classes);
    if (indices) {
        idx[o] = len;
        *indices = idx;
    }
    return out;
}
