- Fixed #ZETACOMP-15 : Template string functions are now multibyte safe

# Thanks Andreas Schamberger


git-svn-id: https://svn.apache.org/repos/asf/incubator/zetacomponents/trunk@1159948 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/Template/src/functions/string_code.php b/Template/src/functions/string_code.php
index 3741194..3f61028 100644
--- a/Template/src/functions/string_code.php
+++ b/Template/src/functions/string_code.php
@@ -27,7 +27,7 @@
 
 /**
  * This class contains a bundle of static functions, each implementing a specific
- * function used inside the template language. 
+ * function used inside the template language.
  *
  * @package Template
  * @version //autogen//
@@ -36,6 +36,100 @@
 class ezcTemplateString
 {
     /**
+     *  Stores the charset used for iconv
+     */
+    const CHARSET = 'utf-8';
+
+    /**
+     * Lower to upper case conversion table.
+     *
+     * Included on demand when mbstring functions are not available.
+     * Generated from http://www.unicode.org/Public/UNIDATA/UnicodeData.txt.
+     *
+     * @var array(string=>string)
+     */
+    private static $lowerToUpper = null;
+
+    /**
+     * Upper to lower case conversion table.
+     *
+     * Included on demand when mbstring functions are not available.
+     * Generated from http://www.unicode.org/Public/UNIDATA/UnicodeData.txt.
+     *
+     * @var array(string=>string)
+     */
+    private static $upperToLower = null;
+
+    /**
+     * Escapes all special chars within the given $charlist for using it within
+     * a regular expression character class definition (i.e []^-\ and the
+     * pattern delimiter). By default the pattern delimiter is '/'.
+     *
+     * @param string $charlist
+     * @param string $patternDelimiter
+     * @return string
+     */
+    private static function escapeCharacterClassCharlist( $charlist, $patternDelimiter = '/' )
+    {
+        return preg_replace( '!([\\\\\\-\\]\\[^'. $patternDelimiter .'])!', '\\\${1}', $charlist );
+    }
+
+    /**
+     * Multibyte safe ltrim().
+     *
+     * Based on http://de.php.net/manual/en/function.trim.php#72562.
+     * Added the charlist to the regexp. rtrim seems to be safe for whitespaces.
+     *
+     * @param string $str
+     * @param string $charlist
+     * @return string
+     */
+    public static function ltrim( $str, $charlist = null )
+    {
+        if ( is_null( $charlist ) )
+        {
+            return ltrim( $str );
+        }
+        $charlist = self::escapeCharacterClassCharlist( $charlist );
+        return preg_replace( '/^['.$charlist.']+/u', '', $str );
+    }
+
+    /**
+     * Multibyte safe rtrim().
+     *
+     * Based on http://de.php.net/manual/en/function.trim.php#72562.
+     * Added the charlist to the regexp. rtrim seems to be safe for whitespaces.
+     *
+     * @param string $str
+     * @param string $charlist
+     * @return string
+     */
+    public static function rtrim( $str, $charlist = null )
+    {
+        if ( is_null( $charlist ) )
+        {
+            return rtrim( $str );
+        }
+        $charlist = self::escapeCharacterClassCharlist( $charlist );
+        return preg_replace( '/['.$charlist.']+$/u', '', $str );
+    }
+
+    /**
+     * Multibyte safe str_pad().
+     *
+     * @param string $input
+     * @param int $pad_length
+     * @param string $pad_string
+     * @param mixed $pad_type
+     * @return string
+     */
+    public static function str_pad( $input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT )
+    {
+        $diff = strlen( $input ) - iconv_strlen( $input, self::CHARSET );
+        return str_pad( $input, $pad_length + $diff, $pad_string, $pad_type );
+    }
+
+    /**
      * Returns the number of paragraphs found in the given string.
      *
      * @param string $string
@@ -43,10 +137,15 @@
      */
     public static function str_paragraph_count( $string )
     {
-        $pos = 0;
-        $count = 0;
+        if ( iconv_strlen( $string, self::CHARSET ) == 0 )
+        {
+            return 0;
+        }
 
-        while ( preg_match( "/\n\n+/", $string, $m, PREG_OFFSET_CAPTURE, $pos ) )
+        $pos = 0;
+        $count = 1;
+
+        while ( preg_match( "/\n\n+/u", $string, $m, PREG_OFFSET_CAPTURE, $pos ) )
         {
             ++$count;
             $pos = $m[0][1] + 1;
@@ -54,7 +153,274 @@
 
         return $count;
     }
+
+    /**
+     * Multibyte safe str_word_count().
+     *
+     * Based on http://de.php.net/manual/en/function.str-word-count.php#85592.
+     * Added the $charlist parameter and fixed the offsets for $format=2.
+     *
+     * @param string $string
+     * @param int $format
+     * 		0 - returns the number of words found
+     * 		1 - returns an array containing all the words found inside the string
+     * 		2 - returns an associative array, where the key is the numeric position of the word inside the string and the value is the actual word itself
+     * @param string $charlist
+     * @return mixed
+     */
+    public static function str_word_count( $string, $format = 0, $charlist = null )
+    {
+        if ( !is_null( $charlist ) )
+        {
+            $charlist = self::escapeCharacterClassCharlist( $charlist );
+        }
+        else
+        {
+            $charlist = '';
+        }
+
+        $pattern = "/\p{L}[\p{L}\p{Mn}\p{Pd}'\x{2019}".$charlist."]*/u";
+        $matches = array();
+        switch ( $format )
+        {
+            case 1:
+                preg_match_all( $pattern, $string, $matches );
+                return $matches[0];
+            case 2:
+                preg_match_all( $pattern, $string, $matches, PREG_OFFSET_CAPTURE );
+                $result = array();
+                $diff = 0;
+                foreach ( $matches[0] as $match )
+                {
+                    // reduce wrong offset by multibyte difference
+                    $offset = $match[1] - $diff;
+                    $result[$offset] = $match[0];
+                    // add multibyte offset difference of current word
+                    $diff += strlen( $match[0] ) - iconv_strlen( $match[0], self::CHARSET );
+                }
+                return $result;
+            default:
+                return preg_match_all( $pattern, $string, $matches );
+         }
+    }
+
+    /**
+     * Multibyte safe strpos().
+     *
+     * @param string $haystack
+     * @param mixed $needle
+     * @param int $offset
+     * @return int|bool
+     */
+    public static function strpos( $haystack, $needle, $offset = 0 )
+    {
+        return iconv_strpos( $haystack, $needle, $offset, self::CHARSET );
+    }
+
+    /**
+     * Multibyte safe strrpos().
+     *
+     * @param string $haystack
+     * @param mixed $needle
+     * @param int $offset
+     * @param bool $useMbString
+     * @return string
+     */
+    public static function strrpos( $haystack, $needle, $offset = 0, $useMbString = true )
+    {
+        if ( $useMbString === true && function_exists( 'mb_strrpos' ) )
+        {
+            return mb_strrpos( $haystack, $needle, $offset, self::CHARSET );
+        }
+        else
+        {
+            $addOffset = 0;
+            if ( $offset > 0 )
+            {
+                $haystack = iconv_substr( $haystack, $offset, iconv_strlen( $haystack, self::CHARSET ), self::CHARSET );
+                $addOffset = $offset;
+            }
+            elseif( $offset < 0 )
+            {
+                $haystack = iconv_substr( $haystack, 0, $offset, self::CHARSET );
+            }
+            $result = iconv_strrpos( $haystack, $needle, self::CHARSET );
+            return ( $result === false ) ? $result : $result + $addOffset;
+        }
+    }
+
+    /**
+     * Multibyte safe strrev().
+     *
+     * Based on http://de.php.net/manual/en/function.strrev.php#62422.
+     *
+     * @param string $str
+     * @return string
+     */
+    public static function strrev( $string )
+    {
+        if ( empty( $string ) )
+        {
+            return $string;
+        }
+        $matches = array();
+        preg_match_all( '/./us', $string, $matches );
+        return implode( '', array_reverse( $matches[0] ) );
+    }
+
+    /**
+     * Multibyte safe strtolower().
+     * Uses mb_strtolower() if available otherwise falls back to own conversion
+     * table.
+     *
+     * @param string $str
+     * @param bool $useMbString
+     * @return string
+     */
+    public static function strtolower( $str, $useMbString = true )
+    {
+        if ( empty( $str ) )
+        {
+            return $str;
+        }
+        if ( $useMbString === true && function_exists( 'mb_strtolower' ) )
+        {
+            return mb_strtolower( $str, self::CHARSET );
+        }
+        if ( is_null( self::$upperToLower ) )
+        {
+            self::$upperToLower = new ezcTemplateStringUpperToLowerUnicodeMap();
+        }
+        return strtr( $str, self::$upperToLower->unicodeTable );
+    }
+
+    /**
+     * Multibyte safe strtoupper().
+     * Uses mb_strtoupper() if available otherwise falls back to own conversion
+     * table.
+     *
+     * @param string $str
+     * @param bool $useMbString
+     * @return string
+     */
+    public static function strtoupper( $str, $useMbString = true )
+    {
+        if ( empty( $str ) )
+        {
+            return $str;
+        }
+        if ( $useMbString === true && function_exists( 'mb_strtoupper' ) )
+        {
+            return mb_strtoupper( $str, self::CHARSET );
+        }
+        if ( is_null( self::$lowerToUpper ) )
+        {
+            self::$lowerToUpper = new ezcTemplateStringLowerToUpperUnicodeMap();
+        }
+        return strtr( $str, self::$lowerToUpper->unicodeTable );
+    }
+
+    /**
+     * Multibyte safe trim().
+     *
+     * @param string $str
+     * @param string $charlist
+     * @return string
+     */
+    public static function trim( $str, $charlist = null )
+    {
+        if ( is_null( $charlist ) )
+        {
+            return trim( $str );
+        }
+        return self::ltrim( self::rtrim( $str, $charlist ), $charlist );
+    }
+
+    /**
+     * Multibyte safe ucfirst().
+     *
+     * @param string $string
+     * @return string
+     */
+    public static function ucfirst( $string )
+    {
+        $strlen = iconv_strlen( $string, self::CHARSET );
+        if ( $strlen == 0 )
+        {
+            return '';
+        }
+        elseif ( $strlen == 1 )
+        {
+            return self::strtoupper( $string );
+        }
+        else
+        {
+            $matches = array();
+            preg_match( '/^(.{1})(.*)$/us', $string, $matches );
+            return self::strtoupper( $matches[1] ) . $matches[2];
+        }
+    }
+
+    /**
+     * Multibyte safe wordwrap().
+     *
+     * @param string $str
+     * @param int $width
+     * @param string $break
+     * @param bool $cut
+     * @return string
+     */
+    public static function wordwrap( $str, $width = 75, $break = "\n", $cut = false )
+    {
+        if ( empty( $str ) )
+        {
+            return $str;
+        }
+        $lines = explode( $break, $str );
+        $return = '';
+        foreach ( $lines as $line )
+        {
+            $line = trim( $line );
+            $length = iconv_strlen( $line, self::CHARSET );
+            if ( $length > $width )
+            {
+                if ( $cut )
+                {
+                    while ( $length > $width )
+                    {
+                        $return .= iconv_substr( $line, 0, $width, self::CHARSET ) . $break;
+                        $line = iconv_substr( $line, $width, iconv_strlen( $line, self::CHARSET ) - $width, self::CHARSET );
+                        $length = iconv_strlen( $line, self::CHARSET );
+                    }
+                    $return .= $line;
+                }
+                else
+                {
+                    $words = explode( ' ', $line );
+                    $tmp = '';
+                    foreach ( $words as $word )
+                    {
+                        $word = trim( $word );
+                        if ( iconv_strlen( $tmp . $word, self::CHARSET ) <= $width )
+                        {
+                            $tmp .= $word . ' ';
+                        }
+                        else
+                        {
+                            $return .= trim( $tmp ) . $break;
+                            $tmp = $word . ' ';
+                        }
+                    }
+                    $return .= trim( $tmp );
+                }
+            }
+            else
+            {
+                $return .= $line. $break;
+            }
+        }
+        return $return;
+    }
 }
 
-
-?>
+?>
\ No newline at end of file
diff --git a/Template/src/functions/string_functions.php b/Template/src/functions/string_functions.php
index dd325f6..e7a4946 100644
--- a/Template/src/functions/string_functions.php
+++ b/Template/src/functions/string_functions.php
@@ -33,7 +33,12 @@
 class ezcTemplateStringFunctions extends ezcTemplateFunctions
 {
     /**
-     * Translates a function used in the Template language to a PHP function call.  
+     *  Stores the charset used for iconv
+     */
+    const CHARSET = 'utf-8';
+
+    /**
+     * Translates a function used in the Template language to a PHP function call.
      * The function call is represented by an array with three elements:
      *
      * 1. The return typehint. Is it an array, a non-array, or both.
@@ -50,46 +55,53 @@
         {
             // str_replace( $sl, $index, $len, $sr )
             // substr( $sl, 0, $index ) . $sr . substr( $sl, $index + $len );
-            case "str_replace": 
-                return array( ezcTemplateAstNode::TYPE_VALUE, array( "%left", "%index", "%length", "%right" ), 
-                   self::concat( 
-                       self::functionCall( "substr", array( "%left", self::value( 0 ), "%index" ) ),
-                       self::concat( 
-                           "%right", 
-                           self::functionCall( 
-                               "substr", 
-                               array( "%left", array( "ezcTemplateAdditionOperatorAstNode", array( "%index", "%length" ) ) ) 
-                           ) 
-                       ) 
+            case "str_replace":
+                return array( ezcTemplateAstNode::TYPE_VALUE, array( "%left", "%index", "%length", "%right" ),
+                   self::concat(
+                       self::functionCall( "iconv_substr", array( "%left", self::value( 0 ), "%index", self::value( self::CHARSET ) ) ),
+                       self::concat(
+                           "%right",
+                           self::functionCall(
+                               "iconv_substr",
+                               array( "%left", array( "ezcTemplateAdditionOperatorAstNode", array( "%index", "%length" ) ),
+                                    self::functionCall( "iconv_strlen", array("%left", self::value( self::CHARSET ) ) ), self::value( self::CHARSET ) )
+                           )
+                       )
                     )
-                 ); 
+                 );
 
 
-            // str_remove( $s, $index, $len ) 
+            // str_remove( $s, $index, $len )
             // substr( $s, 0, $index ) . substr( $s, $index + $len );
-             case "str_remove": 
-                 return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%index", "%length" ), 
-                   self::concat( 
-                       self::functionCall( "substr", array( "%string", self::value( 0 ), "%index" ) ),
-                       self::functionCall( "substr", array( "%string", array( "ezcTemplateAdditionOperatorAstNode", array( "%index", "%length" ) ) ) 
-                           ) 
-                        ) 
+             case "str_remove":
+                 return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%index", "%length" ),
+                   self::concat(
+                       self::functionCall( "iconv_substr", array( "%string", self::value( 0 ), "%index", self::value( self::CHARSET ) ) ),
+                       self::functionCall( "iconv_substr",
+                       array( "%string", array( "ezcTemplateAdditionOperatorAstNode", array( "%index", "%length" ) ),
+                              self::functionCall( "iconv_strlen", array("%string", self::value( self::CHARSET ) ) ), self::value( self::CHARSET ) )
+                           )
+                        )
                      );
-  
+
             // string str_chop( $s, $len ) ( QString::chop ):
             // substr( $s, 0, strlen( $string ) - $len );
-             case "str_chop": 
-                return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%length" ), 
-                       self::functionCall( "substr", array( 
-                           "%string", 
-                           self::value( 0 ), 
-                           array( "ezcTemplateSubtractionOperatorAstNode", array( self::functionCall( "strlen", array( "%string" ) ), "%length" ) )
+             case "str_chop":
+                return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%length" ),
+                       self::functionCall( "iconv_substr", array(
+                           "%string",
+                           self::value( 0 ),
+                           array( "ezcTemplateSubtractionOperatorAstNode", array( self::functionCall( "iconv_strlen", array( "%string", self::value( self::CHARSET ) ) ), "%length" ) ),
+                           self::value( self::CHARSET )
                        )
                    ) );
-                       
+
             // string str_chop_front( $s, $len )
             // substr( $s, $len );
-             case "str_chop_front": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length" ), self::functionCall( "substr", array( "%string", "%length" ) ) );
+            case "str_chop_front":
+                return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length" ),
+                    self::functionCall( "iconv_substr", array( "%string", "%length",
+                        self::functionCall( "iconv_strlen", array("%string", self::value( self::CHARSET ) ) ), self::value( self::CHARSET ) ) ) );
 
              case "str_append": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%left", "%right" ), self::concat( "%left", "%right" ) );
 
@@ -104,193 +116,196 @@
             case "str_nat_compare": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%left", "%right"), self::functionCall( "strnatcmp", array( "%left", "%right" ) ) );
 
             // str_contains( $sl, $sr ) ( QString::compare )::
-            // strpos( $sl, $sr ) !== false 
-            case "str_contains": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%left", "%right" ), 
-                array( "ezcTemplateNotIdenticalOperatorAstNode", 
-                array( self::functionCall( "strpos", array( "%left", "%right" ) ), self::value( false ) ) ) );
+            // strpos( $sl, $sr ) !== false
+            case "str_contains": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%left", "%right" ),
+                array( "ezcTemplateNotIdenticalOperatorAstNode",
+                array( self::functionCall( "ezcTemplateString::strpos", array( "%left", "%right" ) ), self::value( false ) ) ) );
 
             // str_len( $s )
             // strlen( $s )
-            case "str_len": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), self::functionCall( "strlen", array( "%string" ) ) );
+            case "str_len": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), self::functionCall( "iconv_strlen", array( "%string", self::value( self::CHARSET ) ) ) );
 
             // str_left( $s, $len )
             // substr( $s, 0, $len )
-            case "str_left": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length"), self::functionCall( "substr", array( "%string", self::value( 0 ), "%length" ) ) );
+            case "str_left": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length"), self::functionCall( "iconv_substr", array( "%string", self::value( 0 ), "%length", self::value( self::CHARSET ) ) ) );
 
             // str_starts_with( $sl, $sr )
             // strpos( $sl, $sr ) === 0
             case "str_starts_with": return array(
-                ezcTemplateAstNode::TYPE_VALUE,  
-                array( "%haystack", "%needle" ), 
-                array( "ezcTemplateIdenticalOperatorAstNode", array( 
-                    self::functionCall( "strpos", array( "%haystack", "%needle" ) ),
+                ezcTemplateAstNode::TYPE_VALUE,
+                array( "%haystack", "%needle" ),
+                array( "ezcTemplateIdenticalOperatorAstNode", array(
+                    self::functionCall( "ezcTemplateString::strpos", array( "%haystack", "%needle" ) ),
                     self::value( 0 )
-                ) ) ); 
+                ) ) );
 
             // str_right( $s, $len )
             // substr( $s, -$len )
-            case "str_right": return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%length" ),
-                self::functionCall( "substr", array( "%string", array( "ezcTemplateArithmeticNegationOperatorAstNode",  array( "%length" ) ) ) ) );
+            case "str_right":
+                return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%length" ),
+                    self::functionCall(
+                        "iconv_substr", array( "%string", array( "ezcTemplateArithmeticNegationOperatorAstNode", array( "%length" ) ),
+                        self::functionCall( "iconv_strlen", array("%string", self::value( self::CHARSET ) ) ), self::value( self::CHARSET ) ) ) );
 
             // str_ends_with( $sl, $sr )
             // strrpos( $sl, $sr ) === ( strlen( $sl ) - strlen( $sr) )
             case "str_ends_with": return array(
                 ezcTemplateAstNode::TYPE_VALUE,
                 array( "%haystack", "%needle" ),
-                array( "ezcTemplateIdenticalOperatorAstNode", array( 
-                    self::functionCall( "strrpos", array( "%haystack", "%needle" ) ),
-                    array( "ezcTemplateSubtractionOperatorAstNode", array( 
-                        self::functionCall( "strlen", array( "%haystack" ) ), 
-                        self::functionCall( "strlen", array( "%needle" ) ) 
-                    ) ) ) ) ); 
+                array( "ezcTemplateIdenticalOperatorAstNode", array(
+                    self::functionCall( "ezcTemplateString::strrpos", array( "%haystack", "%needle" ) ),
+                    array( "ezcTemplateSubtractionOperatorAstNode", array(
+                        self::functionCall( "iconv_strlen", array( "%haystack", self::value( self::CHARSET ) ) ),
+                        self::functionCall( "iconv_strlen", array( "%needle", self::value( self::CHARSET ) ) )
+                    ) ) ) ) );
 
             // str_mid( $s, $index, $len )
             // substr( $s, $index, $len )
-            case "str_mid": return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%index", "%length" ), 
-                self::functionCall( "substr", array( "%string", "%index", "%length" ) ) );
+            case "str_mid": return array( ezcTemplateAstNode::TYPE_VALUE,  array( "%string", "%index", "%length" ),
+                self::functionCall( "iconv_substr", array( "%string", "%index", "%length", self::value( self::CHARSET ) ) ) );
 
             // str_at( $s, $index )
             // substr( $s, $index, 1 )
-            case "str_at": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%index" ), 
-                self::functionCall( "substr", array( "%string", "%index", self::value( 1 ) ) ) );
+            case "str_at": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%index" ),
+                self::functionCall( "iconv_substr", array( "%string", "%index", self::value( 1 ), self::value( self::CHARSET ) ) ) );
 
             // str_fill( $s, $len )
             // str_repeat( $s, $len )
-            case "str_fill": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length" ), 
+            case "str_fill": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length" ),
                 self::functionCall( "str_repeat", array( "%string", "%length" ) ) );
 
             // str_index_of( $sl, $sr [, $index ] )
             // strpos( $sl, $sr [, $index ] )
-            case "str_index_of": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%haystack", "%needle", "[%index]" ), 
-                self::functionCall( "strpos", array( "%haystack", "%needle", "[%index]" ) ) );
-            
+            case "str_index_of": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%haystack", "%needle", "[%index]" ),
+                self::functionCall( "ezcTemplateString::strpos", array( "%haystack", "%needle", "[%index]" ) ) );
+
             // str_last_index( $sl, $sr [, $index] )
             // strrpos( $sl, $sr [, $index ] )
-            case "str_last_index": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%haystack", "%needle", "[%index]" ), 
-                self::functionCall( "strrpos", array( "%haystack", "%needle", "[%index]" ) ) );
-             
+            case "str_last_index": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%haystack", "%needle", "[%index]" ),
+                self::functionCall( "ezcTemplateString::strrpos", array( "%haystack", "%needle", "[%index]" ) ) );
+
             // str_is_empty( $s )
             // strlen( $s ) === 0
-            case "str_is_empty": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
-                array( "ezcTemplateIdenticalOperatorAstNode", array( 
-                    self::functionCall( "strlen", array( "%string" ) ),
+            case "str_is_empty": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
+                array( "ezcTemplateIdenticalOperatorAstNode", array(
+                    self::functionCall( "iconv_strlen", array( "%string", self::value( self::CHARSET ) ) ),
                     self::value( 0 ) ) ) );
-             
+
             // str_pad_left( $s, $len, $fill )
             // str_pad( $s, $len, $fill, STR_PAD_LEFT )
-            case "str_pad_left": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length", "%fill" ), 
-                    self::functionCall( "str_pad", array( "%string", "%length", "%fill", self::constant( "STR_PAD_LEFT" ) ) ) );
-             
+            case "str_pad_left": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length", "%fill" ),
+                    self::functionCall( "ezcTemplateString::str_pad", array( "%string", "%length", "%fill", self::constant( "STR_PAD_LEFT" ) ) ) );
+
             // str_pad_right( $s, $len, $fill ) ( QString::rightJustified() )::
             // str_pad( $s, $len, $fill, STR_PAD_RIGHT )
-            case "str_pad_right": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length", "%fill" ), 
-                    self::functionCall( "str_pad", array( "%string", "%length", "%fill", self::constant( "STR_PAD_RIGHT" ) ) ) );
-             
+            case "str_pad_right": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%length", "%fill" ),
+                    self::functionCall( "ezcTemplateString::str_pad", array( "%string", "%length", "%fill", self::constant( "STR_PAD_RIGHT" ) ) ) );
+
             // str_number( $num, $decimals, $point, $sep )
             // number_format( $num, $decimals, $point, $sep )
-            case "str_number": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%number", "%decimals", "%point", "%separator" ), 
+            case "str_number": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%number", "%decimals", "%point", "%separator" ),
                     self::functionCall( "number_format", array( "%number", "%decimals", "%point", "%separator") ) );
-             
+
             // str_trim( $s [, $chars ] )
             // trim( $s [, $chars] )
-            case "str_trim": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%chars]" ), 
-                    self::functionCall( "trim", array( "%string", "[%chars]") ) );
-             
+            case "str_trim": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%chars]" ),
+                    self::functionCall( "ezcTemplateString::trim", array( "%string", "[%chars]") ) );
+
             // str_trim_left( $s [, $chars] )
             // ltrim( $s [, $chars] )
-            case "str_trim_left": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%chars]" ), 
-                    self::functionCall( "ltrim", array( "%string", "[%chars]") ) );
-             
+            case "str_trim_left": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%chars]" ),
+                    self::functionCall( "ezcTemplateString::ltrim", array( "%string", "[%chars]") ) );
+
             // str_trim_right( $s [, $chars] )
             // rtrim( $s, [$chars] )
-            case "str_trim_right": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%chars]" ), 
-                    self::functionCall( "rtrim", array( "%string", "[%chars]") ) );
-             
+            case "str_trim_right": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%chars]" ),
+                    self::functionCall( "ezcTemplateString::rtrim", array( "%string", "[%chars]") ) );
+
             // str_simplified( $s )
             // trim( preg_replace( "/(\n|\t|\r\n|\s)+/", " ", $s ) )
-            case "str_simplify": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
-                    self::functionCall( "trim", array(
+            case "str_simplify": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
+                    self::functionCall( "ezcTemplateString::trim", array(
                         self::functionCall( "preg_replace", array( self::constant( '"/(\n|\t|\r\n|\s)+/"' ), self::value( " " ), "%string" ) )
                     ) ) );
-             
+
             // str_split( $s, $sep[, $max] )
             // explode( $s, $sep, $max )
-            case "str_split": return array( ezcTemplateAstNode::TYPE_VALUE | ezcTemplateAstNode::TYPE_ARRAY, array( "%string", "%separator", "[%max]" ), 
+            case "str_split": return array( ezcTemplateAstNode::TYPE_VALUE | ezcTemplateAstNode::TYPE_ARRAY, array( "%string", "%separator", "[%max]" ),
                     self::functionCall( "explode", array( "%separator", "%string", "[%max]" ) ) );
-             
+
             // str_join( $s_list, $sep )
             // join( $sList, $sep )
-            case "str_join": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%list", "%separator" ), 
+            case "str_join": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%list", "%separator" ),
                     self::functionCall( "join", array( "%separator", "%list" ) ) );
-             
+
             // str_printf( $format [...] )
             // sprintf( $format [...] )
             // TODO
-             
+
             // str_chr( $ord1 [, $ord2...] )::
             // ord( $ord1 ) [ . ord( $ord2 ) ...]
-            // TODO 
-            
+            // TODO
+
             // str_ord( $c )
             // ord( $c )
-            case "str_ord": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%char" ), 
+            case "str_ord": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%char" ),
                     self::functionCall( "ord", array( "%char" ) ) );
 
             // chr( $c )
-            case "str_chr": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%char" ), 
+            case "str_chr": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%char" ),
                     self::functionCall( "chr", array( "%char" ) ) );
-            
+
             // str_ord_list( $s )::
             // chr( $s[0] ) [ . chr( $s[1] ) ]
             // TODO
-             
+
             // str_upper( $s )
             // strtoupper( $s )
-            case "str_upper": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
-                    self::functionCall( "strtoupper", array( "%string") ) );
-            
+            case "str_upper": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
+                    self::functionCall( "ezcTemplateString::strtoupper", array( "%string") ) );
+
             // str_lower( $s )
             // strtolower( $s )
-            case "str_lower": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
-                    self::functionCall( "strtolower", array( "%string") ) );
-             
+            case "str_lower": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
+                    self::functionCall( "ezcTemplateString::strtolower", array( "%string") ) );
+
             // str_capitalize( $s )::
             // ucfirst( $s )
-            case "str_capitalize": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
-                    self::functionCall( "ucfirst", array( "%string") ) );
-             
+            case "str_capitalize": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
+                    self::functionCall( "ezcTemplateString::ucfirst", array( "%string") ) );
+
             // str_find_replace( $s, $find, $replace, $count )::
             // str_replace( $s, $replace, $find, $count )
-            case "str_find_replace": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%find", "%replace", "[%count]" ), 
+            case "str_find_replace": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%find", "%replace", "[%count]" ),
                     self::functionCall( "str_replace", array( "%find", "%replace", "%string", "[%count]") ) );
-             
+
             // str_reverse( $s )::
             // strrev( $s )
-            case "str_reverse": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
-                    self::functionCall( "strrev", array( "%string" ) ) );
-             
+            case "str_reverse": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
+                    self::functionCall( "ezcTemplateString::strrev", array( "%string" ) ) );
+
             // str_section( $s, $sep, $start, $end = -1 )
             // join( array_slice( split( $s, $sep, $end != -1 ? $end, false ), $start, $end ? $end : false ) )
             // TODO
 
              // str_char_count( $s )::
             // strlen( $s )
-            case "str_char_count": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
-                    self::functionCall( "strlen", array( "%string" ) ) );
-             
+            case "str_char_count": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
+                    self::functionCall( "iconv_strlen", array( "%string", self::value( self::CHARSET ) ) ) );
+
             // str_word_count( $s [, $wordsep] )
             // str_word_count( $s, 0 [, $wordsep] )
-            case "str_word_count": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%wordsep]" ), 
-                    self::functionCall( "str_word_count", array( "%string", self::value( 0 ), "[%wordsep]" ) ) );
- 
+            case "str_word_count": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "[%wordsep]" ),
+                    self::functionCall( "ezcTemplateString::str_word_count", array( "%string", self::value( 0 ), "[%wordsep]" ) ) );
+
             // - *string* str_paragraph_count( $s )::
             // Code.
-            case "str_paragraph_count": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), 
+            case "str_paragraph_count": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ),
                     self::functionCall( "ezcTemplateString::str_paragraph_count", array( "%string" ) ) );
- 
-           // 
+
+           //
             // - *string* str_sentence_count( $s )::
-            // 
+            //
             //     $pos = 0;
             //     $count = 0;
             //     while ( preg_match( "/. /", $s, $m, PREG_OFFSET_CAPTURE, $pos )
@@ -299,40 +314,40 @@
             //         $pos = $m[0][1];
             //     }
             // TODO
-            // 
+            //
             // - *string* str_break( $s, $eol = contextaware, $lbreak = contextaware )::
-            // 
+            //
             //     str_replace( context_eol_char( $eol ), context_linebreak_char( $eol ), $s )
-            // 
+            //
             // TODO
-            // 
+            //
             // - *string* str_break_chars( $s, $cbreak )::
-            // 
+            //
             //     $sNew = '';
             //     for ( $i = 0; $i < strlen( $s ) - 1; ++$i )
             //     {
             //         $sNew .= $s[$i] . $cbreak;
             //     }
             //     $sNew .= $s[strlen( $s ) - 1];
-            // 
+            //
             // TODO
-            
+
             // str_wrap( $s, $width, $break, $cut )
             // wordwrap( $s, $width, $break, $cut )
-            case "str_wrap": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%width", "%break", "[%cut]" ), 
-                    self::functionCall( "wordwrap", array( "%string", "%width", "%break", "[%cut]" ) ) );
+            case "str_wrap": return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string", "%width", "%break", "[%cut]" ),
+                    self::functionCall( "ezcTemplateString::wordwrap", array( "%string", "%width", "%break", "[%cut]" ) ) );
 
             // base64_encode( $s )
             case "str_base64_encode":
                 return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), self::functionCall( "base64_encode", array( "%string" ) ) );
-            
+
             // base64_decode( $s )
             case "str_base64_decode":
                 return array( ezcTemplateAstNode::TYPE_VALUE, array( "%string" ), self::functionCall( "base64_decode", array( "%string" ) ) );
- 
-            // 
+
+            //
             // - *string* str_wrap_indent::
-            // 
+            //
             //    $tmp = wordwrap( $s, $width, $break, $cut )
             //    $lines = explode( "\n", $tmp );
             //    $newLines = array();
@@ -341,71 +356,71 @@
             //        $newLines[] = $prefix . $line . $suffix;
             //    }
             //    return join( "\n", $newLines )
-            // 
+            //
             // TODO
             // - *string* str_block( $s, $prefix, $suffix )
-            // 
-            // 
+            //
+            //
             // - *string* str_shorten_right( $s, $max_size )
-            // 
+            //
             // - *string* str_shorten_mid( $s, $max_size )
-            // 
+            //
             // - *string* str_shorten_left( $s, $max_size )
-            // 
+            //
             // - *string* str_crc32( $s )::
-            // 
+            //
             //     crc32( $s )
-            // 
+            //
             // - *string* str_md5( $s )::
-            // 
+            //
             //     md5( $s )
-            // 
+            //
             // - *string* str_sha1( $s )::
-            // 
+            //
             //     sha1( $s )
-            // 
+            //
             // - *string* str_rot13( $s )::
-            // 
+            //
             //     str_rot13( $s )
-            // 
+            //
             // Some of the functions are also available as case insensitive versions, they are:
-            // 
+            //
             // - *string* stri_contains( $sl, $sr ) ( QString::compare )::
-            // 
+            //
             //     stristr( $sl, $sr ) !== false
-            // 
+            //
             // - *string* stri_starts_with( $sl, $sr ) ( QString::startsWith )::
-            // 
+            //
             //     stripos( strtolower( $sl ), strtolower( $sr ) ) === 0
-            // 
+            //
             // - *string* stri_ends_with( $sl, $sr ) ( QString::endsWith )::
-            // 
+            //
             //     strripos( $sl, $sr ) === ( strlen( $sl ) - 1 )
-            // 
+            //
             // - *string* stri_index( $sl, $sr [, $from] ) ( QString::indexOf )::
-            // 
+            //
             //     stripos( $sl, $sr [, $from ] )
-            // 
+            //
             // - *string* stri_last_index( $sl, $sr [, $from] ) ( QString::lastIndexOf )::
-            // 
+            //
             //     strirpos( $sl, $sr [, $from ] )
-            // 
+            //
             // - *string* stri_find_replace( $s, $find, $replace, $count )::
-            // 
+            //
             //     str_ireplace( $s, $replace, $find, $count )
-            // 
+            //
             // - *string* stri_compare( $sl, $sr ) ( QString::compare )::
-            // 
+            //
             //     strcasecmp( $sl, $sr );
-            // 
+            //
             // - *string* stri_nat_compare( $sl, $sr )::
-            // 
+            //
             //     strnatcasecmp( $sl, $sr );
-            // 
+            //
 
         }
 
         return null;
     }
 }
-?>
+?>
\ No newline at end of file
diff --git a/Template/src/structs/lower_to_upper.php b/Template/src/structs/lower_to_upper.php
new file mode 100644
index 0000000..b62e429
--- /dev/null
+++ b/Template/src/structs/lower_to_upper.php
@@ -0,0 +1,1082 @@
+<?php
+/**
+ * File containing a mapping from unicode lowercase to uppercase letters.
+ *
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * THIS FILE IS MACHINE GENERATED. USE THE FOLLOWING SCRIPT TO REBUILD IT:
+ * - Template/src/unicode/generate_unicode_tables.php
+ *
+ * @package Template
+ * @version //autogentag//
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @access private
+ */
+
+class ezcTemplateStringLowerToUpperUnicodeMap extends ezcBaseStruct
+{
+    public $unicodeTable = array(
+    "\x61" => "\x41", // LATIN SMALL LETTER A
+    "\x62" => "\x42", // LATIN SMALL LETTER B
+    "\x63" => "\x43", // LATIN SMALL LETTER C
+    "\x64" => "\x44", // LATIN SMALL LETTER D
+    "\x65" => "\x45", // LATIN SMALL LETTER E
+    "\x66" => "\x46", // LATIN SMALL LETTER F
+    "\x67" => "\x47", // LATIN SMALL LETTER G
+    "\x68" => "\x48", // LATIN SMALL LETTER H
+    "\x69" => "\x49", // LATIN SMALL LETTER I
+    "\x6a" => "\x4a", // LATIN SMALL LETTER J
+    "\x6b" => "\x4b", // LATIN SMALL LETTER K
+    "\x6c" => "\x4c", // LATIN SMALL LETTER L
+    "\x6d" => "\x4d", // LATIN SMALL LETTER M
+    "\x6e" => "\x4e", // LATIN SMALL LETTER N
+    "\x6f" => "\x4f", // LATIN SMALL LETTER O
+    "\x70" => "\x50", // LATIN SMALL LETTER P
+    "\x71" => "\x51", // LATIN SMALL LETTER Q
+    "\x72" => "\x52", // LATIN SMALL LETTER R
+    "\x73" => "\x53", // LATIN SMALL LETTER S
+    "\x74" => "\x54", // LATIN SMALL LETTER T
+    "\x75" => "\x55", // LATIN SMALL LETTER U
+    "\x76" => "\x56", // LATIN SMALL LETTER V
+    "\x77" => "\x57", // LATIN SMALL LETTER W
+    "\x78" => "\x58", // LATIN SMALL LETTER X
+    "\x79" => "\x59", // LATIN SMALL LETTER Y
+    "\x7a" => "\x5a", // LATIN SMALL LETTER Z
+    "\xc2\xb5" => "\xce\x9c", // MICRO SIGN
+    "\xc3\xa0" => "\xc3\x80", // LATIN SMALL LETTER A WITH GRAVE
+    "\xc3\xa1" => "\xc3\x81", // LATIN SMALL LETTER A WITH ACUTE
+    "\xc3\xa2" => "\xc3\x82", // LATIN SMALL LETTER A WITH CIRCUMFLEX
+    "\xc3\xa3" => "\xc3\x83", // LATIN SMALL LETTER A WITH TILDE
+    "\xc3\xa4" => "\xc3\x84", // LATIN SMALL LETTER A WITH DIAERESIS
+    "\xc3\xa5" => "\xc3\x85", // LATIN SMALL LETTER A WITH RING ABOVE
+    "\xc3\xa6" => "\xc3\x86", // LATIN SMALL LETTER AE
+    "\xc3\xa7" => "\xc3\x87", // LATIN SMALL LETTER C WITH CEDILLA
+    "\xc3\xa8" => "\xc3\x88", // LATIN SMALL LETTER E WITH GRAVE
+    "\xc3\xa9" => "\xc3\x89", // LATIN SMALL LETTER E WITH ACUTE
+    "\xc3\xaa" => "\xc3\x8a", // LATIN SMALL LETTER E WITH CIRCUMFLEX
+    "\xc3\xab" => "\xc3\x8b", // LATIN SMALL LETTER E WITH DIAERESIS
+    "\xc3\xac" => "\xc3\x8c", // LATIN SMALL LETTER I WITH GRAVE
+    "\xc3\xad" => "\xc3\x8d", // LATIN SMALL LETTER I WITH ACUTE
+    "\xc3\xae" => "\xc3\x8e", // LATIN SMALL LETTER I WITH CIRCUMFLEX
+    "\xc3\xaf" => "\xc3\x8f", // LATIN SMALL LETTER I WITH DIAERESIS
+    "\xc3\xb0" => "\xc3\x90", // LATIN SMALL LETTER ETH
+    "\xc3\xb1" => "\xc3\x91", // LATIN SMALL LETTER N WITH TILDE
+    "\xc3\xb2" => "\xc3\x92", // LATIN SMALL LETTER O WITH GRAVE
+    "\xc3\xb3" => "\xc3\x93", // LATIN SMALL LETTER O WITH ACUTE
+    "\xc3\xb4" => "\xc3\x94", // LATIN SMALL LETTER O WITH CIRCUMFLEX
+    "\xc3\xb5" => "\xc3\x95", // LATIN SMALL LETTER O WITH TILDE
+    "\xc3\xb6" => "\xc3\x96", // LATIN SMALL LETTER O WITH DIAERESIS
+    "\xc3\xb8" => "\xc3\x98", // LATIN SMALL LETTER O WITH STROKE
+    "\xc3\xb9" => "\xc3\x99", // LATIN SMALL LETTER U WITH GRAVE
+    "\xc3\xba" => "\xc3\x9a", // LATIN SMALL LETTER U WITH ACUTE
+    "\xc3\xbb" => "\xc3\x9b", // LATIN SMALL LETTER U WITH CIRCUMFLEX
+    "\xc3\xbc" => "\xc3\x9c", // LATIN SMALL LETTER U WITH DIAERESIS
+    "\xc3\xbd" => "\xc3\x9d", // LATIN SMALL LETTER Y WITH ACUTE
+    "\xc3\xbe" => "\xc3\x9e", // LATIN SMALL LETTER THORN
+    "\xc3\xbf" => "\xc5\xb8", // LATIN SMALL LETTER Y WITH DIAERESIS
+    "\xc4\x81" => "\xc4\x80", // LATIN SMALL LETTER A WITH MACRON
+    "\xc4\x83" => "\xc4\x82", // LATIN SMALL LETTER A WITH BREVE
+    "\xc4\x85" => "\xc4\x84", // LATIN SMALL LETTER A WITH OGONEK
+    "\xc4\x87" => "\xc4\x86", // LATIN SMALL LETTER C WITH ACUTE
+    "\xc4\x89" => "\xc4\x88", // LATIN SMALL LETTER C WITH CIRCUMFLEX
+    "\xc4\x8b" => "\xc4\x8a", // LATIN SMALL LETTER C WITH DOT ABOVE
+    "\xc4\x8d" => "\xc4\x8c", // LATIN SMALL LETTER C WITH CARON
+    "\xc4\x8f" => "\xc4\x8e", // LATIN SMALL LETTER D WITH CARON
+    "\xc4\x91" => "\xc4\x90", // LATIN SMALL LETTER D WITH STROKE
+    "\xc4\x93" => "\xc4\x92", // LATIN SMALL LETTER E WITH MACRON
+    "\xc4\x95" => "\xc4\x94", // LATIN SMALL LETTER E WITH BREVE
+    "\xc4\x97" => "\xc4\x96", // LATIN SMALL LETTER E WITH DOT ABOVE
+    "\xc4\x99" => "\xc4\x98", // LATIN SMALL LETTER E WITH OGONEK
+    "\xc4\x9b" => "\xc4\x9a", // LATIN SMALL LETTER E WITH CARON
+    "\xc4\x9d" => "\xc4\x9c", // LATIN SMALL LETTER G WITH CIRCUMFLEX
+    "\xc4\x9f" => "\xc4\x9e", // LATIN SMALL LETTER G WITH BREVE
+    "\xc4\xa1" => "\xc4\xa0", // LATIN SMALL LETTER G WITH DOT ABOVE
+    "\xc4\xa3" => "\xc4\xa2", // LATIN SMALL LETTER G WITH CEDILLA
+    "\xc4\xa5" => "\xc4\xa4", // LATIN SMALL LETTER H WITH CIRCUMFLEX
+    "\xc4\xa7" => "\xc4\xa6", // LATIN SMALL LETTER H WITH STROKE
+    "\xc4\xa9" => "\xc4\xa8", // LATIN SMALL LETTER I WITH TILDE
+    "\xc4\xab" => "\xc4\xaa", // LATIN SMALL LETTER I WITH MACRON
+    "\xc4\xad" => "\xc4\xac", // LATIN SMALL LETTER I WITH BREVE
+    "\xc4\xaf" => "\xc4\xae", // LATIN SMALL LETTER I WITH OGONEK
+    "\xc4\xb1" => "\x49", // LATIN SMALL LETTER DOTLESS I
+    "\xc4\xb3" => "\xc4\xb2", // LATIN SMALL LIGATURE IJ
+    "\xc4\xb5" => "\xc4\xb4", // LATIN SMALL LETTER J WITH CIRCUMFLEX
+    "\xc4\xb7" => "\xc4\xb6", // LATIN SMALL LETTER K WITH CEDILLA
+    "\xc4\xba" => "\xc4\xb9", // LATIN SMALL LETTER L WITH ACUTE
+    "\xc4\xbc" => "\xc4\xbb", // LATIN SMALL LETTER L WITH CEDILLA
+    "\xc4\xbe" => "\xc4\xbd", // LATIN SMALL LETTER L WITH CARON
+    "\xc5\x80" => "\xc4\xbf", // LATIN SMALL LETTER L WITH MIDDLE DOT
+    "\xc5\x82" => "\xc5\x81", // LATIN SMALL LETTER L WITH STROKE
+    "\xc5\x84" => "\xc5\x83", // LATIN SMALL LETTER N WITH ACUTE
+    "\xc5\x86" => "\xc5\x85", // LATIN SMALL LETTER N WITH CEDILLA
+    "\xc5\x88" => "\xc5\x87", // LATIN SMALL LETTER N WITH CARON
+    "\xc5\x8b" => "\xc5\x8a", // LATIN SMALL LETTER ENG
+    "\xc5\x8d" => "\xc5\x8c", // LATIN SMALL LETTER O WITH MACRON
+    "\xc5\x8f" => "\xc5\x8e", // LATIN SMALL LETTER O WITH BREVE
+    "\xc5\x91" => "\xc5\x90", // LATIN SMALL LETTER O WITH DOUBLE ACUTE
+    "\xc5\x93" => "\xc5\x92", // LATIN SMALL LIGATURE OE
+    "\xc5\x95" => "\xc5\x94", // LATIN SMALL LETTER R WITH ACUTE
+    "\xc5\x97" => "\xc5\x96", // LATIN SMALL LETTER R WITH CEDILLA
+    "\xc5\x99" => "\xc5\x98", // LATIN SMALL LETTER R WITH CARON
+    "\xc5\x9b" => "\xc5\x9a", // LATIN SMALL LETTER S WITH ACUTE
+    "\xc5\x9d" => "\xc5\x9c", // LATIN SMALL LETTER S WITH CIRCUMFLEX
+    "\xc5\x9f" => "\xc5\x9e", // LATIN SMALL LETTER S WITH CEDILLA
+    "\xc5\xa1" => "\xc5\xa0", // LATIN SMALL LETTER S WITH CARON
+    "\xc5\xa3" => "\xc5\xa2", // LATIN SMALL LETTER T WITH CEDILLA
+    "\xc5\xa5" => "\xc5\xa4", // LATIN SMALL LETTER T WITH CARON
+    "\xc5\xa7" => "\xc5\xa6", // LATIN SMALL LETTER T WITH STROKE
+    "\xc5\xa9" => "\xc5\xa8", // LATIN SMALL LETTER U WITH TILDE
+    "\xc5\xab" => "\xc5\xaa", // LATIN SMALL LETTER U WITH MACRON
+    "\xc5\xad" => "\xc5\xac", // LATIN SMALL LETTER U WITH BREVE
+    "\xc5\xaf" => "\xc5\xae", // LATIN SMALL LETTER U WITH RING ABOVE
+    "\xc5\xb1" => "\xc5\xb0", // LATIN SMALL LETTER U WITH DOUBLE ACUTE
+    "\xc5\xb3" => "\xc5\xb2", // LATIN SMALL LETTER U WITH OGONEK
+    "\xc5\xb5" => "\xc5\xb4", // LATIN SMALL LETTER W WITH CIRCUMFLEX
+    "\xc5\xb7" => "\xc5\xb6", // LATIN SMALL LETTER Y WITH CIRCUMFLEX
+    "\xc5\xba" => "\xc5\xb9", // LATIN SMALL LETTER Z WITH ACUTE
+    "\xc5\xbc" => "\xc5\xbb", // LATIN SMALL LETTER Z WITH DOT ABOVE
+    "\xc5\xbe" => "\xc5\xbd", // LATIN SMALL LETTER Z WITH CARON
+    "\xc5\xbf" => "\x53", // LATIN SMALL LETTER LONG S
+    "\xc6\x80" => "\xc9\x83", // LATIN SMALL LETTER B WITH STROKE
+    "\xc6\x83" => "\xc6\x82", // LATIN SMALL LETTER B WITH TOPBAR
+    "\xc6\x85" => "\xc6\x84", // LATIN SMALL LETTER TONE SIX
+    "\xc6\x88" => "\xc6\x87", // LATIN SMALL LETTER C WITH HOOK
+    "\xc6\x8c" => "\xc6\x8b", // LATIN SMALL LETTER D WITH TOPBAR
+    "\xc6\x92" => "\xc6\x91", // LATIN SMALL LETTER F WITH HOOK
+    "\xc6\x95" => "\xc7\xb6", // LATIN SMALL LETTER HV
+    "\xc6\x99" => "\xc6\x98", // LATIN SMALL LETTER K WITH HOOK
+    "\xc6\x9a" => "\xc8\xbd", // LATIN SMALL LETTER L WITH BAR
+    "\xc6\x9e" => "\xc8\xa0", // LATIN SMALL LETTER N WITH LONG RIGHT LEG
+    "\xc6\xa1" => "\xc6\xa0", // LATIN SMALL LETTER O WITH HORN
+    "\xc6\xa3" => "\xc6\xa2", // LATIN SMALL LETTER OI
+    "\xc6\xa5" => "\xc6\xa4", // LATIN SMALL LETTER P WITH HOOK
+    "\xc6\xa8" => "\xc6\xa7", // LATIN SMALL LETTER TONE TWO
+    "\xc6\xad" => "\xc6\xac", // LATIN SMALL LETTER T WITH HOOK
+    "\xc6\xb0" => "\xc6\xaf", // LATIN SMALL LETTER U WITH HORN
+    "\xc6\xb4" => "\xc6\xb3", // LATIN SMALL LETTER Y WITH HOOK
+    "\xc6\xb6" => "\xc6\xb5", // LATIN SMALL LETTER Z WITH STROKE
+    "\xc6\xb9" => "\xc6\xb8", // LATIN SMALL LETTER EZH REVERSED
+    "\xc6\xbd" => "\xc6\xbc", // LATIN SMALL LETTER TONE FIVE
+    "\xc6\xbf" => "\xc7\xb7", // LATIN LETTER WYNN
+    "\xc7\x85" => "\xc7\x84", // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
+    "\xc7\x86" => "\xc7\x84", // LATIN SMALL LETTER DZ WITH CARON
+    "\xc7\x88" => "\xc7\x87", // LATIN CAPITAL LETTER L WITH SMALL LETTER J
+    "\xc7\x89" => "\xc7\x87", // LATIN SMALL LETTER LJ
+    "\xc7\x8b" => "\xc7\x8a", // LATIN CAPITAL LETTER N WITH SMALL LETTER J
+    "\xc7\x8c" => "\xc7\x8a", // LATIN SMALL LETTER NJ
+    "\xc7\x8e" => "\xc7\x8d", // LATIN SMALL LETTER A WITH CARON
+    "\xc7\x90" => "\xc7\x8f", // LATIN SMALL LETTER I WITH CARON
+    "\xc7\x92" => "\xc7\x91", // LATIN SMALL LETTER O WITH CARON
+    "\xc7\x94" => "\xc7\x93", // LATIN SMALL LETTER U WITH CARON
+    "\xc7\x96" => "\xc7\x95", // LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+    "\xc7\x98" => "\xc7\x97", // LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+    "\xc7\x9a" => "\xc7\x99", // LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+    "\xc7\x9c" => "\xc7\x9b", // LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+    "\xc7\x9d" => "\xc6\x8e", // LATIN SMALL LETTER TURNED E
+    "\xc7\x9f" => "\xc7\x9e", // LATIN SMALL LETTER A WITH DIAERESIS AND MACRON
+    "\xc7\xa1" => "\xc7\xa0", // LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON
+    "\xc7\xa3" => "\xc7\xa2", // LATIN SMALL LETTER AE WITH MACRON
+    "\xc7\xa5" => "\xc7\xa4", // LATIN SMALL LETTER G WITH STROKE
+    "\xc7\xa7" => "\xc7\xa6", // LATIN SMALL LETTER G WITH CARON
+    "\xc7\xa9" => "\xc7\xa8", // LATIN SMALL LETTER K WITH CARON
+    "\xc7\xab" => "\xc7\xaa", // LATIN SMALL LETTER O WITH OGONEK
+    "\xc7\xad" => "\xc7\xac", // LATIN SMALL LETTER O WITH OGONEK AND MACRON
+    "\xc7\xaf" => "\xc7\xae", // LATIN SMALL LETTER EZH WITH CARON
+    "\xc7\xb2" => "\xc7\xb1", // LATIN CAPITAL LETTER D WITH SMALL LETTER Z
+    "\xc7\xb3" => "\xc7\xb1", // LATIN SMALL LETTER DZ
+    "\xc7\xb5" => "\xc7\xb4", // LATIN SMALL LETTER G WITH ACUTE
+    "\xc7\xb9" => "\xc7\xb8", // LATIN SMALL LETTER N WITH GRAVE
+    "\xc7\xbb" => "\xc7\xba", // LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
+    "\xc7\xbd" => "\xc7\xbc", // LATIN SMALL LETTER AE WITH ACUTE
+    "\xc7\xbf" => "\xc7\xbe", // LATIN SMALL LETTER O WITH STROKE AND ACUTE
+    "\xc8\x81" => "\xc8\x80", // LATIN SMALL LETTER A WITH DOUBLE GRAVE
+    "\xc8\x83" => "\xc8\x82", // LATIN SMALL LETTER A WITH INVERTED BREVE
+    "\xc8\x85" => "\xc8\x84", // LATIN SMALL LETTER E WITH DOUBLE GRAVE
+    "\xc8\x87" => "\xc8\x86", // LATIN SMALL LETTER E WITH INVERTED BREVE
+    "\xc8\x89" => "\xc8\x88", // LATIN SMALL LETTER I WITH DOUBLE GRAVE
+    "\xc8\x8b" => "\xc8\x8a", // LATIN SMALL LETTER I WITH INVERTED BREVE
+    "\xc8\x8d" => "\xc8\x8c", // LATIN SMALL LETTER O WITH DOUBLE GRAVE
+    "\xc8\x8f" => "\xc8\x8e", // LATIN SMALL LETTER O WITH INVERTED BREVE
+    "\xc8\x91" => "\xc8\x90", // LATIN SMALL LETTER R WITH DOUBLE GRAVE
+    "\xc8\x93" => "\xc8\x92", // LATIN SMALL LETTER R WITH INVERTED BREVE
+    "\xc8\x95" => "\xc8\x94", // LATIN SMALL LETTER U WITH DOUBLE GRAVE
+    "\xc8\x97" => "\xc8\x96", // LATIN SMALL LETTER U WITH INVERTED BREVE
+    "\xc8\x99" => "\xc8\x98", // LATIN SMALL LETTER S WITH COMMA BELOW
+    "\xc8\x9b" => "\xc8\x9a", // LATIN SMALL LETTER T WITH COMMA BELOW
+    "\xc8\x9d" => "\xc8\x9c", // LATIN SMALL LETTER YOGH
+    "\xc8\x9f" => "\xc8\x9e", // LATIN SMALL LETTER H WITH CARON
+    "\xc8\xa3" => "\xc8\xa2", // LATIN SMALL LETTER OU
+    "\xc8\xa5" => "\xc8\xa4", // LATIN SMALL LETTER Z WITH HOOK
+    "\xc8\xa7" => "\xc8\xa6", // LATIN SMALL LETTER A WITH DOT ABOVE
+    "\xc8\xa9" => "\xc8\xa8", // LATIN SMALL LETTER E WITH CEDILLA
+    "\xc8\xab" => "\xc8\xaa", // LATIN SMALL LETTER O WITH DIAERESIS AND MACRON
+    "\xc8\xad" => "\xc8\xac", // LATIN SMALL LETTER O WITH TILDE AND MACRON
+    "\xc8\xaf" => "\xc8\xae", // LATIN SMALL LETTER O WITH DOT ABOVE
+    "\xc8\xb1" => "\xc8\xb0", // LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON
+    "\xc8\xb3" => "\xc8\xb2", // LATIN SMALL LETTER Y WITH MACRON
+    "\xc8\xbc" => "\xc8\xbb", // LATIN SMALL LETTER C WITH STROKE
+    "\xc8\xbf" => "\xe2\xb1\xbe", // LATIN SMALL LETTER S WITH SWASH TAIL
+    "\xc9\x80" => "\xe2\xb1\xbf", // LATIN SMALL LETTER Z WITH SWASH TAIL
+    "\xc9\x82" => "\xc9\x81", // LATIN SMALL LETTER GLOTTAL STOP
+    "\xc9\x87" => "\xc9\x86", // LATIN SMALL LETTER E WITH STROKE
+    "\xc9\x89" => "\xc9\x88", // LATIN SMALL LETTER J WITH STROKE
+    "\xc9\x8b" => "\xc9\x8a", // LATIN SMALL LETTER Q WITH HOOK TAIL
+    "\xc9\x8d" => "\xc9\x8c", // LATIN SMALL LETTER R WITH STROKE
+    "\xc9\x8f" => "\xc9\x8e", // LATIN SMALL LETTER Y WITH STROKE
+    "\xc9\x90" => "\xe2\xb1\xaf", // LATIN SMALL LETTER TURNED A
+    "\xc9\x91" => "\xe2\xb1\xad", // LATIN SMALL LETTER ALPHA
+    "\xc9\x92" => "\xe2\xb1\xb0", // LATIN SMALL LETTER TURNED ALPHA
+    "\xc9\x93" => "\xc6\x81", // LATIN SMALL LETTER B WITH HOOK
+    "\xc9\x94" => "\xc6\x86", // LATIN SMALL LETTER OPEN O
+    "\xc9\x96" => "\xc6\x89", // LATIN SMALL LETTER D WITH TAIL
+    "\xc9\x97" => "\xc6\x8a", // LATIN SMALL LETTER D WITH HOOK
+    "\xc9\x99" => "\xc6\x8f", // LATIN SMALL LETTER SCHWA
+    "\xc9\x9b" => "\xc6\x90", // LATIN SMALL LETTER OPEN E
+    "\xc9\xa0" => "\xc6\x93", // LATIN SMALL LETTER G WITH HOOK
+    "\xc9\xa3" => "\xc6\x94", // LATIN SMALL LETTER GAMMA
+    "\xc9\xa5" => "\xea\x9e\x8d", // LATIN SMALL LETTER TURNED H
+    "\xc9\xa8" => "\xc6\x97", // LATIN SMALL LETTER I WITH STROKE
+    "\xc9\xa9" => "\xc6\x96", // LATIN SMALL LETTER IOTA
+    "\xc9\xab" => "\xe2\xb1\xa2", // LATIN SMALL LETTER L WITH MIDDLE TILDE
+    "\xc9\xaf" => "\xc6\x9c", // LATIN SMALL LETTER TURNED M
+    "\xc9\xb1" => "\xe2\xb1\xae", // LATIN SMALL LETTER M WITH HOOK
+    "\xc9\xb2" => "\xc6\x9d", // LATIN SMALL LETTER N WITH LEFT HOOK
+    "\xc9\xb5" => "\xc6\x9f", // LATIN SMALL LETTER BARRED O
+    "\xc9\xbd" => "\xe2\xb1\xa4", // LATIN SMALL LETTER R WITH TAIL
+    "\xca\x80" => "\xc6\xa6", // LATIN LETTER SMALL CAPITAL R
+    "\xca\x83" => "\xc6\xa9", // LATIN SMALL LETTER ESH
+    "\xca\x88" => "\xc6\xae", // LATIN SMALL LETTER T WITH RETROFLEX HOOK
+    "\xca\x89" => "\xc9\x84", // LATIN SMALL LETTER U BAR
+    "\xca\x8a" => "\xc6\xb1", // LATIN SMALL LETTER UPSILON
+    "\xca\x8b" => "\xc6\xb2", // LATIN SMALL LETTER V WITH HOOK
+    "\xca\x8c" => "\xc9\x85", // LATIN SMALL LETTER TURNED V
+    "\xca\x92" => "\xc6\xb7", // LATIN SMALL LETTER EZH
+    "\xcd\x85" => "\xce\x99", // COMBINING GREEK YPOGEGRAMMENI
+    "\xcd\xb1" => "\xcd\xb0", // GREEK SMALL LETTER HETA
+    "\xcd\xb3" => "\xcd\xb2", // GREEK SMALL LETTER ARCHAIC SAMPI
+    "\xcd\xb7" => "\xcd\xb6", // GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
+    "\xcd\xbb" => "\xcf\xbd", // GREEK SMALL REVERSED LUNATE SIGMA SYMBOL
+    "\xcd\xbc" => "\xcf\xbe", // GREEK SMALL DOTTED LUNATE SIGMA SYMBOL
+    "\xcd\xbd" => "\xcf\xbf", // GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
+    "\xce\xac" => "\xce\x86", // GREEK SMALL LETTER ALPHA WITH TONOS
+    "\xce\xad" => "\xce\x88", // GREEK SMALL LETTER EPSILON WITH TONOS
+    "\xce\xae" => "\xce\x89", // GREEK SMALL LETTER ETA WITH TONOS
+    "\xce\xaf" => "\xce\x8a", // GREEK SMALL LETTER IOTA WITH TONOS
+    "\xce\xb1" => "\xce\x91", // GREEK SMALL LETTER ALPHA
+    "\xce\xb2" => "\xce\x92", // GREEK SMALL LETTER BETA
+    "\xce\xb3" => "\xce\x93", // GREEK SMALL LETTER GAMMA
+    "\xce\xb4" => "\xce\x94", // GREEK SMALL LETTER DELTA
+    "\xce\xb5" => "\xce\x95", // GREEK SMALL LETTER EPSILON
+    "\xce\xb6" => "\xce\x96", // GREEK SMALL LETTER ZETA
+    "\xce\xb7" => "\xce\x97", // GREEK SMALL LETTER ETA
+    "\xce\xb8" => "\xce\x98", // GREEK SMALL LETTER THETA
+    "\xce\xb9" => "\xce\x99", // GREEK SMALL LETTER IOTA
+    "\xce\xba" => "\xce\x9a", // GREEK SMALL LETTER KAPPA
+    "\xce\xbb" => "\xce\x9b", // GREEK SMALL LETTER LAMDA
+    "\xce\xbc" => "\xce\x9c", // GREEK SMALL LETTER MU
+    "\xce\xbd" => "\xce\x9d", // GREEK SMALL LETTER NU
+    "\xce\xbe" => "\xce\x9e", // GREEK SMALL LETTER XI
+    "\xce\xbf" => "\xce\x9f", // GREEK SMALL LETTER OMICRON
+    "\xcf\x80" => "\xce\xa0", // GREEK SMALL LETTER PI
+    "\xcf\x81" => "\xce\xa1", // GREEK SMALL LETTER RHO
+    "\xcf\x82" => "\xce\xa3", // GREEK SMALL LETTER FINAL SIGMA
+    "\xcf\x83" => "\xce\xa3", // GREEK SMALL LETTER SIGMA
+    "\xcf\x84" => "\xce\xa4", // GREEK SMALL LETTER TAU
+    "\xcf\x85" => "\xce\xa5", // GREEK SMALL LETTER UPSILON
+    "\xcf\x86" => "\xce\xa6", // GREEK SMALL LETTER PHI
+    "\xcf\x87" => "\xce\xa7", // GREEK SMALL LETTER CHI
+    "\xcf\x88" => "\xce\xa8", // GREEK SMALL LETTER PSI
+    "\xcf\x89" => "\xce\xa9", // GREEK SMALL LETTER OMEGA
+    "\xcf\x8a" => "\xce\xaa", // GREEK SMALL LETTER IOTA WITH DIALYTIKA
+    "\xcf\x8b" => "\xce\xab", // GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+    "\xcf\x8c" => "\xce\x8c", // GREEK SMALL LETTER OMICRON WITH TONOS
+    "\xcf\x8d" => "\xce\x8e", // GREEK SMALL LETTER UPSILON WITH TONOS
+    "\xcf\x8e" => "\xce\x8f", // GREEK SMALL LETTER OMEGA WITH TONOS
+    "\xcf\x90" => "\xce\x92", // GREEK BETA SYMBOL
+    "\xcf\x91" => "\xce\x98", // GREEK THETA SYMBOL
+    "\xcf\x95" => "\xce\xa6", // GREEK PHI SYMBOL
+    "\xcf\x96" => "\xce\xa0", // GREEK PI SYMBOL
+    "\xcf\x97" => "\xcf\x8f", // GREEK KAI SYMBOL
+    "\xcf\x99" => "\xcf\x98", // GREEK SMALL LETTER ARCHAIC KOPPA
+    "\xcf\x9b" => "\xcf\x9a", // GREEK SMALL LETTER STIGMA
+    "\xcf\x9d" => "\xcf\x9c", // GREEK SMALL LETTER DIGAMMA
+    "\xcf\x9f" => "\xcf\x9e", // GREEK SMALL LETTER KOPPA
+    "\xcf\xa1" => "\xcf\xa0", // GREEK SMALL LETTER SAMPI
+    "\xcf\xa3" => "\xcf\xa2", // COPTIC SMALL LETTER SHEI
+    "\xcf\xa5" => "\xcf\xa4", // COPTIC SMALL LETTER FEI
+    "\xcf\xa7" => "\xcf\xa6", // COPTIC SMALL LETTER KHEI
+    "\xcf\xa9" => "\xcf\xa8", // COPTIC SMALL LETTER HORI
+    "\xcf\xab" => "\xcf\xaa", // COPTIC SMALL LETTER GANGIA
+    "\xcf\xad" => "\xcf\xac", // COPTIC SMALL LETTER SHIMA
+    "\xcf\xaf" => "\xcf\xae", // COPTIC SMALL LETTER DEI
+    "\xcf\xb0" => "\xce\x9a", // GREEK KAPPA SYMBOL
+    "\xcf\xb1" => "\xce\xa1", // GREEK RHO SYMBOL
+    "\xcf\xb2" => "\xcf\xb9", // GREEK LUNATE SIGMA SYMBOL
+    "\xcf\xb5" => "\xce\x95", // GREEK LUNATE EPSILON SYMBOL
+    "\xcf\xb8" => "\xcf\xb7", // GREEK SMALL LETTER SHO
+    "\xcf\xbb" => "\xcf\xba", // GREEK SMALL LETTER SAN
+    "\xd0\xb0" => "\xd0\x90", // CYRILLIC SMALL LETTER A
+    "\xd0\xb1" => "\xd0\x91", // CYRILLIC SMALL LETTER BE
+    "\xd0\xb2" => "\xd0\x92", // CYRILLIC SMALL LETTER VE
+    "\xd0\xb3" => "\xd0\x93", // CYRILLIC SMALL LETTER GHE
+    "\xd0\xb4" => "\xd0\x94", // CYRILLIC SMALL LETTER DE
+    "\xd0\xb5" => "\xd0\x95", // CYRILLIC SMALL LETTER IE
+    "\xd0\xb6" => "\xd0\x96", // CYRILLIC SMALL LETTER ZHE
+    "\xd0\xb7" => "\xd0\x97", // CYRILLIC SMALL LETTER ZE
+    "\xd0\xb8" => "\xd0\x98", // CYRILLIC SMALL LETTER I
+    "\xd0\xb9" => "\xd0\x99", // CYRILLIC SMALL LETTER SHORT I
+    "\xd0\xba" => "\xd0\x9a", // CYRILLIC SMALL LETTER KA
+    "\xd0\xbb" => "\xd0\x9b", // CYRILLIC SMALL LETTER EL
+    "\xd0\xbc" => "\xd0\x9c", // CYRILLIC SMALL LETTER EM
+    "\xd0\xbd" => "\xd0\x9d", // CYRILLIC SMALL LETTER EN
+    "\xd0\xbe" => "\xd0\x9e", // CYRILLIC SMALL LETTER O
+    "\xd0\xbf" => "\xd0\x9f", // CYRILLIC SMALL LETTER PE
+    "\xd1\x80" => "\xd0\xa0", // CYRILLIC SMALL LETTER ER
+    "\xd1\x81" => "\xd0\xa1", // CYRILLIC SMALL LETTER ES
+    "\xd1\x82" => "\xd0\xa2", // CYRILLIC SMALL LETTER TE
+    "\xd1\x83" => "\xd0\xa3", // CYRILLIC SMALL LETTER U
+    "\xd1\x84" => "\xd0\xa4", // CYRILLIC SMALL LETTER EF
+    "\xd1\x85" => "\xd0\xa5", // CYRILLIC SMALL LETTER HA
+    "\xd1\x86" => "\xd0\xa6", // CYRILLIC SMALL LETTER TSE
+    "\xd1\x87" => "\xd0\xa7", // CYRILLIC SMALL LETTER CHE
+    "\xd1\x88" => "\xd0\xa8", // CYRILLIC SMALL LETTER SHA
+    "\xd1\x89" => "\xd0\xa9", // CYRILLIC SMALL LETTER SHCHA
+    "\xd1\x8a" => "\xd0\xaa", // CYRILLIC SMALL LETTER HARD SIGN
+    "\xd1\x8b" => "\xd0\xab", // CYRILLIC SMALL LETTER YERU
+    "\xd1\x8c" => "\xd0\xac", // CYRILLIC SMALL LETTER SOFT SIGN
+    "\xd1\x8d" => "\xd0\xad", // CYRILLIC SMALL LETTER E
+    "\xd1\x8e" => "\xd0\xae", // CYRILLIC SMALL LETTER YU
+    "\xd1\x8f" => "\xd0\xaf", // CYRILLIC SMALL LETTER YA
+    "\xd1\x90" => "\xd0\x80", // CYRILLIC SMALL LETTER IE WITH GRAVE
+    "\xd1\x91" => "\xd0\x81", // CYRILLIC SMALL LETTER IO
+    "\xd1\x92" => "\xd0\x82", // CYRILLIC SMALL LETTER DJE
+    "\xd1\x93" => "\xd0\x83", // CYRILLIC SMALL LETTER GJE
+    "\xd1\x94" => "\xd0\x84", // CYRILLIC SMALL LETTER UKRAINIAN IE
+    "\xd1\x95" => "\xd0\x85", // CYRILLIC SMALL LETTER DZE
+    "\xd1\x96" => "\xd0\x86", // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+    "\xd1\x97" => "\xd0\x87", // CYRILLIC SMALL LETTER YI
+    "\xd1\x98" => "\xd0\x88", // CYRILLIC SMALL LETTER JE
+    "\xd1\x99" => "\xd0\x89", // CYRILLIC SMALL LETTER LJE
+    "\xd1\x9a" => "\xd0\x8a", // CYRILLIC SMALL LETTER NJE
+    "\xd1\x9b" => "\xd0\x8b", // CYRILLIC SMALL LETTER TSHE
+    "\xd1\x9c" => "\xd0\x8c", // CYRILLIC SMALL LETTER KJE
+    "\xd1\x9d" => "\xd0\x8d", // CYRILLIC SMALL LETTER I WITH GRAVE
+    "\xd1\x9e" => "\xd0\x8e", // CYRILLIC SMALL LETTER SHORT U
+    "\xd1\x9f" => "\xd0\x8f", // CYRILLIC SMALL LETTER DZHE
+    "\xd1\xa1" => "\xd1\xa0", // CYRILLIC SMALL LETTER OMEGA
+    "\xd1\xa3" => "\xd1\xa2", // CYRILLIC SMALL LETTER YAT
+    "\xd1\xa5" => "\xd1\xa4", // CYRILLIC SMALL LETTER IOTIFIED E
+    "\xd1\xa7" => "\xd1\xa6", // CYRILLIC SMALL LETTER LITTLE YUS
+    "\xd1\xa9" => "\xd1\xa8", // CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS
+    "\xd1\xab" => "\xd1\xaa", // CYRILLIC SMALL LETTER BIG YUS
+    "\xd1\xad" => "\xd1\xac", // CYRILLIC SMALL LETTER IOTIFIED BIG YUS
+    "\xd1\xaf" => "\xd1\xae", // CYRILLIC SMALL LETTER KSI
+    "\xd1\xb1" => "\xd1\xb0", // CYRILLIC SMALL LETTER PSI
+    "\xd1\xb3" => "\xd1\xb2", // CYRILLIC SMALL LETTER FITA
+    "\xd1\xb5" => "\xd1\xb4", // CYRILLIC SMALL LETTER IZHITSA
+    "\xd1\xb7" => "\xd1\xb6", // CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+    "\xd1\xb9" => "\xd1\xb8", // CYRILLIC SMALL LETTER UK
+    "\xd1\xbb" => "\xd1\xba", // CYRILLIC SMALL LETTER ROUND OMEGA
+    "\xd1\xbd" => "\xd1\xbc", // CYRILLIC SMALL LETTER OMEGA WITH TITLO
+    "\xd1\xbf" => "\xd1\xbe", // CYRILLIC SMALL LETTER OT
+    "\xd2\x81" => "\xd2\x80", // CYRILLIC SMALL LETTER KOPPA
+    "\xd2\x8b" => "\xd2\x8a", // CYRILLIC SMALL LETTER SHORT I WITH TAIL
+    "\xd2\x8d" => "\xd2\x8c", // CYRILLIC SMALL LETTER SEMISOFT SIGN
+    "\xd2\x8f" => "\xd2\x8e", // CYRILLIC SMALL LETTER ER WITH TICK
+    "\xd2\x91" => "\xd2\x90", // CYRILLIC SMALL LETTER GHE WITH UPTURN
+    "\xd2\x93" => "\xd2\x92", // CYRILLIC SMALL LETTER GHE WITH STROKE
+    "\xd2\x95" => "\xd2\x94", // CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK
+    "\xd2\x97" => "\xd2\x96", // CYRILLIC SMALL LETTER ZHE WITH DESCENDER
+    "\xd2\x99" => "\xd2\x98", // CYRILLIC SMALL LETTER ZE WITH DESCENDER
+    "\xd2\x9b" => "\xd2\x9a", // CYRILLIC SMALL LETTER KA WITH DESCENDER
+    "\xd2\x9d" => "\xd2\x9c", // CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE
+    "\xd2\x9f" => "\xd2\x9e", // CYRILLIC SMALL LETTER KA WITH STROKE
+    "\xd2\xa1" => "\xd2\xa0", // CYRILLIC SMALL LETTER BASHKIR KA
+    "\xd2\xa3" => "\xd2\xa2", // CYRILLIC SMALL LETTER EN WITH DESCENDER
+    "\xd2\xa5" => "\xd2\xa4", // CYRILLIC SMALL LIGATURE EN GHE
+    "\xd2\xa7" => "\xd2\xa6", // CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK
+    "\xd2\xa9" => "\xd2\xa8", // CYRILLIC SMALL LETTER ABKHASIAN HA
+    "\xd2\xab" => "\xd2\xaa", // CYRILLIC SMALL LETTER ES WITH DESCENDER
+    "\xd2\xad" => "\xd2\xac", // CYRILLIC SMALL LETTER TE WITH DESCENDER
+    "\xd2\xaf" => "\xd2\xae", // CYRILLIC SMALL LETTER STRAIGHT U
+    "\xd2\xb1" => "\xd2\xb0", // CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE
+    "\xd2\xb3" => "\xd2\xb2", // CYRILLIC SMALL LETTER HA WITH DESCENDER
+    "\xd2\xb5" => "\xd2\xb4", // CYRILLIC SMALL LIGATURE TE TSE
+    "\xd2\xb7" => "\xd2\xb6", // CYRILLIC SMALL LETTER CHE WITH DESCENDER
+    "\xd2\xb9" => "\xd2\xb8", // CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE
+    "\xd2\xbb" => "\xd2\xba", // CYRILLIC SMALL LETTER SHHA
+    "\xd2\xbd" => "\xd2\xbc", // CYRILLIC SMALL LETTER ABKHASIAN CHE
+    "\xd2\xbf" => "\xd2\xbe", // CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER
+    "\xd3\x82" => "\xd3\x81", // CYRILLIC SMALL LETTER ZHE WITH BREVE
+    "\xd3\x84" => "\xd3\x83", // CYRILLIC SMALL LETTER KA WITH HOOK
+    "\xd3\x86" => "\xd3\x85", // CYRILLIC SMALL LETTER EL WITH TAIL
+    "\xd3\x88" => "\xd3\x87", // CYRILLIC SMALL LETTER EN WITH HOOK
+    "\xd3\x8a" => "\xd3\x89", // CYRILLIC SMALL LETTER EN WITH TAIL
+    "\xd3\x8c" => "\xd3\x8b", // CYRILLIC SMALL LETTER KHAKASSIAN CHE
+    "\xd3\x8e" => "\xd3\x8d", // CYRILLIC SMALL LETTER EM WITH TAIL
+    "\xd3\x8f" => "\xd3\x80", // CYRILLIC SMALL LETTER PALOCHKA
+    "\xd3\x91" => "\xd3\x90", // CYRILLIC SMALL LETTER A WITH BREVE
+    "\xd3\x93" => "\xd3\x92", // CYRILLIC SMALL LETTER A WITH DIAERESIS
+    "\xd3\x95" => "\xd3\x94", // CYRILLIC SMALL LIGATURE A IE
+    "\xd3\x97" => "\xd3\x96", // CYRILLIC SMALL LETTER IE WITH BREVE
+    "\xd3\x99" => "\xd3\x98", // CYRILLIC SMALL LETTER SCHWA
+    "\xd3\x9b" => "\xd3\x9a", // CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS
+    "\xd3\x9d" => "\xd3\x9c", // CYRILLIC SMALL LETTER ZHE WITH DIAERESIS
+    "\xd3\x9f" => "\xd3\x9e", // CYRILLIC SMALL LETTER ZE WITH DIAERESIS
+    "\xd3\xa1" => "\xd3\xa0", // CYRILLIC SMALL LETTER ABKHASIAN DZE
+    "\xd3\xa3" => "\xd3\xa2", // CYRILLIC SMALL LETTER I WITH MACRON
+    "\xd3\xa5" => "\xd3\xa4", // CYRILLIC SMALL LETTER I WITH DIAERESIS
+    "\xd3\xa7" => "\xd3\xa6", // CYRILLIC SMALL LETTER O WITH DIAERESIS
+    "\xd3\xa9" => "\xd3\xa8", // CYRILLIC SMALL LETTER BARRED O
+    "\xd3\xab" => "\xd3\xaa", // CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS
+    "\xd3\xad" => "\xd3\xac", // CYRILLIC SMALL LETTER E WITH DIAERESIS
+    "\xd3\xaf" => "\xd3\xae", // CYRILLIC SMALL LETTER U WITH MACRON
+    "\xd3\xb1" => "\xd3\xb0", // CYRILLIC SMALL LETTER U WITH DIAERESIS
+    "\xd3\xb3" => "\xd3\xb2", // CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE
+    "\xd3\xb5" => "\xd3\xb4", // CYRILLIC SMALL LETTER CHE WITH DIAERESIS
+    "\xd3\xb7" => "\xd3\xb6", // CYRILLIC SMALL LETTER GHE WITH DESCENDER
+    "\xd3\xb9" => "\xd3\xb8", // CYRILLIC SMALL LETTER YERU WITH DIAERESIS
+    "\xd3\xbb" => "\xd3\xba", // CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK
+    "\xd3\xbd" => "\xd3\xbc", // CYRILLIC SMALL LETTER HA WITH HOOK
+    "\xd3\xbf" => "\xd3\xbe", // CYRILLIC SMALL LETTER HA WITH STROKE
+    "\xd4\x81" => "\xd4\x80", // CYRILLIC SMALL LETTER KOMI DE
+    "\xd4\x83" => "\xd4\x82", // CYRILLIC SMALL LETTER KOMI DJE
+    "\xd4\x85" => "\xd4\x84", // CYRILLIC SMALL LETTER KOMI ZJE
+    "\xd4\x87" => "\xd4\x86", // CYRILLIC SMALL LETTER KOMI DZJE
+    "\xd4\x89" => "\xd4\x88", // CYRILLIC SMALL LETTER KOMI LJE
+    "\xd4\x8b" => "\xd4\x8a", // CYRILLIC SMALL LETTER KOMI NJE
+    "\xd4\x8d" => "\xd4\x8c", // CYRILLIC SMALL LETTER KOMI SJE
+    "\xd4\x8f" => "\xd4\x8e", // CYRILLIC SMALL LETTER KOMI TJE
+    "\xd4\x91" => "\xd4\x90", // CYRILLIC SMALL LETTER REVERSED ZE
+    "\xd4\x93" => "\xd4\x92", // CYRILLIC SMALL LETTER EL WITH HOOK
+    "\xd4\x95" => "\xd4\x94", // CYRILLIC SMALL LETTER LHA
+    "\xd4\x97" => "\xd4\x96", // CYRILLIC SMALL LETTER RHA
+    "\xd4\x99" => "\xd4\x98", // CYRILLIC SMALL LETTER YAE
+    "\xd4\x9b" => "\xd4\x9a", // CYRILLIC SMALL LETTER QA
+    "\xd4\x9d" => "\xd4\x9c", // CYRILLIC SMALL LETTER WE
+    "\xd4\x9f" => "\xd4\x9e", // CYRILLIC SMALL LETTER ALEUT KA
+    "\xd4\xa1" => "\xd4\xa0", // CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK
+    "\xd4\xa3" => "\xd4\xa2", // CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK
+    "\xd4\xa5" => "\xd4\xa4", // CYRILLIC SMALL LETTER PE WITH DESCENDER
+    "\xd4\xa7" => "\xd4\xa6", // CYRILLIC SMALL LETTER SHHA WITH DESCENDER
+    "\xd5\xa1" => "\xd4\xb1", // ARMENIAN SMALL LETTER AYB
+    "\xd5\xa2" => "\xd4\xb2", // ARMENIAN SMALL LETTER BEN
+    "\xd5\xa3" => "\xd4\xb3", // ARMENIAN SMALL LETTER GIM
+    "\xd5\xa4" => "\xd4\xb4", // ARMENIAN SMALL LETTER DA
+    "\xd5\xa5" => "\xd4\xb5", // ARMENIAN SMALL LETTER ECH
+    "\xd5\xa6" => "\xd4\xb6", // ARMENIAN SMALL LETTER ZA
+    "\xd5\xa7" => "\xd4\xb7", // ARMENIAN SMALL LETTER EH
+    "\xd5\xa8" => "\xd4\xb8", // ARMENIAN SMALL LETTER ET
+    "\xd5\xa9" => "\xd4\xb9", // ARMENIAN SMALL LETTER TO
+    "\xd5\xaa" => "\xd4\xba", // ARMENIAN SMALL LETTER ZHE
+    "\xd5\xab" => "\xd4\xbb", // ARMENIAN SMALL LETTER INI
+    "\xd5\xac" => "\xd4\xbc", // ARMENIAN SMALL LETTER LIWN
+    "\xd5\xad" => "\xd4\xbd", // ARMENIAN SMALL LETTER XEH
+    "\xd5\xae" => "\xd4\xbe", // ARMENIAN SMALL LETTER CA
+    "\xd5\xaf" => "\xd4\xbf", // ARMENIAN SMALL LETTER KEN
+    "\xd5\xb0" => "\xd5\x80", // ARMENIAN SMALL LETTER HO
+    "\xd5\xb1" => "\xd5\x81", // ARMENIAN SMALL LETTER JA
+    "\xd5\xb2" => "\xd5\x82", // ARMENIAN SMALL LETTER GHAD
+    "\xd5\xb3" => "\xd5\x83", // ARMENIAN SMALL LETTER CHEH
+    "\xd5\xb4" => "\xd5\x84", // ARMENIAN SMALL LETTER MEN
+    "\xd5\xb5" => "\xd5\x85", // ARMENIAN SMALL LETTER YI
+    "\xd5\xb6" => "\xd5\x86", // ARMENIAN SMALL LETTER NOW
+    "\xd5\xb7" => "\xd5\x87", // ARMENIAN SMALL LETTER SHA
+    "\xd5\xb8" => "\xd5\x88", // ARMENIAN SMALL LETTER VO
+    "\xd5\xb9" => "\xd5\x89", // ARMENIAN SMALL LETTER CHA
+    "\xd5\xba" => "\xd5\x8a", // ARMENIAN SMALL LETTER PEH
+    "\xd5\xbb" => "\xd5\x8b", // ARMENIAN SMALL LETTER JHEH
+    "\xd5\xbc" => "\xd5\x8c", // ARMENIAN SMALL LETTER RA
+    "\xd5\xbd" => "\xd5\x8d", // ARMENIAN SMALL LETTER SEH
+    "\xd5\xbe" => "\xd5\x8e", // ARMENIAN SMALL LETTER VEW
+    "\xd5\xbf" => "\xd5\x8f", // ARMENIAN SMALL LETTER TIWN
+    "\xd6\x80" => "\xd5\x90", // ARMENIAN SMALL LETTER REH
+    "\xd6\x81" => "\xd5\x91", // ARMENIAN SMALL LETTER CO
+    "\xd6\x82" => "\xd5\x92", // ARMENIAN SMALL LETTER YIWN
+    "\xd6\x83" => "\xd5\x93", // ARMENIAN SMALL LETTER PIWR
+    "\xd6\x84" => "\xd5\x94", // ARMENIAN SMALL LETTER KEH
+    "\xd6\x85" => "\xd5\x95", // ARMENIAN SMALL LETTER OH
+    "\xd6\x86" => "\xd5\x96", // ARMENIAN SMALL LETTER FEH
+    "\xe1\xb5\xb9" => "\xea\x9d\xbd", // LATIN SMALL LETTER INSULAR G
+    "\xe1\xb5\xbd" => "\xe2\xb1\xa3", // LATIN SMALL LETTER P WITH STROKE
+    "\xe1\xb8\x81" => "\xe1\xb8\x80", // LATIN SMALL LETTER A WITH RING BELOW
+    "\xe1\xb8\x83" => "\xe1\xb8\x82", // LATIN SMALL LETTER B WITH DOT ABOVE
+    "\xe1\xb8\x85" => "\xe1\xb8\x84", // LATIN SMALL LETTER B WITH DOT BELOW
+    "\xe1\xb8\x87" => "\xe1\xb8\x86", // LATIN SMALL LETTER B WITH LINE BELOW
+    "\xe1\xb8\x89" => "\xe1\xb8\x88", // LATIN SMALL LETTER C WITH CEDILLA AND ACUTE
+    "\xe1\xb8\x8b" => "\xe1\xb8\x8a", // LATIN SMALL LETTER D WITH DOT ABOVE
+    "\xe1\xb8\x8d" => "\xe1\xb8\x8c", // LATIN SMALL LETTER D WITH DOT BELOW
+    "\xe1\xb8\x8f" => "\xe1\xb8\x8e", // LATIN SMALL LETTER D WITH LINE BELOW
+    "\xe1\xb8\x91" => "\xe1\xb8\x90", // LATIN SMALL LETTER D WITH CEDILLA
+    "\xe1\xb8\x93" => "\xe1\xb8\x92", // LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW
+    "\xe1\xb8\x95" => "\xe1\xb8\x94", // LATIN SMALL LETTER E WITH MACRON AND GRAVE
+    "\xe1\xb8\x97" => "\xe1\xb8\x96", // LATIN SMALL LETTER E WITH MACRON AND ACUTE
+    "\xe1\xb8\x99" => "\xe1\xb8\x98", // LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW
+    "\xe1\xb8\x9b" => "\xe1\xb8\x9a", // LATIN SMALL LETTER E WITH TILDE BELOW
+    "\xe1\xb8\x9d" => "\xe1\xb8\x9c", // LATIN SMALL LETTER E WITH CEDILLA AND BREVE
+    "\xe1\xb8\x9f" => "\xe1\xb8\x9e", // LATIN SMALL LETTER F WITH DOT ABOVE
+    "\xe1\xb8\xa1" => "\xe1\xb8\xa0", // LATIN SMALL LETTER G WITH MACRON
+    "\xe1\xb8\xa3" => "\xe1\xb8\xa2", // LATIN SMALL LETTER H WITH DOT ABOVE
+    "\xe1\xb8\xa5" => "\xe1\xb8\xa4", // LATIN SMALL LETTER H WITH DOT BELOW
+    "\xe1\xb8\xa7" => "\xe1\xb8\xa6", // LATIN SMALL LETTER H WITH DIAERESIS
+    "\xe1\xb8\xa9" => "\xe1\xb8\xa8", // LATIN SMALL LETTER H WITH CEDILLA
+    "\xe1\xb8\xab" => "\xe1\xb8\xaa", // LATIN SMALL LETTER H WITH BREVE BELOW
+    "\xe1\xb8\xad" => "\xe1\xb8\xac", // LATIN SMALL LETTER I WITH TILDE BELOW
+    "\xe1\xb8\xaf" => "\xe1\xb8\xae", // LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE
+    "\xe1\xb8\xb1" => "\xe1\xb8\xb0", // LATIN SMALL LETTER K WITH ACUTE
+    "\xe1\xb8\xb3" => "\xe1\xb8\xb2", // LATIN SMALL LETTER K WITH DOT BELOW
+    "\xe1\xb8\xb5" => "\xe1\xb8\xb4", // LATIN SMALL LETTER K WITH LINE BELOW
+    "\xe1\xb8\xb7" => "\xe1\xb8\xb6", // LATIN SMALL LETTER L WITH DOT BELOW
+    "\xe1\xb8\xb9" => "\xe1\xb8\xb8", // LATIN SMALL LETTER L WITH DOT BELOW AND MACRON
+    "\xe1\xb8\xbb" => "\xe1\xb8\xba", // LATIN SMALL LETTER L WITH LINE BELOW
+    "\xe1\xb8\xbd" => "\xe1\xb8\xbc", // LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW
+    "\xe1\xb8\xbf" => "\xe1\xb8\xbe", // LATIN SMALL LETTER M WITH ACUTE
+    "\xe1\xb9\x81" => "\xe1\xb9\x80", // LATIN SMALL LETTER M WITH DOT ABOVE
+    "\xe1\xb9\x83" => "\xe1\xb9\x82", // LATIN SMALL LETTER M WITH DOT BELOW
+    "\xe1\xb9\x85" => "\xe1\xb9\x84", // LATIN SMALL LETTER N WITH DOT ABOVE
+    "\xe1\xb9\x87" => "\xe1\xb9\x86", // LATIN SMALL LETTER N WITH DOT BELOW
+    "\xe1\xb9\x89" => "\xe1\xb9\x88", // LATIN SMALL LETTER N WITH LINE BELOW
+    "\xe1\xb9\x8b" => "\xe1\xb9\x8a", // LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW
+    "\xe1\xb9\x8d" => "\xe1\xb9\x8c", // LATIN SMALL LETTER O WITH TILDE AND ACUTE
+    "\xe1\xb9\x8f" => "\xe1\xb9\x8e", // LATIN SMALL LETTER O WITH TILDE AND DIAERESIS
+    "\xe1\xb9\x91" => "\xe1\xb9\x90", // LATIN SMALL LETTER O WITH MACRON AND GRAVE
+    "\xe1\xb9\x93" => "\xe1\xb9\x92", // LATIN SMALL LETTER O WITH MACRON AND ACUTE
+    "\xe1\xb9\x95" => "\xe1\xb9\x94", // LATIN SMALL LETTER P WITH ACUTE
+    "\xe1\xb9\x97" => "\xe1\xb9\x96", // LATIN SMALL LETTER P WITH DOT ABOVE
+    "\xe1\xb9\x99" => "\xe1\xb9\x98", // LATIN SMALL LETTER R WITH DOT ABOVE
+    "\xe1\xb9\x9b" => "\xe1\xb9\x9a", // LATIN SMALL LETTER R WITH DOT BELOW
+    "\xe1\xb9\x9d" => "\xe1\xb9\x9c", // LATIN SMALL LETTER R WITH DOT BELOW AND MACRON
+    "\xe1\xb9\x9f" => "\xe1\xb9\x9e", // LATIN SMALL LETTER R WITH LINE BELOW
+    "\xe1\xb9\xa1" => "\xe1\xb9\xa0", // LATIN SMALL LETTER S WITH DOT ABOVE
+    "\xe1\xb9\xa3" => "\xe1\xb9\xa2", // LATIN SMALL LETTER S WITH DOT BELOW
+    "\xe1\xb9\xa5" => "\xe1\xb9\xa4", // LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE
+    "\xe1\xb9\xa7" => "\xe1\xb9\xa6", // LATIN SMALL LETTER S WITH CARON AND DOT ABOVE
+    "\xe1\xb9\xa9" => "\xe1\xb9\xa8", // LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE
+    "\xe1\xb9\xab" => "\xe1\xb9\xaa", // LATIN SMALL LETTER T WITH DOT ABOVE
+    "\xe1\xb9\xad" => "\xe1\xb9\xac", // LATIN SMALL LETTER T WITH DOT BELOW
+    "\xe1\xb9\xaf" => "\xe1\xb9\xae", // LATIN SMALL LETTER T WITH LINE BELOW
+    "\xe1\xb9\xb1" => "\xe1\xb9\xb0", // LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW
+    "\xe1\xb9\xb3" => "\xe1\xb9\xb2", // LATIN SMALL LETTER U WITH DIAERESIS BELOW
+    "\xe1\xb9\xb5" => "\xe1\xb9\xb4", // LATIN SMALL LETTER U WITH TILDE BELOW
+    "\xe1\xb9\xb7" => "\xe1\xb9\xb6", // LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW
+    "\xe1\xb9\xb9" => "\xe1\xb9\xb8", // LATIN SMALL LETTER U WITH TILDE AND ACUTE
+    "\xe1\xb9\xbb" => "\xe1\xb9\xba", // LATIN SMALL LETTER U WITH MACRON AND DIAERESIS
+    "\xe1\xb9\xbd" => "\xe1\xb9\xbc", // LATIN SMALL LETTER V WITH TILDE
+    "\xe1\xb9\xbf" => "\xe1\xb9\xbe", // LATIN SMALL LETTER V WITH DOT BELOW
+    "\xe1\xba\x81" => "\xe1\xba\x80", // LATIN SMALL LETTER W WITH GRAVE
+    "\xe1\xba\x83" => "\xe1\xba\x82", // LATIN SMALL LETTER W WITH ACUTE
+    "\xe1\xba\x85" => "\xe1\xba\x84", // LATIN SMALL LETTER W WITH DIAERESIS
+    "\xe1\xba\x87" => "\xe1\xba\x86", // LATIN SMALL LETTER W WITH DOT ABOVE
+    "\xe1\xba\x89" => "\xe1\xba\x88", // LATIN SMALL LETTER W WITH DOT BELOW
+    "\xe1\xba\x8b" => "\xe1\xba\x8a", // LATIN SMALL LETTER X WITH DOT ABOVE
+    "\xe1\xba\x8d" => "\xe1\xba\x8c", // LATIN SMALL LETTER X WITH DIAERESIS
+    "\xe1\xba\x8f" => "\xe1\xba\x8e", // LATIN SMALL LETTER Y WITH DOT ABOVE
+    "\xe1\xba\x91" => "\xe1\xba\x90", // LATIN SMALL LETTER Z WITH CIRCUMFLEX
+    "\xe1\xba\x93" => "\xe1\xba\x92", // LATIN SMALL LETTER Z WITH DOT BELOW
+    "\xe1\xba\x95" => "\xe1\xba\x94", // LATIN SMALL LETTER Z WITH LINE BELOW
+    "\xe1\xba\x9b" => "\xe1\xb9\xa0", // LATIN SMALL LETTER LONG S WITH DOT ABOVE
+    "\xe1\xba\xa1" => "\xe1\xba\xa0", // LATIN SMALL LETTER A WITH DOT BELOW
+    "\xe1\xba\xa3" => "\xe1\xba\xa2", // LATIN SMALL LETTER A WITH HOOK ABOVE
+    "\xe1\xba\xa5" => "\xe1\xba\xa4", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE
+    "\xe1\xba\xa7" => "\xe1\xba\xa6", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE
+    "\xe1\xba\xa9" => "\xe1\xba\xa8", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+    "\xe1\xba\xab" => "\xe1\xba\xaa", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE
+    "\xe1\xba\xad" => "\xe1\xba\xac", // LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+    "\xe1\xba\xaf" => "\xe1\xba\xae", // LATIN SMALL LETTER A WITH BREVE AND ACUTE
+    "\xe1\xba\xb1" => "\xe1\xba\xb0", // LATIN SMALL LETTER A WITH BREVE AND GRAVE
+    "\xe1\xba\xb3" => "\xe1\xba\xb2", // LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE
+    "\xe1\xba\xb5" => "\xe1\xba\xb4", // LATIN SMALL LETTER A WITH BREVE AND TILDE
+    "\xe1\xba\xb7" => "\xe1\xba\xb6", // LATIN SMALL LETTER A WITH BREVE AND DOT BELOW
+    "\xe1\xba\xb9" => "\xe1\xba\xb8", // LATIN SMALL LETTER E WITH DOT BELOW
+    "\xe1\xba\xbb" => "\xe1\xba\xba", // LATIN SMALL LETTER E WITH HOOK ABOVE
+    "\xe1\xba\xbd" => "\xe1\xba\xbc", // LATIN SMALL LETTER E WITH TILDE
+    "\xe1\xba\xbf" => "\xe1\xba\xbe", // LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE
+    "\xe1\xbb\x81" => "\xe1\xbb\x80", // LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE
+    "\xe1\xbb\x83" => "\xe1\xbb\x82", // LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+    "\xe1\xbb\x85" => "\xe1\xbb\x84", // LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE
+    "\xe1\xbb\x87" => "\xe1\xbb\x86", // LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+    "\xe1\xbb\x89" => "\xe1\xbb\x88", // LATIN SMALL LETTER I WITH HOOK ABOVE
+    "\xe1\xbb\x8b" => "\xe1\xbb\x8a", // LATIN SMALL LETTER I WITH DOT BELOW
+    "\xe1\xbb\x8d" => "\xe1\xbb\x8c", // LATIN SMALL LETTER O WITH DOT BELOW
+    "\xe1\xbb\x8f" => "\xe1\xbb\x8e", // LATIN SMALL LETTER O WITH HOOK ABOVE
+    "\xe1\xbb\x91" => "\xe1\xbb\x90", // LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE
+    "\xe1\xbb\x93" => "\xe1\xbb\x92", // LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE
+    "\xe1\xbb\x95" => "\xe1\xbb\x94", // LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+    "\xe1\xbb\x97" => "\xe1\xbb\x96", // LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE
+    "\xe1\xbb\x99" => "\xe1\xbb\x98", // LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+    "\xe1\xbb\x9b" => "\xe1\xbb\x9a", // LATIN SMALL LETTER O WITH HORN AND ACUTE
+    "\xe1\xbb\x9d" => "\xe1\xbb\x9c", // LATIN SMALL LETTER O WITH HORN AND GRAVE
+    "\xe1\xbb\x9f" => "\xe1\xbb\x9e", // LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE
+    "\xe1\xbb\xa1" => "\xe1\xbb\xa0", // LATIN SMALL LETTER O WITH HORN AND TILDE
+    "\xe1\xbb\xa3" => "\xe1\xbb\xa2", // LATIN SMALL LETTER O WITH HORN AND DOT BELOW
+    "\xe1\xbb\xa5" => "\xe1\xbb\xa4", // LATIN SMALL LETTER U WITH DOT BELOW
+    "\xe1\xbb\xa7" => "\xe1\xbb\xa6", // LATIN SMALL LETTER U WITH HOOK ABOVE
+    "\xe1\xbb\xa9" => "\xe1\xbb\xa8", // LATIN SMALL LETTER U WITH HORN AND ACUTE
+    "\xe1\xbb\xab" => "\xe1\xbb\xaa", // LATIN SMALL LETTER U WITH HORN AND GRAVE
+    "\xe1\xbb\xad" => "\xe1\xbb\xac", // LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE
+    "\xe1\xbb\xaf" => "\xe1\xbb\xae", // LATIN SMALL LETTER U WITH HORN AND TILDE
+    "\xe1\xbb\xb1" => "\xe1\xbb\xb0", // LATIN SMALL LETTER U WITH HORN AND DOT BELOW
+    "\xe1\xbb\xb3" => "\xe1\xbb\xb2", // LATIN SMALL LETTER Y WITH GRAVE
+    "\xe1\xbb\xb5" => "\xe1\xbb\xb4", // LATIN SMALL LETTER Y WITH DOT BELOW
+    "\xe1\xbb\xb7" => "\xe1\xbb\xb6", // LATIN SMALL LETTER Y WITH HOOK ABOVE
+    "\xe1\xbb\xb9" => "\xe1\xbb\xb8", // LATIN SMALL LETTER Y WITH TILDE
+    "\xe1\xbb\xbb" => "\xe1\xbb\xba", // LATIN SMALL LETTER MIDDLE-WELSH LL
+    "\xe1\xbb\xbd" => "\xe1\xbb\xbc", // LATIN SMALL LETTER MIDDLE-WELSH V
+    "\xe1\xbb\xbf" => "\xe1\xbb\xbe", // LATIN SMALL LETTER Y WITH LOOP
+    "\xe1\xbc\x80" => "\xe1\xbc\x88", // GREEK SMALL LETTER ALPHA WITH PSILI
+    "\xe1\xbc\x81" => "\xe1\xbc\x89", // GREEK SMALL LETTER ALPHA WITH DASIA
+    "\xe1\xbc\x82" => "\xe1\xbc\x8a", // GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA
+    "\xe1\xbc\x83" => "\xe1\xbc\x8b", // GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA
+    "\xe1\xbc\x84" => "\xe1\xbc\x8c", // GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA
+    "\xe1\xbc\x85" => "\xe1\xbc\x8d", // GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA
+    "\xe1\xbc\x86" => "\xe1\xbc\x8e", // GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI
+    "\xe1\xbc\x87" => "\xe1\xbc\x8f", // GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI
+    "\xe1\xbc\x90" => "\xe1\xbc\x98", // GREEK SMALL LETTER EPSILON WITH PSILI
+    "\xe1\xbc\x91" => "\xe1\xbc\x99", // GREEK SMALL LETTER EPSILON WITH DASIA
+    "\xe1\xbc\x92" => "\xe1\xbc\x9a", // GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA
+    "\xe1\xbc\x93" => "\xe1\xbc\x9b", // GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA
+    "\xe1\xbc\x94" => "\xe1\xbc\x9c", // GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA
+    "\xe1\xbc\x95" => "\xe1\xbc\x9d", // GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+    "\xe1\xbc\xa0" => "\xe1\xbc\xa8", // GREEK SMALL LETTER ETA WITH PSILI
+    "\xe1\xbc\xa1" => "\xe1\xbc\xa9", // GREEK SMALL LETTER ETA WITH DASIA
+    "\xe1\xbc\xa2" => "\xe1\xbc\xaa", // GREEK SMALL LETTER ETA WITH PSILI AND VARIA
+    "\xe1\xbc\xa3" => "\xe1\xbc\xab", // GREEK SMALL LETTER ETA WITH DASIA AND VARIA
+    "\xe1\xbc\xa4" => "\xe1\xbc\xac", // GREEK SMALL LETTER ETA WITH PSILI AND OXIA
+    "\xe1\xbc\xa5" => "\xe1\xbc\xad", // GREEK SMALL LETTER ETA WITH DASIA AND OXIA
+    "\xe1\xbc\xa6" => "\xe1\xbc\xae", // GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI
+    "\xe1\xbc\xa7" => "\xe1\xbc\xaf", // GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI
+    "\xe1\xbc\xb0" => "\xe1\xbc\xb8", // GREEK SMALL LETTER IOTA WITH PSILI
+    "\xe1\xbc\xb1" => "\xe1\xbc\xb9", // GREEK SMALL LETTER IOTA WITH DASIA
+    "\xe1\xbc\xb2" => "\xe1\xbc\xba", // GREEK SMALL LETTER IOTA WITH PSILI AND VARIA
+    "\xe1\xbc\xb3" => "\xe1\xbc\xbb", // GREEK SMALL LETTER IOTA WITH DASIA AND VARIA
+    "\xe1\xbc\xb4" => "\xe1\xbc\xbc", // GREEK SMALL LETTER IOTA WITH PSILI AND OXIA
+    "\xe1\xbc\xb5" => "\xe1\xbc\xbd", // GREEK SMALL LETTER IOTA WITH DASIA AND OXIA
+    "\xe1\xbc\xb6" => "\xe1\xbc\xbe", // GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI
+    "\xe1\xbc\xb7" => "\xe1\xbc\xbf", // GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI
+    "\xe1\xbd\x80" => "\xe1\xbd\x88", // GREEK SMALL LETTER OMICRON WITH PSILI
+    "\xe1\xbd\x81" => "\xe1\xbd\x89", // GREEK SMALL LETTER OMICRON WITH DASIA
+    "\xe1\xbd\x82" => "\xe1\xbd\x8a", // GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA
+    "\xe1\xbd\x83" => "\xe1\xbd\x8b", // GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA
+    "\xe1\xbd\x84" => "\xe1\xbd\x8c", // GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA
+    "\xe1\xbd\x85" => "\xe1\xbd\x8d", // GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+    "\xe1\xbd\x91" => "\xe1\xbd\x99", // GREEK SMALL LETTER UPSILON WITH DASIA
+    "\xe1\xbd\x93" => "\xe1\xbd\x9b", // GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA
+    "\xe1\xbd\x95" => "\xe1\xbd\x9d", // GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA
+    "\xe1\xbd\x97" => "\xe1\xbd\x9f", // GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+    "\xe1\xbd\xa0" => "\xe1\xbd\xa8", // GREEK SMALL LETTER OMEGA WITH PSILI
+    "\xe1\xbd\xa1" => "\xe1\xbd\xa9", // GREEK SMALL LETTER OMEGA WITH DASIA
+    "\xe1\xbd\xa2" => "\xe1\xbd\xaa", // GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA
+    "\xe1\xbd\xa3" => "\xe1\xbd\xab", // GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA
+    "\xe1\xbd\xa4" => "\xe1\xbd\xac", // GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA
+    "\xe1\xbd\xa5" => "\xe1\xbd\xad", // GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA
+    "\xe1\xbd\xa6" => "\xe1\xbd\xae", // GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI
+    "\xe1\xbd\xa7" => "\xe1\xbd\xaf", // GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI
+    "\xe1\xbd\xb0" => "\xe1\xbe\xba", // GREEK SMALL LETTER ALPHA WITH VARIA
+    "\xe1\xbd\xb1" => "\xe1\xbe\xbb", // GREEK SMALL LETTER ALPHA WITH OXIA
+    "\xe1\xbd\xb2" => "\xe1\xbf\x88", // GREEK SMALL LETTER EPSILON WITH VARIA
+    "\xe1\xbd\xb3" => "\xe1\xbf\x89", // GREEK SMALL LETTER EPSILON WITH OXIA
+    "\xe1\xbd\xb4" => "\xe1\xbf\x8a", // GREEK SMALL LETTER ETA WITH VARIA
+    "\xe1\xbd\xb5" => "\xe1\xbf\x8b", // GREEK SMALL LETTER ETA WITH OXIA
+    "\xe1\xbd\xb6" => "\xe1\xbf\x9a", // GREEK SMALL LETTER IOTA WITH VARIA
+    "\xe1\xbd\xb7" => "\xe1\xbf\x9b", // GREEK SMALL LETTER IOTA WITH OXIA
+    "\xe1\xbd\xb8" => "\xe1\xbf\xb8", // GREEK SMALL LETTER OMICRON WITH VARIA
+    "\xe1\xbd\xb9" => "\xe1\xbf\xb9", // GREEK SMALL LETTER OMICRON WITH OXIA
+    "\xe1\xbd\xba" => "\xe1\xbf\xaa", // GREEK SMALL LETTER UPSILON WITH VARIA
+    "\xe1\xbd\xbb" => "\xe1\xbf\xab", // GREEK SMALL LETTER UPSILON WITH OXIA
+    "\xe1\xbd\xbc" => "\xe1\xbf\xba", // GREEK SMALL LETTER OMEGA WITH VARIA
+    "\xe1\xbd\xbd" => "\xe1\xbf\xbb", // GREEK SMALL LETTER OMEGA WITH OXIA
+    "\xe1\xbe\x80" => "\xe1\xbe\x88", // GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
+    "\xe1\xbe\x81" => "\xe1\xbe\x89", // GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x82" => "\xe1\xbe\x8a", // GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x83" => "\xe1\xbe\x8b", // GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x84" => "\xe1\xbe\x8c", // GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x85" => "\xe1\xbe\x8d", // GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x86" => "\xe1\xbe\x8e", // GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+    "\xe1\xbe\x87" => "\xe1\xbe\x8f", // GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+    "\xe1\xbe\x90" => "\xe1\xbe\x98", // GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
+    "\xe1\xbe\x91" => "\xe1\xbe\x99", // GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x92" => "\xe1\xbe\x9a", // GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x93" => "\xe1\xbe\x9b", // GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x94" => "\xe1\xbe\x9c", // GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x95" => "\xe1\xbe\x9d", // GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+    "\xe1\xbe\x96" => "\xe1\xbe\x9e", // GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+    "\xe1\xbe\x97" => "\xe1\xbe\x9f", // GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+    "\xe1\xbe\xa0" => "\xe1\xbe\xa8", // GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
+    "\xe1\xbe\xa1" => "\xe1\xbe\xa9", // GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
+    "\xe1\xbe\xa2" => "\xe1\xbe\xaa", // GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+    "\xe1\xbe\xa3" => "\xe1\xbe\xab", // GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+    "\xe1\xbe\xa4" => "\xe1\xbe\xac", // GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+    "\xe1\xbe\xa5" => "\xe1\xbe\xad", // GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+    "\xe1\xbe\xa6" => "\xe1\xbe\xae", // GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+    "\xe1\xbe\xa7" => "\xe1\xbe\xaf", // GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+    "\xe1\xbe\xb0" => "\xe1\xbe\xb8", // GREEK SMALL LETTER ALPHA WITH VRACHY
+    "\xe1\xbe\xb1" => "\xe1\xbe\xb9", // GREEK SMALL LETTER ALPHA WITH MACRON
+    "\xe1\xbe\xb3" => "\xe1\xbe\xbc", // GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
+    "\xe1\xbe\xbe" => "\xce\x99", // GREEK PROSGEGRAMMENI
+    "\xe1\xbf\x83" => "\xe1\xbf\x8c", // GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
+    "\xe1\xbf\x90" => "\xe1\xbf\x98", // GREEK SMALL LETTER IOTA WITH VRACHY
+    "\xe1\xbf\x91" => "\xe1\xbf\x99", // GREEK SMALL LETTER IOTA WITH MACRON
+    "\xe1\xbf\xa0" => "\xe1\xbf\xa8", // GREEK SMALL LETTER UPSILON WITH VRACHY
+    "\xe1\xbf\xa1" => "\xe1\xbf\xa9", // GREEK SMALL LETTER UPSILON WITH MACRON
+    "\xe1\xbf\xa5" => "\xe1\xbf\xac", // GREEK SMALL LETTER RHO WITH DASIA
+    "\xe1\xbf\xb3" => "\xe1\xbf\xbc", // GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
+    "\xe2\x85\x8e" => "\xe2\x84\xb2", // TURNED SMALL F
+    "\xe2\x85\xb0" => "\xe2\x85\xa0", // SMALL ROMAN NUMERAL ONE
+    "\xe2\x85\xb1" => "\xe2\x85\xa1", // SMALL ROMAN NUMERAL TWO
+    "\xe2\x85\xb2" => "\xe2\x85\xa2", // SMALL ROMAN NUMERAL THREE
+    "\xe2\x85\xb3" => "\xe2\x85\xa3", // SMALL ROMAN NUMERAL FOUR
+    "\xe2\x85\xb4" => "\xe2\x85\xa4", // SMALL ROMAN NUMERAL FIVE
+    "\xe2\x85\xb5" => "\xe2\x85\xa5", // SMALL ROMAN NUMERAL SIX
+    "\xe2\x85\xb6" => "\xe2\x85\xa6", // SMALL ROMAN NUMERAL SEVEN
+    "\xe2\x85\xb7" => "\xe2\x85\xa7", // SMALL ROMAN NUMERAL EIGHT
+    "\xe2\x85\xb8" => "\xe2\x85\xa8", // SMALL ROMAN NUMERAL NINE
+    "\xe2\x85\xb9" => "\xe2\x85\xa9", // SMALL ROMAN NUMERAL TEN
+    "\xe2\x85\xba" => "\xe2\x85\xaa", // SMALL ROMAN NUMERAL ELEVEN
+    "\xe2\x85\xbb" => "\xe2\x85\xab", // SMALL ROMAN NUMERAL TWELVE
+    "\xe2\x85\xbc" => "\xe2\x85\xac", // SMALL ROMAN NUMERAL FIFTY
+    "\xe2\x85\xbd" => "\xe2\x85\xad", // SMALL ROMAN NUMERAL ONE HUNDRED
+    "\xe2\x85\xbe" => "\xe2\x85\xae", // SMALL ROMAN NUMERAL FIVE HUNDRED
+    "\xe2\x85\xbf" => "\xe2\x85\xaf", // SMALL ROMAN NUMERAL ONE THOUSAND
+    "\xe2\x86\x84" => "\xe2\x86\x83", // LATIN SMALL LETTER REVERSED C
+    "\xe2\x93\x90" => "\xe2\x92\xb6", // CIRCLED LATIN SMALL LETTER A
+    "\xe2\x93\x91" => "\xe2\x92\xb7", // CIRCLED LATIN SMALL LETTER B
+    "\xe2\x93\x92" => "\xe2\x92\xb8", // CIRCLED LATIN SMALL LETTER C
+    "\xe2\x93\x93" => "\xe2\x92\xb9", // CIRCLED LATIN SMALL LETTER D
+    "\xe2\x93\x94" => "\xe2\x92\xba", // CIRCLED LATIN SMALL LETTER E
+    "\xe2\x93\x95" => "\xe2\x92\xbb", // CIRCLED LATIN SMALL LETTER F
+    "\xe2\x93\x96" => "\xe2\x92\xbc", // CIRCLED LATIN SMALL LETTER G
+    "\xe2\x93\x97" => "\xe2\x92\xbd", // CIRCLED LATIN SMALL LETTER H
+    "\xe2\x93\x98" => "\xe2\x92\xbe", // CIRCLED LATIN SMALL LETTER I
+    "\xe2\x93\x99" => "\xe2\x92\xbf", // CIRCLED LATIN SMALL LETTER J
+    "\xe2\x93\x9a" => "\xe2\x93\x80", // CIRCLED LATIN SMALL LETTER K
+    "\xe2\x93\x9b" => "\xe2\x93\x81", // CIRCLED LATIN SMALL LETTER L
+    "\xe2\x93\x9c" => "\xe2\x93\x82", // CIRCLED LATIN SMALL LETTER M
+    "\xe2\x93\x9d" => "\xe2\x93\x83", // CIRCLED LATIN SMALL LETTER N
+    "\xe2\x93\x9e" => "\xe2\x93\x84", // CIRCLED LATIN SMALL LETTER O
+    "\xe2\x93\x9f" => "\xe2\x93\x85", // CIRCLED LATIN SMALL LETTER P
+    "\xe2\x93\xa0" => "\xe2\x93\x86", // CIRCLED LATIN SMALL LETTER Q
+    "\xe2\x93\xa1" => "\xe2\x93\x87", // CIRCLED LATIN SMALL LETTER R
+    "\xe2\x93\xa2" => "\xe2\x93\x88", // CIRCLED LATIN SMALL LETTER S
+    "\xe2\x93\xa3" => "\xe2\x93\x89", // CIRCLED LATIN SMALL LETTER T
+    "\xe2\x93\xa4" => "\xe2\x93\x8a", // CIRCLED LATIN SMALL LETTER U
+    "\xe2\x93\xa5" => "\xe2\x93\x8b", // CIRCLED LATIN SMALL LETTER V
+    "\xe2\x93\xa6" => "\xe2\x93\x8c", // CIRCLED LATIN SMALL LETTER W
+    "\xe2\x93\xa7" => "\xe2\x93\x8d", // CIRCLED LATIN SMALL LETTER X
+    "\xe2\x93\xa8" => "\xe2\x93\x8e", // CIRCLED LATIN SMALL LETTER Y
+    "\xe2\x93\xa9" => "\xe2\x93\x8f", // CIRCLED LATIN SMALL LETTER Z
+    "\xe2\xb0\xb0" => "\xe2\xb0\x80", // GLAGOLITIC SMALL LETTER AZU
+    "\xe2\xb0\xb1" => "\xe2\xb0\x81", // GLAGOLITIC SMALL LETTER BUKY
+    "\xe2\xb0\xb2" => "\xe2\xb0\x82", // GLAGOLITIC SMALL LETTER VEDE
+    "\xe2\xb0\xb3" => "\xe2\xb0\x83", // GLAGOLITIC SMALL LETTER GLAGOLI
+    "\xe2\xb0\xb4" => "\xe2\xb0\x84", // GLAGOLITIC SMALL LETTER DOBRO
+    "\xe2\xb0\xb5" => "\xe2\xb0\x85", // GLAGOLITIC SMALL LETTER YESTU
+    "\xe2\xb0\xb6" => "\xe2\xb0\x86", // GLAGOLITIC SMALL LETTER ZHIVETE
+    "\xe2\xb0\xb7" => "\xe2\xb0\x87", // GLAGOLITIC SMALL LETTER DZELO
+    "\xe2\xb0\xb8" => "\xe2\xb0\x88", // GLAGOLITIC SMALL LETTER ZEMLJA
+    "\xe2\xb0\xb9" => "\xe2\xb0\x89", // GLAGOLITIC SMALL LETTER IZHE
+    "\xe2\xb0\xba" => "\xe2\xb0\x8a", // GLAGOLITIC SMALL LETTER INITIAL IZHE
+    "\xe2\xb0\xbb" => "\xe2\xb0\x8b", // GLAGOLITIC SMALL LETTER I
+    "\xe2\xb0\xbc" => "\xe2\xb0\x8c", // GLAGOLITIC SMALL LETTER DJERVI
+    "\xe2\xb0\xbd" => "\xe2\xb0\x8d", // GLAGOLITIC SMALL LETTER KAKO
+    "\xe2\xb0\xbe" => "\xe2\xb0\x8e", // GLAGOLITIC SMALL LETTER LJUDIJE
+    "\xe2\xb0\xbf" => "\xe2\xb0\x8f", // GLAGOLITIC SMALL LETTER MYSLITE
+    "\xe2\xb1\x80" => "\xe2\xb0\x90", // GLAGOLITIC SMALL LETTER NASHI
+    "\xe2\xb1\x81" => "\xe2\xb0\x91", // GLAGOLITIC SMALL LETTER ONU
+    "\xe2\xb1\x82" => "\xe2\xb0\x92", // GLAGOLITIC SMALL LETTER POKOJI
+    "\xe2\xb1\x83" => "\xe2\xb0\x93", // GLAGOLITIC SMALL LETTER RITSI
+    "\xe2\xb1\x84" => "\xe2\xb0\x94", // GLAGOLITIC SMALL LETTER SLOVO
+    "\xe2\xb1\x85" => "\xe2\xb0\x95", // GLAGOLITIC SMALL LETTER TVRIDO
+    "\xe2\xb1\x86" => "\xe2\xb0\x96", // GLAGOLITIC SMALL LETTER UKU
+    "\xe2\xb1\x87" => "\xe2\xb0\x97", // GLAGOLITIC SMALL LETTER FRITU
+    "\xe2\xb1\x88" => "\xe2\xb0\x98", // GLAGOLITIC SMALL LETTER HERU
+    "\xe2\xb1\x89" => "\xe2\xb0\x99", // GLAGOLITIC SMALL LETTER OTU
+    "\xe2\xb1\x8a" => "\xe2\xb0\x9a", // GLAGOLITIC SMALL LETTER PE
+    "\xe2\xb1\x8b" => "\xe2\xb0\x9b", // GLAGOLITIC SMALL LETTER SHTA
+    "\xe2\xb1\x8c" => "\xe2\xb0\x9c", // GLAGOLITIC SMALL LETTER TSI
+    "\xe2\xb1\x8d" => "\xe2\xb0\x9d", // GLAGOLITIC SMALL LETTER CHRIVI
+    "\xe2\xb1\x8e" => "\xe2\xb0\x9e", // GLAGOLITIC SMALL LETTER SHA
+    "\xe2\xb1\x8f" => "\xe2\xb0\x9f", // GLAGOLITIC SMALL LETTER YERU
+    "\xe2\xb1\x90" => "\xe2\xb0\xa0", // GLAGOLITIC SMALL LETTER YERI
+    "\xe2\xb1\x91" => "\xe2\xb0\xa1", // GLAGOLITIC SMALL LETTER YATI
+    "\xe2\xb1\x92" => "\xe2\xb0\xa2", // GLAGOLITIC SMALL LETTER SPIDERY HA
+    "\xe2\xb1\x93" => "\xe2\xb0\xa3", // GLAGOLITIC SMALL LETTER YU
+    "\xe2\xb1\x94" => "\xe2\xb0\xa4", // GLAGOLITIC SMALL LETTER SMALL YUS
+    "\xe2\xb1\x95" => "\xe2\xb0\xa5", // GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL
+    "\xe2\xb1\x96" => "\xe2\xb0\xa6", // GLAGOLITIC SMALL LETTER YO
+    "\xe2\xb1\x97" => "\xe2\xb0\xa7", // GLAGOLITIC SMALL LETTER IOTATED SMALL YUS
+    "\xe2\xb1\x98" => "\xe2\xb0\xa8", // GLAGOLITIC SMALL LETTER BIG YUS
+    "\xe2\xb1\x99" => "\xe2\xb0\xa9", // GLAGOLITIC SMALL LETTER IOTATED BIG YUS
+    "\xe2\xb1\x9a" => "\xe2\xb0\xaa", // GLAGOLITIC SMALL LETTER FITA
+    "\xe2\xb1\x9b" => "\xe2\xb0\xab", // GLAGOLITIC SMALL LETTER IZHITSA
+    "\xe2\xb1\x9c" => "\xe2\xb0\xac", // GLAGOLITIC SMALL LETTER SHTAPIC
+    "\xe2\xb1\x9d" => "\xe2\xb0\xad", // GLAGOLITIC SMALL LETTER TROKUTASTI A
+    "\xe2\xb1\x9e" => "\xe2\xb0\xae", // GLAGOLITIC SMALL LETTER LATINATE MYSLITE
+    "\xe2\xb1\xa1" => "\xe2\xb1\xa0", // LATIN SMALL LETTER L WITH DOUBLE BAR
+    "\xe2\xb1\xa5" => "\xc8\xba", // LATIN SMALL LETTER A WITH STROKE
+    "\xe2\xb1\xa6" => "\xc8\xbe", // LATIN SMALL LETTER T WITH DIAGONAL STROKE
+    "\xe2\xb1\xa8" => "\xe2\xb1\xa7", // LATIN SMALL LETTER H WITH DESCENDER
+    "\xe2\xb1\xaa" => "\xe2\xb1\xa9", // LATIN SMALL LETTER K WITH DESCENDER
+    "\xe2\xb1\xac" => "\xe2\xb1\xab", // LATIN SMALL LETTER Z WITH DESCENDER
+    "\xe2\xb1\xb3" => "\xe2\xb1\xb2", // LATIN SMALL LETTER W WITH HOOK
+    "\xe2\xb1\xb6" => "\xe2\xb1\xb5", // LATIN SMALL LETTER HALF H
+    "\xe2\xb2\x81" => "\xe2\xb2\x80", // COPTIC SMALL LETTER ALFA
+    "\xe2\xb2\x83" => "\xe2\xb2\x82", // COPTIC SMALL LETTER VIDA
+    "\xe2\xb2\x85" => "\xe2\xb2\x84", // COPTIC SMALL LETTER GAMMA
+    "\xe2\xb2\x87" => "\xe2\xb2\x86", // COPTIC SMALL LETTER DALDA
+    "\xe2\xb2\x89" => "\xe2\xb2\x88", // COPTIC SMALL LETTER EIE
+    "\xe2\xb2\x8b" => "\xe2\xb2\x8a", // COPTIC SMALL LETTER SOU
+    "\xe2\xb2\x8d" => "\xe2\xb2\x8c", // COPTIC SMALL LETTER ZATA
+    "\xe2\xb2\x8f" => "\xe2\xb2\x8e", // COPTIC SMALL LETTER HATE
+    "\xe2\xb2\x91" => "\xe2\xb2\x90", // COPTIC SMALL LETTER THETHE
+    "\xe2\xb2\x93" => "\xe2\xb2\x92", // COPTIC SMALL LETTER IAUDA
+    "\xe2\xb2\x95" => "\xe2\xb2\x94", // COPTIC SMALL LETTER KAPA
+    "\xe2\xb2\x97" => "\xe2\xb2\x96", // COPTIC SMALL LETTER LAULA
+    "\xe2\xb2\x99" => "\xe2\xb2\x98", // COPTIC SMALL LETTER MI
+    "\xe2\xb2\x9b" => "\xe2\xb2\x9a", // COPTIC SMALL LETTER NI
+    "\xe2\xb2\x9d" => "\xe2\xb2\x9c", // COPTIC SMALL LETTER KSI
+    "\xe2\xb2\x9f" => "\xe2\xb2\x9e", // COPTIC SMALL LETTER O
+    "\xe2\xb2\xa1" => "\xe2\xb2\xa0", // COPTIC SMALL LETTER PI
+    "\xe2\xb2\xa3" => "\xe2\xb2\xa2", // COPTIC SMALL LETTER RO
+    "\xe2\xb2\xa5" => "\xe2\xb2\xa4", // COPTIC SMALL LETTER SIMA
+    "\xe2\xb2\xa7" => "\xe2\xb2\xa6", // COPTIC SMALL LETTER TAU
+    "\xe2\xb2\xa9" => "\xe2\xb2\xa8", // COPTIC SMALL LETTER UA
+    "\xe2\xb2\xab" => "\xe2\xb2\xaa", // COPTIC SMALL LETTER FI
+    "\xe2\xb2\xad" => "\xe2\xb2\xac", // COPTIC SMALL LETTER KHI
+    "\xe2\xb2\xaf" => "\xe2\xb2\xae", // COPTIC SMALL LETTER PSI
+    "\xe2\xb2\xb1" => "\xe2\xb2\xb0", // COPTIC SMALL LETTER OOU
+    "\xe2\xb2\xb3" => "\xe2\xb2\xb2", // COPTIC SMALL LETTER DIALECT-P ALEF
+    "\xe2\xb2\xb5" => "\xe2\xb2\xb4", // COPTIC SMALL LETTER OLD COPTIC AIN
+    "\xe2\xb2\xb7" => "\xe2\xb2\xb6", // COPTIC SMALL LETTER CRYPTOGRAMMIC EIE
+    "\xe2\xb2\xb9" => "\xe2\xb2\xb8", // COPTIC SMALL LETTER DIALECT-P KAPA
+    "\xe2\xb2\xbb" => "\xe2\xb2\xba", // COPTIC SMALL LETTER DIALECT-P NI
+    "\xe2\xb2\xbd" => "\xe2\xb2\xbc", // COPTIC SMALL LETTER CRYPTOGRAMMIC NI
+    "\xe2\xb2\xbf" => "\xe2\xb2\xbe", // COPTIC SMALL LETTER OLD COPTIC OOU
+    "\xe2\xb3\x81" => "\xe2\xb3\x80", // COPTIC SMALL LETTER SAMPI
+    "\xe2\xb3\x83" => "\xe2\xb3\x82", // COPTIC SMALL LETTER CROSSED SHEI
+    "\xe2\xb3\x85" => "\xe2\xb3\x84", // COPTIC SMALL LETTER OLD COPTIC SHEI
+    "\xe2\xb3\x87" => "\xe2\xb3\x86", // COPTIC SMALL LETTER OLD COPTIC ESH
+    "\xe2\xb3\x89" => "\xe2\xb3\x88", // COPTIC SMALL LETTER AKHMIMIC KHEI
+    "\xe2\xb3\x8b" => "\xe2\xb3\x8a", // COPTIC SMALL LETTER DIALECT-P HORI
+    "\xe2\xb3\x8d" => "\xe2\xb3\x8c", // COPTIC SMALL LETTER OLD COPTIC HORI
+    "\xe2\xb3\x8f" => "\xe2\xb3\x8e", // COPTIC SMALL LETTER OLD COPTIC HA
+    "\xe2\xb3\x91" => "\xe2\xb3\x90", // COPTIC SMALL LETTER L-SHAPED HA
+    "\xe2\xb3\x93" => "\xe2\xb3\x92", // COPTIC SMALL LETTER OLD COPTIC HEI
+    "\xe2\xb3\x95" => "\xe2\xb3\x94", // COPTIC SMALL LETTER OLD COPTIC HAT
+    "\xe2\xb3\x97" => "\xe2\xb3\x96", // COPTIC SMALL LETTER OLD COPTIC GANGIA
+    "\xe2\xb3\x99" => "\xe2\xb3\x98", // COPTIC SMALL LETTER OLD COPTIC DJA
+    "\xe2\xb3\x9b" => "\xe2\xb3\x9a", // COPTIC SMALL LETTER OLD COPTIC SHIMA
+    "\xe2\xb3\x9d" => "\xe2\xb3\x9c", // COPTIC SMALL LETTER OLD NUBIAN SHIMA
+    "\xe2\xb3\x9f" => "\xe2\xb3\x9e", // COPTIC SMALL LETTER OLD NUBIAN NGI
+    "\xe2\xb3\xa1" => "\xe2\xb3\xa0", // COPTIC SMALL LETTER OLD NUBIAN NYI
+    "\xe2\xb3\xa3" => "\xe2\xb3\xa2", // COPTIC SMALL LETTER OLD NUBIAN WAU
+    "\xe2\xb3\xac" => "\xe2\xb3\xab", // COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI
+    "\xe2\xb3\xae" => "\xe2\xb3\xad", // COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA
+    "\xe2\xb4\x80" => "\xe1\x82\xa0", // GEORGIAN SMALL LETTER AN
+    "\xe2\xb4\x81" => "\xe1\x82\xa1", // GEORGIAN SMALL LETTER BAN
+    "\xe2\xb4\x82" => "\xe1\x82\xa2", // GEORGIAN SMALL LETTER GAN
+    "\xe2\xb4\x83" => "\xe1\x82\xa3", // GEORGIAN SMALL LETTER DON
+    "\xe2\xb4\x84" => "\xe1\x82\xa4", // GEORGIAN SMALL LETTER EN
+    "\xe2\xb4\x85" => "\xe1\x82\xa5", // GEORGIAN SMALL LETTER VIN
+    "\xe2\xb4\x86" => "\xe1\x82\xa6", // GEORGIAN SMALL LETTER ZEN
+    "\xe2\xb4\x87" => "\xe1\x82\xa7", // GEORGIAN SMALL LETTER TAN
+    "\xe2\xb4\x88" => "\xe1\x82\xa8", // GEORGIAN SMALL LETTER IN
+    "\xe2\xb4\x89" => "\xe1\x82\xa9", // GEORGIAN SMALL LETTER KAN
+    "\xe2\xb4\x8a" => "\xe1\x82\xaa", // GEORGIAN SMALL LETTER LAS
+    "\xe2\xb4\x8b" => "\xe1\x82\xab", // GEORGIAN SMALL LETTER MAN
+    "\xe2\xb4\x8c" => "\xe1\x82\xac", // GEORGIAN SMALL LETTER NAR
+    "\xe2\xb4\x8d" => "\xe1\x82\xad", // GEORGIAN SMALL LETTER ON
+    "\xe2\xb4\x8e" => "\xe1\x82\xae", // GEORGIAN SMALL LETTER PAR
+    "\xe2\xb4\x8f" => "\xe1\x82\xaf", // GEORGIAN SMALL LETTER ZHAR
+    "\xe2\xb4\x90" => "\xe1\x82\xb0", // GEORGIAN SMALL LETTER RAE
+    "\xe2\xb4\x91" => "\xe1\x82\xb1", // GEORGIAN SMALL LETTER SAN
+    "\xe2\xb4\x92" => "\xe1\x82\xb2", // GEORGIAN SMALL LETTER TAR
+    "\xe2\xb4\x93" => "\xe1\x82\xb3", // GEORGIAN SMALL LETTER UN
+    "\xe2\xb4\x94" => "\xe1\x82\xb4", // GEORGIAN SMALL LETTER PHAR
+    "\xe2\xb4\x95" => "\xe1\x82\xb5", // GEORGIAN SMALL LETTER KHAR
+    "\xe2\xb4\x96" => "\xe1\x82\xb6", // GEORGIAN SMALL LETTER GHAN
+    "\xe2\xb4\x97" => "\xe1\x82\xb7", // GEORGIAN SMALL LETTER QAR
+    "\xe2\xb4\x98" => "\xe1\x82\xb8", // GEORGIAN SMALL LETTER SHIN
+    "\xe2\xb4\x99" => "\xe1\x82\xb9", // GEORGIAN SMALL LETTER CHIN
+    "\xe2\xb4\x9a" => "\xe1\x82\xba", // GEORGIAN SMALL LETTER CAN
+    "\xe2\xb4\x9b" => "\xe1\x82\xbb", // GEORGIAN SMALL LETTER JIL
+    "\xe2\xb4\x9c" => "\xe1\x82\xbc", // GEORGIAN SMALL LETTER CIL
+    "\xe2\xb4\x9d" => "\xe1\x82\xbd", // GEORGIAN SMALL LETTER CHAR
+    "\xe2\xb4\x9e" => "\xe1\x82\xbe", // GEORGIAN SMALL LETTER XAN
+    "\xe2\xb4\x9f" => "\xe1\x82\xbf", // GEORGIAN SMALL LETTER JHAN
+    "\xe2\xb4\xa0" => "\xe1\x83\x80", // GEORGIAN SMALL LETTER HAE
+    "\xe2\xb4\xa1" => "\xe1\x83\x81", // GEORGIAN SMALL LETTER HE
+    "\xe2\xb4\xa2" => "\xe1\x83\x82", // GEORGIAN SMALL LETTER HIE
+    "\xe2\xb4\xa3" => "\xe1\x83\x83", // GEORGIAN SMALL LETTER WE
+    "\xe2\xb4\xa4" => "\xe1\x83\x84", // GEORGIAN SMALL LETTER HAR
+    "\xe2\xb4\xa5" => "\xe1\x83\x85", // GEORGIAN SMALL LETTER HOE
+    "\xea\x99\x81" => "\xea\x99\x80", // CYRILLIC SMALL LETTER ZEMLYA
+    "\xea\x99\x83" => "\xea\x99\x82", // CYRILLIC SMALL LETTER DZELO
+    "\xea\x99\x85" => "\xea\x99\x84", // CYRILLIC SMALL LETTER REVERSED DZE
+    "\xea\x99\x87" => "\xea\x99\x86", // CYRILLIC SMALL LETTER IOTA
+    "\xea\x99\x89" => "\xea\x99\x88", // CYRILLIC SMALL LETTER DJERV
+    "\xea\x99\x8b" => "\xea\x99\x8a", // CYRILLIC SMALL LETTER MONOGRAPH UK
+    "\xea\x99\x8d" => "\xea\x99\x8c", // CYRILLIC SMALL LETTER BROAD OMEGA
+    "\xea\x99\x8f" => "\xea\x99\x8e", // CYRILLIC SMALL LETTER NEUTRAL YER
+    "\xea\x99\x91" => "\xea\x99\x90", // CYRILLIC SMALL LETTER YERU WITH BACK YER
+    "\xea\x99\x93" => "\xea\x99\x92", // CYRILLIC SMALL LETTER IOTIFIED YAT
+    "\xea\x99\x95" => "\xea\x99\x94", // CYRILLIC SMALL LETTER REVERSED YU
+    "\xea\x99\x97" => "\xea\x99\x96", // CYRILLIC SMALL LETTER IOTIFIED A
+    "\xea\x99\x99" => "\xea\x99\x98", // CYRILLIC SMALL LETTER CLOSED LITTLE YUS
+    "\xea\x99\x9b" => "\xea\x99\x9a", // CYRILLIC SMALL LETTER BLENDED YUS
+    "\xea\x99\x9d" => "\xea\x99\x9c", // CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS
+    "\xea\x99\x9f" => "\xea\x99\x9e", // CYRILLIC SMALL LETTER YN
+    "\xea\x99\xa1" => "\xea\x99\xa0", // CYRILLIC SMALL LETTER REVERSED TSE
+    "\xea\x99\xa3" => "\xea\x99\xa2", // CYRILLIC SMALL LETTER SOFT DE
+    "\xea\x99\xa5" => "\xea\x99\xa4", // CYRILLIC SMALL LETTER SOFT EL
+    "\xea\x99\xa7" => "\xea\x99\xa6", // CYRILLIC SMALL LETTER SOFT EM
+    "\xea\x99\xa9" => "\xea\x99\xa8", // CYRILLIC SMALL LETTER MONOCULAR O
+    "\xea\x99\xab" => "\xea\x99\xaa", // CYRILLIC SMALL LETTER BINOCULAR O
+    "\xea\x99\xad" => "\xea\x99\xac", // CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
+    "\xea\x9a\x81" => "\xea\x9a\x80", // CYRILLIC SMALL LETTER DWE
+    "\xea\x9a\x83" => "\xea\x9a\x82", // CYRILLIC SMALL LETTER DZWE
+    "\xea\x9a\x85" => "\xea\x9a\x84", // CYRILLIC SMALL LETTER ZHWE
+    "\xea\x9a\x87" => "\xea\x9a\x86", // CYRILLIC SMALL LETTER CCHE
+    "\xea\x9a\x89" => "\xea\x9a\x88", // CYRILLIC SMALL LETTER DZZE
+    "\xea\x9a\x8b" => "\xea\x9a\x8a", // CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK
+    "\xea\x9a\x8d" => "\xea\x9a\x8c", // CYRILLIC SMALL LETTER TWE
+    "\xea\x9a\x8f" => "\xea\x9a\x8e", // CYRILLIC SMALL LETTER TSWE
+    "\xea\x9a\x91" => "\xea\x9a\x90", // CYRILLIC SMALL LETTER TSSE
+    "\xea\x9a\x93" => "\xea\x9a\x92", // CYRILLIC SMALL LETTER TCHE
+    "\xea\x9a\x95" => "\xea\x9a\x94", // CYRILLIC SMALL LETTER HWE
+    "\xea\x9a\x97" => "\xea\x9a\x96", // CYRILLIC SMALL LETTER SHWE
+    "\xea\x9c\xa3" => "\xea\x9c\xa2", // LATIN SMALL LETTER EGYPTOLOGICAL ALEF
+    "\xea\x9c\xa5" => "\xea\x9c\xa4", // LATIN SMALL LETTER EGYPTOLOGICAL AIN
+    "\xea\x9c\xa7" => "\xea\x9c\xa6", // LATIN SMALL LETTER HENG
+    "\xea\x9c\xa9" => "\xea\x9c\xa8", // LATIN SMALL LETTER TZ
+    "\xea\x9c\xab" => "\xea\x9c\xaa", // LATIN SMALL LETTER TRESILLO
+    "\xea\x9c\xad" => "\xea\x9c\xac", // LATIN SMALL LETTER CUATRILLO
+    "\xea\x9c\xaf" => "\xea\x9c\xae", // LATIN SMALL LETTER CUATRILLO WITH COMMA
+    "\xea\x9c\xb3" => "\xea\x9c\xb2", // LATIN SMALL LETTER AA
+    "\xea\x9c\xb5" => "\xea\x9c\xb4", // LATIN SMALL LETTER AO
+    "\xea\x9c\xb7" => "\xea\x9c\xb6", // LATIN SMALL LETTER AU
+    "\xea\x9c\xb9" => "\xea\x9c\xb8", // LATIN SMALL LETTER AV
+    "\xea\x9c\xbb" => "\xea\x9c\xba", // LATIN SMALL LETTER AV WITH HORIZONTAL BAR
+    "\xea\x9c\xbd" => "\xea\x9c\xbc", // LATIN SMALL LETTER AY
+    "\xea\x9c\xbf" => "\xea\x9c\xbe", // LATIN SMALL LETTER REVERSED C WITH DOT
+    "\xea\x9d\x81" => "\xea\x9d\x80", // LATIN SMALL LETTER K WITH STROKE
+    "\xea\x9d\x83" => "\xea\x9d\x82", // LATIN SMALL LETTER K WITH DIAGONAL STROKE
+    "\xea\x9d\x85" => "\xea\x9d\x84", // LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE
+    "\xea\x9d\x87" => "\xea\x9d\x86", // LATIN SMALL LETTER BROKEN L
+    "\xea\x9d\x89" => "\xea\x9d\x88", // LATIN SMALL LETTER L WITH HIGH STROKE
+    "\xea\x9d\x8b" => "\xea\x9d\x8a", // LATIN SMALL LETTER O WITH LONG STROKE OVERLAY
+    "\xea\x9d\x8d" => "\xea\x9d\x8c", // LATIN SMALL LETTER O WITH LOOP
+    "\xea\x9d\x8f" => "\xea\x9d\x8e", // LATIN SMALL LETTER OO
+    "\xea\x9d\x91" => "\xea\x9d\x90", // LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER
+    "\xea\x9d\x93" => "\xea\x9d\x92", // LATIN SMALL LETTER P WITH FLOURISH
+    "\xea\x9d\x95" => "\xea\x9d\x94", // LATIN SMALL LETTER P WITH SQUIRREL TAIL
+    "\xea\x9d\x97" => "\xea\x9d\x96", // LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER
+    "\xea\x9d\x99" => "\xea\x9d\x98", // LATIN SMALL LETTER Q WITH DIAGONAL STROKE
+    "\xea\x9d\x9b" => "\xea\x9d\x9a", // LATIN SMALL LETTER R ROTUNDA
+    "\xea\x9d\x9d" => "\xea\x9d\x9c", // LATIN SMALL LETTER RUM ROTUNDA
+    "\xea\x9d\x9f" => "\xea\x9d\x9e", // LATIN SMALL LETTER V WITH DIAGONAL STROKE
+    "\xea\x9d\xa1" => "\xea\x9d\xa0", // LATIN SMALL LETTER VY
+    "\xea\x9d\xa3" => "\xea\x9d\xa2", // LATIN SMALL LETTER VISIGOTHIC Z
+    "\xea\x9d\xa5" => "\xea\x9d\xa4", // LATIN SMALL LETTER THORN WITH STROKE
+    "\xea\x9d\xa7" => "\xea\x9d\xa6", // LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER
+    "\xea\x9d\xa9" => "\xea\x9d\xa8", // LATIN SMALL LETTER VEND
+    "\xea\x9d\xab" => "\xea\x9d\xaa", // LATIN SMALL LETTER ET
+    "\xea\x9d\xad" => "\xea\x9d\xac", // LATIN SMALL LETTER IS
+    "\xea\x9d\xaf" => "\xea\x9d\xae", // LATIN SMALL LETTER CON
+    "\xea\x9d\xba" => "\xea\x9d\xb9", // LATIN SMALL LETTER INSULAR D
+    "\xea\x9d\xbc" => "\xea\x9d\xbb", // LATIN SMALL LETTER INSULAR F
+    "\xea\x9d\xbf" => "\xea\x9d\xbe", // LATIN SMALL LETTER TURNED INSULAR G
+    "\xea\x9e\x81" => "\xea\x9e\x80", // LATIN SMALL LETTER TURNED L
+    "\xea\x9e\x83" => "\xea\x9e\x82", // LATIN SMALL LETTER INSULAR R
+    "\xea\x9e\x85" => "\xea\x9e\x84", // LATIN SMALL LETTER INSULAR S
+    "\xea\x9e\x87" => "\xea\x9e\x86", // LATIN SMALL LETTER INSULAR T
+    "\xea\x9e\x8c" => "\xea\x9e\x8b", // LATIN SMALL LETTER SALTILLO
+    "\xea\x9e\x91" => "\xea\x9e\x90", // LATIN SMALL LETTER N WITH DESCENDER
+    "\xea\x9e\xa1" => "\xea\x9e\xa0", // LATIN SMALL LETTER G WITH OBLIQUE STROKE
+    "\xea\x9e\xa3" => "\xea\x9e\xa2", // LATIN SMALL LETTER K WITH OBLIQUE STROKE
+    "\xea\x9e\xa5" => "\xea\x9e\xa4", // LATIN SMALL LETTER N WITH OBLIQUE STROKE
+    "\xea\x9e\xa7" => "\xea\x9e\xa6", // LATIN SMALL LETTER R WITH OBLIQUE STROKE
+    "\xea\x9e\xa9" => "\xea\x9e\xa8", // LATIN SMALL LETTER S WITH OBLIQUE STROKE
+    "\xef\xbd\x81" => "\xef\xbc\xa1", // FULLWIDTH LATIN SMALL LETTER A
+    "\xef\xbd\x82" => "\xef\xbc\xa2", // FULLWIDTH LATIN SMALL LETTER B
+    "\xef\xbd\x83" => "\xef\xbc\xa3", // FULLWIDTH LATIN SMALL LETTER C
+    "\xef\xbd\x84" => "\xef\xbc\xa4", // FULLWIDTH LATIN SMALL LETTER D
+    "\xef\xbd\x85" => "\xef\xbc\xa5", // FULLWIDTH LATIN SMALL LETTER E
+    "\xef\xbd\x86" => "\xef\xbc\xa6", // FULLWIDTH LATIN SMALL LETTER F
+    "\xef\xbd\x87" => "\xef\xbc\xa7", // FULLWIDTH LATIN SMALL LETTER G
+    "\xef\xbd\x88" => "\xef\xbc\xa8", // FULLWIDTH LATIN SMALL LETTER H
+    "\xef\xbd\x89" => "\xef\xbc\xa9", // FULLWIDTH LATIN SMALL LETTER I
+    "\xef\xbd\x8a" => "\xef\xbc\xaa", // FULLWIDTH LATIN SMALL LETTER J
+    "\xef\xbd\x8b" => "\xef\xbc\xab", // FULLWIDTH LATIN SMALL LETTER K
+    "\xef\xbd\x8c" => "\xef\xbc\xac", // FULLWIDTH LATIN SMALL LETTER L
+    "\xef\xbd\x8d" => "\xef\xbc\xad", // FULLWIDTH LATIN SMALL LETTER M
+    "\xef\xbd\x8e" => "\xef\xbc\xae", // FULLWIDTH LATIN SMALL LETTER N
+    "\xef\xbd\x8f" => "\xef\xbc\xaf", // FULLWIDTH LATIN SMALL LETTER O
+    "\xef\xbd\x90" => "\xef\xbc\xb0", // FULLWIDTH LATIN SMALL LETTER P
+    "\xef\xbd\x91" => "\xef\xbc\xb1", // FULLWIDTH LATIN SMALL LETTER Q
+    "\xef\xbd\x92" => "\xef\xbc\xb2", // FULLWIDTH LATIN SMALL LETTER R
+    "\xef\xbd\x93" => "\xef\xbc\xb3", // FULLWIDTH LATIN SMALL LETTER S
+    "\xef\xbd\x94" => "\xef\xbc\xb4", // FULLWIDTH LATIN SMALL LETTER T
+    "\xef\xbd\x95" => "\xef\xbc\xb5", // FULLWIDTH LATIN SMALL LETTER U
+    "\xef\xbd\x96" => "\xef\xbc\xb6", // FULLWIDTH LATIN SMALL LETTER V
+    "\xef\xbd\x97" => "\xef\xbc\xb7", // FULLWIDTH LATIN SMALL LETTER W
+    "\xef\xbd\x98" => "\xef\xbc\xb8", // FULLWIDTH LATIN SMALL LETTER X
+    "\xef\xbd\x99" => "\xef\xbc\xb9", // FULLWIDTH LATIN SMALL LETTER Y
+    "\xef\xbd\x9a" => "\xef\xbc\xba", // FULLWIDTH LATIN SMALL LETTER Z
+    "\xf0\x90\x90\xa8" => "\xf0\x90\x90\x80", // DESERET SMALL LETTER LONG I
+    "\xf0\x90\x90\xa9" => "\xf0\x90\x90\x81", // DESERET SMALL LETTER LONG E
+    "\xf0\x90\x90\xaa" => "\xf0\x90\x90\x82", // DESERET SMALL LETTER LONG A
+    "\xf0\x90\x90\xab" => "\xf0\x90\x90\x83", // DESERET SMALL LETTER LONG AH
+    "\xf0\x90\x90\xac" => "\xf0\x90\x90\x84", // DESERET SMALL LETTER LONG O
+    "\xf0\x90\x90\xad" => "\xf0\x90\x90\x85", // DESERET SMALL LETTER LONG OO
+    "\xf0\x90\x90\xae" => "\xf0\x90\x90\x86", // DESERET SMALL LETTER SHORT I
+    "\xf0\x90\x90\xaf" => "\xf0\x90\x90\x87", // DESERET SMALL LETTER SHORT E
+    "\xf0\x90\x90\xb0" => "\xf0\x90\x90\x88", // DESERET SMALL LETTER SHORT A
+    "\xf0\x90\x90\xb1" => "\xf0\x90\x90\x89", // DESERET SMALL LETTER SHORT AH
+    "\xf0\x90\x90\xb2" => "\xf0\x90\x90\x8a", // DESERET SMALL LETTER SHORT O
+    "\xf0\x90\x90\xb3" => "\xf0\x90\x90\x8b", // DESERET SMALL LETTER SHORT OO
+    "\xf0\x90\x90\xb4" => "\xf0\x90\x90\x8c", // DESERET SMALL LETTER AY
+    "\xf0\x90\x90\xb5" => "\xf0\x90\x90\x8d", // DESERET SMALL LETTER OW
+    "\xf0\x90\x90\xb6" => "\xf0\x90\x90\x8e", // DESERET SMALL LETTER WU
+    "\xf0\x90\x90\xb7" => "\xf0\x90\x90\x8f", // DESERET SMALL LETTER YEE
+    "\xf0\x90\x90\xb8" => "\xf0\x90\x90\x90", // DESERET SMALL LETTER H
+    "\xf0\x90\x90\xb9" => "\xf0\x90\x90\x91", // DESERET SMALL LETTER PEE
+    "\xf0\x90\x90\xba" => "\xf0\x90\x90\x92", // DESERET SMALL LETTER BEE
+    "\xf0\x90\x90\xbb" => "\xf0\x90\x90\x93", // DESERET SMALL LETTER TEE
+    "\xf0\x90\x90\xbc" => "\xf0\x90\x90\x94", // DESERET SMALL LETTER DEE
+    "\xf0\x90\x90\xbd" => "\xf0\x90\x90\x95", // DESERET SMALL LETTER CHEE
+    "\xf0\x90\x90\xbe" => "\xf0\x90\x90\x96", // DESERET SMALL LETTER JEE
+    "\xf0\x90\x90\xbf" => "\xf0\x90\x90\x97", // DESERET SMALL LETTER KAY
+    "\xf0\x90\x91\x80" => "\xf0\x90\x90\x98", // DESERET SMALL LETTER GAY
+    "\xf0\x90\x91\x81" => "\xf0\x90\x90\x99", // DESERET SMALL LETTER EF
+    "\xf0\x90\x91\x82" => "\xf0\x90\x90\x9a", // DESERET SMALL LETTER VEE
+    "\xf0\x90\x91\x83" => "\xf0\x90\x90\x9b", // DESERET SMALL LETTER ETH
+    "\xf0\x90\x91\x84" => "\xf0\x90\x90\x9c", // DESERET SMALL LETTER THEE
+    "\xf0\x90\x91\x85" => "\xf0\x90\x90\x9d", // DESERET SMALL LETTER ES
+    "\xf0\x90\x91\x86" => "\xf0\x90\x90\x9e", // DESERET SMALL LETTER ZEE
+    "\xf0\x90\x91\x87" => "\xf0\x90\x90\x9f", // DESERET SMALL LETTER ESH
+    "\xf0\x90\x91\x88" => "\xf0\x90\x90\xa0", // DESERET SMALL LETTER ZHEE
+    "\xf0\x90\x91\x89" => "\xf0\x90\x90\xa1", // DESERET SMALL LETTER ER
+    "\xf0\x90\x91\x8a" => "\xf0\x90\x90\xa2", // DESERET SMALL LETTER EL
+    "\xf0\x90\x91\x8b" => "\xf0\x90\x90\xa3", // DESERET SMALL LETTER EM
+    "\xf0\x90\x91\x8c" => "\xf0\x90\x90\xa4", // DESERET SMALL LETTER EN
+    "\xf0\x90\x91\x8d" => "\xf0\x90\x90\xa5", // DESERET SMALL LETTER ENG
+    "\xf0\x90\x91\x8e" => "\xf0\x90\x90\xa6", // DESERET SMALL LETTER OI
+    "\xf0\x90\x91\x8f" => "\xf0\x90\x90\xa7", // DESERET SMALL LETTER EW
+);
+}
\ No newline at end of file
diff --git a/Template/src/structs/upper_to_lower.php b/Template/src/structs/upper_to_lower.php
new file mode 100644
index 0000000..b9f3495
--- /dev/null
+++ b/Template/src/structs/upper_to_lower.php
@@ -0,0 +1,1073 @@
+<?php
+/**
+ * File containing a mapping from unicode uppercase to lowercase letters.
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * THIS FILE IS MACHINE GENERATED. USE THE FOLLOWING SCRIPT TO REBUILD IT:
+ * - Template/src/unicode/generate_unicode_tables.php
+ *
+ * @package Template
+ * @version //autogentag//
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @access private
+ */
+
+class ezcTemplateStringUpperToLowerUnicodeMap extends ezcBaseStruct
+{
+    public $unicodeTable = array(
+    "\x41" => "\x61", // LATIN CAPITAL LETTER A
+    "\x42" => "\x62", // LATIN CAPITAL LETTER B
+    "\x43" => "\x63", // LATIN CAPITAL LETTER C
+    "\x44" => "\x64", // LATIN CAPITAL LETTER D
+    "\x45" => "\x65", // LATIN CAPITAL LETTER E
+    "\x46" => "\x66", // LATIN CAPITAL LETTER F
+    "\x47" => "\x67", // LATIN CAPITAL LETTER G
+    "\x48" => "\x68", // LATIN CAPITAL LETTER H
+    "\x49" => "\x69", // LATIN CAPITAL LETTER I
+    "\x4a" => "\x6a", // LATIN CAPITAL LETTER J
+    "\x4b" => "\x6b", // LATIN CAPITAL LETTER K
+    "\x4c" => "\x6c", // LATIN CAPITAL LETTER L
+    "\x4d" => "\x6d", // LATIN CAPITAL LETTER M
+    "\x4e" => "\x6e", // LATIN CAPITAL LETTER N
+    "\x4f" => "\x6f", // LATIN CAPITAL LETTER O
+    "\x50" => "\x70", // LATIN CAPITAL LETTER P
+    "\x51" => "\x71", // LATIN CAPITAL LETTER Q
+    "\x52" => "\x72", // LATIN CAPITAL LETTER R
+    "\x53" => "\x73", // LATIN CAPITAL LETTER S
+    "\x54" => "\x74", // LATIN CAPITAL LETTER T
+    "\x55" => "\x75", // LATIN CAPITAL LETTER U
+    "\x56" => "\x76", // LATIN CAPITAL LETTER V
+    "\x57" => "\x77", // LATIN CAPITAL LETTER W
+    "\x58" => "\x78", // LATIN CAPITAL LETTER X
+    "\x59" => "\x79", // LATIN CAPITAL LETTER Y
+    "\x5a" => "\x7a", // LATIN CAPITAL LETTER Z
+    "\xc3\x80" => "\xc3\xa0", // LATIN CAPITAL LETTER A WITH GRAVE
+    "\xc3\x81" => "\xc3\xa1", // LATIN CAPITAL LETTER A WITH ACUTE
+    "\xc3\x82" => "\xc3\xa2", // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+    "\xc3\x83" => "\xc3\xa3", // LATIN CAPITAL LETTER A WITH TILDE
+    "\xc3\x84" => "\xc3\xa4", // LATIN CAPITAL LETTER A WITH DIAERESIS
+    "\xc3\x85" => "\xc3\xa5", // LATIN CAPITAL LETTER A WITH RING ABOVE
+    "\xc3\x86" => "\xc3\xa6", // LATIN CAPITAL LETTER AE
+    "\xc3\x87" => "\xc3\xa7", // LATIN CAPITAL LETTER C WITH CEDILLA
+    "\xc3\x88" => "\xc3\xa8", // LATIN CAPITAL LETTER E WITH GRAVE
+    "\xc3\x89" => "\xc3\xa9", // LATIN CAPITAL LETTER E WITH ACUTE
+    "\xc3\x8a" => "\xc3\xaa", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+    "\xc3\x8b" => "\xc3\xab", // LATIN CAPITAL LETTER E WITH DIAERESIS
+    "\xc3\x8c" => "\xc3\xac", // LATIN CAPITAL LETTER I WITH GRAVE
+    "\xc3\x8d" => "\xc3\xad", // LATIN CAPITAL LETTER I WITH ACUTE
+    "\xc3\x8e" => "\xc3\xae", // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+    "\xc3\x8f" => "\xc3\xaf", // LATIN CAPITAL LETTER I WITH DIAERESIS
+    "\xc3\x90" => "\xc3\xb0", // LATIN CAPITAL LETTER ETH
+    "\xc3\x91" => "\xc3\xb1", // LATIN CAPITAL LETTER N WITH TILDE
+    "\xc3\x92" => "\xc3\xb2", // LATIN CAPITAL LETTER O WITH GRAVE
+    "\xc3\x93" => "\xc3\xb3", // LATIN CAPITAL LETTER O WITH ACUTE
+    "\xc3\x94" => "\xc3\xb4", // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+    "\xc3\x95" => "\xc3\xb5", // LATIN CAPITAL LETTER O WITH TILDE
+    "\xc3\x96" => "\xc3\xb6", // LATIN CAPITAL LETTER O WITH DIAERESIS
+    "\xc3\x98" => "\xc3\xb8", // LATIN CAPITAL LETTER O WITH STROKE
+    "\xc3\x99" => "\xc3\xb9", // LATIN CAPITAL LETTER U WITH GRAVE
+    "\xc3\x9a" => "\xc3\xba", // LATIN CAPITAL LETTER U WITH ACUTE
+    "\xc3\x9b" => "\xc3\xbb", // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+    "\xc3\x9c" => "\xc3\xbc", // LATIN CAPITAL LETTER U WITH DIAERESIS
+    "\xc3\x9d" => "\xc3\xbd", // LATIN CAPITAL LETTER Y WITH ACUTE
+    "\xc3\x9e" => "\xc3\xbe", // LATIN CAPITAL LETTER THORN
+    "\xc4\x80" => "\xc4\x81", // LATIN CAPITAL LETTER A WITH MACRON
+    "\xc4\x82" => "\xc4\x83", // LATIN CAPITAL LETTER A WITH BREVE
+    "\xc4\x84" => "\xc4\x85", // LATIN CAPITAL LETTER A WITH OGONEK
+    "\xc4\x86" => "\xc4\x87", // LATIN CAPITAL LETTER C WITH ACUTE
+    "\xc4\x88" => "\xc4\x89", // LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+    "\xc4\x8a" => "\xc4\x8b", // LATIN CAPITAL LETTER C WITH DOT ABOVE
+    "\xc4\x8c" => "\xc4\x8d", // LATIN CAPITAL LETTER C WITH CARON
+    "\xc4\x8e" => "\xc4\x8f", // LATIN CAPITAL LETTER D WITH CARON
+    "\xc4\x90" => "\xc4\x91", // LATIN CAPITAL LETTER D WITH STROKE
+    "\xc4\x92" => "\xc4\x93", // LATIN CAPITAL LETTER E WITH MACRON
+    "\xc4\x94" => "\xc4\x95", // LATIN CAPITAL LETTER E WITH BREVE
+    "\xc4\x96" => "\xc4\x97", // LATIN CAPITAL LETTER E WITH DOT ABOVE
+    "\xc4\x98" => "\xc4\x99", // LATIN CAPITAL LETTER E WITH OGONEK
+    "\xc4\x9a" => "\xc4\x9b", // LATIN CAPITAL LETTER E WITH CARON
+    "\xc4\x9c" => "\xc4\x9d", // LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+    "\xc4\x9e" => "\xc4\x9f", // LATIN CAPITAL LETTER G WITH BREVE
+    "\xc4\xa0" => "\xc4\xa1", // LATIN CAPITAL LETTER G WITH DOT ABOVE
+    "\xc4\xa2" => "\xc4\xa3", // LATIN CAPITAL LETTER G WITH CEDILLA
+    "\xc4\xa4" => "\xc4\xa5", // LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+    "\xc4\xa6" => "\xc4\xa7", // LATIN CAPITAL LETTER H WITH STROKE
+    "\xc4\xa8" => "\xc4\xa9", // LATIN CAPITAL LETTER I WITH TILDE
+    "\xc4\xaa" => "\xc4\xab", // LATIN CAPITAL LETTER I WITH MACRON
+    "\xc4\xac" => "\xc4\xad", // LATIN CAPITAL LETTER I WITH BREVE
+    "\xc4\xae" => "\xc4\xaf", // LATIN CAPITAL LETTER I WITH OGONEK
+    "\xc4\xb0" => "\x69", // LATIN CAPITAL LETTER I WITH DOT ABOVE
+    "\xc4\xb2" => "\xc4\xb3", // LATIN CAPITAL LIGATURE IJ
+    "\xc4\xb4" => "\xc4\xb5", // LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+    "\xc4\xb6" => "\xc4\xb7", // LATIN CAPITAL LETTER K WITH CEDILLA
+    "\xc4\xb9" => "\xc4\xba", // LATIN CAPITAL LETTER L WITH ACUTE
+    "\xc4\xbb" => "\xc4\xbc", // LATIN CAPITAL LETTER L WITH CEDILLA
+    "\xc4\xbd" => "\xc4\xbe", // LATIN CAPITAL LETTER L WITH CARON
+    "\xc4\xbf" => "\xc5\x80", // LATIN CAPITAL LETTER L WITH MIDDLE DOT
+    "\xc5\x81" => "\xc5\x82", // LATIN CAPITAL LETTER L WITH STROKE
+    "\xc5\x83" => "\xc5\x84", // LATIN CAPITAL LETTER N WITH ACUTE
+    "\xc5\x85" => "\xc5\x86", // LATIN CAPITAL LETTER N WITH CEDILLA
+    "\xc5\x87" => "\xc5\x88", // LATIN CAPITAL LETTER N WITH CARON
+    "\xc5\x8a" => "\xc5\x8b", // LATIN CAPITAL LETTER ENG
+    "\xc5\x8c" => "\xc5\x8d", // LATIN CAPITAL LETTER O WITH MACRON
+    "\xc5\x8e" => "\xc5\x8f", // LATIN CAPITAL LETTER O WITH BREVE
+    "\xc5\x90" => "\xc5\x91", // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+    "\xc5\x92" => "\xc5\x93", // LATIN CAPITAL LIGATURE OE
+    "\xc5\x94" => "\xc5\x95", // LATIN CAPITAL LETTER R WITH ACUTE
+    "\xc5\x96" => "\xc5\x97", // LATIN CAPITAL LETTER R WITH CEDILLA
+    "\xc5\x98" => "\xc5\x99", // LATIN CAPITAL LETTER R WITH CARON
+    "\xc5\x9a" => "\xc5\x9b", // LATIN CAPITAL LETTER S WITH ACUTE
+    "\xc5\x9c" => "\xc5\x9d", // LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+    "\xc5\x9e" => "\xc5\x9f", // LATIN CAPITAL LETTER S WITH CEDILLA
+    "\xc5\xa0" => "\xc5\xa1", // LATIN CAPITAL LETTER S WITH CARON
+    "\xc5\xa2" => "\xc5\xa3", // LATIN CAPITAL LETTER T WITH CEDILLA
+    "\xc5\xa4" => "\xc5\xa5", // LATIN CAPITAL LETTER T WITH CARON
+    "\xc5\xa6" => "\xc5\xa7", // LATIN CAPITAL LETTER T WITH STROKE
+    "\xc5\xa8" => "\xc5\xa9", // LATIN CAPITAL LETTER U WITH TILDE
+    "\xc5\xaa" => "\xc5\xab", // LATIN CAPITAL LETTER U WITH MACRON
+    "\xc5\xac" => "\xc5\xad", // LATIN CAPITAL LETTER U WITH BREVE
+    "\xc5\xae" => "\xc5\xaf", // LATIN CAPITAL LETTER U WITH RING ABOVE
+    "\xc5\xb0" => "\xc5\xb1", // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+    "\xc5\xb2" => "\xc5\xb3", // LATIN CAPITAL LETTER U WITH OGONEK
+    "\xc5\xb4" => "\xc5\xb5", // LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+    "\xc5\xb6" => "\xc5\xb7", // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+    "\xc5\xb8" => "\xc3\xbf", // LATIN CAPITAL LETTER Y WITH DIAERESIS
+    "\xc5\xb9" => "\xc5\xba", // LATIN CAPITAL LETTER Z WITH ACUTE
+    "\xc5\xbb" => "\xc5\xbc", // LATIN CAPITAL LETTER Z WITH DOT ABOVE
+    "\xc5\xbd" => "\xc5\xbe", // LATIN CAPITAL LETTER Z WITH CARON
+    "\xc6\x81" => "\xc9\x93", // LATIN CAPITAL LETTER B WITH HOOK
+    "\xc6\x82" => "\xc6\x83", // LATIN CAPITAL LETTER B WITH TOPBAR
+    "\xc6\x84" => "\xc6\x85", // LATIN CAPITAL LETTER TONE SIX
+    "\xc6\x86" => "\xc9\x94", // LATIN CAPITAL LETTER OPEN O
+    "\xc6\x87" => "\xc6\x88", // LATIN CAPITAL LETTER C WITH HOOK
+    "\xc6\x89" => "\xc9\x96", // LATIN CAPITAL LETTER AFRICAN D
+    "\xc6\x8a" => "\xc9\x97", // LATIN CAPITAL LETTER D WITH HOOK
+    "\xc6\x8b" => "\xc6\x8c", // LATIN CAPITAL LETTER D WITH TOPBAR
+    "\xc6\x8e" => "\xc7\x9d", // LATIN CAPITAL LETTER REVERSED E
+    "\xc6\x8f" => "\xc9\x99", // LATIN CAPITAL LETTER SCHWA
+    "\xc6\x90" => "\xc9\x9b", // LATIN CAPITAL LETTER OPEN E
+    "\xc6\x91" => "\xc6\x92", // LATIN CAPITAL LETTER F WITH HOOK
+    "\xc6\x93" => "\xc9\xa0", // LATIN CAPITAL LETTER G WITH HOOK
+    "\xc6\x94" => "\xc9\xa3", // LATIN CAPITAL LETTER GAMMA
+    "\xc6\x96" => "\xc9\xa9", // LATIN CAPITAL LETTER IOTA
+    "\xc6\x97" => "\xc9\xa8", // LATIN CAPITAL LETTER I WITH STROKE
+    "\xc6\x98" => "\xc6\x99", // LATIN CAPITAL LETTER K WITH HOOK
+    "\xc6\x9c" => "\xc9\xaf", // LATIN CAPITAL LETTER TURNED M
+    "\xc6\x9d" => "\xc9\xb2", // LATIN CAPITAL LETTER N WITH LEFT HOOK
+    "\xc6\x9f" => "\xc9\xb5", // LATIN CAPITAL LETTER O WITH MIDDLE TILDE
+    "\xc6\xa0" => "\xc6\xa1", // LATIN CAPITAL LETTER O WITH HORN
+    "\xc6\xa2" => "\xc6\xa3", // LATIN CAPITAL LETTER OI
+    "\xc6\xa4" => "\xc6\xa5", // LATIN CAPITAL LETTER P WITH HOOK
+    "\xc6\xa6" => "\xca\x80", // LATIN LETTER YR
+    "\xc6\xa7" => "\xc6\xa8", // LATIN CAPITAL LETTER TONE TWO
+    "\xc6\xa9" => "\xca\x83", // LATIN CAPITAL LETTER ESH
+    "\xc6\xac" => "\xc6\xad", // LATIN CAPITAL LETTER T WITH HOOK
+    "\xc6\xae" => "\xca\x88", // LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
+    "\xc6\xaf" => "\xc6\xb0", // LATIN CAPITAL LETTER U WITH HORN
+    "\xc6\xb1" => "\xca\x8a", // LATIN CAPITAL LETTER UPSILON
+    "\xc6\xb2" => "\xca\x8b", // LATIN CAPITAL LETTER V WITH HOOK
+    "\xc6\xb3" => "\xc6\xb4", // LATIN CAPITAL LETTER Y WITH HOOK
+    "\xc6\xb5" => "\xc6\xb6", // LATIN CAPITAL LETTER Z WITH STROKE
+    "\xc6\xb7" => "\xca\x92", // LATIN CAPITAL LETTER EZH
+    "\xc6\xb8" => "\xc6\xb9", // LATIN CAPITAL LETTER EZH REVERSED
+    "\xc6\xbc" => "\xc6\xbd", // LATIN CAPITAL LETTER TONE FIVE
+    "\xc7\x84" => "\xc7\x86", // LATIN CAPITAL LETTER DZ WITH CARON
+    "\xc7\x85" => "\xc7\x86", // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
+    "\xc7\x87" => "\xc7\x89", // LATIN CAPITAL LETTER LJ
+    "\xc7\x88" => "\xc7\x89", // LATIN CAPITAL LETTER L WITH SMALL LETTER J
+    "\xc7\x8a" => "\xc7\x8c", // LATIN CAPITAL LETTER NJ
+    "\xc7\x8b" => "\xc7\x8c", // LATIN CAPITAL LETTER N WITH SMALL LETTER J
+    "\xc7\x8d" => "\xc7\x8e", // LATIN CAPITAL LETTER A WITH CARON
+    "\xc7\x8f" => "\xc7\x90", // LATIN CAPITAL LETTER I WITH CARON
+    "\xc7\x91" => "\xc7\x92", // LATIN CAPITAL LETTER O WITH CARON
+    "\xc7\x93" => "\xc7\x94", // LATIN CAPITAL LETTER U WITH CARON
+    "\xc7\x95" => "\xc7\x96", // LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+    "\xc7\x97" => "\xc7\x98", // LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+    "\xc7\x99" => "\xc7\x9a", // LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+    "\xc7\x9b" => "\xc7\x9c", // LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+    "\xc7\x9e" => "\xc7\x9f", // LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
+    "\xc7\xa0" => "\xc7\xa1", // LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
+    "\xc7\xa2" => "\xc7\xa3", // LATIN CAPITAL LETTER AE WITH MACRON
+    "\xc7\xa4" => "\xc7\xa5", // LATIN CAPITAL LETTER G WITH STROKE
+    "\xc7\xa6" => "\xc7\xa7", // LATIN CAPITAL LETTER G WITH CARON
+    "\xc7\xa8" => "\xc7\xa9", // LATIN CAPITAL LETTER K WITH CARON
+    "\xc7\xaa" => "\xc7\xab", // LATIN CAPITAL LETTER O WITH OGONEK
+    "\xc7\xac" => "\xc7\xad", // LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
+    "\xc7\xae" => "\xc7\xaf", // LATIN CAPITAL LETTER EZH WITH CARON
+    "\xc7\xb1" => "\xc7\xb3", // LATIN CAPITAL LETTER DZ
+    "\xc7\xb2" => "\xc7\xb3", // LATIN CAPITAL LETTER D WITH SMALL LETTER Z
+    "\xc7\xb4" => "\xc7\xb5", // LATIN CAPITAL LETTER G WITH ACUTE
+    "\xc7\xb6" => "\xc6\x95", // LATIN CAPITAL LETTER HWAIR
+    "\xc7\xb7" => "\xc6\xbf", // LATIN CAPITAL LETTER WYNN
+    "\xc7\xb8" => "\xc7\xb9", // LATIN CAPITAL LETTER N WITH GRAVE
+    "\xc7\xba" => "\xc7\xbb", // LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
+    "\xc7\xbc" => "\xc7\xbd", // LATIN CAPITAL LETTER AE WITH ACUTE
+    "\xc7\xbe" => "\xc7\xbf", // LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
+    "\xc8\x80" => "\xc8\x81", // LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
+    "\xc8\x82" => "\xc8\x83", // LATIN CAPITAL LETTER A WITH INVERTED BREVE
+    "\xc8\x84" => "\xc8\x85", // LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
+    "\xc8\x86" => "\xc8\x87", // LATIN CAPITAL LETTER E WITH INVERTED BREVE
+    "\xc8\x88" => "\xc8\x89", // LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
+    "\xc8\x8a" => "\xc8\x8b", // LATIN CAPITAL LETTER I WITH INVERTED BREVE
+    "\xc8\x8c" => "\xc8\x8d", // LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
+    "\xc8\x8e" => "\xc8\x8f", // LATIN CAPITAL LETTER O WITH INVERTED BREVE
+    "\xc8\x90" => "\xc8\x91", // LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
+    "\xc8\x92" => "\xc8\x93", // LATIN CAPITAL LETTER R WITH INVERTED BREVE
+    "\xc8\x94" => "\xc8\x95", // LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
+    "\xc8\x96" => "\xc8\x97", // LATIN CAPITAL LETTER U WITH INVERTED BREVE
+    "\xc8\x98" => "\xc8\x99", // LATIN CAPITAL LETTER S WITH COMMA BELOW
+    "\xc8\x9a" => "\xc8\x9b", // LATIN CAPITAL LETTER T WITH COMMA BELOW
+    "\xc8\x9c" => "\xc8\x9d", // LATIN CAPITAL LETTER YOGH
+    "\xc8\x9e" => "\xc8\x9f", // LATIN CAPITAL LETTER H WITH CARON
+    "\xc8\xa0" => "\xc6\x9e", // LATIN CAPITAL LETTER N WITH LONG RIGHT LEG
+    "\xc8\xa2" => "\xc8\xa3", // LATIN CAPITAL LETTER OU
+    "\xc8\xa4" => "\xc8\xa5", // LATIN CAPITAL LETTER Z WITH HOOK
+    "\xc8\xa6" => "\xc8\xa7", // LATIN CAPITAL LETTER A WITH DOT ABOVE
+    "\xc8\xa8" => "\xc8\xa9", // LATIN CAPITAL LETTER E WITH CEDILLA
+    "\xc8\xaa" => "\xc8\xab", // LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
+    "\xc8\xac" => "\xc8\xad", // LATIN CAPITAL LETTER O WITH TILDE AND MACRON
+    "\xc8\xae" => "\xc8\xaf", // LATIN CAPITAL LETTER O WITH DOT ABOVE
+    "\xc8\xb0" => "\xc8\xb1", // LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
+    "\xc8\xb2" => "\xc8\xb3", // LATIN CAPITAL LETTER Y WITH MACRON
+    "\xc8\xba" => "\xe2\xb1\xa5", // LATIN CAPITAL LETTER A WITH STROKE
+    "\xc8\xbb" => "\xc8\xbc", // LATIN CAPITAL LETTER C WITH STROKE
+    "\xc8\xbd" => "\xc6\x9a", // LATIN CAPITAL LETTER L WITH BAR
+    "\xc8\xbe" => "\xe2\xb1\xa6", // LATIN CAPITAL LETTER T WITH DIAGONAL STROKE
+    "\xc9\x81" => "\xc9\x82", // LATIN CAPITAL LETTER GLOTTAL STOP
+    "\xc9\x83" => "\xc6\x80", // LATIN CAPITAL LETTER B WITH STROKE
+    "\xc9\x84" => "\xca\x89", // LATIN CAPITAL LETTER U BAR
+    "\xc9\x85" => "\xca\x8c", // LATIN CAPITAL LETTER TURNED V
+    "\xc9\x86" => "\xc9\x87", // LATIN CAPITAL LETTER E WITH STROKE
+    "\xc9\x88" => "\xc9\x89", // LATIN CAPITAL LETTER J WITH STROKE
+    "\xc9\x8a" => "\xc9\x8b", // LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL
+    "\xc9\x8c" => "\xc9\x8d", // LATIN CAPITAL LETTER R WITH STROKE
+    "\xc9\x8e" => "\xc9\x8f", // LATIN CAPITAL LETTER Y WITH STROKE
+    "\xcd\xb0" => "\xcd\xb1", // GREEK CAPITAL LETTER HETA
+    "\xcd\xb2" => "\xcd\xb3", // GREEK CAPITAL LETTER ARCHAIC SAMPI
+    "\xcd\xb6" => "\xcd\xb7", // GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA
+    "\xce\x86" => "\xce\xac", // GREEK CAPITAL LETTER ALPHA WITH TONOS
+    "\xce\x88" => "\xce\xad", // GREEK CAPITAL LETTER EPSILON WITH TONOS
+    "\xce\x89" => "\xce\xae", // GREEK CAPITAL LETTER ETA WITH TONOS
+    "\xce\x8a" => "\xce\xaf", // GREEK CAPITAL LETTER IOTA WITH TONOS
+    "\xce\x8c" => "\xcf\x8c", // GREEK CAPITAL LETTER OMICRON WITH TONOS
+    "\xce\x8e" => "\xcf\x8d", // GREEK CAPITAL LETTER UPSILON WITH TONOS
+    "\xce\x8f" => "\xcf\x8e", // GREEK CAPITAL LETTER OMEGA WITH TONOS
+    "\xce\x91" => "\xce\xb1", // GREEK CAPITAL LETTER ALPHA
+    "\xce\x92" => "\xce\xb2", // GREEK CAPITAL LETTER BETA
+    "\xce\x93" => "\xce\xb3", // GREEK CAPITAL LETTER GAMMA
+    "\xce\x94" => "\xce\xb4", // GREEK CAPITAL LETTER DELTA
+    "\xce\x95" => "\xce\xb5", // GREEK CAPITAL LETTER EPSILON
+    "\xce\x96" => "\xce\xb6", // GREEK CAPITAL LETTER ZETA
+    "\xce\x97" => "\xce\xb7", // GREEK CAPITAL LETTER ETA
+    "\xce\x98" => "\xce\xb8", // GREEK CAPITAL LETTER THETA
+    "\xce\x99" => "\xce\xb9", // GREEK CAPITAL LETTER IOTA
+    "\xce\x9a" => "\xce\xba", // GREEK CAPITAL LETTER KAPPA
+    "\xce\x9b" => "\xce\xbb", // GREEK CAPITAL LETTER LAMDA
+    "\xce\x9c" => "\xce\xbc", // GREEK CAPITAL LETTER MU
+    "\xce\x9d" => "\xce\xbd", // GREEK CAPITAL LETTER NU
+    "\xce\x9e" => "\xce\xbe", // GREEK CAPITAL LETTER XI
+    "\xce\x9f" => "\xce\xbf", // GREEK CAPITAL LETTER OMICRON
+    "\xce\xa0" => "\xcf\x80", // GREEK CAPITAL LETTER PI
+    "\xce\xa1" => "\xcf\x81", // GREEK CAPITAL LETTER RHO
+    "\xce\xa3" => "\xcf\x83", // GREEK CAPITAL LETTER SIGMA
+    "\xce\xa4" => "\xcf\x84", // GREEK CAPITAL LETTER TAU
+    "\xce\xa5" => "\xcf\x85", // GREEK CAPITAL LETTER UPSILON
+    "\xce\xa6" => "\xcf\x86", // GREEK CAPITAL LETTER PHI
+    "\xce\xa7" => "\xcf\x87", // GREEK CAPITAL LETTER CHI
+    "\xce\xa8" => "\xcf\x88", // GREEK CAPITAL LETTER PSI
+    "\xce\xa9" => "\xcf\x89", // GREEK CAPITAL LETTER OMEGA
+    "\xce\xaa" => "\xcf\x8a", // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+    "\xce\xab" => "\xcf\x8b", // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+    "\xcf\x8f" => "\xcf\x97", // GREEK CAPITAL KAI SYMBOL
+    "\xcf\x98" => "\xcf\x99", // GREEK LETTER ARCHAIC KOPPA
+    "\xcf\x9a" => "\xcf\x9b", // GREEK LETTER STIGMA
+    "\xcf\x9c" => "\xcf\x9d", // GREEK LETTER DIGAMMA
+    "\xcf\x9e" => "\xcf\x9f", // GREEK LETTER KOPPA
+    "\xcf\xa0" => "\xcf\xa1", // GREEK LETTER SAMPI
+    "\xcf\xa2" => "\xcf\xa3", // COPTIC CAPITAL LETTER SHEI
+    "\xcf\xa4" => "\xcf\xa5", // COPTIC CAPITAL LETTER FEI
+    "\xcf\xa6" => "\xcf\xa7", // COPTIC CAPITAL LETTER KHEI
+    "\xcf\xa8" => "\xcf\xa9", // COPTIC CAPITAL LETTER HORI
+    "\xcf\xaa" => "\xcf\xab", // COPTIC CAPITAL LETTER GANGIA
+    "\xcf\xac" => "\xcf\xad", // COPTIC CAPITAL LETTER SHIMA
+    "\xcf\xae" => "\xcf\xaf", // COPTIC CAPITAL LETTER DEI
+    "\xcf\xb4" => "\xce\xb8", // GREEK CAPITAL THETA SYMBOL
+    "\xcf\xb7" => "\xcf\xb8", // GREEK CAPITAL LETTER SHO
+    "\xcf\xb9" => "\xcf\xb2", // GREEK CAPITAL LUNATE SIGMA SYMBOL
+    "\xcf\xba" => "\xcf\xbb", // GREEK CAPITAL LETTER SAN
+    "\xcf\xbd" => "\xcd\xbb", // GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL
+    "\xcf\xbe" => "\xcd\xbc", // GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL
+    "\xcf\xbf" => "\xcd\xbd", // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+    "\xd0\x80" => "\xd1\x90", // CYRILLIC CAPITAL LETTER IE WITH GRAVE
+    "\xd0\x81" => "\xd1\x91", // CYRILLIC CAPITAL LETTER IO
+    "\xd0\x82" => "\xd1\x92", // CYRILLIC CAPITAL LETTER DJE
+    "\xd0\x83" => "\xd1\x93", // CYRILLIC CAPITAL LETTER GJE
+    "\xd0\x84" => "\xd1\x94", // CYRILLIC CAPITAL LETTER UKRAINIAN IE
+    "\xd0\x85" => "\xd1\x95", // CYRILLIC CAPITAL LETTER DZE
+    "\xd0\x86" => "\xd1\x96", // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+    "\xd0\x87" => "\xd1\x97", // CYRILLIC CAPITAL LETTER YI
+    "\xd0\x88" => "\xd1\x98", // CYRILLIC CAPITAL LETTER JE
+    "\xd0\x89" => "\xd1\x99", // CYRILLIC CAPITAL LETTER LJE
+    "\xd0\x8a" => "\xd1\x9a", // CYRILLIC CAPITAL LETTER NJE
+    "\xd0\x8b" => "\xd1\x9b", // CYRILLIC CAPITAL LETTER TSHE
+    "\xd0\x8c" => "\xd1\x9c", // CYRILLIC CAPITAL LETTER KJE
+    "\xd0\x8d" => "\xd1\x9d", // CYRILLIC CAPITAL LETTER I WITH GRAVE
+    "\xd0\x8e" => "\xd1\x9e", // CYRILLIC CAPITAL LETTER SHORT U
+    "\xd0\x8f" => "\xd1\x9f", // CYRILLIC CAPITAL LETTER DZHE
+    "\xd0\x90" => "\xd0\xb0", // CYRILLIC CAPITAL LETTER A
+    "\xd0\x91" => "\xd0\xb1", // CYRILLIC CAPITAL LETTER BE
+    "\xd0\x92" => "\xd0\xb2", // CYRILLIC CAPITAL LETTER VE
+    "\xd0\x93" => "\xd0\xb3", // CYRILLIC CAPITAL LETTER GHE
+    "\xd0\x94" => "\xd0\xb4", // CYRILLIC CAPITAL LETTER DE
+    "\xd0\x95" => "\xd0\xb5", // CYRILLIC CAPITAL LETTER IE
+    "\xd0\x96" => "\xd0\xb6", // CYRILLIC CAPITAL LETTER ZHE
+    "\xd0\x97" => "\xd0\xb7", // CYRILLIC CAPITAL LETTER ZE
+    "\xd0\x98" => "\xd0\xb8", // CYRILLIC CAPITAL LETTER I
+    "\xd0\x99" => "\xd0\xb9", // CYRILLIC CAPITAL LETTER SHORT I
+    "\xd0\x9a" => "\xd0\xba", // CYRILLIC CAPITAL LETTER KA
+    "\xd0\x9b" => "\xd0\xbb", // CYRILLIC CAPITAL LETTER EL
+    "\xd0\x9c" => "\xd0\xbc", // CYRILLIC CAPITAL LETTER EM
+    "\xd0\x9d" => "\xd0\xbd", // CYRILLIC CAPITAL LETTER EN
+    "\xd0\x9e" => "\xd0\xbe", // CYRILLIC CAPITAL LETTER O
+    "\xd0\x9f" => "\xd0\xbf", // CYRILLIC CAPITAL LETTER PE
+    "\xd0\xa0" => "\xd1\x80", // CYRILLIC CAPITAL LETTER ER
+    "\xd0\xa1" => "\xd1\x81", // CYRILLIC CAPITAL LETTER ES
+    "\xd0\xa2" => "\xd1\x82", // CYRILLIC CAPITAL LETTER TE
+    "\xd0\xa3" => "\xd1\x83", // CYRILLIC CAPITAL LETTER U
+    "\xd0\xa4" => "\xd1\x84", // CYRILLIC CAPITAL LETTER EF
+    "\xd0\xa5" => "\xd1\x85", // CYRILLIC CAPITAL LETTER HA
+    "\xd0\xa6" => "\xd1\x86", // CYRILLIC CAPITAL LETTER TSE
+    "\xd0\xa7" => "\xd1\x87", // CYRILLIC CAPITAL LETTER CHE
+    "\xd0\xa8" => "\xd1\x88", // CYRILLIC CAPITAL LETTER SHA
+    "\xd0\xa9" => "\xd1\x89", // CYRILLIC CAPITAL LETTER SHCHA
+    "\xd0\xaa" => "\xd1\x8a", // CYRILLIC CAPITAL LETTER HARD SIGN
+    "\xd0\xab" => "\xd1\x8b", // CYRILLIC CAPITAL LETTER YERU
+    "\xd0\xac" => "\xd1\x8c", // CYRILLIC CAPITAL LETTER SOFT SIGN
+    "\xd0\xad" => "\xd1\x8d", // CYRILLIC CAPITAL LETTER E
+    "\xd0\xae" => "\xd1\x8e", // CYRILLIC CAPITAL LETTER YU
+    "\xd0\xaf" => "\xd1\x8f", // CYRILLIC CAPITAL LETTER YA
+    "\xd1\xa0" => "\xd1\xa1", // CYRILLIC CAPITAL LETTER OMEGA
+    "\xd1\xa2" => "\xd1\xa3", // CYRILLIC CAPITAL LETTER YAT
+    "\xd1\xa4" => "\xd1\xa5", // CYRILLIC CAPITAL LETTER IOTIFIED E
+    "\xd1\xa6" => "\xd1\xa7", // CYRILLIC CAPITAL LETTER LITTLE YUS
+    "\xd1\xa8" => "\xd1\xa9", // CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
+    "\xd1\xaa" => "\xd1\xab", // CYRILLIC CAPITAL LETTER BIG YUS
+    "\xd1\xac" => "\xd1\xad", // CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
+    "\xd1\xae" => "\xd1\xaf", // CYRILLIC CAPITAL LETTER KSI
+    "\xd1\xb0" => "\xd1\xb1", // CYRILLIC CAPITAL LETTER PSI
+    "\xd1\xb2" => "\xd1\xb3", // CYRILLIC CAPITAL LETTER FITA
+    "\xd1\xb4" => "\xd1\xb5", // CYRILLIC CAPITAL LETTER IZHITSA
+    "\xd1\xb6" => "\xd1\xb7", // CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
+    "\xd1\xb8" => "\xd1\xb9", // CYRILLIC CAPITAL LETTER UK
+    "\xd1\xba" => "\xd1\xbb", // CYRILLIC CAPITAL LETTER ROUND OMEGA
+    "\xd1\xbc" => "\xd1\xbd", // CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
+    "\xd1\xbe" => "\xd1\xbf", // CYRILLIC CAPITAL LETTER OT
+    "\xd2\x80" => "\xd2\x81", // CYRILLIC CAPITAL LETTER KOPPA
+    "\xd2\x8a" => "\xd2\x8b", // CYRILLIC CAPITAL LETTER SHORT I WITH TAIL
+    "\xd2\x8c" => "\xd2\x8d", // CYRILLIC CAPITAL LETTER SEMISOFT SIGN
+    "\xd2\x8e" => "\xd2\x8f", // CYRILLIC CAPITAL LETTER ER WITH TICK
+    "\xd2\x90" => "\xd2\x91", // CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+    "\xd2\x92" => "\xd2\x93", // CYRILLIC CAPITAL LETTER GHE WITH STROKE
+    "\xd2\x94" => "\xd2\x95", // CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
+    "\xd2\x96" => "\xd2\x97", // CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
+    "\xd2\x98" => "\xd2\x99", // CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
+    "\xd2\x9a" => "\xd2\x9b", // CYRILLIC CAPITAL LETTER KA WITH DESCENDER
+    "\xd2\x9c" => "\xd2\x9d", // CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
+    "\xd2\x9e" => "\xd2\x9f", // CYRILLIC CAPITAL LETTER KA WITH STROKE
+    "\xd2\xa0" => "\xd2\xa1", // CYRILLIC CAPITAL LETTER BASHKIR KA
+    "\xd2\xa2" => "\xd2\xa3", // CYRILLIC CAPITAL LETTER EN WITH DESCENDER
+    "\xd2\xa4" => "\xd2\xa5", // CYRILLIC CAPITAL LIGATURE EN GHE
+    "\xd2\xa6" => "\xd2\xa7", // CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
+    "\xd2\xa8" => "\xd2\xa9", // CYRILLIC CAPITAL LETTER ABKHASIAN HA
+    "\xd2\xaa" => "\xd2\xab", // CYRILLIC CAPITAL LETTER ES WITH DESCENDER
+    "\xd2\xac" => "\xd2\xad", // CYRILLIC CAPITAL LETTER TE WITH DESCENDER
+    "\xd2\xae" => "\xd2\xaf", // CYRILLIC CAPITAL LETTER STRAIGHT U
+    "\xd2\xb0" => "\xd2\xb1", // CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
+    "\xd2\xb2" => "\xd2\xb3", // CYRILLIC CAPITAL LETTER HA WITH DESCENDER
+    "\xd2\xb4" => "\xd2\xb5", // CYRILLIC CAPITAL LIGATURE TE TSE
+    "\xd2\xb6" => "\xd2\xb7", // CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
+    "\xd2\xb8" => "\xd2\xb9", // CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
+    "\xd2\xba" => "\xd2\xbb", // CYRILLIC CAPITAL LETTER SHHA
+    "\xd2\xbc" => "\xd2\xbd", // CYRILLIC CAPITAL LETTER ABKHASIAN CHE
+    "\xd2\xbe" => "\xd2\xbf", // CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
+    "\xd3\x80" => "\xd3\x8f", // CYRILLIC LETTER PALOCHKA
+    "\xd3\x81" => "\xd3\x82", // CYRILLIC CAPITAL LETTER ZHE WITH BREVE
+    "\xd3\x83" => "\xd3\x84", // CYRILLIC CAPITAL LETTER KA WITH HOOK
+    "\xd3\x85" => "\xd3\x86", // CYRILLIC CAPITAL LETTER EL WITH TAIL
+    "\xd3\x87" => "\xd3\x88", // CYRILLIC CAPITAL LETTER EN WITH HOOK
+    "\xd3\x89" => "\xd3\x8a", // CYRILLIC CAPITAL LETTER EN WITH TAIL
+    "\xd3\x8b" => "\xd3\x8c", // CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
+    "\xd3\x8d" => "\xd3\x8e", // CYRILLIC CAPITAL LETTER EM WITH TAIL
+    "\xd3\x90" => "\xd3\x91", // CYRILLIC CAPITAL LETTER A WITH BREVE
+    "\xd3\x92" => "\xd3\x93", // CYRILLIC CAPITAL LETTER A WITH DIAERESIS
+    "\xd3\x94" => "\xd3\x95", // CYRILLIC CAPITAL LIGATURE A IE
+    "\xd3\x96" => "\xd3\x97", // CYRILLIC CAPITAL LETTER IE WITH BREVE
+    "\xd3\x98" => "\xd3\x99", // CYRILLIC CAPITAL LETTER SCHWA
+    "\xd3\x9a" => "\xd3\x9b", // CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
+    "\xd3\x9c" => "\xd3\x9d", // CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
+    "\xd3\x9e" => "\xd3\x9f", // CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
+    "\xd3\xa0" => "\xd3\xa1", // CYRILLIC CAPITAL LETTER ABKHASIAN DZE
+    "\xd3\xa2" => "\xd3\xa3", // CYRILLIC CAPITAL LETTER I WITH MACRON
+    "\xd3\xa4" => "\xd3\xa5", // CYRILLIC CAPITAL LETTER I WITH DIAERESIS
+    "\xd3\xa6" => "\xd3\xa7", // CYRILLIC CAPITAL LETTER O WITH DIAERESIS
+    "\xd3\xa8" => "\xd3\xa9", // CYRILLIC CAPITAL LETTER BARRED O
+    "\xd3\xaa" => "\xd3\xab", // CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
+    "\xd3\xac" => "\xd3\xad", // CYRILLIC CAPITAL LETTER E WITH DIAERESIS
+    "\xd3\xae" => "\xd3\xaf", // CYRILLIC CAPITAL LETTER U WITH MACRON
+    "\xd3\xb0" => "\xd3\xb1", // CYRILLIC CAPITAL LETTER U WITH DIAERESIS
+    "\xd3\xb2" => "\xd3\xb3", // CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
+    "\xd3\xb4" => "\xd3\xb5", // CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
+    "\xd3\xb6" => "\xd3\xb7", // CYRILLIC CAPITAL LETTER GHE WITH DESCENDER
+    "\xd3\xb8" => "\xd3\xb9", // CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
+    "\xd3\xba" => "\xd3\xbb", // CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK
+    "\xd3\xbc" => "\xd3\xbd", // CYRILLIC CAPITAL LETTER HA WITH HOOK
+    "\xd3\xbe" => "\xd3\xbf", // CYRILLIC CAPITAL LETTER HA WITH STROKE
+    "\xd4\x80" => "\xd4\x81", // CYRILLIC CAPITAL LETTER KOMI DE
+    "\xd4\x82" => "\xd4\x83", // CYRILLIC CAPITAL LETTER KOMI DJE
+    "\xd4\x84" => "\xd4\x85", // CYRILLIC CAPITAL LETTER KOMI ZJE
+    "\xd4\x86" => "\xd4\x87", // CYRILLIC CAPITAL LETTER KOMI DZJE
+    "\xd4\x88" => "\xd4\x89", // CYRILLIC CAPITAL LETTER KOMI LJE
+    "\xd4\x8a" => "\xd4\x8b", // CYRILLIC CAPITAL LETTER KOMI NJE
+    "\xd4\x8c" => "\xd4\x8d", // CYRILLIC CAPITAL LETTER KOMI SJE
+    "\xd4\x8e" => "\xd4\x8f", // CYRILLIC CAPITAL LETTER KOMI TJE
+    "\xd4\x90" => "\xd4\x91", // CYRILLIC CAPITAL LETTER REVERSED ZE
+    "\xd4\x92" => "\xd4\x93", // CYRILLIC CAPITAL LETTER EL WITH HOOK
+    "\xd4\x94" => "\xd4\x95", // CYRILLIC CAPITAL LETTER LHA
+    "\xd4\x96" => "\xd4\x97", // CYRILLIC CAPITAL LETTER RHA
+    "\xd4\x98" => "\xd4\x99", // CYRILLIC CAPITAL LETTER YAE
+    "\xd4\x9a" => "\xd4\x9b", // CYRILLIC CAPITAL LETTER QA
+    "\xd4\x9c" => "\xd4\x9d", // CYRILLIC CAPITAL LETTER WE
+    "\xd4\x9e" => "\xd4\x9f", // CYRILLIC CAPITAL LETTER ALEUT KA
+    "\xd4\xa0" => "\xd4\xa1", // CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK
+    "\xd4\xa2" => "\xd4\xa3", // CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK
+    "\xd4\xa4" => "\xd4\xa5", // CYRILLIC CAPITAL LETTER PE WITH DESCENDER
+    "\xd4\xa6" => "\xd4\xa7", // CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER
+    "\xd4\xb1" => "\xd5\xa1", // ARMENIAN CAPITAL LETTER AYB
+    "\xd4\xb2" => "\xd5\xa2", // ARMENIAN CAPITAL LETTER BEN
+    "\xd4\xb3" => "\xd5\xa3", // ARMENIAN CAPITAL LETTER GIM
+    "\xd4\xb4" => "\xd5\xa4", // ARMENIAN CAPITAL LETTER DA
+    "\xd4\xb5" => "\xd5\xa5", // ARMENIAN CAPITAL LETTER ECH
+    "\xd4\xb6" => "\xd5\xa6", // ARMENIAN CAPITAL LETTER ZA
+    "\xd4\xb7" => "\xd5\xa7", // ARMENIAN CAPITAL LETTER EH
+    "\xd4\xb8" => "\xd5\xa8", // ARMENIAN CAPITAL LETTER ET
+    "\xd4\xb9" => "\xd5\xa9", // ARMENIAN CAPITAL LETTER TO
+    "\xd4\xba" => "\xd5\xaa", // ARMENIAN CAPITAL LETTER ZHE
+    "\xd4\xbb" => "\xd5\xab", // ARMENIAN CAPITAL LETTER INI
+    "\xd4\xbc" => "\xd5\xac", // ARMENIAN CAPITAL LETTER LIWN
+    "\xd4\xbd" => "\xd5\xad", // ARMENIAN CAPITAL LETTER XEH
+    "\xd4\xbe" => "\xd5\xae", // ARMENIAN CAPITAL LETTER CA
+    "\xd4\xbf" => "\xd5\xaf", // ARMENIAN CAPITAL LETTER KEN
+    "\xd5\x80" => "\xd5\xb0", // ARMENIAN CAPITAL LETTER HO
+    "\xd5\x81" => "\xd5\xb1", // ARMENIAN CAPITAL LETTER JA
+    "\xd5\x82" => "\xd5\xb2", // ARMENIAN CAPITAL LETTER GHAD
+    "\xd5\x83" => "\xd5\xb3", // ARMENIAN CAPITAL LETTER CHEH
+    "\xd5\x84" => "\xd5\xb4", // ARMENIAN CAPITAL LETTER MEN
+    "\xd5\x85" => "\xd5\xb5", // ARMENIAN CAPITAL LETTER YI
+    "\xd5\x86" => "\xd5\xb6", // ARMENIAN CAPITAL LETTER NOW
+    "\xd5\x87" => "\xd5\xb7", // ARMENIAN CAPITAL LETTER SHA
+    "\xd5\x88" => "\xd5\xb8", // ARMENIAN CAPITAL LETTER VO
+    "\xd5\x89" => "\xd5\xb9", // ARMENIAN CAPITAL LETTER CHA
+    "\xd5\x8a" => "\xd5\xba", // ARMENIAN CAPITAL LETTER PEH
+    "\xd5\x8b" => "\xd5\xbb", // ARMENIAN CAPITAL LETTER JHEH
+    "\xd5\x8c" => "\xd5\xbc", // ARMENIAN CAPITAL LETTER RA
+    "\xd5\x8d" => "\xd5\xbd", // ARMENIAN CAPITAL LETTER SEH
+    "\xd5\x8e" => "\xd5\xbe", // ARMENIAN CAPITAL LETTER VEW
+    "\xd5\x8f" => "\xd5\xbf", // ARMENIAN CAPITAL LETTER TIWN
+    "\xd5\x90" => "\xd6\x80", // ARMENIAN CAPITAL LETTER REH
+    "\xd5\x91" => "\xd6\x81", // ARMENIAN CAPITAL LETTER CO
+    "\xd5\x92" => "\xd6\x82", // ARMENIAN CAPITAL LETTER YIWN
+    "\xd5\x93" => "\xd6\x83", // ARMENIAN CAPITAL LETTER PIWR
+    "\xd5\x94" => "\xd6\x84", // ARMENIAN CAPITAL LETTER KEH
+    "\xd5\x95" => "\xd6\x85", // ARMENIAN CAPITAL LETTER OH
+    "\xd5\x96" => "\xd6\x86", // ARMENIAN CAPITAL LETTER FEH
+    "\xe1\x82\xa0" => "\xe2\xb4\x80", // GEORGIAN CAPITAL LETTER AN
+    "\xe1\x82\xa1" => "\xe2\xb4\x81", // GEORGIAN CAPITAL LETTER BAN
+    "\xe1\x82\xa2" => "\xe2\xb4\x82", // GEORGIAN CAPITAL LETTER GAN
+    "\xe1\x82\xa3" => "\xe2\xb4\x83", // GEORGIAN CAPITAL LETTER DON
+    "\xe1\x82\xa4" => "\xe2\xb4\x84", // GEORGIAN CAPITAL LETTER EN
+    "\xe1\x82\xa5" => "\xe2\xb4\x85", // GEORGIAN CAPITAL LETTER VIN
+    "\xe1\x82\xa6" => "\xe2\xb4\x86", // GEORGIAN CAPITAL LETTER ZEN
+    "\xe1\x82\xa7" => "\xe2\xb4\x87", // GEORGIAN CAPITAL LETTER TAN
+    "\xe1\x82\xa8" => "\xe2\xb4\x88", // GEORGIAN CAPITAL LETTER IN
+    "\xe1\x82\xa9" => "\xe2\xb4\x89", // GEORGIAN CAPITAL LETTER KAN
+    "\xe1\x82\xaa" => "\xe2\xb4\x8a", // GEORGIAN CAPITAL LETTER LAS
+    "\xe1\x82\xab" => "\xe2\xb4\x8b", // GEORGIAN CAPITAL LETTER MAN
+    "\xe1\x82\xac" => "\xe2\xb4\x8c", // GEORGIAN CAPITAL LETTER NAR
+    "\xe1\x82\xad" => "\xe2\xb4\x8d", // GEORGIAN CAPITAL LETTER ON
+    "\xe1\x82\xae" => "\xe2\xb4\x8e", // GEORGIAN CAPITAL LETTER PAR
+    "\xe1\x82\xaf" => "\xe2\xb4\x8f", // GEORGIAN CAPITAL LETTER ZHAR
+    "\xe1\x82\xb0" => "\xe2\xb4\x90", // GEORGIAN CAPITAL LETTER RAE
+    "\xe1\x82\xb1" => "\xe2\xb4\x91", // GEORGIAN CAPITAL LETTER SAN
+    "\xe1\x82\xb2" => "\xe2\xb4\x92", // GEORGIAN CAPITAL LETTER TAR
+    "\xe1\x82\xb3" => "\xe2\xb4\x93", // GEORGIAN CAPITAL LETTER UN
+    "\xe1\x82\xb4" => "\xe2\xb4\x94", // GEORGIAN CAPITAL LETTER PHAR
+    "\xe1\x82\xb5" => "\xe2\xb4\x95", // GEORGIAN CAPITAL LETTER KHAR
+    "\xe1\x82\xb6" => "\xe2\xb4\x96", // GEORGIAN CAPITAL LETTER GHAN
+    "\xe1\x82\xb7" => "\xe2\xb4\x97", // GEORGIAN CAPITAL LETTER QAR
+    "\xe1\x82\xb8" => "\xe2\xb4\x98", // GEORGIAN CAPITAL LETTER SHIN
+    "\xe1\x82\xb9" => "\xe2\xb4\x99", // GEORGIAN CAPITAL LETTER CHIN
+    "\xe1\x82\xba" => "\xe2\xb4\x9a", // GEORGIAN CAPITAL LETTER CAN
+    "\xe1\x82\xbb" => "\xe2\xb4\x9b", // GEORGIAN CAPITAL LETTER JIL
+    "\xe1\x82\xbc" => "\xe2\xb4\x9c", // GEORGIAN CAPITAL LETTER CIL
+    "\xe1\x82\xbd" => "\xe2\xb4\x9d", // GEORGIAN CAPITAL LETTER CHAR
+    "\xe1\x82\xbe" => "\xe2\xb4\x9e", // GEORGIAN CAPITAL LETTER XAN
+    "\xe1\x82\xbf" => "\xe2\xb4\x9f", // GEORGIAN CAPITAL LETTER JHAN
+    "\xe1\x83\x80" => "\xe2\xb4\xa0", // GEORGIAN CAPITAL LETTER HAE
+    "\xe1\x83\x81" => "\xe2\xb4\xa1", // GEORGIAN CAPITAL LETTER HE
+    "\xe1\x83\x82" => "\xe2\xb4\xa2", // GEORGIAN CAPITAL LETTER HIE
+    "\xe1\x83\x83" => "\xe2\xb4\xa3", // GEORGIAN CAPITAL LETTER WE
+    "\xe1\x83\x84" => "\xe2\xb4\xa4", // GEORGIAN CAPITAL LETTER HAR
+    "\xe1\x83\x85" => "\xe2\xb4\xa5", // GEORGIAN CAPITAL LETTER HOE
+    "\xe1\xb8\x80" => "\xe1\xb8\x81", // LATIN CAPITAL LETTER A WITH RING BELOW
+    "\xe1\xb8\x82" => "\xe1\xb8\x83", // LATIN CAPITAL LETTER B WITH DOT ABOVE
+    "\xe1\xb8\x84" => "\xe1\xb8\x85", // LATIN CAPITAL LETTER B WITH DOT BELOW
+    "\xe1\xb8\x86" => "\xe1\xb8\x87", // LATIN CAPITAL LETTER B WITH LINE BELOW
+    "\xe1\xb8\x88" => "\xe1\xb8\x89", // LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
+    "\xe1\xb8\x8a" => "\xe1\xb8\x8b", // LATIN CAPITAL LETTER D WITH DOT ABOVE
+    "\xe1\xb8\x8c" => "\xe1\xb8\x8d", // LATIN CAPITAL LETTER D WITH DOT BELOW
+    "\xe1\xb8\x8e" => "\xe1\xb8\x8f", // LATIN CAPITAL LETTER D WITH LINE BELOW
+    "\xe1\xb8\x90" => "\xe1\xb8\x91", // LATIN CAPITAL LETTER D WITH CEDILLA
+    "\xe1\xb8\x92" => "\xe1\xb8\x93", // LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
+    "\xe1\xb8\x94" => "\xe1\xb8\x95", // LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
+    "\xe1\xb8\x96" => "\xe1\xb8\x97", // LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
+    "\xe1\xb8\x98" => "\xe1\xb8\x99", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
+    "\xe1\xb8\x9a" => "\xe1\xb8\x9b", // LATIN CAPITAL LETTER E WITH TILDE BELOW
+    "\xe1\xb8\x9c" => "\xe1\xb8\x9d", // LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
+    "\xe1\xb8\x9e" => "\xe1\xb8\x9f", // LATIN CAPITAL LETTER F WITH DOT ABOVE
+    "\xe1\xb8\xa0" => "\xe1\xb8\xa1", // LATIN CAPITAL LETTER G WITH MACRON
+    "\xe1\xb8\xa2" => "\xe1\xb8\xa3", // LATIN CAPITAL LETTER H WITH DOT ABOVE
+    "\xe1\xb8\xa4" => "\xe1\xb8\xa5", // LATIN CAPITAL LETTER H WITH DOT BELOW
+    "\xe1\xb8\xa6" => "\xe1\xb8\xa7", // LATIN CAPITAL LETTER H WITH DIAERESIS
+    "\xe1\xb8\xa8" => "\xe1\xb8\xa9", // LATIN CAPITAL LETTER H WITH CEDILLA
+    "\xe1\xb8\xaa" => "\xe1\xb8\xab", // LATIN CAPITAL LETTER H WITH BREVE BELOW
+    "\xe1\xb8\xac" => "\xe1\xb8\xad", // LATIN CAPITAL LETTER I WITH TILDE BELOW
+    "\xe1\xb8\xae" => "\xe1\xb8\xaf", // LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
+    "\xe1\xb8\xb0" => "\xe1\xb8\xb1", // LATIN CAPITAL LETTER K WITH ACUTE
+    "\xe1\xb8\xb2" => "\xe1\xb8\xb3", // LATIN CAPITAL LETTER K WITH DOT BELOW
+    "\xe1\xb8\xb4" => "\xe1\xb8\xb5", // LATIN CAPITAL LETTER K WITH LINE BELOW
+    "\xe1\xb8\xb6" => "\xe1\xb8\xb7", // LATIN CAPITAL LETTER L WITH DOT BELOW
+    "\xe1\xb8\xb8" => "\xe1\xb8\xb9", // LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
+    "\xe1\xb8\xba" => "\xe1\xb8\xbb", // LATIN CAPITAL LETTER L WITH LINE BELOW
+    "\xe1\xb8\xbc" => "\xe1\xb8\xbd", // LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
+    "\xe1\xb8\xbe" => "\xe1\xb8\xbf", // LATIN CAPITAL LETTER M WITH ACUTE
+    "\xe1\xb9\x80" => "\xe1\xb9\x81", // LATIN CAPITAL LETTER M WITH DOT ABOVE
+    "\xe1\xb9\x82" => "\xe1\xb9\x83", // LATIN CAPITAL LETTER M WITH DOT BELOW
+    "\xe1\xb9\x84" => "\xe1\xb9\x85", // LATIN CAPITAL LETTER N WITH DOT ABOVE
+    "\xe1\xb9\x86" => "\xe1\xb9\x87", // LATIN CAPITAL LETTER N WITH DOT BELOW
+    "\xe1\xb9\x88" => "\xe1\xb9\x89", // LATIN CAPITAL LETTER N WITH LINE BELOW
+    "\xe1\xb9\x8a" => "\xe1\xb9\x8b", // LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
+    "\xe1\xb9\x8c" => "\xe1\xb9\x8d", // LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
+    "\xe1\xb9\x8e" => "\xe1\xb9\x8f", // LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
+    "\xe1\xb9\x90" => "\xe1\xb9\x91", // LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
+    "\xe1\xb9\x92" => "\xe1\xb9\x93", // LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
+    "\xe1\xb9\x94" => "\xe1\xb9\x95", // LATIN CAPITAL LETTER P WITH ACUTE
+    "\xe1\xb9\x96" => "\xe1\xb9\x97", // LATIN CAPITAL LETTER P WITH DOT ABOVE
+    "\xe1\xb9\x98" => "\xe1\xb9\x99", // LATIN CAPITAL LETTER R WITH DOT ABOVE
+    "\xe1\xb9\x9a" => "\xe1\xb9\x9b", // LATIN CAPITAL LETTER R WITH DOT BELOW
+    "\xe1\xb9\x9c" => "\xe1\xb9\x9d", // LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
+    "\xe1\xb9\x9e" => "\xe1\xb9\x9f", // LATIN CAPITAL LETTER R WITH LINE BELOW
+    "\xe1\xb9\xa0" => "\xe1\xb9\xa1", // LATIN CAPITAL LETTER S WITH DOT ABOVE
+    "\xe1\xb9\xa2" => "\xe1\xb9\xa3", // LATIN CAPITAL LETTER S WITH DOT BELOW
+    "\xe1\xb9\xa4" => "\xe1\xb9\xa5", // LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
+    "\xe1\xb9\xa6" => "\xe1\xb9\xa7", // LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
+    "\xe1\xb9\xa8" => "\xe1\xb9\xa9", // LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
+    "\xe1\xb9\xaa" => "\xe1\xb9\xab", // LATIN CAPITAL LETTER T WITH DOT ABOVE
+    "\xe1\xb9\xac" => "\xe1\xb9\xad", // LATIN CAPITAL LETTER T WITH DOT BELOW
+    "\xe1\xb9\xae" => "\xe1\xb9\xaf", // LATIN CAPITAL LETTER T WITH LINE BELOW
+    "\xe1\xb9\xb0" => "\xe1\xb9\xb1", // LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
+    "\xe1\xb9\xb2" => "\xe1\xb9\xb3", // LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
+    "\xe1\xb9\xb4" => "\xe1\xb9\xb5", // LATIN CAPITAL LETTER U WITH TILDE BELOW
+    "\xe1\xb9\xb6" => "\xe1\xb9\xb7", // LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
+    "\xe1\xb9\xb8" => "\xe1\xb9\xb9", // LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
+    "\xe1\xb9\xba" => "\xe1\xb9\xbb", // LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
+    "\xe1\xb9\xbc" => "\xe1\xb9\xbd", // LATIN CAPITAL LETTER V WITH TILDE
+    "\xe1\xb9\xbe" => "\xe1\xb9\xbf", // LATIN CAPITAL LETTER V WITH DOT BELOW
+    "\xe1\xba\x80" => "\xe1\xba\x81", // LATIN CAPITAL LETTER W WITH GRAVE
+    "\xe1\xba\x82" => "\xe1\xba\x83", // LATIN CAPITAL LETTER W WITH ACUTE
+    "\xe1\xba\x84" => "\xe1\xba\x85", // LATIN CAPITAL LETTER W WITH DIAERESIS
+    "\xe1\xba\x86" => "\xe1\xba\x87", // LATIN CAPITAL LETTER W WITH DOT ABOVE
+    "\xe1\xba\x88" => "\xe1\xba\x89", // LATIN CAPITAL LETTER W WITH DOT BELOW
+    "\xe1\xba\x8a" => "\xe1\xba\x8b", // LATIN CAPITAL LETTER X WITH DOT ABOVE
+    "\xe1\xba\x8c" => "\xe1\xba\x8d", // LATIN CAPITAL LETTER X WITH DIAERESIS
+    "\xe1\xba\x8e" => "\xe1\xba\x8f", // LATIN CAPITAL LETTER Y WITH DOT ABOVE
+    "\xe1\xba\x90" => "\xe1\xba\x91", // LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
+    "\xe1\xba\x92" => "\xe1\xba\x93", // LATIN CAPITAL LETTER Z WITH DOT BELOW
+    "\xe1\xba\x94" => "\xe1\xba\x95", // LATIN CAPITAL LETTER Z WITH LINE BELOW
+    "\xe1\xba\x9e" => "\xc3\x9f", // LATIN CAPITAL LETTER SHARP S
+    "\xe1\xba\xa0" => "\xe1\xba\xa1", // LATIN CAPITAL LETTER A WITH DOT BELOW
+    "\xe1\xba\xa2" => "\xe1\xba\xa3", // LATIN CAPITAL LETTER A WITH HOOK ABOVE
+    "\xe1\xba\xa4" => "\xe1\xba\xa5", // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
+    "\xe1\xba\xa6" => "\xe1\xba\xa7", // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
+    "\xe1\xba\xa8" => "\xe1\xba\xa9", // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
+    "\xe1\xba\xaa" => "\xe1\xba\xab", // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
+    "\xe1\xba\xac" => "\xe1\xba\xad", // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
+    "\xe1\xba\xae" => "\xe1\xba\xaf", // LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
+    "\xe1\xba\xb0" => "\xe1\xba\xb1", // LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
+    "\xe1\xba\xb2" => "\xe1\xba\xb3", // LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
+    "\xe1\xba\xb4" => "\xe1\xba\xb5", // LATIN CAPITAL LETTER A WITH BREVE AND TILDE
+    "\xe1\xba\xb6" => "\xe1\xba\xb7", // LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
+    "\xe1\xba\xb8" => "\xe1\xba\xb9", // LATIN CAPITAL LETTER E WITH DOT BELOW
+    "\xe1\xba\xba" => "\xe1\xba\xbb", // LATIN CAPITAL LETTER E WITH HOOK ABOVE
+    "\xe1\xba\xbc" => "\xe1\xba\xbd", // LATIN CAPITAL LETTER E WITH TILDE
+    "\xe1\xba\xbe" => "\xe1\xba\xbf", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
+    "\xe1\xbb\x80" => "\xe1\xbb\x81", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
+    "\xe1\xbb\x82" => "\xe1\xbb\x83", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
+    "\xe1\xbb\x84" => "\xe1\xbb\x85", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
+    "\xe1\xbb\x86" => "\xe1\xbb\x87", // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
+    "\xe1\xbb\x88" => "\xe1\xbb\x89", // LATIN CAPITAL LETTER I WITH HOOK ABOVE
+    "\xe1\xbb\x8a" => "\xe1\xbb\x8b", // LATIN CAPITAL LETTER I WITH DOT BELOW
+    "\xe1\xbb\x8c" => "\xe1\xbb\x8d", // LATIN CAPITAL LETTER O WITH DOT BELOW
+    "\xe1\xbb\x8e" => "\xe1\xbb\x8f", // LATIN CAPITAL LETTER O WITH HOOK ABOVE
+    "\xe1\xbb\x90" => "\xe1\xbb\x91", // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
+    "\xe1\xbb\x92" => "\xe1\xbb\x93", // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
+    "\xe1\xbb\x94" => "\xe1\xbb\x95", // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
+    "\xe1\xbb\x96" => "\xe1\xbb\x97", // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
+    "\xe1\xbb\x98" => "\xe1\xbb\x99", // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
+    "\xe1\xbb\x9a" => "\xe1\xbb\x9b", // LATIN CAPITAL LETTER O WITH HORN AND ACUTE
+    "\xe1\xbb\x9c" => "\xe1\xbb\x9d", // LATIN CAPITAL LETTER O WITH HORN AND GRAVE
+    "\xe1\xbb\x9e" => "\xe1\xbb\x9f", // LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
+    "\xe1\xbb\xa0" => "\xe1\xbb\xa1", // LATIN CAPITAL LETTER O WITH HORN AND TILDE
+    "\xe1\xbb\xa2" => "\xe1\xbb\xa3", // LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
+    "\xe1\xbb\xa4" => "\xe1\xbb\xa5", // LATIN CAPITAL LETTER U WITH DOT BELOW
+    "\xe1\xbb\xa6" => "\xe1\xbb\xa7", // LATIN CAPITAL LETTER U WITH HOOK ABOVE
+    "\xe1\xbb\xa8" => "\xe1\xbb\xa9", // LATIN CAPITAL LETTER U WITH HORN AND ACUTE
+    "\xe1\xbb\xaa" => "\xe1\xbb\xab", // LATIN CAPITAL LETTER U WITH HORN AND GRAVE
+    "\xe1\xbb\xac" => "\xe1\xbb\xad", // LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
+    "\xe1\xbb\xae" => "\xe1\xbb\xaf", // LATIN CAPITAL LETTER U WITH HORN AND TILDE
+    "\xe1\xbb\xb0" => "\xe1\xbb\xb1", // LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
+    "\xe1\xbb\xb2" => "\xe1\xbb\xb3", // LATIN CAPITAL LETTER Y WITH GRAVE
+    "\xe1\xbb\xb4" => "\xe1\xbb\xb5", // LATIN CAPITAL LETTER Y WITH DOT BELOW
+    "\xe1\xbb\xb6" => "\xe1\xbb\xb7", // LATIN CAPITAL LETTER Y WITH HOOK ABOVE
+    "\xe1\xbb\xb8" => "\xe1\xbb\xb9", // LATIN CAPITAL LETTER Y WITH TILDE
+    "\xe1\xbb\xba" => "\xe1\xbb\xbb", // LATIN CAPITAL LETTER MIDDLE-WELSH LL
+    "\xe1\xbb\xbc" => "\xe1\xbb\xbd", // LATIN CAPITAL LETTER MIDDLE-WELSH V
+    "\xe1\xbb\xbe" => "\xe1\xbb\xbf", // LATIN CAPITAL LETTER Y WITH LOOP
+    "\xe1\xbc\x88" => "\xe1\xbc\x80", // GREEK CAPITAL LETTER ALPHA WITH PSILI
+    "\xe1\xbc\x89" => "\xe1\xbc\x81", // GREEK CAPITAL LETTER ALPHA WITH DASIA
+    "\xe1\xbc\x8a" => "\xe1\xbc\x82", // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
+    "\xe1\xbc\x8b" => "\xe1\xbc\x83", // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
+    "\xe1\xbc\x8c" => "\xe1\xbc\x84", // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
+    "\xe1\xbc\x8d" => "\xe1\xbc\x85", // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
+    "\xe1\xbc\x8e" => "\xe1\xbc\x86", // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
+    "\xe1\xbc\x8f" => "\xe1\xbc\x87", // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
+    "\xe1\xbc\x98" => "\xe1\xbc\x90", // GREEK CAPITAL LETTER EPSILON WITH PSILI
+    "\xe1\xbc\x99" => "\xe1\xbc\x91", // GREEK CAPITAL LETTER EPSILON WITH DASIA
+    "\xe1\xbc\x9a" => "\xe1\xbc\x92", // GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
+    "\xe1\xbc\x9b" => "\xe1\xbc\x93", // GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
+    "\xe1\xbc\x9c" => "\xe1\xbc\x94", // GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
+    "\xe1\xbc\x9d" => "\xe1\xbc\x95", // GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+    "\xe1\xbc\xa8" => "\xe1\xbc\xa0", // GREEK CAPITAL LETTER ETA WITH PSILI
+    "\xe1\xbc\xa9" => "\xe1\xbc\xa1", // GREEK CAPITAL LETTER ETA WITH DASIA
+    "\xe1\xbc\xaa" => "\xe1\xbc\xa2", // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
+    "\xe1\xbc\xab" => "\xe1\xbc\xa3", // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
+    "\xe1\xbc\xac" => "\xe1\xbc\xa4", // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
+    "\xe1\xbc\xad" => "\xe1\xbc\xa5", // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
+    "\xe1\xbc\xae" => "\xe1\xbc\xa6", // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
+    "\xe1\xbc\xaf" => "\xe1\xbc\xa7", // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
+    "\xe1\xbc\xb8" => "\xe1\xbc\xb0", // GREEK CAPITAL LETTER IOTA WITH PSILI
+    "\xe1\xbc\xb9" => "\xe1\xbc\xb1", // GREEK CAPITAL LETTER IOTA WITH DASIA
+    "\xe1\xbc\xba" => "\xe1\xbc\xb2", // GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
+    "\xe1\xbc\xbb" => "\xe1\xbc\xb3", // GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
+    "\xe1\xbc\xbc" => "\xe1\xbc\xb4", // GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
+    "\xe1\xbc\xbd" => "\xe1\xbc\xb5", // GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
+    "\xe1\xbc\xbe" => "\xe1\xbc\xb6", // GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
+    "\xe1\xbc\xbf" => "\xe1\xbc\xb7", // GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
+    "\xe1\xbd\x88" => "\xe1\xbd\x80", // GREEK CAPITAL LETTER OMICRON WITH PSILI
+    "\xe1\xbd\x89" => "\xe1\xbd\x81", // GREEK CAPITAL LETTER OMICRON WITH DASIA
+    "\xe1\xbd\x8a" => "\xe1\xbd\x82", // GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
+    "\xe1\xbd\x8b" => "\xe1\xbd\x83", // GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
+    "\xe1\xbd\x8c" => "\xe1\xbd\x84", // GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
+    "\xe1\xbd\x8d" => "\xe1\xbd\x85", // GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+    "\xe1\xbd\x99" => "\xe1\xbd\x91", // GREEK CAPITAL LETTER UPSILON WITH DASIA
+    "\xe1\xbd\x9b" => "\xe1\xbd\x93", // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+    "\xe1\xbd\x9d" => "\xe1\xbd\x95", // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+    "\xe1\xbd\x9f" => "\xe1\xbd\x97", // GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
+    "\xe1\xbd\xa8" => "\xe1\xbd\xa0", // GREEK CAPITAL LETTER OMEGA WITH PSILI
+    "\xe1\xbd\xa9" => "\xe1\xbd\xa1", // GREEK CAPITAL LETTER OMEGA WITH DASIA
+    "\xe1\xbd\xaa" => "\xe1\xbd\xa2", // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
+    "\xe1\xbd\xab" => "\xe1\xbd\xa3", // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
+    "\xe1\xbd\xac" => "\xe1\xbd\xa4", // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
+    "\xe1\xbd\xad" => "\xe1\xbd\xa5", // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
+    "\xe1\xbd\xae" => "\xe1\xbd\xa6", // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
+    "\xe1\xbd\xaf" => "\xe1\xbd\xa7", // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
+    "\xe1\xbe\x88" => "\xe1\xbe\x80", // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+    "\xe1\xbe\x89" => "\xe1\xbe\x81", // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x8a" => "\xe1\xbe\x82", // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x8b" => "\xe1\xbe\x83", // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x8c" => "\xe1\xbe\x84", // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x8d" => "\xe1\xbe\x85", // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x8e" => "\xe1\xbe\x86", // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+    "\xe1\xbe\x8f" => "\xe1\xbe\x87", // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+    "\xe1\xbe\x98" => "\xe1\xbe\x90", // GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+    "\xe1\xbe\x99" => "\xe1\xbe\x91", // GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x9a" => "\xe1\xbe\x92", // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x9b" => "\xe1\xbe\x93", // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x9c" => "\xe1\xbe\x94", // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x9d" => "\xe1\xbe\x95", // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+    "\xe1\xbe\x9e" => "\xe1\xbe\x96", // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+    "\xe1\xbe\x9f" => "\xe1\xbe\x97", // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+    "\xe1\xbe\xa8" => "\xe1\xbe\xa0", // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+    "\xe1\xbe\xa9" => "\xe1\xbe\xa1", // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+    "\xe1\xbe\xaa" => "\xe1\xbe\xa2", // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+    "\xe1\xbe\xab" => "\xe1\xbe\xa3", // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+    "\xe1\xbe\xac" => "\xe1\xbe\xa4", // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+    "\xe1\xbe\xad" => "\xe1\xbe\xa5", // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+    "\xe1\xbe\xae" => "\xe1\xbe\xa6", // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+    "\xe1\xbe\xaf" => "\xe1\xbe\xa7", // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+    "\xe1\xbe\xb8" => "\xe1\xbe\xb0", // GREEK CAPITAL LETTER ALPHA WITH VRACHY
+    "\xe1\xbe\xb9" => "\xe1\xbe\xb1", // GREEK CAPITAL LETTER ALPHA WITH MACRON
+    "\xe1\xbe\xba" => "\xe1\xbd\xb0", // GREEK CAPITAL LETTER ALPHA WITH VARIA
+    "\xe1\xbe\xbb" => "\xe1\xbd\xb1", // GREEK CAPITAL LETTER ALPHA WITH OXIA
+    "\xe1\xbe\xbc" => "\xe1\xbe\xb3", // GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+    "\xe1\xbf\x88" => "\xe1\xbd\xb2", // GREEK CAPITAL LETTER EPSILON WITH VARIA
+    "\xe1\xbf\x89" => "\xe1\xbd\xb3", // GREEK CAPITAL LETTER EPSILON WITH OXIA
+    "\xe1\xbf\x8a" => "\xe1\xbd\xb4", // GREEK CAPITAL LETTER ETA WITH VARIA
+    "\xe1\xbf\x8b" => "\xe1\xbd\xb5", // GREEK CAPITAL LETTER ETA WITH OXIA
+    "\xe1\xbf\x8c" => "\xe1\xbf\x83", // GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+    "\xe1\xbf\x98" => "\xe1\xbf\x90", // GREEK CAPITAL LETTER IOTA WITH VRACHY
+    "\xe1\xbf\x99" => "\xe1\xbf\x91", // GREEK CAPITAL LETTER IOTA WITH MACRON
+    "\xe1\xbf\x9a" => "\xe1\xbd\xb6", // GREEK CAPITAL LETTER IOTA WITH VARIA
+    "\xe1\xbf\x9b" => "\xe1\xbd\xb7", // GREEK CAPITAL LETTER IOTA WITH OXIA
+    "\xe1\xbf\xa8" => "\xe1\xbf\xa0", // GREEK CAPITAL LETTER UPSILON WITH VRACHY
+    "\xe1\xbf\xa9" => "\xe1\xbf\xa1", // GREEK CAPITAL LETTER UPSILON WITH MACRON
+    "\xe1\xbf\xaa" => "\xe1\xbd\xba", // GREEK CAPITAL LETTER UPSILON WITH VARIA
+    "\xe1\xbf\xab" => "\xe1\xbd\xbb", // GREEK CAPITAL LETTER UPSILON WITH OXIA
+    "\xe1\xbf\xac" => "\xe1\xbf\xa5", // GREEK CAPITAL LETTER RHO WITH DASIA
+    "\xe1\xbf\xb8" => "\xe1\xbd\xb8", // GREEK CAPITAL LETTER OMICRON WITH VARIA
+    "\xe1\xbf\xb9" => "\xe1\xbd\xb9", // GREEK CAPITAL LETTER OMICRON WITH OXIA
+    "\xe1\xbf\xba" => "\xe1\xbd\xbc", // GREEK CAPITAL LETTER OMEGA WITH VARIA
+    "\xe1\xbf\xbb" => "\xe1\xbd\xbd", // GREEK CAPITAL LETTER OMEGA WITH OXIA
+    "\xe1\xbf\xbc" => "\xe1\xbf\xb3", // GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+    "\xe2\x84\xa6" => "\xcf\x89", // OHM SIGN
+    "\xe2\x84\xaa" => "\x6b", // KELVIN SIGN
+    "\xe2\x84\xab" => "\xc3\xa5", // ANGSTROM SIGN
+    "\xe2\x84\xb2" => "\xe2\x85\x8e", // TURNED CAPITAL F
+    "\xe2\x85\xa0" => "\xe2\x85\xb0", // ROMAN NUMERAL ONE
+    "\xe2\x85\xa1" => "\xe2\x85\xb1", // ROMAN NUMERAL TWO
+    "\xe2\x85\xa2" => "\xe2\x85\xb2", // ROMAN NUMERAL THREE
+    "\xe2\x85\xa3" => "\xe2\x85\xb3", // ROMAN NUMERAL FOUR
+    "\xe2\x85\xa4" => "\xe2\x85\xb4", // ROMAN NUMERAL FIVE
+    "\xe2\x85\xa5" => "\xe2\x85\xb5", // ROMAN NUMERAL SIX
+    "\xe2\x85\xa6" => "\xe2\x85\xb6", // ROMAN NUMERAL SEVEN
+    "\xe2\x85\xa7" => "\xe2\x85\xb7", // ROMAN NUMERAL EIGHT
+    "\xe2\x85\xa8" => "\xe2\x85\xb8", // ROMAN NUMERAL NINE
+    "\xe2\x85\xa9" => "\xe2\x85\xb9", // ROMAN NUMERAL TEN
+    "\xe2\x85\xaa" => "\xe2\x85\xba", // ROMAN NUMERAL ELEVEN
+    "\xe2\x85\xab" => "\xe2\x85\xbb", // ROMAN NUMERAL TWELVE
+    "\xe2\x85\xac" => "\xe2\x85\xbc", // ROMAN NUMERAL FIFTY
+    "\xe2\x85\xad" => "\xe2\x85\xbd", // ROMAN NUMERAL ONE HUNDRED
+    "\xe2\x85\xae" => "\xe2\x85\xbe", // ROMAN NUMERAL FIVE HUNDRED
+    "\xe2\x85\xaf" => "\xe2\x85\xbf", // ROMAN NUMERAL ONE THOUSAND
+    "\xe2\x86\x83" => "\xe2\x86\x84", // ROMAN NUMERAL REVERSED ONE HUNDRED
+    "\xe2\x92\xb6" => "\xe2\x93\x90", // CIRCLED LATIN CAPITAL LETTER A
+    "\xe2\x92\xb7" => "\xe2\x93\x91", // CIRCLED LATIN CAPITAL LETTER B
+    "\xe2\x92\xb8" => "\xe2\x93\x92", // CIRCLED LATIN CAPITAL LETTER C
+    "\xe2\x92\xb9" => "\xe2\x93\x93", // CIRCLED LATIN CAPITAL LETTER D
+    "\xe2\x92\xba" => "\xe2\x93\x94", // CIRCLED LATIN CAPITAL LETTER E
+    "\xe2\x92\xbb" => "\xe2\x93\x95", // CIRCLED LATIN CAPITAL LETTER F
+    "\xe2\x92\xbc" => "\xe2\x93\x96", // CIRCLED LATIN CAPITAL LETTER G
+    "\xe2\x92\xbd" => "\xe2\x93\x97", // CIRCLED LATIN CAPITAL LETTER H
+    "\xe2\x92\xbe" => "\xe2\x93\x98", // CIRCLED LATIN CAPITAL LETTER I
+    "\xe2\x92\xbf" => "\xe2\x93\x99", // CIRCLED LATIN CAPITAL LETTER J
+    "\xe2\x93\x80" => "\xe2\x93\x9a", // CIRCLED LATIN CAPITAL LETTER K
+    "\xe2\x93\x81" => "\xe2\x93\x9b", // CIRCLED LATIN CAPITAL LETTER L
+    "\xe2\x93\x82" => "\xe2\x93\x9c", // CIRCLED LATIN CAPITAL LETTER M
+    "\xe2\x93\x83" => "\xe2\x93\x9d", // CIRCLED LATIN CAPITAL LETTER N
+    "\xe2\x93\x84" => "\xe2\x93\x9e", // CIRCLED LATIN CAPITAL LETTER O
+    "\xe2\x93\x85" => "\xe2\x93\x9f", // CIRCLED LATIN CAPITAL LETTER P
+    "\xe2\x93\x86" => "\xe2\x93\xa0", // CIRCLED LATIN CAPITAL LETTER Q
+    "\xe2\x93\x87" => "\xe2\x93\xa1", // CIRCLED LATIN CAPITAL LETTER R
+    "\xe2\x93\x88" => "\xe2\x93\xa2", // CIRCLED LATIN CAPITAL LETTER S
+    "\xe2\x93\x89" => "\xe2\x93\xa3", // CIRCLED LATIN CAPITAL LETTER T
+    "\xe2\x93\x8a" => "\xe2\x93\xa4", // CIRCLED LATIN CAPITAL LETTER U
+    "\xe2\x93\x8b" => "\xe2\x93\xa5", // CIRCLED LATIN CAPITAL LETTER V
+    "\xe2\x93\x8c" => "\xe2\x93\xa6", // CIRCLED LATIN CAPITAL LETTER W
+    "\xe2\x93\x8d" => "\xe2\x93\xa7", // CIRCLED LATIN CAPITAL LETTER X
+    "\xe2\x93\x8e" => "\xe2\x93\xa8", // CIRCLED LATIN CAPITAL LETTER Y
+    "\xe2\x93\x8f" => "\xe2\x93\xa9", // CIRCLED LATIN CAPITAL LETTER Z
+    "\xe2\xb0\x80" => "\xe2\xb0\xb0", // GLAGOLITIC CAPITAL LETTER AZU
+    "\xe2\xb0\x81" => "\xe2\xb0\xb1", // GLAGOLITIC CAPITAL LETTER BUKY
+    "\xe2\xb0\x82" => "\xe2\xb0\xb2", // GLAGOLITIC CAPITAL LETTER VEDE
+    "\xe2\xb0\x83" => "\xe2\xb0\xb3", // GLAGOLITIC CAPITAL LETTER GLAGOLI
+    "\xe2\xb0\x84" => "\xe2\xb0\xb4", // GLAGOLITIC CAPITAL LETTER DOBRO
+    "\xe2\xb0\x85" => "\xe2\xb0\xb5", // GLAGOLITIC CAPITAL LETTER YESTU
+    "\xe2\xb0\x86" => "\xe2\xb0\xb6", // GLAGOLITIC CAPITAL LETTER ZHIVETE
+    "\xe2\xb0\x87" => "\xe2\xb0\xb7", // GLAGOLITIC CAPITAL LETTER DZELO
+    "\xe2\xb0\x88" => "\xe2\xb0\xb8", // GLAGOLITIC CAPITAL LETTER ZEMLJA
+    "\xe2\xb0\x89" => "\xe2\xb0\xb9", // GLAGOLITIC CAPITAL LETTER IZHE
+    "\xe2\xb0\x8a" => "\xe2\xb0\xba", // GLAGOLITIC CAPITAL LETTER INITIAL IZHE
+    "\xe2\xb0\x8b" => "\xe2\xb0\xbb", // GLAGOLITIC CAPITAL LETTER I
+    "\xe2\xb0\x8c" => "\xe2\xb0\xbc", // GLAGOLITIC CAPITAL LETTER DJERVI
+    "\xe2\xb0\x8d" => "\xe2\xb0\xbd", // GLAGOLITIC CAPITAL LETTER KAKO
+    "\xe2\xb0\x8e" => "\xe2\xb0\xbe", // GLAGOLITIC CAPITAL LETTER LJUDIJE
+    "\xe2\xb0\x8f" => "\xe2\xb0\xbf", // GLAGOLITIC CAPITAL LETTER MYSLITE
+    "\xe2\xb0\x90" => "\xe2\xb1\x80", // GLAGOLITIC CAPITAL LETTER NASHI
+    "\xe2\xb0\x91" => "\xe2\xb1\x81", // GLAGOLITIC CAPITAL LETTER ONU
+    "\xe2\xb0\x92" => "\xe2\xb1\x82", // GLAGOLITIC CAPITAL LETTER POKOJI
+    "\xe2\xb0\x93" => "\xe2\xb1\x83", // GLAGOLITIC CAPITAL LETTER RITSI
+    "\xe2\xb0\x94" => "\xe2\xb1\x84", // GLAGOLITIC CAPITAL LETTER SLOVO
+    "\xe2\xb0\x95" => "\xe2\xb1\x85", // GLAGOLITIC CAPITAL LETTER TVRIDO
+    "\xe2\xb0\x96" => "\xe2\xb1\x86", // GLAGOLITIC CAPITAL LETTER UKU
+    "\xe2\xb0\x97" => "\xe2\xb1\x87", // GLAGOLITIC CAPITAL LETTER FRITU
+    "\xe2\xb0\x98" => "\xe2\xb1\x88", // GLAGOLITIC CAPITAL LETTER HERU
+    "\xe2\xb0\x99" => "\xe2\xb1\x89", // GLAGOLITIC CAPITAL LETTER OTU
+    "\xe2\xb0\x9a" => "\xe2\xb1\x8a", // GLAGOLITIC CAPITAL LETTER PE
+    "\xe2\xb0\x9b" => "\xe2\xb1\x8b", // GLAGOLITIC CAPITAL LETTER SHTA
+    "\xe2\xb0\x9c" => "\xe2\xb1\x8c", // GLAGOLITIC CAPITAL LETTER TSI
+    "\xe2\xb0\x9d" => "\xe2\xb1\x8d", // GLAGOLITIC CAPITAL LETTER CHRIVI
+    "\xe2\xb0\x9e" => "\xe2\xb1\x8e", // GLAGOLITIC CAPITAL LETTER SHA
+    "\xe2\xb0\x9f" => "\xe2\xb1\x8f", // GLAGOLITIC CAPITAL LETTER YERU
+    "\xe2\xb0\xa0" => "\xe2\xb1\x90", // GLAGOLITIC CAPITAL LETTER YERI
+    "\xe2\xb0\xa1" => "\xe2\xb1\x91", // GLAGOLITIC CAPITAL LETTER YATI
+    "\xe2\xb0\xa2" => "\xe2\xb1\x92", // GLAGOLITIC CAPITAL LETTER SPIDERY HA
+    "\xe2\xb0\xa3" => "\xe2\xb1\x93", // GLAGOLITIC CAPITAL LETTER YU
+    "\xe2\xb0\xa4" => "\xe2\xb1\x94", // GLAGOLITIC CAPITAL LETTER SMALL YUS
+    "\xe2\xb0\xa5" => "\xe2\xb1\x95", // GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL
+    "\xe2\xb0\xa6" => "\xe2\xb1\x96", // GLAGOLITIC CAPITAL LETTER YO
+    "\xe2\xb0\xa7" => "\xe2\xb1\x97", // GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS
+    "\xe2\xb0\xa8" => "\xe2\xb1\x98", // GLAGOLITIC CAPITAL LETTER BIG YUS
+    "\xe2\xb0\xa9" => "\xe2\xb1\x99", // GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS
+    "\xe2\xb0\xaa" => "\xe2\xb1\x9a", // GLAGOLITIC CAPITAL LETTER FITA
+    "\xe2\xb0\xab" => "\xe2\xb1\x9b", // GLAGOLITIC CAPITAL LETTER IZHITSA
+    "\xe2\xb0\xac" => "\xe2\xb1\x9c", // GLAGOLITIC CAPITAL LETTER SHTAPIC
+    "\xe2\xb0\xad" => "\xe2\xb1\x9d", // GLAGOLITIC CAPITAL LETTER TROKUTASTI A
+    "\xe2\xb0\xae" => "\xe2\xb1\x9e", // GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE
+    "\xe2\xb1\xa0" => "\xe2\xb1\xa1", // LATIN CAPITAL LETTER L WITH DOUBLE BAR
+    "\xe2\xb1\xa2" => "\xc9\xab", // LATIN CAPITAL LETTER L WITH MIDDLE TILDE
+    "\xe2\xb1\xa3" => "\xe1\xb5\xbd", // LATIN CAPITAL LETTER P WITH STROKE
+    "\xe2\xb1\xa4" => "\xc9\xbd", // LATIN CAPITAL LETTER R WITH TAIL
+    "\xe2\xb1\xa7" => "\xe2\xb1\xa8", // LATIN CAPITAL LETTER H WITH DESCENDER
+    "\xe2\xb1\xa9" => "\xe2\xb1\xaa", // LATIN CAPITAL LETTER K WITH DESCENDER
+    "\xe2\xb1\xab" => "\xe2\xb1\xac", // LATIN CAPITAL LETTER Z WITH DESCENDER
+    "\xe2\xb1\xad" => "\xc9\x91", // LATIN CAPITAL LETTER ALPHA
+    "\xe2\xb1\xae" => "\xc9\xb1", // LATIN CAPITAL LETTER M WITH HOOK
+    "\xe2\xb1\xaf" => "\xc9\x90", // LATIN CAPITAL LETTER TURNED A
+    "\xe2\xb1\xb0" => "\xc9\x92", // LATIN CAPITAL LETTER TURNED ALPHA
+    "\xe2\xb1\xb2" => "\xe2\xb1\xb3", // LATIN CAPITAL LETTER W WITH HOOK
+    "\xe2\xb1\xb5" => "\xe2\xb1\xb6", // LATIN CAPITAL LETTER HALF H
+    "\xe2\xb1\xbe" => "\xc8\xbf", // LATIN CAPITAL LETTER S WITH SWASH TAIL
+    "\xe2\xb1\xbf" => "\xc9\x80", // LATIN CAPITAL LETTER Z WITH SWASH TAIL
+    "\xe2\xb2\x80" => "\xe2\xb2\x81", // COPTIC CAPITAL LETTER ALFA
+    "\xe2\xb2\x82" => "\xe2\xb2\x83", // COPTIC CAPITAL LETTER VIDA
+    "\xe2\xb2\x84" => "\xe2\xb2\x85", // COPTIC CAPITAL LETTER GAMMA
+    "\xe2\xb2\x86" => "\xe2\xb2\x87", // COPTIC CAPITAL LETTER DALDA
+    "\xe2\xb2\x88" => "\xe2\xb2\x89", // COPTIC CAPITAL LETTER EIE
+    "\xe2\xb2\x8a" => "\xe2\xb2\x8b", // COPTIC CAPITAL LETTER SOU
+    "\xe2\xb2\x8c" => "\xe2\xb2\x8d", // COPTIC CAPITAL LETTER ZATA
+    "\xe2\xb2\x8e" => "\xe2\xb2\x8f", // COPTIC CAPITAL LETTER HATE
+    "\xe2\xb2\x90" => "\xe2\xb2\x91", // COPTIC CAPITAL LETTER THETHE
+    "\xe2\xb2\x92" => "\xe2\xb2\x93", // COPTIC CAPITAL LETTER IAUDA
+    "\xe2\xb2\x94" => "\xe2\xb2\x95", // COPTIC CAPITAL LETTER KAPA
+    "\xe2\xb2\x96" => "\xe2\xb2\x97", // COPTIC CAPITAL LETTER LAULA
+    "\xe2\xb2\x98" => "\xe2\xb2\x99", // COPTIC CAPITAL LETTER MI
+    "\xe2\xb2\x9a" => "\xe2\xb2\x9b", // COPTIC CAPITAL LETTER NI
+    "\xe2\xb2\x9c" => "\xe2\xb2\x9d", // COPTIC CAPITAL LETTER KSI
+    "\xe2\xb2\x9e" => "\xe2\xb2\x9f", // COPTIC CAPITAL LETTER O
+    "\xe2\xb2\xa0" => "\xe2\xb2\xa1", // COPTIC CAPITAL LETTER PI
+    "\xe2\xb2\xa2" => "\xe2\xb2\xa3", // COPTIC CAPITAL LETTER RO
+    "\xe2\xb2\xa4" => "\xe2\xb2\xa5", // COPTIC CAPITAL LETTER SIMA
+    "\xe2\xb2\xa6" => "\xe2\xb2\xa7", // COPTIC CAPITAL LETTER TAU
+    "\xe2\xb2\xa8" => "\xe2\xb2\xa9", // COPTIC CAPITAL LETTER UA
+    "\xe2\xb2\xaa" => "\xe2\xb2\xab", // COPTIC CAPITAL LETTER FI
+    "\xe2\xb2\xac" => "\xe2\xb2\xad", // COPTIC CAPITAL LETTER KHI
+    "\xe2\xb2\xae" => "\xe2\xb2\xaf", // COPTIC CAPITAL LETTER PSI
+    "\xe2\xb2\xb0" => "\xe2\xb2\xb1", // COPTIC CAPITAL LETTER OOU
+    "\xe2\xb2\xb2" => "\xe2\xb2\xb3", // COPTIC CAPITAL LETTER DIALECT-P ALEF
+    "\xe2\xb2\xb4" => "\xe2\xb2\xb5", // COPTIC CAPITAL LETTER OLD COPTIC AIN
+    "\xe2\xb2\xb6" => "\xe2\xb2\xb7", // COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE
+    "\xe2\xb2\xb8" => "\xe2\xb2\xb9", // COPTIC CAPITAL LETTER DIALECT-P KAPA
+    "\xe2\xb2\xba" => "\xe2\xb2\xbb", // COPTIC CAPITAL LETTER DIALECT-P NI
+    "\xe2\xb2\xbc" => "\xe2\xb2\xbd", // COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI
+    "\xe2\xb2\xbe" => "\xe2\xb2\xbf", // COPTIC CAPITAL LETTER OLD COPTIC OOU
+    "\xe2\xb3\x80" => "\xe2\xb3\x81", // COPTIC CAPITAL LETTER SAMPI
+    "\xe2\xb3\x82" => "\xe2\xb3\x83", // COPTIC CAPITAL LETTER CROSSED SHEI
+    "\xe2\xb3\x84" => "\xe2\xb3\x85", // COPTIC CAPITAL LETTER OLD COPTIC SHEI
+    "\xe2\xb3\x86" => "\xe2\xb3\x87", // COPTIC CAPITAL LETTER OLD COPTIC ESH
+    "\xe2\xb3\x88" => "\xe2\xb3\x89", // COPTIC CAPITAL LETTER AKHMIMIC KHEI
+    "\xe2\xb3\x8a" => "\xe2\xb3\x8b", // COPTIC CAPITAL LETTER DIALECT-P HORI
+    "\xe2\xb3\x8c" => "\xe2\xb3\x8d", // COPTIC CAPITAL LETTER OLD COPTIC HORI
+    "\xe2\xb3\x8e" => "\xe2\xb3\x8f", // COPTIC CAPITAL LETTER OLD COPTIC HA
+    "\xe2\xb3\x90" => "\xe2\xb3\x91", // COPTIC CAPITAL LETTER L-SHAPED HA
+    "\xe2\xb3\x92" => "\xe2\xb3\x93", // COPTIC CAPITAL LETTER OLD COPTIC HEI
+    "\xe2\xb3\x94" => "\xe2\xb3\x95", // COPTIC CAPITAL LETTER OLD COPTIC HAT
+    "\xe2\xb3\x96" => "\xe2\xb3\x97", // COPTIC CAPITAL LETTER OLD COPTIC GANGIA
+    "\xe2\xb3\x98" => "\xe2\xb3\x99", // COPTIC CAPITAL LETTER OLD COPTIC DJA
+    "\xe2\xb3\x9a" => "\xe2\xb3\x9b", // COPTIC CAPITAL LETTER OLD COPTIC SHIMA
+    "\xe2\xb3\x9c" => "\xe2\xb3\x9d", // COPTIC CAPITAL LETTER OLD NUBIAN SHIMA
+    "\xe2\xb3\x9e" => "\xe2\xb3\x9f", // COPTIC CAPITAL LETTER OLD NUBIAN NGI
+    "\xe2\xb3\xa0" => "\xe2\xb3\xa1", // COPTIC CAPITAL LETTER OLD NUBIAN NYI
+    "\xe2\xb3\xa2" => "\xe2\xb3\xa3", // COPTIC CAPITAL LETTER OLD NUBIAN WAU
+    "\xe2\xb3\xab" => "\xe2\xb3\xac", // COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI
+    "\xe2\xb3\xad" => "\xe2\xb3\xae", // COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA
+    "\xea\x99\x80" => "\xea\x99\x81", // CYRILLIC CAPITAL LETTER ZEMLYA
+    "\xea\x99\x82" => "\xea\x99\x83", // CYRILLIC CAPITAL LETTER DZELO
+    "\xea\x99\x84" => "\xea\x99\x85", // CYRILLIC CAPITAL LETTER REVERSED DZE
+    "\xea\x99\x86" => "\xea\x99\x87", // CYRILLIC CAPITAL LETTER IOTA
+    "\xea\x99\x88" => "\xea\x99\x89", // CYRILLIC CAPITAL LETTER DJERV
+    "\xea\x99\x8a" => "\xea\x99\x8b", // CYRILLIC CAPITAL LETTER MONOGRAPH UK
+    "\xea\x99\x8c" => "\xea\x99\x8d", // CYRILLIC CAPITAL LETTER BROAD OMEGA
+    "\xea\x99\x8e" => "\xea\x99\x8f", // CYRILLIC CAPITAL LETTER NEUTRAL YER
+    "\xea\x99\x90" => "\xea\x99\x91", // CYRILLIC CAPITAL LETTER YERU WITH BACK YER
+    "\xea\x99\x92" => "\xea\x99\x93", // CYRILLIC CAPITAL LETTER IOTIFIED YAT
+    "\xea\x99\x94" => "\xea\x99\x95", // CYRILLIC CAPITAL LETTER REVERSED YU
+    "\xea\x99\x96" => "\xea\x99\x97", // CYRILLIC CAPITAL LETTER IOTIFIED A
+    "\xea\x99\x98" => "\xea\x99\x99", // CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS
+    "\xea\x99\x9a" => "\xea\x99\x9b", // CYRILLIC CAPITAL LETTER BLENDED YUS
+    "\xea\x99\x9c" => "\xea\x99\x9d", // CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS
+    "\xea\x99\x9e" => "\xea\x99\x9f", // CYRILLIC CAPITAL LETTER YN
+    "\xea\x99\xa0" => "\xea\x99\xa1", // CYRILLIC CAPITAL LETTER REVERSED TSE
+    "\xea\x99\xa2" => "\xea\x99\xa3", // CYRILLIC CAPITAL LETTER SOFT DE
+    "\xea\x99\xa4" => "\xea\x99\xa5", // CYRILLIC CAPITAL LETTER SOFT EL
+    "\xea\x99\xa6" => "\xea\x99\xa7", // CYRILLIC CAPITAL LETTER SOFT EM
+    "\xea\x99\xa8" => "\xea\x99\xa9", // CYRILLIC CAPITAL LETTER MONOCULAR O
+    "\xea\x99\xaa" => "\xea\x99\xab", // CYRILLIC CAPITAL LETTER BINOCULAR O
+    "\xea\x99\xac" => "\xea\x99\xad", // CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O
+    "\xea\x9a\x80" => "\xea\x9a\x81", // CYRILLIC CAPITAL LETTER DWE
+    "\xea\x9a\x82" => "\xea\x9a\x83", // CYRILLIC CAPITAL LETTER DZWE
+    "\xea\x9a\x84" => "\xea\x9a\x85", // CYRILLIC CAPITAL LETTER ZHWE
+    "\xea\x9a\x86" => "\xea\x9a\x87", // CYRILLIC CAPITAL LETTER CCHE
+    "\xea\x9a\x88" => "\xea\x9a\x89", // CYRILLIC CAPITAL LETTER DZZE
+    "\xea\x9a\x8a" => "\xea\x9a\x8b", // CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK
+    "\xea\x9a\x8c" => "\xea\x9a\x8d", // CYRILLIC CAPITAL LETTER TWE
+    "\xea\x9a\x8e" => "\xea\x9a\x8f", // CYRILLIC CAPITAL LETTER TSWE
+    "\xea\x9a\x90" => "\xea\x9a\x91", // CYRILLIC CAPITAL LETTER TSSE
+    "\xea\x9a\x92" => "\xea\x9a\x93", // CYRILLIC CAPITAL LETTER TCHE
+    "\xea\x9a\x94" => "\xea\x9a\x95", // CYRILLIC CAPITAL LETTER HWE
+    "\xea\x9a\x96" => "\xea\x9a\x97", // CYRILLIC CAPITAL LETTER SHWE
+    "\xea\x9c\xa2" => "\xea\x9c\xa3", // LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF
+    "\xea\x9c\xa4" => "\xea\x9c\xa5", // LATIN CAPITAL LETTER EGYPTOLOGICAL AIN
+    "\xea\x9c\xa6" => "\xea\x9c\xa7", // LATIN CAPITAL LETTER HENG
+    "\xea\x9c\xa8" => "\xea\x9c\xa9", // LATIN CAPITAL LETTER TZ
+    "\xea\x9c\xaa" => "\xea\x9c\xab", // LATIN CAPITAL LETTER TRESILLO
+    "\xea\x9c\xac" => "\xea\x9c\xad", // LATIN CAPITAL LETTER CUATRILLO
+    "\xea\x9c\xae" => "\xea\x9c\xaf", // LATIN CAPITAL LETTER CUATRILLO WITH COMMA
+    "\xea\x9c\xb2" => "\xea\x9c\xb3", // LATIN CAPITAL LETTER AA
+    "\xea\x9c\xb4" => "\xea\x9c\xb5", // LATIN CAPITAL LETTER AO
+    "\xea\x9c\xb6" => "\xea\x9c\xb7", // LATIN CAPITAL LETTER AU
+    "\xea\x9c\xb8" => "\xea\x9c\xb9", // LATIN CAPITAL LETTER AV
+    "\xea\x9c\xba" => "\xea\x9c\xbb", // LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR
+    "\xea\x9c\xbc" => "\xea\x9c\xbd", // LATIN CAPITAL LETTER AY
+    "\xea\x9c\xbe" => "\xea\x9c\xbf", // LATIN CAPITAL LETTER REVERSED C WITH DOT
+    "\xea\x9d\x80" => "\xea\x9d\x81", // LATIN CAPITAL LETTER K WITH STROKE
+    "\xea\x9d\x82" => "\xea\x9d\x83", // LATIN CAPITAL LETTER K WITH DIAGONAL STROKE
+    "\xea\x9d\x84" => "\xea\x9d\x85", // LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE
+    "\xea\x9d\x86" => "\xea\x9d\x87", // LATIN CAPITAL LETTER BROKEN L
+    "\xea\x9d\x88" => "\xea\x9d\x89", // LATIN CAPITAL LETTER L WITH HIGH STROKE
+    "\xea\x9d\x8a" => "\xea\x9d\x8b", // LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY
+    "\xea\x9d\x8c" => "\xea\x9d\x8d", // LATIN CAPITAL LETTER O WITH LOOP
+    "\xea\x9d\x8e" => "\xea\x9d\x8f", // LATIN CAPITAL LETTER OO
+    "\xea\x9d\x90" => "\xea\x9d\x91", // LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER
+    "\xea\x9d\x92" => "\xea\x9d\x93", // LATIN CAPITAL LETTER P WITH FLOURISH
+    "\xea\x9d\x94" => "\xea\x9d\x95", // LATIN CAPITAL LETTER P WITH SQUIRREL TAIL
+    "\xea\x9d\x96" => "\xea\x9d\x97", // LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER
+    "\xea\x9d\x98" => "\xea\x9d\x99", // LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE
+    "\xea\x9d\x9a" => "\xea\x9d\x9b", // LATIN CAPITAL LETTER R ROTUNDA
+    "\xea\x9d\x9c" => "\xea\x9d\x9d", // LATIN CAPITAL LETTER RUM ROTUNDA
+    "\xea\x9d\x9e" => "\xea\x9d\x9f", // LATIN CAPITAL LETTER V WITH DIAGONAL STROKE
+    "\xea\x9d\xa0" => "\xea\x9d\xa1", // LATIN CAPITAL LETTER VY
+    "\xea\x9d\xa2" => "\xea\x9d\xa3", // LATIN CAPITAL LETTER VISIGOTHIC Z
+    "\xea\x9d\xa4" => "\xea\x9d\xa5", // LATIN CAPITAL LETTER THORN WITH STROKE
+    "\xea\x9d\xa6" => "\xea\x9d\xa7", // LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER
+    "\xea\x9d\xa8" => "\xea\x9d\xa9", // LATIN CAPITAL LETTER VEND
+    "\xea\x9d\xaa" => "\xea\x9d\xab", // LATIN CAPITAL LETTER ET
+    "\xea\x9d\xac" => "\xea\x9d\xad", // LATIN CAPITAL LETTER IS
+    "\xea\x9d\xae" => "\xea\x9d\xaf", // LATIN CAPITAL LETTER CON
+    "\xea\x9d\xb9" => "\xea\x9d\xba", // LATIN CAPITAL LETTER INSULAR D
+    "\xea\x9d\xbb" => "\xea\x9d\xbc", // LATIN CAPITAL LETTER INSULAR F
+    "\xea\x9d\xbd" => "\xe1\xb5\xb9", // LATIN CAPITAL LETTER INSULAR G
+    "\xea\x9d\xbe" => "\xea\x9d\xbf", // LATIN CAPITAL LETTER TURNED INSULAR G
+    "\xea\x9e\x80" => "\xea\x9e\x81", // LATIN CAPITAL LETTER TURNED L
+    "\xea\x9e\x82" => "\xea\x9e\x83", // LATIN CAPITAL LETTER INSULAR R
+    "\xea\x9e\x84" => "\xea\x9e\x85", // LATIN CAPITAL LETTER INSULAR S
+    "\xea\x9e\x86" => "\xea\x9e\x87", // LATIN CAPITAL LETTER INSULAR T
+    "\xea\x9e\x8b" => "\xea\x9e\x8c", // LATIN CAPITAL LETTER SALTILLO
+    "\xea\x9e\x8d" => "\xc9\xa5", // LATIN CAPITAL LETTER TURNED H
+    "\xea\x9e\x90" => "\xea\x9e\x91", // LATIN CAPITAL LETTER N WITH DESCENDER
+    "\xea\x9e\xa0" => "\xea\x9e\xa1", // LATIN CAPITAL LETTER G WITH OBLIQUE STROKE
+    "\xea\x9e\xa2" => "\xea\x9e\xa3", // LATIN CAPITAL LETTER K WITH OBLIQUE STROKE
+    "\xea\x9e\xa4" => "\xea\x9e\xa5", // LATIN CAPITAL LETTER N WITH OBLIQUE STROKE
+    "\xea\x9e\xa6" => "\xea\x9e\xa7", // LATIN CAPITAL LETTER R WITH OBLIQUE STROKE
+    "\xea\x9e\xa8" => "\xea\x9e\xa9", // LATIN CAPITAL LETTER S WITH OBLIQUE STROKE
+    "\xef\xbc\xa1" => "\xef\xbd\x81", // FULLWIDTH LATIN CAPITAL LETTER A
+    "\xef\xbc\xa2" => "\xef\xbd\x82", // FULLWIDTH LATIN CAPITAL LETTER B
+    "\xef\xbc\xa3" => "\xef\xbd\x83", // FULLWIDTH LATIN CAPITAL LETTER C
+    "\xef\xbc\xa4" => "\xef\xbd\x84", // FULLWIDTH LATIN CAPITAL LETTER D
+    "\xef\xbc\xa5" => "\xef\xbd\x85", // FULLWIDTH LATIN CAPITAL LETTER E
+    "\xef\xbc\xa6" => "\xef\xbd\x86", // FULLWIDTH LATIN CAPITAL LETTER F
+    "\xef\xbc\xa7" => "\xef\xbd\x87", // FULLWIDTH LATIN CAPITAL LETTER G
+    "\xef\xbc\xa8" => "\xef\xbd\x88", // FULLWIDTH LATIN CAPITAL LETTER H
+    "\xef\xbc\xa9" => "\xef\xbd\x89", // FULLWIDTH LATIN CAPITAL LETTER I
+    "\xef\xbc\xaa" => "\xef\xbd\x8a", // FULLWIDTH LATIN CAPITAL LETTER J
+    "\xef\xbc\xab" => "\xef\xbd\x8b", // FULLWIDTH LATIN CAPITAL LETTER K
+    "\xef\xbc\xac" => "\xef\xbd\x8c", // FULLWIDTH LATIN CAPITAL LETTER L
+    "\xef\xbc\xad" => "\xef\xbd\x8d", // FULLWIDTH LATIN CAPITAL LETTER M
+    "\xef\xbc\xae" => "\xef\xbd\x8e", // FULLWIDTH LATIN CAPITAL LETTER N
+    "\xef\xbc\xaf" => "\xef\xbd\x8f", // FULLWIDTH LATIN CAPITAL LETTER O
+    "\xef\xbc\xb0" => "\xef\xbd\x90", // FULLWIDTH LATIN CAPITAL LETTER P
+    "\xef\xbc\xb1" => "\xef\xbd\x91", // FULLWIDTH LATIN CAPITAL LETTER Q
+    "\xef\xbc\xb2" => "\xef\xbd\x92", // FULLWIDTH LATIN CAPITAL LETTER R
+    "\xef\xbc\xb3" => "\xef\xbd\x93", // FULLWIDTH LATIN CAPITAL LETTER S
+    "\xef\xbc\xb4" => "\xef\xbd\x94", // FULLWIDTH LATIN CAPITAL LETTER T
+    "\xef\xbc\xb5" => "\xef\xbd\x95", // FULLWIDTH LATIN CAPITAL LETTER U
+    "\xef\xbc\xb6" => "\xef\xbd\x96", // FULLWIDTH LATIN CAPITAL LETTER V
+    "\xef\xbc\xb7" => "\xef\xbd\x97", // FULLWIDTH LATIN CAPITAL LETTER W
+    "\xef\xbc\xb8" => "\xef\xbd\x98", // FULLWIDTH LATIN CAPITAL LETTER X
+    "\xef\xbc\xb9" => "\xef\xbd\x99", // FULLWIDTH LATIN CAPITAL LETTER Y
+    "\xef\xbc\xba" => "\xef\xbd\x9a", // FULLWIDTH LATIN CAPITAL LETTER Z
+    "\xf0\x90\x90\x80" => "\xf0\x90\x90\xa8", // DESERET CAPITAL LETTER LONG I
+    "\xf0\x90\x90\x81" => "\xf0\x90\x90\xa9", // DESERET CAPITAL LETTER LONG E
+    "\xf0\x90\x90\x82" => "\xf0\x90\x90\xaa", // DESERET CAPITAL LETTER LONG A
+    "\xf0\x90\x90\x83" => "\xf0\x90\x90\xab", // DESERET CAPITAL LETTER LONG AH
+    "\xf0\x90\x90\x84" => "\xf0\x90\x90\xac", // DESERET CAPITAL LETTER LONG O
+    "\xf0\x90\x90\x85" => "\xf0\x90\x90\xad", // DESERET CAPITAL LETTER LONG OO
+    "\xf0\x90\x90\x86" => "\xf0\x90\x90\xae", // DESERET CAPITAL LETTER SHORT I
+    "\xf0\x90\x90\x87" => "\xf0\x90\x90\xaf", // DESERET CAPITAL LETTER SHORT E
+    "\xf0\x90\x90\x88" => "\xf0\x90\x90\xb0", // DESERET CAPITAL LETTER SHORT A
+    "\xf0\x90\x90\x89" => "\xf0\x90\x90\xb1", // DESERET CAPITAL LETTER SHORT AH
+    "\xf0\x90\x90\x8a" => "\xf0\x90\x90\xb2", // DESERET CAPITAL LETTER SHORT O
+    "\xf0\x90\x90\x8b" => "\xf0\x90\x90\xb3", // DESERET CAPITAL LETTER SHORT OO
+    "\xf0\x90\x90\x8c" => "\xf0\x90\x90\xb4", // DESERET CAPITAL LETTER AY
+    "\xf0\x90\x90\x8d" => "\xf0\x90\x90\xb5", // DESERET CAPITAL LETTER OW
+    "\xf0\x90\x90\x8e" => "\xf0\x90\x90\xb6", // DESERET CAPITAL LETTER WU
+    "\xf0\x90\x90\x8f" => "\xf0\x90\x90\xb7", // DESERET CAPITAL LETTER YEE
+    "\xf0\x90\x90\x90" => "\xf0\x90\x90\xb8", // DESERET CAPITAL LETTER H
+    "\xf0\x90\x90\x91" => "\xf0\x90\x90\xb9", // DESERET CAPITAL LETTER PEE
+    "\xf0\x90\x90\x92" => "\xf0\x90\x90\xba", // DESERET CAPITAL LETTER BEE
+    "\xf0\x90\x90\x93" => "\xf0\x90\x90\xbb", // DESERET CAPITAL LETTER TEE
+    "\xf0\x90\x90\x94" => "\xf0\x90\x90\xbc", // DESERET CAPITAL LETTER DEE
+    "\xf0\x90\x90\x95" => "\xf0\x90\x90\xbd", // DESERET CAPITAL LETTER CHEE
+    "\xf0\x90\x90\x96" => "\xf0\x90\x90\xbe", // DESERET CAPITAL LETTER JEE
+    "\xf0\x90\x90\x97" => "\xf0\x90\x90\xbf", // DESERET CAPITAL LETTER KAY
+    "\xf0\x90\x90\x98" => "\xf0\x90\x91\x80", // DESERET CAPITAL LETTER GAY
+    "\xf0\x90\x90\x99" => "\xf0\x90\x91\x81", // DESERET CAPITAL LETTER EF
+    "\xf0\x90\x90\x9a" => "\xf0\x90\x91\x82", // DESERET CAPITAL LETTER VEE
+    "\xf0\x90\x90\x9b" => "\xf0\x90\x91\x83", // DESERET CAPITAL LETTER ETH
+    "\xf0\x90\x90\x9c" => "\xf0\x90\x91\x84", // DESERET CAPITAL LETTER THEE
+    "\xf0\x90\x90\x9d" => "\xf0\x90\x91\x85", // DESERET CAPITAL LETTER ES
+    "\xf0\x90\x90\x9e" => "\xf0\x90\x91\x86", // DESERET CAPITAL LETTER ZEE
+    "\xf0\x90\x90\x9f" => "\xf0\x90\x91\x87", // DESERET CAPITAL LETTER ESH
+    "\xf0\x90\x90\xa0" => "\xf0\x90\x91\x88", // DESERET CAPITAL LETTER ZHEE
+    "\xf0\x90\x90\xa1" => "\xf0\x90\x91\x89", // DESERET CAPITAL LETTER ER
+    "\xf0\x90\x90\xa2" => "\xf0\x90\x91\x8a", // DESERET CAPITAL LETTER EL
+    "\xf0\x90\x90\xa3" => "\xf0\x90\x91\x8b", // DESERET CAPITAL LETTER EM
+    "\xf0\x90\x90\xa4" => "\xf0\x90\x91\x8c", // DESERET CAPITAL LETTER EN
+    "\xf0\x90\x90\xa5" => "\xf0\x90\x91\x8d", // DESERET CAPITAL LETTER ENG
+    "\xf0\x90\x90\xa6" => "\xf0\x90\x91\x8e", // DESERET CAPITAL LETTER OI
+    "\xf0\x90\x90\xa7" => "\xf0\x90\x91\x8f", // DESERET CAPITAL LETTER EW
+);
+}
\ No newline at end of file
diff --git a/Template/src/template_autoload.php b/Template/src/template_autoload.php
index d0b314f..864a72b 100644
--- a/Template/src/template_autoload.php
+++ b/Template/src/template_autoload.php
@@ -278,8 +278,10 @@
     'ezcTemplateSourceToTstErrorMessages'                => 'Template/error_messages.php',
     'ezcTemplateString'                                  => 'Template/functions/string_code.php',
     'ezcTemplateStringFunctions'                         => 'Template/functions/string_functions.php',
+    'ezcTemplateStringLowerToUpperUnicodeMap'            => 'Template/structs/lower_to_upper.php',
     'ezcTemplateStringSourceToTstParser'                 => 'Template/parsers/source_to_tst/implementations/string.php',
     'ezcTemplateStringTool'                              => 'Template/string_tool.php',
+    'ezcTemplateStringUpperToLowerUnicodeMap'            => 'Template/structs/upper_to_lower.php',
     'ezcTemplateSubtractionAssignmentOperatorAstNode'    => 'Template/syntax_trees/ast/nodes/operators/subtraction_assignment_operator.php',
     'ezcTemplateSubtractionOperatorAstNode'              => 'Template/syntax_trees/ast/nodes/operators/subtraction_operator.php',
     'ezcTemplateSwitchAstNode'                           => 'Template/syntax_trees/ast/nodes/control/switch.php',
diff --git a/Template/src/unicode/generate_unicode_tables.php b/Template/src/unicode/generate_unicode_tables.php
new file mode 100644
index 0000000..5a2acfb
--- /dev/null
+++ b/Template/src/unicode/generate_unicode_tables.php
@@ -0,0 +1,152 @@
+<?php
+$licenseHeader = <<<LICENSE_HEADER
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * THIS FILE IS MACHINE GENERATED. USE THE FOLLOWING SCRIPT TO REBUILD IT:
+ * - Template/src/unicode/generate_unicode_tables.php
+ *
+LICENSE_HEADER;
+
+$lowerToUpper = <<<END
+<?php
+/**
+ * File containing a mapping from unicode lowercase to uppercase letters.
+ *
+
+END
+.$licenseHeader;
+
+$lowerToUpper .= <<<END
+
+ * @package Template
+ * @version //autogentag//
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @access private
+ */
+
+class ezcTemplateStringLowerToUpperUnicodeMap extends ezcBaseStruct
+{
+    public \$unicodeTable = array(
+
+END;
+
+$upperToLower = <<<END
+<?php
+/**
+ * File containing a mapping from unicode uppercase to lowercase letters.
+
+END
+.$licenseHeader;
+
+$upperToLower .= <<<END
+
+ * @package Template
+ * @version //autogentag//
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @access private
+ */
+
+class ezcTemplateStringUpperToLowerUnicodeMap extends ezcBaseStruct
+{
+    public \$unicodeTable = array(
+
+END;
+
+
+$fp = fopen( 'http://www.unicode.org/Public/UNIDATA/UnicodeData.txt', 'r' );
+
+if ( $fp !== false )
+{
+    while ( ( $line = fgets( $fp ) ) !== false )
+    {
+        $columns = explode( ';', $line );
+        $source = getHexStringFromCodepoint( $columns[0] );
+        if ( !empty( $columns[12] ) )
+        {
+            $lowerToUpper .= '    "' . $source . '" => "' . getHexStringFromCodepoint( $columns[12] ) . '", // ' . $columns[1] . PHP_EOL;
+        }
+        if ( !empty( $columns[13] ) )
+        {
+            $upperToLower .= '    "' . $source . '" => "' . getHexStringFromCodepoint( $columns[13] ) . '", // ' . $columns[1] . PHP_EOL;
+        }
+    }
+    fclose( $fp );
+
+    $lowerToUpper .= ');' . PHP_EOL . '}';
+    $upperToLower .= ');' . PHP_EOL . '}';
+
+    file_put_contents(
+        'Template/src/structs/lower_to_upper.php',
+        $lowerToUpper
+    );
+    file_put_contents(
+        'Template/src/structs/upper_to_lower.php',
+        $upperToLower
+    );
+}
+
+/**
+ * Get the hex representation of a unicode codepoint.
+ *
+ * What is going on:
+ * http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-AppendixA
+ * http://developers.sun.com/dev/gadc/technicalpublications/articles/utf8.html
+ *
+ * @param int $codepoint
+ * @return string
+ */
+function getHexStringFromCodepoint( $codepoint )
+{
+    // the comments below explain whats done with the bitwise calculations
+    $codepoint = hexdec( $codepoint );
+    $result = '';
+    if ( $codepoint < 0x80 )
+    {
+        // C1 = U
+        $result = "\\x" . dechex( $codepoint );
+    }
+    elseif ( $codepoint < 0x800 )
+    {
+        // C1 = U \ 64 + 192
+        // C2 = U mod 64 + 128
+        $result = "\\x" . dechex( $codepoint >> 6 | 0xc0 ) .
+            "\\x" . dechex( $codepoint & 0x3f | 0x80 );
+    }
+    elseif ( $codepoint < 0x10000 )
+    {
+        // C1 = U \ 4096 + 224
+        // C2 = (U mod 4096) \ 64 + 128
+        // C3 = U mod 64 + 128
+        $result = "\\x" . dechex( $codepoint >> 12 | 0xe0 ) .
+            "\\x" . dechex( $codepoint >> 6 & 0x3f | 0x80 ) .
+            "\\x" . dechex( $codepoint & 0x3f | 0x80 );
+    }
+    elseif ( $codepoint < 0x110000 )
+    {
+        // C1 = U \ 262144 + 240
+        // C2 = (U mod 262144) \ 4096 + 128
+        // C3 = (U mod 4096) \ 64 + 128
+        // C4 = U mod 64 + 128
+        $result = "\\x" . dechex( $codepoint >> 18 | 0xf0 ) .
+            "\\x" . dechex( $codepoint >> 12 & 0x3f | 0x80 ) .
+            "\\x" . dechex( $codepoint >> 6 & 0x3f | 0x80 ) .
+            "\\x" . dechex( $codepoint & 0x3f | 0x80 );
+    }
+    return $result;
+}
\ No newline at end of file
diff --git a/Template/tests/regression_test.php b/Template/tests/regression_test.php
index 34520f9..8af7c1f 100644
--- a/Template/tests/regression_test.php
+++ b/Template/tests/regression_test.php
@@ -606,4 +606,4 @@
 
 
 
-?>
+?>
\ No newline at end of file
diff --git a/Template/tests/regression_tests/functions/correct/string_functions.in b/Template/tests/regression_tests/functions/correct/string_functions.in
index 98311f9..cba33c9 100644
--- a/Template/tests/regression_tests/functions/correct/string_functions.in
+++ b/Template/tests/regression_tests/functions/correct/string_functions.in
@@ -49,4 +49,4 @@
 39. {str_ord( "A" )}
 40. {str_char_count( "hello" )}
 41. {str_index_of( "Hello", "l")}
-42. {str_chr( 65 )}
+42. {str_chr( 65 )}
\ No newline at end of file
diff --git a/Template/tests/regression_tests/functions/correct/string_functions.out b/Template/tests/regression_tests/functions/correct/string_functions.out
index d0b9b7a..c0ab614 100644
--- a/Template/tests/regression_tests/functions/correct/string_functions.out
+++ b/Template/tests/regression_tests/functions/correct/string_functions.out
@@ -36,7 +36,7 @@
 32. Hello world!
 33. dlrow olleH
 34. 2
-35. 2
+35. 3
 36. abcd
 efgh
 ijkl
@@ -48,4 +48,4 @@
 39. 65
 40. 5
 41. 2
-42. A
+42. A
\ No newline at end of file
diff --git a/Template/tests/string_function_test.php b/Template/tests/string_function_test.php
new file mode 100644
index 0000000..3f27f3f
--- /dev/null
+++ b/Template/tests/string_function_test.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version //autogentag//
+ * @filesource
+ * @package Template
+ * @subpackage Tests
+ */
+
+/**
+ * @package Template
+ * @subpackage Tests
+ */
+class ezcStringFunctionTest extends ezcTestCase
+{
+    public static function suite()
+    {
+         return new PHPUnit_Framework_TestSuite( __CLASS__ );
+    }
+
+    public function testLtrim()
+    {
+        $in = '  test8test test';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::ltrim( $in ), $out );
+
+        $in = '8888test8test test';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::ltrim( $in, '8' ), $out );
+
+        $in = 'üöätest8test test';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::ltrim( $in, 'üöä' ), $out );
+    }
+
+    public function testRtrim()
+    {
+        $in = 'test8test test  ';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::rtrim( $in ), $out );
+
+        $in = 'test8test test888';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::rtrim( $in, '8' ), $out );
+
+        $in = 'test8test testüöä';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::rtrim( $in, 'üöä' ), $out );
+    }
+
+    public function testStrpad()
+    {
+        $in = 'äöüßasdfgh';
+        $out = '_____äöüßasdfgh';
+        self::assertEquals( ezcTemplateString::str_pad( $in, 15, '_', STR_PAD_LEFT ), $out );
+
+        $in = 'äöüßasdfgh';
+        $out = 'äöüßasdfgh_____';
+        self::assertEquals( ezcTemplateString::str_pad( $in, 15, '_', STR_PAD_RIGHT ), $out );
+    }
+
+    public function testStrParagraphCount()
+    {
+$in = <<<END
+Lörem ipsüm dölör sit ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä sänctüs est Lörem ipsüm dölör sit ämet. Lörem ipsüm dölör sit ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä sänctüs est Lörem ipsüm dölör sit ämet. Lörem ipsüm dölör sit ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä sänctüs est Lörem ipsüm dölör sit ämet.
+
+Düis äütem vel eüm iriüre dölör in hendrerit in vülpütäte velit esse mölestie cönseqüät, vel illüm dölöre eü feügiät nüllä fäcilisis ät verö erös et äccümsän et iüstö ödiö dignissim qüi bländit präesent lüptätüm zzril delenit äügüe düis dölöre te feügäit nüllä fäcilisi. Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit, sed diäm nönümmy nibh eüismöd tincidünt üt läöreet dölöre mägnä äliqüäm erät völütpät.
+
+Ut wisi enim äd minim veniäm, qüis nöstrüd exerci tätiön üllämcörper süscipit löbörtis nisl üt äliqüip ex eä cömmödö cönseqüät. Düis äütem vel eüm iriüre dölör in hendrerit in vülpütäte velit esse mölestie cönseqüät, vel illüm dölöre eü feügiät nüllä fäcilisis ät verö erös et äccümsän et iüstö ödiö dignissim qüi bländit präesent lüptätüm zzril delenit äügüe düis dölöre te feügäit nüllä fäcilisi.
+
+Näm liber tempör cüm sölütä nöbis eleifend öptiön cöngüe nihil imperdiet döming id qüöd mäzim pläcerät fäcer pössim ässüm. Lörem ipsüm dölör sit ämet, cönsectetüer ädipiscing elit, sed diäm nönümmy nibh eüismöd tincidünt üt läöreet dölöre mägnä äliqüäm erät völütpät. Ut wisi enim äd minim veniäm, qüis nöstrüd exerci tätiön üllämcörper süscipit löbörtis nisl üt äliqüip ex eä cömmödö cönseqüät.
+
+Düis äütem vel eüm iriüre dölör in hendrerit in vülpütäte velit esse mölestie cönseqüät, vel illüm dölöre eü feügiät nüllä fäcilisis.
+
+END;
+        $out = 5;
+        self::assertEquals( ezcTemplateString::str_paragraph_count( $in ), $out );
+    }
+
+    public function testStrWordCount()
+    {
+        $in = "Lörem ipsüm dölör sit ämet, cönse8tetür sädipscing elitr.";
+        $out = 9;
+        self::assertEquals( ezcTemplateString::str_word_count( $in ), $out );
+
+        $out = 8;
+        self::assertEquals( ezcTemplateString::str_word_count( $in, 0, '8' ), $out );
+
+        $out = array(
+            'Lörem',
+            'ipsüm',
+            'dölör',
+            'sit',
+            'ämet',
+            'cönse',
+            'tetür',
+            'sädipscing',
+            'elitr',
+        );
+        self::assertEquals( ezcTemplateString::str_word_count( $in, 1 ), $out );
+
+        $out = array(
+            'Lörem',
+            'ipsüm',
+            'dölör',
+            'sit',
+            'ämet',
+            'cönse8tetür',
+            'sädipscing',
+            'elitr',
+        );
+        self::assertEquals( ezcTemplateString::str_word_count( $in, 1, '8' ), $out );
+
+        $out = array(
+            0 => 'Lörem',
+            6 => 'ipsüm',
+            12 => 'dölör',
+            18 => 'sit',
+            22 => 'ämet',
+            28 => 'cönse',
+            34 => 'tetür',
+            40 => 'sädipscing',
+            51 => 'elitr',
+        );
+        self::assertEquals( ezcTemplateString::str_word_count( $in, 2 ), $out );
+
+        $out = array(
+            0 => 'Lörem',
+            6 => 'ipsüm',
+            12 => 'dölör',
+            18 => 'sit',
+            22 => 'ämet',
+            28 => 'cönse8tetür',
+            40 => 'sädipscing',
+            51 => 'elitr',
+        );
+        self::assertEquals( ezcTemplateString::str_word_count( $in, 2, '8' ), $out );
+    }
+
+    public function testStrpos()
+    {
+        $in = 'äöüß';
+        $out = 1;
+        self::assertEquals( ezcTemplateString::strpos( $in, 'ö' ), $out );
+
+        $in = 'äöüß';
+        $out = 0;
+        self::assertEquals( ezcTemplateString::strpos( $in, 'ä' ), $out );
+
+        $in = 'äöüß';
+        $out = false;
+        self::assertEquals( ezcTemplateString::strpos( $in, 'q' ), $out );
+
+        $in = 'äöüß';
+        $out = 3;
+        self::assertEquals( ezcTemplateString::strpos( $in, 'ß', 1 ), $out );
+    }
+
+    public function testStrrpos()
+    {
+        $in = 'äöüß';
+        $out = 2;
+        self::assertEquals( ezcTemplateString::strrpos( $in, 'ü' ), $out );
+
+        $in = 'äöüß';
+        $out = 2;
+        self::assertEquals( ezcTemplateString::strrpos( $in, 'ü', 0, false ), $out );
+
+        $in = 'äöüß';
+        $out = 2;
+        self::assertEquals( ezcTemplateString::strrpos( $in, 'ü', 1, false ), $out );
+
+        $in = 'äöüß';
+        $out = 2;
+        self::assertEquals( ezcTemplateString::strrpos( $in, 'ü', -1, false ), $out );
+    }
+
+    public function testStrrev()
+    {
+        $in = 'äöüß';
+        $out = 'ßüöä';
+        self::assertEquals( ezcTemplateString::strrev( $in ), $out );
+
+        $in = 'äaöoüußs';
+        $out = 'sßuüoöaä';
+        self::assertEquals( ezcTemplateString::strrev( $in ), $out );
+    }
+
+    public function testStrtolower()
+    {
+        $in = 'ÄÖÜÀÉASDFGHJKLtuzerui"§$%&/()=';
+        $out = 'äöüàéasdfghjkltuzerui"§$%&/()=';
+        // use mb string extension = true
+        self::assertEquals( ezcTemplateString::strtolower( $in ), $out );
+        // use mb string extension = false to test custom strtolower using conversion table
+        self::assertEquals( ezcTemplateString::strtolower( $in, false ), $out );
+    }
+
+    public function testStrtoupper()
+    {
+        $in = 'äöüàéasdfghjkltuzerui"§$%&/()=';
+        $out = 'ÄÖÜÀÉASDFGHJKLTUZERUI"§$%&/()=';
+        // use mb string extension = true
+        self::assertEquals( ezcTemplateString::strtoupper( $in ), $out );
+        // use mb string extension = false to test custom strtolower using conversion table
+        self::assertEquals( ezcTemplateString::strtoupper( $in, false ), $out );
+    }
+
+    public function testTrim()
+    {
+        $in = '  test8test test  ';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::trim( $in ), $out );
+
+        $in = '888test8test test888';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::trim( $in, '8' ), $out );
+
+        $in = 'üöätest8test testüöä';
+        $out = 'test8test test';
+        self::assertEquals( ezcTemplateString::trim( $in, 'üöä' ), $out );
+    }
+
+    public function testUcfirst()
+    {
+        $in = 'äaöoüußs';
+        $out = 'Äaöoüußs';
+        self::assertEquals( ezcTemplateString::ucfirst( $in ), $out );
+
+        $in = 'aäaöoüußs';
+        $out = 'Aäaöoüußs';
+        self::assertEquals( ezcTemplateString::ucfirst( $in ), $out );
+    }
+
+    public function testWordwrap()
+    {
+$in = <<<END
+Lörem ipsüm dölör sit ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä sänctüs est Lörem ipsüm dölör sit ämet. Lörem ipsüm dölör sit ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä sänctüs est Lörem ipsüm dölör sit ämet. Lörem ipsüm dölör sit ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä sänctüs est Lörem ipsüm dölör sit ämet.
+END;
+$out = <<<END
+Lörem ipsüm dölör sit ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd
+tempör invidünt üt läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At
+verö eös et äccüsäm et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren,
+nö seä täkimätä sänctüs est Lörem ipsüm dölör sit ämet. Lörem ipsüm dölör sit
+ämet, cönsetetür sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt
+läböre et dölöre mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm
+et jüstö düö dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä
+sänctüs est Lörem ipsüm dölör sit ämet. Lörem ipsüm dölör sit ämet, cönsetetür
+sädipscing elitr, sed diäm nönümy eirmöd tempör invidünt üt läböre et dölöre
+mägnä äliqüyäm erät, sed diäm völüptüä. At verö eös et äccüsäm et jüstö düö
+dölöres et eä rebüm. Stet clitä käsd gübergren, nö seä täkimätä sänctüs est
+Lörem ipsüm dölör sit ämet.
+END;
+        self::assertEquals( ezcTemplateString::wordwrap( $in, 80, "\n" ), $out );
+    }
+}
+
+?>
\ No newline at end of file
diff --git a/Template/tests/suite.php b/Template/tests/suite.php
index adde017..134b3e4 100644
--- a/Template/tests/suite.php
+++ b/Template/tests/suite.php
@@ -44,6 +44,7 @@
 require_once 'cache_test.php';
 require_once 'cache_manager_test.php';
 require_once 'locale_test.php';
+require_once 'string_function_test.php';
 
 /**
  * @package Template
@@ -74,6 +75,7 @@
         $this->addTest( ezcTemplateCacheManagerTest::suite() );
         $this->addTest( ezcTemplateTest::suite() );
         $this->addTest( ezcTemplateLocaleTest::suite() );
+        $this->addTest( ezcStringFunctionTest::suite() );
     }
 
     public static function suite()
@@ -81,4 +83,4 @@
         return new ezcTemplateSuite();
     }
 }
-?>
+?>
\ No newline at end of file