[ Index ]

PHP Cross Reference of phpwcms V1.5.0 _r431 (28.01.12)

title

Body

[close]

/include/inc_ext/idna_convert/ -> idna_convert.class.php (source)

   1  <?php
   2  // {{{ license
   3  
   4  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
   5  //
   6  // +----------------------------------------------------------------------+
   7  // | This library is free software; you can redistribute it and/or modify |
   8  // | it under the terms of the GNU Lesser General Public License as       |
   9  // | published by the Free Software Foundation; either version 2.1 of the |
  10  // | License, or (at your option) any later version.                      |
  11  // |                                                                      |
  12  // | This library is distributed in the hope that it will be useful, but  |
  13  // | WITHOUT ANY WARRANTY; without even the implied warranty of           |
  14  // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
  15  // | Lesser General Public License for more details.                      |
  16  // |                                                                      |
  17  // | You should have received a copy of the GNU Lesser General Public     |
  18  // | License along with this library; if not, write to the Free Software  |
  19  // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 |
  20  // | USA.                                                                 |
  21  // +----------------------------------------------------------------------+
  22  //
  23  
  24  // }}}
  25  
  26  /**
  27   * Encode/decode Internationalized Domain Names.
  28   *
  29   * The class allows to convert internationalized domain names
  30   * (see RFC 3490 for details) as they can be used with various registries worldwide
  31   * to be translated between their original (localized) form and their encoded form
  32   * as it will be used in the DNS (Domain Name System).
  33   *
  34   * The class provides two public methods, encode() and decode(), which do exactly
  35   * what you would expect them to do. You are allowed to use complete domain names,
  36   * simple strings and complete email addresses as well. That means, that you might
  37   * use any of the following notations:
  38   *
  39   * - www.nörgler.com
  40   * - xn--nrgler-wxa
  41   * - xn--brse-5qa.xn--knrz-1ra.info
  42   *
  43   * Unicode input might be given as either UTF-8 string, UCS-4 string or UCS-4 array.
  44   * Unicode output is available in the same formats.
  45   * You can select your preferred format via {@link set_paramter()}.
  46   *
  47   * ACE input and output is always expected to be ASCII.
  48   *
  49   * @author  Matthias Sommerfeld <mso@phlylabs.de>
  50   * @copyright 2004-2011 phlyLabs Berlin, http://phlylabs.de
  51   * @version 0.8.0 2011-03-11
  52   */
  53  class idna_convert
  54  {
  55      // NP See below
  56  
  57      // Internal settings, do not mess with them
  58      protected $_punycode_prefix = 'xn--';
  59      protected $_invalid_ucs = 0x80000000;
  60      protected $_max_ucs = 0x10FFFF;
  61      protected $_base = 36;
  62      protected $_tmin = 1;
  63      protected $_tmax = 26;
  64      protected $_skew = 38;
  65      protected $_damp = 700;
  66      protected $_initial_bias = 72;
  67      protected $_initial_n = 0x80;
  68      protected $_sbase = 0xAC00;
  69      protected $_lbase = 0x1100;
  70      protected $_vbase = 0x1161;
  71      protected $_tbase = 0x11A7;
  72      protected $_lcount = 19;
  73      protected $_vcount = 21;
  74      protected $_tcount = 28;
  75      protected $_ncount = 588;   // _vcount * _tcount
  76      protected $_scount = 11172; // _lcount * _tcount * _vcount
  77      protected $_error = false;
  78  
  79      protected static $_mb_string_overload = null;
  80  
  81      // See {@link set_paramter()} for details of how to change the following
  82      // settings from within your script / application
  83      protected $_api_encoding = 'utf8';   // Default input charset is UTF-8
  84      protected $_allow_overlong = false;  // Overlong UTF-8 encodings are forbidden
  85      protected $_strict_mode = false;     // Behave strict or not
  86      protected $_idn_version = 2003;      // Can be either 2003 (old, default) or 2008
  87  
  88      /**
  89       * the constructor
  90       *
  91       * @param array $options
  92       * @return boolean
  93       * @since 0.5.2
  94       */
  95      public function __construct($options = false)
  96      {
  97          $this->slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount;
  98          // If parameters are given, pass these to the respective method
  99          if (is_array($options)) {
 100              $this->set_parameter($options);
 101          }
 102  
 103          // populate mbstring overloading cache if not set
 104          if (self::$_mb_string_overload === null) {
 105              self::$_mb_string_overload = (extension_loaded('mbstring')
 106                  && (ini_get('mbstring.func_overload') & 0x02) === 0x02);
 107          }
 108      }
 109  
 110      /**
 111       * Sets a new option value. Available options and values:
 112       * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8,
 113       *         'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8]
 114       * [overlong - Unicode does not allow unnecessarily long encodings of chars,
 115       *             to allow this, set this parameter to true, else to false;
 116       *             default is false.]
 117       * [strict - true: strict mode, good for registration purposes - Causes errors
 118       *           on failures; false: loose mode, ideal for "wildlife" applications
 119       *           by silently ignoring errors and returning the original input instead
 120       *
 121       * @param    mixed     Parameter to set (string: single parameter; array of Parameter => Value pairs)
 122       * @param    string    Value to use (if parameter 1 is a string)
 123       * @return   boolean   true on success, false otherwise
 124       */
 125      public function set_parameter($option, $value = false)
 126      {
 127          if (!is_array($option)) {
 128              $option = array($option => $value);
 129          }
 130          foreach ($option as $k => $v) {
 131              switch ($k) {
 132              case 'encoding':
 133                  switch ($v) {
 134                  case 'utf8':
 135                  case 'ucs4_string':
 136                  case 'ucs4_array':
 137                      $this->_api_encoding = $v;
 138                      break;
 139                  default:
 140                      $this->_error('Set Parameter: Unknown parameter '.$v.' for option '.$k);
 141                      return false;
 142                  }
 143                  break;
 144              case 'overlong':
 145                  $this->_allow_overlong = ($v) ? true : false;
 146                  break;
 147              case 'strict':
 148                  $this->_strict_mode = ($v) ? true : false;
 149                  break;
 150              case 'idn_version':
 151                  if (in_array($v, array('2003', '2008'))) {
 152                      $this->_idn_version = $v;
 153                  } else {
 154                      $this->_error('Set Parameter: Unknown parameter '.$v.' for option '.$k);
 155                  }
 156                  break;
 157              case 'encode_german_sz': // Deprecated
 158                  if (!$v) {
 159                      self::$NP['replacemaps'][0xDF] = array(0x73, 0x73);
 160                  } else {
 161                      unset(self::$NP['replacemaps'][0xDF]);
 162                  }
 163                  break;
 164              default:
 165                  $this->_error('Set Parameter: Unknown option '.$k);
 166                  return false;
 167              }
 168          }
 169          return true;
 170      }
 171  
 172      /**
 173       * Decode a given ACE domain name
 174       * @param    string   Domain name (ACE string)
 175       * [@param    string   Desired output encoding, see {@link set_parameter}]
 176       * @return   string   Decoded Domain name (UTF-8 or UCS-4)
 177       */
 178      public function decode($input, $one_time_encoding = false)
 179      {
 180          // Optionally set
 181          if ($one_time_encoding) {
 182              switch ($one_time_encoding) {
 183              case 'utf8':
 184              case 'ucs4_string':
 185              case 'ucs4_array':
 186                  break;
 187              default:
 188                  $this->_error('Unknown encoding '.$one_time_encoding);
 189                  return false;
 190              }
 191          }
 192          // Make sure to drop any newline characters around
 193          $input = trim($input);
 194  
 195          // Negotiate input and try to determine, whether it is a plain string,
 196          // an email address or something like a complete URL
 197          if (strpos($input, '@')) { // Maybe it is an email address
 198              // No no in strict mode
 199              if ($this->_strict_mode) {
 200                  $this->_error('Only simple domain name parts can be handled in strict mode');
 201                  return false;
 202              }
 203              list ($email_pref, $input) = explode('@', $input, 2);
 204              $arr = explode('.', $input);
 205              foreach ($arr as $k => $v) {
 206                  if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) {
 207                      $conv = $this->_decode($v);
 208                      if ($conv) $arr[$k] = $conv;
 209                  }
 210              }
 211              $input = join('.', $arr);
 212              $arr = explode('.', $email_pref);
 213              foreach ($arr as $k => $v) {
 214                  if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) {
 215                      $conv = $this->_decode($v);
 216                      if ($conv) $arr[$k] = $conv;
 217                  }
 218              }
 219              $email_pref = join('.', $arr);
 220              $return = $email_pref . '@' . $input;
 221          } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters)
 222              // No no in strict mode
 223              if ($this->_strict_mode) {
 224                  $this->_error('Only simple domain name parts can be handled in strict mode');
 225                  return false;
 226              }
 227              $parsed = parse_url($input);
 228              if (isset($parsed['host'])) {
 229                  $arr = explode('.', $parsed['host']);
 230                  foreach ($arr as $k => $v) {
 231                      $conv = $this->_decode($v);
 232                      if ($conv) $arr[$k] = $conv;
 233                  }
 234                  $parsed['host'] = join('.', $arr);
 235                  $return =
 236                          (empty($parsed['scheme']) ? '' : $parsed['scheme'].(strtolower($parsed['scheme']) == 'mailto' ? ':' : '://'))
 237                          .(empty($parsed['user']) ? '' : $parsed['user'].(empty($parsed['pass']) ? '' : ':'.$parsed['pass']).'@')
 238                          .$parsed['host']
 239                          .(empty($parsed['port']) ? '' : ':'.$parsed['port'])
 240                          .(empty($parsed['path']) ? '' : $parsed['path'])
 241                          .(empty($parsed['query']) ? '' : '?'.$parsed['query'])
 242                          .(empty($parsed['fragment']) ? '' : '#'.$parsed['fragment']);
 243              } else { // parse_url seems to have failed, try without it
 244                  $arr = explode('.', $input);
 245                  foreach ($arr as $k => $v) {
 246                      $conv = $this->_decode($v);
 247                      $arr[$k] = ($conv) ? $conv : $v;
 248                  }
 249                  $return = join('.', $arr);
 250              }
 251          } else { // Otherwise we consider it being a pure domain name string
 252              $return = $this->_decode($input);
 253              if (!$return) $return = $input;
 254          }
 255          // The output is UTF-8 by default, other output formats need conversion here
 256          // If one time encoding is given, use this, else the objects property
 257          switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) {
 258          case 'utf8':
 259              return $return;
 260              break;
 261          case 'ucs4_string':
 262             return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return));
 263             break;
 264          case 'ucs4_array':
 265              return $this->_utf8_to_ucs4($return);
 266              break;
 267          default:
 268              $this->_error('Unsupported output format');
 269              return false;
 270          }
 271      }
 272  
 273      /**
 274       * Encode a given UTF-8 domain name
 275       * @param    string   Domain name (UTF-8 or UCS-4)
 276       * [@param    string   Desired input encoding, see {@link set_parameter}]
 277       * @return   string   Encoded Domain name (ACE string)
 278       */
 279      public function encode($decoded, $one_time_encoding = false)
 280      {
 281          // Forcing conversion of input to UCS4 array
 282          // If one time encoding is given, use this, else the objects property
 283          switch ($one_time_encoding ? $one_time_encoding : $this->_api_encoding) {
 284          case 'utf8':
 285              $decoded = $this->_utf8_to_ucs4($decoded);
 286              break;
 287          case 'ucs4_string':
 288             $decoded = $this->_ucs4_string_to_ucs4($decoded);
 289          case 'ucs4_array':
 290             break;
 291          default:
 292              $this->_error('Unsupported input format: '.($one_time_encoding ? $one_time_encoding : $this->_api_encoding));
 293              return false;
 294          }
 295  
 296          // No input, no output, what else did you expect?
 297          if (empty($decoded)) return '';
 298  
 299          // Anchors for iteration
 300          $last_begin = 0;
 301          // Output string
 302          $output = '';
 303          foreach ($decoded as $k => $v) {
 304              // Make sure to use just the plain dot
 305              switch($v) {
 306              case 0x3002:
 307              case 0xFF0E:
 308              case 0xFF61:
 309                  $decoded[$k] = 0x2E;
 310                  // Right, no break here, the above are converted to dots anyway
 311              // Stumbling across an anchoring character
 312              case 0x2E:
 313              case 0x2F:
 314              case 0x3A:
 315              case 0x3F:
 316              case 0x40:
 317                  // Neither email addresses nor URLs allowed in strict mode
 318                  if ($this->_strict_mode) {
 319                     $this->_error('Neither email addresses nor URLs are allowed in strict mode.');
 320                     return false;
 321                  } else {
 322                      // Skip first char
 323                      if ($k) {
 324                          $encoded = '';
 325                          $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin)));
 326                          if ($encoded) {
 327                              $output .= $encoded;
 328                          } else {
 329                              $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin)));
 330                          }
 331                          $output .= chr($decoded[$k]);
 332                      }
 333                      $last_begin = $k + 1;
 334                  }
 335              }
 336          }
 337          // Catch the rest of the string
 338          if ($last_begin) {
 339              $inp_len = sizeof($decoded);
 340              $encoded = '';
 341              $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
 342              if ($encoded) {
 343                  $output .= $encoded;
 344              } else {
 345                  $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
 346              }
 347              return $output;
 348          } else {
 349              if ($output = $this->_encode($decoded)) {
 350                  return $output;
 351              } else {
 352                  return $this->_ucs4_to_utf8($decoded);
 353              }
 354          }
 355      }
 356  
 357      /**
 358       * Removes a weakness of encode(), which cannot properly handle URIs but instead encodes their
 359       * path or query components, too.
 360       * @param string  $uri  Expects the URI as a UTF-8 (or ASCII) string
 361       * @return  string  The URI encoded to Punycode, everything but the host component is left alone
 362       * @since 0.6.4
 363       */
 364      public function encode_uri($uri)
 365      {
 366          $parsed = parse_url($uri);
 367          if (!isset($parsed['host'])) {
 368              $this->_error('The given string does not look like a URI');
 369              return false;
 370          }
 371          $arr = explode('.', $parsed['host']);
 372          foreach ($arr as $k => $v) {
 373              $conv = $this->encode($v, 'utf8');
 374              if ($conv) $arr[$k] = $conv;
 375          }
 376          $parsed['host'] = join('.', $arr);
 377          $return =
 378                  (empty($parsed['scheme']) ? '' : $parsed['scheme'].(strtolower($parsed['scheme']) == 'mailto' ? ':' : '://'))
 379                  .(empty($parsed['user']) ? '' : $parsed['user'].(empty($parsed['pass']) ? '' : ':'.$parsed['pass']).'@')
 380                  .$parsed['host']
 381                  .(empty($parsed['port']) ? '' : ':'.$parsed['port'])
 382                  .(empty($parsed['path']) ? '' : $parsed['path'])
 383                  .(empty($parsed['query']) ? '' : '?'.$parsed['query'])
 384                  .(empty($parsed['fragment']) ? '' : '#'.$parsed['fragment']);
 385          return $return;
 386      }
 387  
 388      /**
 389       * Use this method to get the last error ocurred
 390       * @param    void
 391       * @return   string   The last error, that occured
 392       */
 393      public function get_last_error()
 394      {
 395          return $this->_error;
 396      }
 397  
 398      /**
 399       * The actual decoding algorithm
 400       * @param string
 401       * @return mixed
 402       */
 403      protected function _decode($encoded)
 404      {
 405          $decoded = array();
 406          // find the Punycode prefix
 407          if (!preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $encoded)) {
 408              $this->_error('This is not a punycode string');
 409              return false;
 410          }
 411          $encode_test = preg_replace('!^'.preg_quote($this->_punycode_prefix, '!').'!', '', $encoded);
 412          // If nothing left after removing the prefix, it is hopeless
 413          if (!$encode_test) {
 414              $this->_error('The given encoded string was empty');
 415              return false;
 416          }
 417          // Find last occurence of the delimiter
 418          $delim_pos = strrpos($encoded, '-');
 419          if ($delim_pos > self::byteLength($this->_punycode_prefix)) {
 420              for ($k = self::byteLength($this->_punycode_prefix); $k < $delim_pos; ++$k) {
 421                  $decoded[] = ord($encoded{$k});
 422              }
 423          }
 424          $deco_len = count($decoded);
 425          $enco_len = self::byteLength($encoded);
 426  
 427          // Wandering through the strings; init
 428          $is_first = true;
 429          $bias = $this->_initial_bias;
 430          $idx = 0;
 431          $char = $this->_initial_n;
 432  
 433          for ($enco_idx = ($delim_pos) ? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) {
 434              for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) {
 435                  $digit = $this->_decode_digit($encoded{$enco_idx++});
 436                  $idx += $digit * $w;
 437                  $t = ($k <= $bias) ? $this->_tmin :
 438                          (($k >= $bias + $this->_tmax) ? $this->_tmax : ($k - $bias));
 439                  if ($digit < $t) break;
 440                  $w = (int) ($w * ($this->_base - $t));
 441              }
 442              $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first);
 443              $is_first = false;
 444              $char += (int) ($idx / ($deco_len + 1));
 445              $idx %= ($deco_len + 1);
 446              if ($deco_len > 0) {
 447                  // Make room for the decoded char
 448                  for ($i = $deco_len; $i > $idx; $i--) $decoded[$i] = $decoded[($i - 1)];
 449              }
 450              $decoded[$idx++] = $char;
 451          }
 452          return $this->_ucs4_to_utf8($decoded);
 453      }
 454  
 455      /**
 456       * The actual encoding algorithm
 457       * @param  string
 458       * @return mixed
 459       */
 460      protected function _encode($decoded)
 461      {
 462          // We cannot encode a domain name containing the Punycode prefix
 463          $extract = self::byteLength($this->_punycode_prefix);
 464          $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix);
 465          $check_deco = array_slice($decoded, 0, $extract);
 466  
 467          if ($check_pref == $check_deco) {
 468              $this->_error('This is already a punycode string');
 469              return false;
 470          }
 471          // We will not try to encode strings consisting of basic code points only
 472          $encodable = false;
 473          foreach ($decoded as $k => $v) {
 474              if ($v > 0x7a) {
 475                  $encodable = true;
 476                  break;
 477              }
 478          }
 479          if (!$encodable) {
 480              $this->_error('The given string does not contain encodable chars');
 481              return false;
 482          }
 483          // Do NAMEPREP
 484          $decoded = $this->_nameprep($decoded);
 485          if (!$decoded || !is_array($decoded)) return false; // NAMEPREP failed
 486          $deco_len  = count($decoded);
 487          if (!$deco_len) return false; // Empty array
 488          $codecount = 0; // How many chars have been consumed
 489          $encoded = '';
 490          // Copy all basic code points to output
 491          for ($i = 0; $i < $deco_len; ++$i) {
 492              $test = $decoded[$i];
 493              // Will match [-0-9a-zA-Z]
 494              if ((0x2F < $test && $test < 0x40) || (0x40 < $test && $test < 0x5B)
 495                      || (0x60 < $test && $test <= 0x7B) || (0x2D == $test)) {
 496                  $encoded .= chr($decoded[$i]);
 497                  $codecount++;
 498              }
 499          }
 500          if ($codecount == $deco_len) return $encoded; // All codepoints were basic ones
 501  
 502          // Start with the prefix; copy it to output
 503          $encoded = $this->_punycode_prefix.$encoded;
 504          // If we have basic code points in output, add an hyphen to the end
 505          if ($codecount) $encoded .= '-';
 506          // Now find and encode all non-basic code points
 507          $is_first = true;
 508          $cur_code = $this->_initial_n;
 509          $bias = $this->_initial_bias;
 510          $delta = 0;
 511          while ($codecount < $deco_len) {
 512              // Find the smallest code point >= the current code point and
 513              // remember the last ouccrence of it in the input
 514              for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) {
 515                  if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) {
 516                      $next_code = $decoded[$i];
 517                  }
 518              }
 519              $delta += ($next_code - $cur_code) * ($codecount + 1);
 520              $cur_code = $next_code;
 521  
 522              // Scan input again and encode all characters whose code point is $cur_code
 523              for ($i = 0; $i < $deco_len; $i++) {
 524                  if ($decoded[$i] < $cur_code) {
 525                      $delta++;
 526                  } elseif ($decoded[$i] == $cur_code) {
 527                      for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) {
 528                          $t = ($k <= $bias) ? $this->_tmin :
 529                                  (($k >= $bias + $this->_tmax) ? $this->_tmax : $k - $bias);
 530                          if ($q < $t) break;
 531                          $encoded .= $this->_encode_digit(intval($t + (($q - $t) % ($this->_base - $t)))); //v0.4.5 Changed from ceil() to intval()
 532                          $q = (int) (($q - $t) / ($this->_base - $t));
 533                      }
 534                      $encoded .= $this->_encode_digit($q);
 535                      $bias = $this->_adapt($delta, $codecount+1, $is_first);
 536                      $codecount++;
 537                      $delta = 0;
 538                      $is_first = false;
 539                  }
 540              }
 541              $delta++;
 542              $cur_code++;
 543          }
 544          return $encoded;
 545      }
 546  
 547      /**
 548       * Adapt the bias according to the current code point and position
 549       * @param int $delta
 550       * @param int $npoints
 551       * @param int $is_first
 552       * @return int
 553       */
 554      protected function _adapt($delta, $npoints, $is_first)
 555      {
 556          $delta = intval($is_first ? ($delta / $this->_damp) : ($delta / 2));
 557          $delta += intval($delta / $npoints);
 558          for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) {
 559              $delta = intval($delta / ($this->_base - $this->_tmin));
 560          }
 561          return intval($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew));
 562      }
 563  
 564      /**
 565       * Encoding a certain digit
 566       * @param    int $d
 567       * @return string
 568       */
 569      protected function _encode_digit($d)
 570      {
 571          return chr($d + 22 + 75 * ($d < 26));
 572      }
 573  
 574      /**
 575       * Decode a certain digit
 576       * @param    int $cp
 577       * @return int
 578       */
 579      protected function _decode_digit($cp)
 580      {
 581          $cp = ord($cp);
 582          return ($cp - 48 < 10) ? $cp - 22 : (($cp - 65 < 26) ? $cp - 65 : (($cp - 97 < 26) ? $cp - 97 : $this->_base));
 583      }
 584  
 585      /**
 586       * Internal error handling method
 587       * @param  string $error
 588       */
 589      protected function _error($error = '')
 590      {
 591          $this->_error = $error;
 592      }
 593  
 594      /**
 595       * Do Nameprep according to RFC3491 and RFC3454
 596       * @param    array    Unicode Characters
 597       * @return   string   Unicode Characters, Nameprep'd
 598       */
 599      protected function _nameprep($input)
 600      {
 601          $output = array();
 602          $error = false;
 603          //
 604          // Mapping
 605          // Walking through the input array, performing the required steps on each of
 606          // the input chars and putting the result into the output array
 607          // While mapping required chars we apply the cannonical ordering
 608          foreach ($input as $v) {
 609              // Map to nothing == skip that code point
 610              if (in_array($v, self::$NP['map_nothing'])) continue;
 611              // Try to find prohibited input
 612              if (in_array($v, self::$NP['prohibit']) || in_array($v, self::$NP['general_prohibited'])) {
 613                  $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v));
 614                  return false;
 615              }
 616              foreach (self::$NP['prohibit_ranges'] as $range) {
 617                  if ($range[0] <= $v && $v <= $range[1]) {
 618                      $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v));
 619                      return false;
 620                  }
 621              }
 622  
 623              if (0xAC00 <= $v && $v <= 0xD7AF) {
 624                  // Hangul syllable decomposition
 625                  foreach ($this->_hangul_decompose($v) as $out) {
 626                      $output[] = (int) $out;
 627                  }
 628              } elseif (($this->_idn_version == '2003') && isset(self::$NP['replacemaps'][$v])) {
 629                  // There's a decomposition mapping for that code point
 630                  // Decompositions only in version 2003 (original) of IDNA
 631                  foreach ($this->_apply_cannonical_ordering(self::$NP['replacemaps'][$v]) as $out) {
 632                      $output[] = (int) $out;
 633                  }
 634              } else {
 635                  $output[] = (int) $v;
 636              }
 637          }
 638          // Before applying any Combining, try to rearrange any Hangul syllables
 639          $output = $this->_hangul_compose($output);
 640          //
 641          // Combine code points
 642          //
 643          $last_class = 0;
 644          $last_starter = 0;
 645          $out_len = count($output);
 646          for ($i = 0; $i < $out_len; ++$i) {
 647              $class = $this->_get_combining_class($output[$i]);
 648              if ((!$last_class || $last_class > $class) && $class) {
 649                  // Try to match
 650                  $seq_len = $i - $last_starter;
 651                  $out = $this->_combine(array_slice($output, $last_starter, $seq_len));
 652                  // On match: Replace the last starter with the composed character and remove
 653                  // the now redundant non-starter(s)
 654                  if ($out) {
 655                      $output[$last_starter] = $out;
 656                      if (count($out) != $seq_len) {
 657                          for ($j = $i+1; $j < $out_len; ++$j) $output[$j-1] = $output[$j];
 658                          unset($output[$out_len]);
 659                      }
 660                      // Rewind the for loop by one, since there can be more possible compositions
 661                      $i--;
 662                      $out_len--;
 663                      $last_class = ($i == $last_starter) ? 0 : $this->_get_combining_class($output[$i-1]);
 664                      continue;
 665                  }
 666              }
 667              // The current class is 0
 668              if (!$class) $last_starter = $i;
 669              $last_class = $class;
 670          }
 671          return $output;
 672      }
 673  
 674      /**
 675       * Decomposes a Hangul syllable
 676       * (see http://www.unicode.org/unicode/reports/tr15/#Hangul
 677       * @param    integer  32bit UCS4 code point
 678       * @return   array    Either Hangul Syllable decomposed or original 32bit value as one value array
 679       */
 680      protected function _hangul_decompose($char)
 681      {
 682          $sindex = (int) $char - $this->_sbase;
 683          if ($sindex < 0 || $sindex >= $this->_scount) return array($char);
 684          $result = array();
 685          $result[] = (int) $this->_lbase + $sindex / $this->_ncount;
 686          $result[] = (int) $this->_vbase + ($sindex % $this->_ncount) / $this->_tcount;
 687          $T = intval($this->_tbase + $sindex % $this->_tcount);
 688          if ($T != $this->_tbase) $result[] = $T;
 689          return $result;
 690      }
 691      /**
 692       * Ccomposes a Hangul syllable
 693       * (see http://www.unicode.org/unicode/reports/tr15/#Hangul
 694       * @param    array    Decomposed UCS4 sequence
 695       * @return   array    UCS4 sequence with syllables composed
 696       */
 697      protected function _hangul_compose($input)
 698      {
 699          $inp_len = count($input);
 700          if (!$inp_len) return array();
 701          $result = array();
 702          $last = (int) $input[0];
 703          $result[] = $last; // copy first char from input to output
 704  
 705          for ($i = 1; $i < $inp_len; ++$i) {
 706              $char = (int) $input[$i];
 707              $sindex = $last - $this->_sbase;
 708              $lindex = $last - $this->_lbase;
 709              $vindex = $char - $this->_vbase;
 710              $tindex = $char - $this->_tbase;
 711              // Find out, whether two current characters are LV and T
 712              if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount == 0)
 713                      && 0 <= $tindex && $tindex <= $this->_tcount) {
 714                  // create syllable of form LVT
 715                  $last += $tindex;
 716                  $result[(count($result) - 1)] = $last; // reset last
 717                  continue; // discard char
 718              }
 719              // Find out, whether two current characters form L and V
 720              if (0 <= $lindex && $lindex < $this->_lcount && 0 <= $vindex && $vindex < $this->_vcount) {
 721                  // create syllable of form LV
 722                  $last = (int) $this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount;
 723                  $result[(count($result) - 1)] = $last; // reset last
 724                  continue; // discard char
 725              }
 726              // if neither case was true, just add the character
 727              $last = $char;
 728              $result[] = $char;
 729          }
 730          return $result;
 731      }
 732  
 733      /**
 734       * Returns the combining class of a certain wide char
 735       * @param    integer    Wide char to check (32bit integer)
 736       * @return   integer    Combining class if found, else 0
 737       */
 738      protected function _get_combining_class($char)
 739      {
 740          return isset(self::$NP['norm_combcls'][$char]) ? self::$NP['norm_combcls'][$char] : 0;
 741      }
 742  
 743      /**
 744       * Applies the cannonical ordering of a decomposed UCS4 sequence
 745       * @param    array      Decomposed UCS4 sequence
 746       * @return   array      Ordered USC4 sequence
 747       */
 748      protected function _apply_cannonical_ordering($input)
 749      {
 750          $swap = true;
 751          $size = count($input);
 752          while ($swap) {
 753              $swap = false;
 754              $last = $this->_get_combining_class(intval($input[0]));
 755              for ($i = 0; $i < $size-1; ++$i) {
 756                  $next = $this->_get_combining_class(intval($input[$i+1]));
 757                  if ($next != 0 && $last > $next) {
 758                      // Move item leftward until it fits
 759                      for ($j = $i + 1; $j > 0; --$j) {
 760                          if ($this->_get_combining_class(intval($input[$j-1])) <= $next) break;
 761                          $t = intval($input[$j]);
 762                          $input[$j] = intval($input[$j-1]);
 763                          $input[$j-1] = $t;
 764                          $swap = true;
 765                      }
 766                      // Reentering the loop looking at the old character again
 767                      $next = $last;
 768                  }
 769                  $last = $next;
 770              }
 771          }
 772          return $input;
 773      }
 774  
 775      /**
 776       * Do composition of a sequence of starter and non-starter
 777       * @param    array      UCS4 Decomposed sequence
 778       * @return   array      Ordered USC4 sequence
 779       */
 780      protected function _combine($input)
 781      {
 782          $inp_len = count($input);
 783          foreach (self::$NP['replacemaps'] as $np_src => $np_target) {
 784              if ($np_target[0] != $input[0]) continue;
 785              if (count($np_target) != $inp_len) continue;
 786              $hit = false;
 787              foreach ($input as $k2 => $v2) {
 788                  if ($v2 == $np_target[$k2]) {
 789                      $hit = true;
 790                  } else {
 791                      $hit = false;
 792                      break;
 793                  }
 794              }
 795              if ($hit) return $np_src;
 796          }
 797          return false;
 798      }
 799  
 800      /**
 801       * This converts an UTF-8 encoded string to its UCS-4 representation
 802       * By talking about UCS-4 "strings" we mean arrays of 32bit integers representing
 803       * each of the "chars". This is due to PHP not being able to handle strings with
 804       * bit depth different from 8. This apllies to the reverse method _ucs4_to_utf8(), too.
 805       * The following UTF-8 encodings are supported:
 806       * bytes bits  representation
 807       * 1        7  0xxxxxxx
 808       * 2       11  110xxxxx 10xxxxxx
 809       * 3       16  1110xxxx 10xxxxxx 10xxxxxx
 810       * 4       21  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 811       * 5       26  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 812       * 6       31  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 813       * Each x represents a bit that can be used to store character data.
 814       * The five and six byte sequences are part of Annex D of ISO/IEC 10646-1:2000
 815       * @param string $input
 816       * @return string
 817       */
 818      protected function _utf8_to_ucs4($input)
 819      {
 820          $output = array();
 821          $out_len = 0;
 822          $inp_len = self::byteLength($input);
 823          $mode = 'next';
 824          $test = 'none';
 825          for ($k = 0; $k < $inp_len; ++$k) {
 826              $v = ord($input{$k}); // Extract byte from input string
 827              if ($v < 128) { // We found an ASCII char - put into stirng as is
 828                  $output[$out_len] = $v;
 829                  ++$out_len;
 830                  if ('add' == $mode) {
 831                      $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
 832                      return false;
 833                  }
 834                  continue;
 835              }
 836              if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char
 837                  $start_byte = $v;
 838                  $mode = 'add';
 839                  $test = 'range';
 840                  if ($v >> 5 == 6) { // &110xxxxx 10xxxxx
 841                      $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left
 842                      $v = ($v - 192) << 6;
 843                  } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx
 844                      $next_byte = 1;
 845                      $v = ($v - 224) << 12;
 846                  } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
 847                      $next_byte = 2;
 848                      $v = ($v - 240) << 18;
 849                  } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 850                      $next_byte = 3;
 851                      $v = ($v - 248) << 24;
 852                  } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
 853                      $next_byte = 4;
 854                      $v = ($v - 252) << 30;
 855                  } else {
 856                      $this->_error('This might be UTF-8, but I don\'t understand it at byte '.$k);
 857                      return false;
 858                  }
 859                  if ('add' == $mode) {
 860                      $output[$out_len] = (int) $v;
 861                      ++$out_len;
 862                      continue;
 863                  }
 864              }
 865              if ('add' == $mode) {
 866                  if (!$this->_allow_overlong && $test == 'range') {
 867                      $test = 'none';
 868                      if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) {
 869                          $this->_error('Bogus UTF-8 character detected (out of legal range) at byte '.$k);
 870                          return false;
 871                      }
 872                  }
 873                  if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx
 874                      $v = ($v - 128) << ($next_byte * 6);
 875                      $output[($out_len - 1)] += $v;
 876                      --$next_byte;
 877                  } else {
 878                      $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
 879                      return false;
 880                  }
 881                  if ($next_byte < 0) {
 882                      $mode = 'next';
 883                  }
 884              }
 885          } // for
 886          return $output;
 887      }
 888  
 889      /**
 890       * Convert UCS-4 string into UTF-8 string
 891       * See _utf8_to_ucs4() for details
 892       * @param string  $input
 893       * @return string
 894       */
 895      protected function _ucs4_to_utf8($input)
 896      {
 897          $output = '';
 898          foreach ($input as $k => $v) {
 899              if ($v < 128) { // 7bit are transferred literally
 900                  $output .= chr($v);
 901              } elseif ($v < (1 << 11)) { // 2 bytes
 902                  $output .= chr(192+($v >> 6)).chr(128+($v & 63));
 903              } elseif ($v < (1 << 16)) { // 3 bytes
 904                  $output .= chr(224+($v >> 12)).chr(128+(($v >> 6) & 63)).chr(128+($v & 63));
 905              } elseif ($v < (1 << 21)) { // 4 bytes
 906                  $output .= chr(240+($v >> 18)).chr(128+(($v >> 12) & 63)).chr(128+(($v >> 6) & 63)).chr(128+($v & 63));
 907              } elseif (self::$safe_mode) {
 908                  $output .= self::$safe_char;
 909              } else {
 910                  $this->_error('Conversion from UCS-4 to UTF-8 failed: malformed input at byte '.$k);
 911                  return false;
 912              }
 913          }
 914          return $output;
 915      }
 916  
 917      /**
 918       * Convert UCS-4 array into UCS-4 string
 919       *
 920       * @param array $input
 921       * @return string
 922       */
 923      protected function _ucs4_to_ucs4_string($input)
 924      {
 925          $output = '';
 926          // Take array values and split output to 4 bytes per value
 927          // The bit mask is 255, which reads &11111111
 928          foreach ($input as $v) {
 929              $output .= chr(($v >> 24) & 255).chr(($v >> 16) & 255).chr(($v >> 8) & 255).chr($v & 255);
 930          }
 931          return $output;
 932      }
 933  
 934      /**
 935       * Convert UCS-4 strin into UCS-4 garray
 936       *
 937       * @param  string $input
 938       * @return array
 939       */
 940      protected function _ucs4_string_to_ucs4($input)
 941      {
 942          $output = array();
 943          $inp_len = self::byteLength($input);
 944          // Input length must be dividable by 4
 945          if ($inp_len % 4) {
 946              $this->_error('Input UCS4 string is broken');
 947              return false;
 948          }
 949          // Empty input - return empty output
 950          if (!$inp_len) return $output;
 951          for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) {
 952              // Increment output position every 4 input bytes
 953              if (!($i % 4)) {
 954                  $out_len++;
 955                  $output[$out_len] = 0;
 956              }
 957              $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) );
 958          }
 959          return $output;
 960      }
 961  
 962      /**
 963       * Gets the length of a string in bytes even if mbstring function
 964       * overloading is turned on
 965       *
 966       * @param string $string the string for which to get the length.
 967       * @return integer the length of the string in bytes.
 968       */
 969      protected static function byteLength($string)
 970      {
 971          if (self::$_mb_string_overload) {
 972              return mb_strlen($string, '8bit');
 973          }
 974          return strlen((binary) $string);
 975      }
 976  
 977      /**
 978       * Attempts to return a concrete IDNA instance.
 979       *
 980       * @param array $params Set of paramaters
 981       * @return idna_convert
 982       * @access public
 983       */
 984      public function getInstance($params = array())
 985      {
 986          return new idna_convert($params);
 987      }
 988  
 989      /**
 990       * Attempts to return a concrete IDNA instance for either php4 or php5,
 991       * only creating a new instance if no IDNA instance with the same
 992       * parameters currently exists.
 993       *
 994       * @param array $params Set of paramaters
 995       *
 996       * @return object idna_convert
 997       * @access public
 998       */
 999      public function singleton($params = array())
1000      {
1001          static $instances;
1002          if (!isset($instances)) {
1003              $instances = array();
1004          }
1005          $signature = serialize($params);
1006          if (!isset($instances[$signature])) {
1007              $instances[$signature] = idna_convert::getInstance($params);
1008          }
1009          return $instances[$signature];
1010      }
1011  
1012      /**
1013       * Holds all relevant mapping tables
1014       * See RFC3454 for details
1015       *
1016       * @private array
1017       * @since 0.5.2
1018       */
1019      protected static $NP = array
1020              ('map_nothing' => array(0xAD, 0x34F, 0x1806, 0x180B, 0x180C, 0x180D, 0x200B, 0x200C
1021                      ,0x200D, 0x2060, 0xFE00, 0xFE01, 0xFE02, 0xFE03, 0xFE04, 0xFE05, 0xFE06, 0xFE07
1022                      ,0xFE08, 0xFE09, 0xFE0A, 0xFE0B, 0xFE0C, 0xFE0D, 0xFE0E, 0xFE0F, 0xFEFF
1023                      )
1024              ,'general_prohibited' => array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
1025                      ,20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 ,33, 34, 35, 36, 37, 38, 39, 40, 41, 42
1026                      ,43, 44, 47, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126, 127, 0x3002
1027                      )
1028              ,'prohibit' => array(0xA0, 0x340, 0x341, 0x6DD, 0x70F, 0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003
1029                      ,0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x200C, 0x200D, 0x200E, 0x200F
1030                      ,0x2028, 0x2029, 0x202A, 0x202B, 0x202C, 0x202D, 0x202E, 0x202F, 0x205F, 0x206A, 0x206B, 0x206C
1031                      ,0x206D, 0x206E, 0x206F, 0x3000, 0xFEFF, 0xFFF9, 0xFFFA, 0xFFFB, 0xFFFC, 0xFFFD, 0xFFFE, 0xFFFF
1032                      ,0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE
1033                      ,0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, 0xBFFFF
1034                      ,0xCFFFE, 0xCFFFF, 0xDFFFE, 0xDFFFF, 0xE0001, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, 0x10FFFF
1035                      )
1036              ,'prohibit_ranges' => array(array(0x80, 0x9F), array(0x2060, 0x206F), array(0x1D173, 0x1D17A)
1037                      ,array(0xE000, 0xF8FF) ,array(0xF0000, 0xFFFFD), array(0x100000, 0x10FFFD)
1038                      ,array(0xFDD0, 0xFDEF), array(0xD800, 0xDFFF), array(0x2FF0, 0x2FFB), array(0xE0020, 0xE007F)
1039                      )
1040              ,'replacemaps' => array(0x41 => array(0x61), 0x42 => array(0x62), 0x43 => array(0x63)
1041                      ,0x44 => array(0x64), 0x45 => array(0x65), 0x46 => array(0x66), 0x47 => array(0x67)
1042                      ,0x48 => array(0x68), 0x49 => array(0x69), 0x4A => array(0x6A), 0x4B => array(0x6B)
1043                      ,0x4C => array(0x6C), 0x4D => array(0x6D), 0x4E => array(0x6E), 0x4F => array(0x6F)
1044                      ,0x50 => array(0x70), 0x51 => array(0x71), 0x52 => array(0x72), 0x53 => array(0x73)
1045                      ,0x54 => array(0x74), 0x55 => array(0x75), 0x56 => array(0x76), 0x57 => array(0x77)
1046                      ,0x58 => array(0x78), 0x59 => array(0x79), 0x5A => array(0x7A), 0xB5 => array(0x3BC)
1047                      ,0xC0 => array(0xE0), 0xC1 => array(0xE1), 0xC2 => array(0xE2), 0xC3 => array(0xE3)
1048                      ,0xC4 => array(0xE4), 0xC5 => array(0xE5), 0xC6 => array(0xE6), 0xC7 => array(0xE7)
1049                      ,0xC8 => array(0xE8), 0xC9 => array(0xE9), 0xCA => array(0xEA), 0xCB => array(0xEB)
1050                      ,0xCC => array(0xEC), 0xCD => array(0xED), 0xCE => array(0xEE), 0xCF => array(0xEF)
1051                      ,0xD0 => array(0xF0), 0xD1 => array(0xF1), 0xD2 => array(0xF2), 0xD3 => array(0xF3)
1052                      ,0xD4 => array(0xF4), 0xD5 => array(0xF5), 0xD6 => array(0xF6), 0xD8 => array(0xF8)
1053                      ,0xD9 => array(0xF9), 0xDA => array(0xFA), 0xDB => array(0xFB), 0xDC => array(0xFC)
1054                      ,0xDD => array(0xFD), 0xDE => array(0xFE), 0xDF => array(0x73, 0x73)
1055                      ,0x100 => array(0x101), 0x102 => array(0x103), 0x104 => array(0x105)
1056                      ,0x106 => array(0x107), 0x108 => array(0x109), 0x10A => array(0x10B)
1057                      ,0x10C => array(0x10D), 0x10E => array(0x10F), 0x110 => array(0x111)
1058                      ,0x112 => array(0x113), 0x114 => array(0x115), 0x116 => array(0x117)
1059                      ,0x118 => array(0x119), 0x11A => array(0x11B), 0x11C => array(0x11D)
1060                      ,0x11E => array(0x11F), 0x120 => array(0x121), 0x122 => array(0x123)
1061                      ,0x124 => array(0x125), 0x126 => array(0x127), 0x128 => array(0x129)
1062                      ,0x12A => array(0x12B), 0x12C => array(0x12D), 0x12E => array(0x12F)
1063                      ,0x130 => array(0x69, 0x307), 0x132 => array(0x133), 0x134 => array(0x135)
1064                      ,0x136 => array(0x137), 0x139 => array(0x13A), 0x13B => array(0x13C)
1065                      ,0x13D => array(0x13E), 0x13F => array(0x140), 0x141 => array(0x142)
1066                      ,0x143 => array(0x144), 0x145 => array(0x146), 0x147 => array(0x148)
1067                      ,0x149 => array(0x2BC, 0x6E), 0x14A => array(0x14B), 0x14C => array(0x14D)
1068                      ,0x14E => array(0x14F), 0x150 => array(0x151), 0x152 => array(0x153)
1069                      ,0x154 => array(0x155), 0x156 => array(0x157), 0x158 => array(0x159)
1070                      ,0x15A => array(0x15B), 0x15C => array(0x15D), 0x15E => array(0x15F)
1071                      ,0x160 => array(0x161), 0x162 => array(0x163), 0x164 => array(0x165)
1072                      ,0x166 => array(0x167), 0x168 => array(0x169), 0x16A => array(0x16B)
1073                      ,0x16C => array(0x16D), 0x16E => array(0x16F), 0x170 => array(0x171)
1074                      ,0x172 => array(0x173), 0x174 => array(0x175), 0x176 => array(0x177)
1075                      ,0x178 => array(0xFF), 0x179 => array(0x17A), 0x17B => array(0x17C)
1076                      ,0x17D => array(0x17E), 0x17F => array(0x73), 0x181 => array(0x253)
1077                      ,0x182 => array(0x183), 0x184 => array(0x185), 0x186 => array(0x254)
1078                      ,0x187 => array(0x188), 0x189 => array(0x256), 0x18A => array(0x257)
1079                      ,0x18B => array(0x18C), 0x18E => array(0x1DD), 0x18F => array(0x259)
1080                      ,0x190 => array(0x25B), 0x191 => array(0x192), 0x193 => array(0x260)
1081                      ,0x194 => array(0x263), 0x196 => array(0x269), 0x197 => array(0x268)
1082                      ,0x198 => array(0x199), 0x19C => array(0x26F), 0x19D => array(0x272)
1083                      ,0x19F => array(0x275), 0x1A0 => array(0x1A1), 0x1A2 => array(0x1A3)
1084                      ,0x1A4 => array(0x1A5), 0x1A6 => array(0x280), 0x1A7 => array(0x1A8)
1085                      ,0x1A9 => array(0x283), 0x1AC => array(0x1AD), 0x1AE => array(0x288)
1086                      ,0x1AF => array(0x1B0), 0x1B1 => array(0x28A), 0x1B2 => array(0x28B)
1087                      ,0x1B3 => array(0x1B4), 0x1B5 => array(0x1B6), 0x1B7 => array(0x292)
1088                      ,0x1B8 => array(0x1B9), 0x1BC => array(0x1BD), 0x1C4 => array(0x1C6)
1089                      ,0x1C5 => array(0x1C6), 0x1C7 => array(0x1C9), 0x1C8 => array(0x1C9)
1090                      ,0x1CA => array(0x1CC), 0x1CB => array(0x1CC), 0x1CD => array(0x1CE)
1091                      ,0x1CF => array(0x1D0), 0x1D1   => array(0x1D2), 0x1D3   => array(0x1D4)
1092                      ,0x1D5   => array(0x1D6), 0x1D7   => array(0x1D8), 0x1D9   => array(0x1DA)
1093                      ,0x1DB   => array(0x1DC), 0x1DE   => array(0x1DF), 0x1E0   => array(0x1E1)
1094                      ,0x1E2   => array(0x1E3), 0x1E4   => array(0x1E5), 0x1E6   => array(0x1E7)
1095                      ,0x1E8   => array(0x1E9), 0x1EA   => array(0x1EB), 0x1EC   => array(0x1ED)
1096                      ,0x1EE   => array(0x1EF), 0x1F0   => array(0x6A, 0x30C), 0x1F1   => array(0x1F3)
1097                      ,0x1F2   => array(0x1F3), 0x1F4   => array(0x1F5), 0x1F6   => array(0x195)
1098                      ,0x1F7   => array(0x1BF), 0x1F8   => array(0x1F9), 0x1FA   => array(0x1FB)
1099                      ,0x1FC   => array(0x1FD), 0x1FE   => array(0x1FF), 0x200   => array(0x201)
1100                      ,0x202   => array(0x203), 0x204   => array(0x205), 0x206   => array(0x207)
1101                      ,0x208   => array(0x209), 0x20A   => array(0x20B), 0x20C   => array(0x20D)
1102                      ,0x20E   => array(0x20F), 0x210   => array(0x211), 0x212   => array(0x213)
1103                      ,0x214   => array(0x215), 0x216   => array(0x217), 0x218   => array(0x219)
1104                      ,0x21A   => array(0x21B), 0x21C   => array(0x21D), 0x21E   => array(0x21F)
1105                      ,0x220   => array(0x19E), 0x222   => array(0x223), 0x224   => array(0x225)
1106                      ,0x226   => array(0x227), 0x228   => array(0x229), 0x22A   => array(0x22B)
1107                      ,0x22C   => array(0x22D), 0x22E   => array(0x22F), 0x230   => array(0x231)
1108                      ,0x232   => array(0x233), 0x345   => array(0x3B9), 0x37A   => array(0x20, 0x3B9)
1109                      ,0x386   => array(0x3AC), 0x388   => array(0x3AD), 0x389   => array(0x3AE)
1110                      ,0x38A   => array(0x3AF), 0x38C   => array(0x3CC), 0x38E   => array(0x3CD)
1111                      ,0x38F   => array(0x3CE), 0x390   => array(0x3B9, 0x308, 0x301)
1112                      ,0x391   => array(0x3B1), 0x392   => array(0x3B2), 0x393   => array(0x3B3)
1113                      ,0x394   => array(0x3B4), 0x395   => array(0x3B5), 0x396   => array(0x3B6)
1114                      ,0x397   => array(0x3B7), 0x398   => array(0x3B8), 0x399   => array(0x3B9)
1115                      ,0x39A   => array(0x3BA), 0x39B   => array(0x3BB), 0x39C   => array(0x3BC)
1116                      ,0x39D   => array(0x3BD), 0x39E   => array(0x3BE), 0x39F   => array(0x3BF)
1117                      ,0x3A0   => array(0x3C0), 0x3A1   => array(0x3C1), 0x3A3   => array(0x3C3)
1118                      ,0x3A4   => array(0x3C4), 0x3A5   => array(0x3C5), 0x3A6   => array(0x3C6)
1119                      ,0x3A7   => array(0x3C7), 0x3A8   => array(0x3C8), 0x3A9   => array(0x3C9)
1120                      ,0x3AA   => array(0x3CA), 0x3AB   => array(0x3CB), 0x3B0   => array(0x3C5, 0x308, 0x301)
1121                      ,0x3C2   => array(0x3C3), 0x3D0   => array(0x3B2), 0x3D1   => array(0x3B8)
1122                      ,0x3D2   => array(0x3C5), 0x3D3   => array(0x3CD), 0x3D4   => array(0x3CB)
1123                      ,0x3D5   => array(0x3C6), 0x3D6   => array(0x3C0), 0x3D8   => array(0x3D9)
1124                      ,0x3DA   => array(0x3DB), 0x3DC   => array(0x3DD), 0x3DE   => array(0x3DF)
1125                      ,0x3E0   => array(0x3E1), 0x3E2   => array(0x3E3), 0x3E4   => array(0x3E5)
1126                      ,0x3E6   => array(0x3E7), 0x3E8   => array(0x3E9), 0x3EA   => array(0x3EB)
1127                      ,0x3EC   => array(0x3ED), 0x3EE   => array(0x3EF), 0x3F0   => array(0x3BA)
1128                      ,0x3F1   => array(0x3C1), 0x3F2   => array(0x3C3), 0x3F4   => array(0x3B8)
1129                      ,0x3F5   => array(0x3B5), 0x400   => array(0x450), 0x401   => array(0x451)
1130                      ,0x402   => array(0x452), 0x403   => array(0x453), 0x404   => array(0x454)
1131                      ,0x405   => array(0x455), 0x406   => array(0x456), 0x407   => array(0x457)
1132                      ,0x408   => array(0x458), 0x409   => array(0x459), 0x40A   => array(0x45A)
1133                      ,0x40B   => array(0x45B), 0x40C   => array(0x45C), 0x40D   => array(0x45D)
1134                      ,0x40E   => array(0x45E), 0x40F   => array(0x45F), 0x410   => array(0x430)
1135                      ,0x411   => array(0x431), 0x412   => array(0x432), 0x413   => array(0x433)
1136                      ,0x414   => array(0x434), 0x415   => array(0x435), 0x416   => array(0x436)
1137                      ,0x417   => array(0x437), 0x418   => array(0x438), 0x419   => array(0x439)
1138                      ,0x41A   => array(0x43A), 0x41B   => array(0x43B), 0x41C   => array(0x43C)
1139                      ,0x41D   => array(0x43D), 0x41E   => array(0x43E), 0x41F   => array(0x43F)
1140                      ,0x420   => array(0x440), 0x421   => array(0x441), 0x422   => array(0x442)
1141                      ,0x423   => array(0x443), 0x424   => array(0x444), 0x425   => array(0x445)
1142                      ,0x426   => array(0x446), 0x427   => array(0x447), 0x428   => array(0x448)
1143                      ,0x429   => array(0x449), 0x42A   => array(0x44A), 0x42B   => array(0x44B)
1144                      ,0x42C   => array(0x44C), 0x42D   => array(0x44D), 0x42E   => array(0x44E)
1145                      ,0x42F   => array(0x44F), 0x460   => array(0x461), 0x462   => array(0x463)
1146                      ,0x464   => array(0x465), 0x466   => array(0x467), 0x468   => array(0x469)
1147                      ,0x46A   => array(0x46B), 0x46C   => array(0x46D), 0x46E   => array(0x46F)
1148                      ,0x470   => array(0x471), 0x472   => array(0x473), 0x474   => array(0x475)
1149                      ,0x476   => array(0x477), 0x478   => array(0x479), 0x47A   => array(0x47B)
1150                      ,0x47C   => array(0x47D), 0x47E   => array(0x47F), 0x480   => array(0x481)
1151                      ,0x48A   => array(0x48B), 0x48C   => array(0x48D), 0x48E   => array(0x48F)
1152                      ,0x490   => array(0x491), 0x492   => array(0x493), 0x494   => array(0x495)
1153                      ,0x496   => array(0x497), 0x498   => array(0x499), 0x49A   => array(0x49B)
1154                      ,0x49C   => array(0x49D), 0x49E   => array(0x49F), 0x4A0   => array(0x4A1)
1155                      ,0x4A2   => array(0x4A3), 0x4A4   => array(0x4A5), 0x4A6   => array(0x4A7)
1156                      ,0x4A8   => array(0x4A9), 0x4AA   => array(0x4AB), 0x4AC   => array(0x4AD)
1157                      ,0x4AE   => array(0x4AF), 0x4B0   => array(0x4B1), 0x4B2   => array(0x4B3)
1158                      ,0x4B4   => array(0x4B5), 0x4B6   => array(0x4B7), 0x4B8   => array(0x4B9)
1159                      ,0x4BA   => array(0x4BB), 0x4BC   => array(0x4BD), 0x4BE   => array(0x4BF)
1160                      ,0x4C1   => array(0x4C2), 0x4C3   => array(0x4C4), 0x4C5   => array(0x4C6)
1161                      ,0x4C7   => array(0x4C8), 0x4C9   => array(0x4CA), 0x4CB   => array(0x4CC)
1162                      ,0x4CD   => array(0x4CE), 0x4D0   => array(0x4D1), 0x4D2   => array(0x4D3)
1163                      ,0x4D4   => array(0x4D5), 0x4D6   => array(0x4D7), 0x4D8   => array(0x4D9)
1164                      ,0x4DA   => array(0x4DB), 0x4DC   => array(0x4DD), 0x4DE   => array(0x4DF)
1165                      ,0x4E0   => array(0x4E1), 0x4E2   => array(0x4E3), 0x4E4   => array(0x4E5)
1166                      ,0x4E6   => array(0x4E7), 0x4E8   => array(0x4E9), 0x4EA   => array(0x4EB)
1167                      ,0x4EC   => array(0x4ED), 0x4EE   => array(0x4EF), 0x4F0   => array(0x4F1)
1168                      ,0x4F2   => array(0x4F3), 0x4F4   => array(0x4F5), 0x4F8   => array(0x4F9)
1169                      ,0x500   => array(0x501), 0x502   => array(0x503), 0x504   => array(0x505)
1170                      ,0x506   => array(0x507), 0x508   => array(0x509), 0x50A   => array(0x50B)
1171                      ,0x50C   => array(0x50D), 0x50E   => array(0x50F), 0x531   => array(0x561)
1172                      ,0x532   => array(0x562), 0x533   => array(0x563), 0x534   => array(0x564)
1173                      ,0x535   => array(0x565), 0x536   => array(0x566), 0x537   => array(0x567)
1174                      ,0x538   => array(0x568), 0x539   => array(0x569), 0x53A   => array(0x56A)
1175                      ,0x53B   => array(0x56B), 0x53C   => array(0x56C), 0x53D   => array(0x56D)
1176                      ,0x53E   => array(0x56E), 0x53F   => array(0x56F), 0x540   => array(0x570)
1177                      ,0x541   => array(0x571), 0x542   => array(0x572), 0x543   => array(0x573)
1178                      ,0x544   => array(0x574), 0x545   => array(0x575), 0x546   => array(0x576)
1179                      ,0x547   => array(0x577), 0x548   => array(0x578), 0x549   => array(0x579)
1180                      ,0x54A   => array(0x57A), 0x54B   => array(0x57B), 0x54C   => array(0x57C)
1181                      ,0x54D   => array(0x57D), 0x54E   => array(0x57E), 0x54F   => array(0x57F)
1182                      ,0x550   => array(0x580), 0x551   => array(0x581), 0x552   => array(0x582)
1183                      ,0x553   => array(0x583), 0x554   => array(0x584), 0x555   => array(0x585)
1184                      ,0x556 => array(0x586), 0x587 => array(0x565, 0x582), 0xE33 => array(0xE4D, 0xE32)
1185                      ,0x1E00  => array(0x1E01), 0x1E02  => array(0x1E03), 0x1E04  => array(0x1E05)
1186                      ,0x1E06  => array(0x1E07), 0x1E08  => array(0x1E09), 0x1E0A  => array(0x1E0B)
1187                      ,0x1E0C  => array(0x1E0D), 0x1E0E  => array(0x1E0F), 0x1E10  => array(0x1E11)
1188                      ,0x1E12  => array(0x1E13), 0x1E14  => array(0x1E15), 0x1E16  => array(0x1E17)
1189                      ,0x1E18  => array(0x1E19), 0x1E1A  => array(0x1E1B), 0x1E1C  => array(0x1E1D)
1190                      ,0x1E1E  => array(0x1E1F), 0x1E20  => array(0x1E21), 0x1E22  => array(0x1E23)
1191                      ,0x1E24  => array(0x1E25), 0x1E26  => array(0x1E27), 0x1E28  => array(0x1E29)
1192                      ,0x1E2A  => array(0x1E2B), 0x1E2C  => array(0x1E2D), 0x1E2E  => array(0x1E2F)
1193                      ,0x1E30  => array(0x1E31), 0x1E32  => array(0x1E33), 0x1E34  => array(0x1E35)
1194                      ,0x1E36  => array(0x1E37), 0x1E38  => array(0x1E39), 0x1E3A  => array(0x1E3B)
1195                      ,0x1E3C  => array(0x1E3D), 0x1E3E  => array(0x1E3F), 0x1E40  => array(0x1E41)
1196                      ,0x1E42  => array(0x1E43), 0x1E44  => array(0x1E45), 0x1E46  => array(0x1E47)
1197                      ,0x1E48  => array(0x1E49), 0x1E4A  => array(0x1E4B), 0x1E4C  => array(0x1E4D)
1198                      ,0x1E4E  => array(0x1E4F), 0x1E50  => array(0x1E51), 0x1E52  => array(0x1E53)
1199                      ,0x1E54  => array(0x1E55), 0x1E56  => array(0x1E57), 0x1E58  => array(0x1E59)
1200                      ,0x1E5A  => array(0x1E5B), 0x1E5C  => array(0x1E5D), 0x1E5E  => array(0x1E5F)
1201                      ,0x1E60  => array(0x1E61), 0x1E62  => array(0x1E63), 0x1E64  => array(0x1E65)
1202                      ,0x1E66  => array(0x1E67), 0x1E68  => array(0x1E69), 0x1E6A  => array(0x1E6B)
1203                      ,0x1E6C  => array(0x1E6D), 0x1E6E  => array(0x1E6F), 0x1E70  => array(0x1E71)
1204                      ,0x1E72  => array(0x1E73), 0x1E74  => array(0x1E75), 0x1E76  => array(0x1E77)
1205                      ,0x1E78  => array(0x1E79), 0x1E7A  => array(0x1E7B), 0x1E7C  => array(0x1E7D)
1206                      ,0x1E7E  => array(0x1E7F), 0x1E80  => array(0x1E81), 0x1E82  => array(0x1E83)
1207                      ,0x1E84  => array(0x1E85), 0x1E86  => array(0x1E87), 0x1E88  => array(0x1E89)
1208                      ,0x1E8A  => array(0x1E8B), 0x1E8C  => array(0x1E8D), 0x1E8E  => array(0x1E8F)
1209                      ,0x1E90  => array(0x1E91), 0x1E92  => array(0x1E93), 0x1E94  => array(0x1E95)
1210                      ,0x1E96  => array(0x68, 0x331), 0x1E97  => array(0x74, 0x308), 0x1E98  => array(0x77, 0x30A)
1211                      ,0x1E99  => array(0x79, 0x30A), 0x1E9A  => array(0x61, 0x2BE), 0x1E9B  => array(0x1E61)
1212                      ,0x1EA0  => array(0x1EA1), 0x1EA2  => array(0x1EA3), 0x1EA4  => array(0x1EA5)
1213                      ,0x1EA6  => array(0x1EA7), 0x1EA8  => array(0x1EA9), 0x1EAA  => array(0x1EAB)
1214                      ,0x1EAC  => array(0x1EAD), 0x1EAE  => array(0x1EAF), 0x1EB0  => array(0x1EB1)
1215                      ,0x1EB2  => array(0x1EB3), 0x1EB4  => array(0x1EB5), 0x1EB6  => array(0x1EB7)
1216                      ,0x1EB8  => array(0x1EB9), 0x1EBA  => array(0x1EBB), 0x1EBC  => array(0x1EBD)
1217                      ,0x1EBE  => array(0x1EBF), 0x1EC0  => array(0x1EC1), 0x1EC2  => array(0x1EC3)
1218                      ,0x1EC4  => array(0x1EC5), 0x1EC6  => array(0x1EC7), 0x1EC8  => array(0x1EC9)
1219                      ,0x1ECA  => array(0x1ECB), 0x1ECC  => array(0x1ECD), 0x1ECE  => array(0x1ECF)
1220                      ,0x1ED0  => array(0x1ED1), 0x1ED2  => array(0x1ED3), 0x1ED4  => array(0x1ED5)
1221                      ,0x1ED6  => array(0x1ED7), 0x1ED8  => array(0x1ED9), 0x1EDA  => array(0x1EDB)
1222                      ,0x1EDC  => array(0x1EDD), 0x1EDE  => array(0x1EDF), 0x1EE0  => array(0x1EE1)
1223                      ,0x1EE2  => array(0x1EE3), 0x1EE4  => array(0x1EE5), 0x1EE6  => array(0x1EE7)
1224                      ,0x1EE8  => array(0x1EE9), 0x1EEA  => array(0x1EEB), 0x1EEC  => array(0x1EED)
1225                      ,0x1EEE  => array(0x1EEF), 0x1EF0  => array(0x1EF1), 0x1EF2  => array(0x1EF3)
1226                      ,0x1EF4  => array(0x1EF5), 0x1EF6  => array(0x1EF7), 0x1EF8  => array(0x1EF9)
1227                      ,0x1F08  => array(0x1F00), 0x1F09  => array(0x1F01), 0x1F0A  => array(0x1F02)
1228                      ,0x1F0B  => array(0x1F03), 0x1F0C  => array(0x1F04), 0x1F0D  => array(0x1F05)
1229                      ,0x1F0E  => array(0x1F06), 0x1F0F  => array(0x1F07), 0x1F18  => array(0x1F10)
1230                      ,0x1F19  => array(0x1F11), 0x1F1A  => array(0x1F12), 0x1F1B  => array(0x1F13)
1231                      ,0x1F1C  => array(0x1F14), 0x1F1D  => array(0x1F15), 0x1F28  => array(0x1F20)
1232                      ,0x1F29  => array(0x1F21), 0x1F2A  => array(0x1F22), 0x1F2B  => array(0x1F23)
1233                      ,0x1F2C  => array(0x1F24), 0x1F2D  => array(0x1F25), 0x1F2E  => array(0x1F26)
1234                      ,0x1F2F  => array(0x1F27), 0x1F38  => array(0x1F30), 0x1F39  => array(0x1F31)
1235                      ,0x1F3A  => array(0x1F32), 0x1F3B  => array(0x1F33), 0x1F3C  => array(0x1F34)
1236                      ,0x1F3D  => array(0x1F35), 0x1F3E  => array(0x1F36), 0x1F3F  => array(0x1F37)
1237                      ,0x1F48  => array(0x1F40), 0x1F49  => array(0x1F41), 0x1F4A  => array(0x1F42)
1238                      ,0x1F4B  => array(0x1F43), 0x1F4C  => array(0x1F44), 0x1F4D  => array(0x1F45)
1239                      ,0x1F50  => array(0x3C5, 0x313), 0x1F52  => array(0x3C5, 0x313, 0x300)
1240                      ,0x1F54  => array(0x3C5, 0x313, 0x301), 0x1F56  => array(0x3C5, 0x313, 0x342)
1241                      ,0x1F59  => array(0x1F51), 0x1F5B  => array(0x1F53), 0x1F5D  => array(0x1F55)
1242                      ,0x1F5F  => array(0x1F57), 0x1F68  => array(0x1F60), 0x1F69  => array(0x1F61)
1243                      ,0x1F6A  => array(0x1F62), 0x1F6B  => array(0x1F63), 0x1F6C  => array(0x1F64)
1244                      ,0x1F6D  => array(0x1F65), 0x1F6E  => array(0x1F66), 0x1F6F  => array(0x1F67)
1245                      ,0x1F80  => array(0x1F00, 0x3B9), 0x1F81  => array(0x1F01, 0x3B9)
1246                      ,0x1F82  => array(0x1F02, 0x3B9), 0x1F83  => array(0x1F03, 0x3B9)
1247                      ,0x1F84  => array(0x1F04, 0x3B9), 0x1F85  => array(0x1F05, 0x3B9)
1248                      ,0x1F86  => array(0x1F06, 0x3B9), 0x1F87  => array(0x1F07, 0x3B9)
1249                      ,0x1F88  => array(0x1F00, 0x3B9), 0x1F89  => array(0x1F01, 0x3B9)
1250                      ,0x1F8A  => array(0x1F02, 0x3B9), 0x1F8B  => array(0x1F03, 0x3B9)
1251                      ,0x1F8C  => array(0x1F04, 0x3B9), 0x1F8D  => array(0x1F05, 0x3B9)
1252                      ,0x1F8E  => array(0x1F06, 0x3B9), 0x1F8F  => array(0x1F07, 0x3B9)
1253                      ,0x1F90  => array(0x1F20, 0x3B9), 0x1F91  => array(0x1F21, 0x3B9)
1254                      ,0x1F92  => array(0x1F22, 0x3B9), 0x1F93  => array(0x1F23, 0x3B9)
1255                      ,0x1F94  => array(0x1F24, 0x3B9), 0x1F95  => array(0x1F25, 0x3B9)
1256                      ,0x1F96  => array(0x1F26, 0x3B9), 0x1F97  => array(0x1F27, 0x3B9)
1257                      ,0x1F98  => array(0x1F20, 0x3B9), 0x1F99  => array(0x1F21, 0x3B9)
1258                      ,0x1F9A  => array(0x1F22, 0x3B9), 0x1F9B  => array(0x1F23, 0x3B9)
1259                      ,0x1F9C  => array(0x1F24, 0x3B9), 0x1F9D  => array(0x1F25, 0x3B9)
1260                      ,0x1F9E  => array(0x1F26, 0x3B9), 0x1F9F  => array(0x1F27, 0x3B9)
1261                      ,0x1FA0  => array(0x1F60, 0x3B9), 0x1FA1  => array(0x1F61, 0x3B9)
1262                      ,0x1FA2  => array(0x1F62, 0x3B9), 0x1FA3  => array(0x1F63, 0x3B9)
1263                      ,0x1FA4  => array(0x1F64, 0x3B9), 0x1FA5  => array(0x1F65, 0x3B9)
1264                      ,0x1FA6  => array(0x1F66, 0x3B9), 0x1FA7  => array(0x1F67, 0x3B9)
1265                      ,0x1FA8  => array(0x1F60, 0x3B9), 0x1FA9  => array(0x1F61, 0x3B9)
1266                      ,0x1FAA  => array(0x1F62, 0x3B9), 0x1FAB  => array(0x1F63, 0x3B9)
1267                      ,0x1FAC  => array(0x1F64, 0x3B9), 0x1FAD  => array(0x1F65, 0x3B9)
1268                      ,0x1FAE  => array(0x1F66, 0x3B9), 0x1FAF  => array(0x1F67, 0x3B9)
1269                      ,0x1FB2  => array(0x1F70, 0x3B9), 0x1FB3  => array(0x3B1, 0x3B9)
1270                      ,0x1FB4  => array(0x3AC, 0x3B9), 0x1FB6  => array(0x3B1, 0x342)
1271                      ,0x1FB7  => array(0x3B1, 0x342, 0x3B9), 0x1FB8  => array(0x1FB0)
1272                      ,0x1FB9  => array(0x1FB1), 0x1FBA  => array(0x1F70), 0x1FBB  => array(0x1F71)
1273                      ,0x1FBC  => array(0x3B1, 0x3B9), 0x1FBE  => array(0x3B9)
1274                      ,0x1FC2  => array(0x1F74, 0x3B9), 0x1FC3  => array(0x3B7, 0x3B9)
1275                      ,0x1FC4  => array(0x3AE, 0x3B9), 0x1FC6  => array(0x3B7, 0x342)
1276                      ,0x1FC7  => array(0x3B7, 0x342, 0x3B9), 0x1FC8  => array(0x1F72)
1277                      ,0x1FC9  => array(0x1F73), 0x1FCA  => array(0x1F74), 0x1FCB  => array(0x1F75)
1278                      ,0x1FCC  => array(0x3B7, 0x3B9), 0x1FD2  => array(0x3B9, 0x308, 0x300)
1279                      ,0x1FD3  => array(0x3B9, 0x308, 0x301), 0x1FD6  => array(0x3B9, 0x342)
1280                      ,0x1FD7  => array(0x3B9, 0x308, 0x342), 0x1FD8  => array(0x1FD0)
1281                      ,0x1FD9  => array(0x1FD1), 0x1FDA  => array(0x1F76)
1282                      ,0x1FDB  => array(0x1F77), 0x1FE2  => array(0x3C5, 0x308, 0x300)
1283                      ,0x1FE3  => array(0x3C5, 0x308, 0x301), 0x1FE4  => array(0x3C1, 0x313)
1284                      ,0x1FE6  => array(0x3C5, 0x342), 0x1FE7  => array(0x3C5, 0x308, 0x342)
1285                      ,0x1FE8  => array(0x1FE0), 0x1FE9  => array(0x1FE1)
1286                      ,0x1FEA  => array(0x1F7A), 0x1FEB  => array(0x1F7B)
1287                      ,0x1FEC  => array(0x1FE5), 0x1FF2  => array(0x1F7C, 0x3B9)
1288                      ,0x1FF3  => array(0x3C9, 0x3B9), 0x1FF4  => array(0x3CE, 0x3B9)
1289                      ,0x1FF6  => array(0x3C9, 0x342), 0x1FF7  => array(0x3C9, 0x342, 0x3B9)
1290                      ,0x1FF8  => array(0x1F78), 0x1FF9  => array(0x1F79), 0x1FFA  => array(0x1F7C)
1291                      ,0x1FFB  => array(0x1F7D), 0x1FFC  => array(0x3C9, 0x3B9)
1292                      ,0x20A8  => array(0x72, 0x73), 0x2102  => array(0x63), 0x2103  => array(0xB0, 0x63)
1293                      ,0x2107  => array(0x25B), 0x2109  => array(0xB0, 0x66), 0x210B  => array(0x68)
1294                      ,0x210C  => array(0x68), 0x210D  => array(0x68), 0x2110  => array(0x69)
1295                      ,0x2111  => array(0x69), 0x2112  => array(0x6C), 0x2115  => array(0x6E)
1296                      ,0x2116  => array(0x6E, 0x6F), 0x2119  => array(0x70), 0x211A  => array(0x71)
1297                      ,0x211B  => array(0x72), 0x211C  => array(0x72), 0x211D  => array(0x72)
1298                      ,0x2120  => array(0x73, 0x6D), 0x2121  => array(0x74, 0x65, 0x6C)
1299                      ,0x2122  => array(0x74, 0x6D), 0x2124  => array(0x7A), 0x2126  => array(0x3C9)
1300                      ,0x2128  => array(0x7A), 0x212A  => array(0x6B), 0x212B  => array(0xE5)
1301                      ,0x212C  => array(0x62), 0x212D  => array(0x63), 0x2130  => array(0x65)
1302                      ,0x2131  => array(0x66), 0x2133  => array(0x6D), 0x213E  => array(0x3B3)
1303                      ,0x213F  => array(0x3C0), 0x2145  => array(0x64) ,0x2160  => array(0x2170)
1304                      ,0x2161  => array(0x2171), 0x2162  => array(0x2172), 0x2163  => array(0x2173)
1305                      ,0x2164  => array(0x2174), 0x2165  => array(0x2175), 0x2166  => array(0x2176)
1306                      ,0x2167  => array(0x2177), 0x2168  => array(0x2178), 0x2169  => array(0x2179)
1307                      ,0x216A  => array(0x217A), 0x216B  => array(0x217B), 0x216C  => array(0x217C)
1308                      ,0x216D  => array(0x217D), 0x216E  => array(0x217E), 0x216F  => array(0x217F)
1309                      ,0x24B6  => array(0x24D0), 0x24B7  => array(0x24D1), 0x24B8  => array(0x24D2)
1310                      ,0x24B9  => array(0x24D3), 0x24BA  => array(0x24D4), 0x24BB  => array(0x24D5)
1311                      ,0x24BC  => array(0x24D6), 0x24BD  => array(0x24D7), 0x24BE  => array(0x24D8)
1312                      ,0x24BF  => array(0x24D9), 0x24C0  => array(0x24DA), 0x24C1  => array(0x24DB)
1313                      ,0x24C2  => array(0x24DC), 0x24C3  => array(0x24DD), 0x24C4  => array(0x24DE)
1314                      ,0x24C5  => array(0x24DF), 0x24C6  => array(0x24E0), 0x24C7  => array(0x24E1)
1315                      ,0x24C8  => array(0x24E2), 0x24C9  => array(0x24E3), 0x24CA  => array(0x24E4)
1316                      ,0x24CB  => array(0x24E5), 0x24CC  => array(0x24E6), 0x24CD  => array(0x24E7)
1317                      ,0x24CE  => array(0x24E8), 0x24CF  => array(0x24E9), 0x3371  => array(0x68, 0x70, 0x61)
1318                      ,0x3373  => array(0x61, 0x75), 0x3375  => array(0x6F, 0x76)
1319                      ,0x3380  => array(0x70, 0x61), 0x3381  => array(0x6E, 0x61)
1320                      ,0x3382  => array(0x3BC, 0x61), 0x3383  => array(0x6D, 0x61)
1321                      ,0x3384  => array(0x6B, 0x61), 0x3385  => array(0x6B, 0x62)
1322                      ,0x3386  => array(0x6D, 0x62), 0x3387  => array(0x67, 0x62)
1323                      ,0x338A  => array(0x70, 0x66), 0x338B  => array(0x6E, 0x66)
1324                      ,0x338C  => array(0x3BC, 0x66), 0x3390  => array(0x68, 0x7A)
1325                      ,0x3391  => array(0x6B, 0x68, 0x7A), 0x3392  => array(0x6D, 0x68, 0x7A)
1326                      ,0x3393  => array(0x67, 0x68, 0x7A), 0x3394  => array(0x74, 0x68, 0x7A)
1327                      ,0x33A9  => array(0x70, 0x61), 0x33AA  => array(0x6B, 0x70, 0x61)
1328                      ,0x33AB  => array(0x6D, 0x70, 0x61), 0x33AC  => array(0x67, 0x70, 0x61)
1329                      ,0x33B4  => array(0x70, 0x76), 0x33B5  => array(0x6E, 0x76)
1330                      ,0x33B6  => array(0x3BC, 0x76), 0x33B7  => array(0x6D, 0x76)
1331                      ,0x33B8  => array(0x6B, 0x76), 0x33B9  => array(0x6D, 0x76)
1332                      ,0x33BA  => array(0x70, 0x77), 0x33BB  => array(0x6E, 0x77)
1333                      ,0x33BC  => array(0x3BC, 0x77), 0x33BD  => array(0x6D, 0x77)
1334                      ,0x33BE  => array(0x6B, 0x77), 0x33BF  => array(0x6D, 0x77)
1335                      ,0x33C0  => array(0x6B, 0x3C9), 0x33C1  => array(0x6D, 0x3C9) /*
1336                      ,0x33C2  => array(0x61, 0x2E, 0x6D, 0x2E) */
1337                      ,0x33C3  => array(0x62, 0x71), 0x33C6  => array(0x63, 0x2215, 0x6B, 0x67)
1338                      ,0x33C7  => array(0x63, 0x6F, 0x2E), 0x33C8  => array(0x64, 0x62)
1339                      ,0x33C9  => array(0x67, 0x79), 0x33CB  => array(0x68, 0x70)
1340                      ,0x33CD  => array(0x6B, 0x6B), 0x33CE  => array(0x6B, 0x6D)
1341                      ,0x33D7  => array(0x70, 0x68), 0x33D9  => array(0x70, 0x70, 0x6D)
1342                      ,0x33DA  => array(0x70, 0x72), 0x33DC  => array(0x73, 0x76)
1343                      ,0x33DD  => array(0x77, 0x62), 0xFB00  => array(0x66, 0x66)
1344                      ,0xFB01  => array(0x66, 0x69), 0xFB02  => array(0x66, 0x6C)
1345                      ,0xFB03  => array(0x66, 0x66, 0x69), 0xFB04  => array(0x66, 0x66, 0x6C)
1346                      ,0xFB05  => array(0x73, 0x74), 0xFB06  => array(0x73, 0x74)
1347                      ,0xFB13  => array(0x574, 0x576), 0xFB14  => array(0x574, 0x565)
1348                      ,0xFB15  => array(0x574, 0x56B), 0xFB16  => array(0x57E, 0x576)
1349                      ,0xFB17  => array(0x574, 0x56D), 0xFF21  => array(0xFF41)
1350                      ,0xFF22  => array(0xFF42), 0xFF23  => array(0xFF43), 0xFF24  => array(0xFF44)
1351                      ,0xFF25  => array(0xFF45), 0xFF26  => array(0xFF46), 0xFF27  => array(0xFF47)
1352                      ,0xFF28  => array(0xFF48), 0xFF29  => array(0xFF49), 0xFF2A  => array(0xFF4A)
1353                      ,0xFF2B  => array(0xFF4B), 0xFF2C  => array(0xFF4C), 0xFF2D  => array(0xFF4D)
1354                      ,0xFF2E  => array(0xFF4E), 0xFF2F  => array(0xFF4F), 0xFF30  => array(0xFF50)
1355                      ,0xFF31  => array(0xFF51), 0xFF32  => array(0xFF52), 0xFF33  => array(0xFF53)
1356                      ,0xFF34  => array(0xFF54), 0xFF35  => array(0xFF55), 0xFF36  => array(0xFF56)
1357                      ,0xFF37  => array(0xFF57), 0xFF38  => array(0xFF58), 0xFF39  => array(0xFF59)
1358                      ,0xFF3A  => array(0xFF5A), 0x10400 => array(0x10428), 0x10401 => array(0x10429)
1359                      ,0x10402 => array(0x1042A), 0x10403 => array(0x1042B), 0x10404 => array(0x1042C)
1360                      ,0x10405 => array(0x1042D), 0x10406 => array(0x1042E), 0x10407 => array(0x1042F)
1361                      ,0x10408 => array(0x10430), 0x10409 => array(0x10431), 0x1040A => array(0x10432)
1362                      ,0x1040B => array(0x10433), 0x1040C => array(0x10434), 0x1040D => array(0x10435)
1363                      ,0x1040E => array(0x10436), 0x1040F => array(0x10437), 0x10410 => array(0x10438)
1364                      ,0x10411 => array(0x10439), 0x10412 => array(0x1043A), 0x10413 => array(0x1043B)
1365                      ,0x10414 => array(0x1043C), 0x10415 => array(0x1043D), 0x10416 => array(0x1043E)
1366                      ,0x10417 => array(0x1043F), 0x10418 => array(0x10440), 0x10419 => array(0x10441)
1367                      ,0x1041A => array(0x10442), 0x1041B => array(0x10443), 0x1041C => array(0x10444)
1368                      ,0x1041D => array(0x10445), 0x1041E => array(0x10446), 0x1041F => array(0x10447)
1369                      ,0x10420 => array(0x10448), 0x10421 => array(0x10449), 0x10422 => array(0x1044A)
1370                      ,0x10423 => array(0x1044B), 0x10424 => array(0x1044C), 0x10425 => array(0x1044D)
1371                      ,0x1D400 => array(0x61), 0x1D401 => array(0x62), 0x1D402 => array(0x63)
1372                      ,0x1D403 => array(0x64), 0x1D404 => array(0x65), 0x1D405 => array(0x66)
1373                      ,0x1D406 => array(0x67), 0x1D407 => array(0x68), 0x1D408 => array(0x69)
1374                      ,0x1D409 => array(0x6A), 0x1D40A => array(0x6B), 0x1D40B => array(0x6C)
1375                      ,0x1D40C => array(0x6D), 0x1D40D => array(0x6E), 0x1D40E => array(0x6F)
1376                      ,0x1D40F => array(0x70), 0x1D410 => array(0x71), 0x1D411 => array(0x72)
1377                      ,0x1D412 => array(0x73), 0x1D413 => array(0x74), 0x1D414 => array(0x75)
1378                      ,0x1D415 => array(0x76), 0x1D416 => array(0x77), 0x1D417 => array(0x78)
1379                      ,0x1D418 => array(0x79), 0x1D419 => array(0x7A), 0x1D434 => array(0x61)
1380                      ,0x1D435 => array(0x62), 0x1D436 => array(0x63), 0x1D437 => array(0x64)
1381                      ,0x1D438 => array(0x65), 0x1D439 => array(0x66), 0x1D43A => array(0x67)
1382                      ,0x1D43B => array(0x68), 0x1D43C => array(0x69), 0x1D43D => array(0x6A)
1383                      ,0x1D43E => array(0x6B), 0x1D43F => array(0x6C), 0x1D440 => array(0x6D)
1384                      ,0x1D441 => array(0x6E), 0x1D442 => array(0x6F), 0x1D443 => array(0x70)
1385                      ,0x1D444 => array(0x71), 0x1D445 => array(0x72), 0x1D446 => array(0x73)
1386                      ,0x1D447 => array(0x74), 0x1D448 => array(0x75), 0x1D449 => array(0x76)
1387                      ,0x1D44A => array(0x77), 0x1D44B => array(0x78), 0x1D44C => array(0x79)
1388                      ,0x1D44D => array(0x7A), 0x1D468 => array(0x61), 0x1D469 => array(0x62)
1389                      ,0x1D46A => array(0x63), 0x1D46B => array(0x64), 0x1D46C => array(0x65)
1390                      ,0x1D46D => array(0x66), 0x1D46E => array(0x67), 0x1D46F => array(0x68)
1391                      ,0x1D470 => array(0x69), 0x1D471 => array(0x6A), 0x1D472 => array(0x6B)
1392                      ,0x1D473 => array(0x6C), 0x1D474 => array(0x6D), 0x1D475 => array(0x6E)
1393                      ,0x1D476 => array(0x6F), 0x1D477 => array(0x70), 0x1D478 => array(0x71)
1394                      ,0x1D479 => array(0x72), 0x1D47A => array(0x73), 0x1D47B => array(0x74)
1395                      ,0x1D47C => array(0x75), 0x1D47D => array(0x76), 0x1D47E => array(0x77)
1396                      ,0x1D47F => array(0x78), 0x1D480 => array(0x79), 0x1D481 => array(0x7A)
1397                      ,0x1D49C => array(0x61), 0x1D49E => array(0x63), 0x1D49F => array(0x64)
1398                      ,0x1D4A2 => array(0x67), 0x1D4A5 => array(0x6A), 0x1D4A6 => array(0x6B)
1399                      ,0x1D4A9 => array(0x6E), 0x1D4AA => array(0x6F), 0x1D4AB => array(0x70)
1400                      ,0x1D4AC => array(0x71), 0x1D4AE => array(0x73), 0x1D4AF => array(0x74)
1401                      ,0x1D4B0 => array(0x75), 0x1D4B1 => array(0x76), 0x1D4B2 => array(0x77)
1402                      ,0x1D4B3 => array(0x78), 0x1D4B4 => array(0x79), 0x1D4B5 => array(0x7A)
1403                      ,0x1D4D0 => array(0x61), 0x1D4D1 => array(0x62), 0x1D4D2 => array(0x63)
1404                      ,0x1D4D3 => array(0x64), 0x1D4D4 => array(0x65), 0x1D4D5 => array(0x66)
1405                      ,0x1D4D6 => array(0x67), 0x1D4D7 => array(0x68), 0x1D4D8 => array(0x69)
1406                      ,0x1D4D9 => array(0x6A), 0x1D4DA => array(0x6B), 0x1D4DB => array(0x6C)
1407                      ,0x1D4DC => array(0x6D), 0x1D4DD => array(0x6E), 0x1D4DE => array(0x6F)
1408                      ,0x1D4DF => array(0x70), 0x1D4E0 => array(0x71), 0x1D4E1 => array(0x72)
1409                      ,0x1D4E2 => array(0x73), 0x1D4E3 => array(0x74), 0x1D4E4 => array(0x75)
1410                      ,0x1D4E5 => array(0x76), 0x1D4E6 => array(0x77), 0x1D4E7 => array(0x78)
1411                      ,0x1D4E8 => array(0x79), 0x1D4E9 => array(0x7A), 0x1D504 => array(0x61)
1412                      ,0x1D505 => array(0x62), 0x1D507 => array(0x64), 0x1D508 => array(0x65)
1413                      ,0x1D509 => array(0x66), 0x1D50A => array(0x67), 0x1D50D => array(0x6A)
1414                      ,0x1D50E => array(0x6B), 0x1D50F => array(0x6C), 0x1D510 => array(0x6D)
1415                      ,0x1D511 => array(0x6E), 0x1D512 => array(0x6F), 0x1D513 => array(0x70)
1416                      ,0x1D514 => array(0x71), 0x1D516 => array(0x73), 0x1D517 => array(0x74)
1417                      ,0x1D518 => array(0x75), 0x1D519 => array(0x76), 0x1D51A => array(0x77)
1418                      ,0x1D51B => array(0x78), 0x1D51C => array(0x79), 0x1D538 => array(0x61)
1419                      ,0x1D539 => array(0x62), 0x1D53B => array(0x64), 0x1D53C => array(0x65)
1420                      ,0x1D53D => array(0x66), 0x1D53E => array(0x67), 0x1D540 => array(0x69)
1421                      ,0x1D541 => array(0x6A), 0x1D542 => array(0x6B), 0x1D543 => array(0x6C)
1422                      ,0x1D544 => array(0x6D), 0x1D546 => array(0x6F), 0x1D54A => array(0x73)
1423                      ,0x1D54B => array(0x74), 0x1D54C => array(0x75), 0x1D54D => array(0x76)
1424                      ,0x1D54E => array(0x77), 0x1D54F => array(0x78), 0x1D550 => array(0x79)
1425                      ,0x1D56C => array(0x61), 0x1D56D => array(0x62), 0x1D56E => array(0x63)
1426                      ,0x1D56F => array(0x64), 0x1D570 => array(0x65), 0x1D571 => array(0x66)
1427                      ,0x1D572 => array(0x67), 0x1D573 => array(0x68), 0x1D574 => array(0x69)
1428                      ,0x1D575 => array(0x6A), 0x1D576 => array(0x6B), 0x1D577 => array(0x6C)
1429                      ,0x1D578 => array(0x6D), 0x1D579 => array(0x6E), 0x1D57A => array(0x6F)
1430                      ,0x1D57B => array(0x70), 0x1D57C => array(0x71), 0x1D57D => array(0x72)
1431                      ,0x1D57E => array(0x73), 0x1D57F => array(0x74), 0x1D580 => array(0x75)
1432                      ,0x1D581 => array(0x76), 0x1D582 => array(0x77), 0x1D583 => array(0x78)
1433                      ,0x1D584 => array(0x79), 0x1D585 => array(0x7A), 0x1D5A0 => array(0x61)
1434                      ,0x1D5A1 => array(0x62), 0x1D5A2 => array(0x63), 0x1D5A3 => array(0x64)
1435                      ,0x1D5A4 => array(0x65), 0x1D5A5 => array(0x66), 0x1D5A6 => array(0x67)
1436                      ,0x1D5A7 => array(0x68), 0x1D5A8 => array(0x69), 0x1D5A9 => array(0x6A)
1437                      ,0x1D5AA => array(0x6B), 0x1D5AB => array(0x6C), 0x1D5AC => array(0x6D)
1438                      ,0x1D5AD => array(0x6E), 0x1D5AE => array(0x6F), 0x1D5AF => array(0x70)
1439                      ,0x1D5B0 => array(0x71), 0x1D5B1 => array(0x72), 0x1D5B2 => array(0x73)
1440                      ,0x1D5B3 => array(0x74), 0x1D5B4 => array(0x75), 0x1D5B5 => array(0x76)
1441                      ,0x1D5B6 => array(0x77), 0x1D5B7 => array(0x78), 0x1D5B8 => array(0x79)
1442                      ,0x1D5B9 => array(0x7A), 0x1D5D4 => array(0x61), 0x1D5D5 => array(0x62)
1443                      ,0x1D5D6 => array(0x63), 0x1D5D7 => array(0x64), 0x1D5D8 => array(0x65)
1444                      ,0x1D5D9 => array(0x66), 0x1D5DA => array(0x67), 0x1D5DB => array(0x68)
1445                      ,0x1D5DC => array(0x69), 0x1D5DD => array(0x6A), 0x1D5DE => array(0x6B)
1446                      ,0x1D5DF => array(0x6C), 0x1D5E0 => array(0x6D), 0x1D5E1 => array(0x6E)
1447                      ,0x1D5E2 => array(0x6F), 0x1D5E3 => array(0x70), 0x1D5E4 => array(0x71)
1448                      ,0x1D5E5 => array(0x72), 0x1D5E6 => array(0x73), 0x1D5E7 => array(0x74)
1449                      ,0x1D5E8 => array(0x75), 0x1D5E9 => array(0x76), 0x1D5EA => array(0x77)
1450                      ,0x1D5EB => array(0x78), 0x1D5EC => array(0x79), 0x1D5ED => array(0x7A)
1451                      ,0x1D608 => array(0x61), 0x1D609 => array(0x62) ,0x1D60A => array(0x63)
1452                      ,0x1D60B => array(0x64), 0x1D60C => array(0x65), 0x1D60D => array(0x66)
1453                      ,0x1D60E => array(0x67), 0x1D60F => array(0x68), 0x1D610 => array(0x69)
1454                      ,0x1D611 => array(0x6A), 0x1D612 => array(0x6B), 0x1D613 => array(0x6C)
1455                      ,0x1D614 => array(0x6D), 0x1D615 => array(0x6E), 0x1D616 => array(0x6F)
1456                      ,0x1D617 => array(0x70), 0x1D618 => array(0x71), 0x1D619 => array(0x72)
1457                      ,0x1D61A => array(0x73), 0x1D61B => array(0x74), 0x1D61C => array(0x75)
1458                      ,0x1D61D => array(0x76), 0x1D61E => array(0x77), 0x1D61F => array(0x78)
1459                      ,0x1D620 => array(0x79), 0x1D621 => array(0x7A), 0x1D63C => array(0x61)
1460                      ,0x1D63D => array(0x62), 0x1D63E => array(0x63), 0x1D63F => array(0x64)
1461                      ,0x1D640 => array(0x65), 0x1D641 => array(0x66), 0x1D642 => array(0x67)
1462                      ,0x1D643 => array(0x68), 0x1D644 => array(0x69), 0x1D645 => array(0x6A)
1463                      ,0x1D646 => array(0x6B), 0x1D647 => array(0x6C), 0x1D648 => array(0x6D)
1464                      ,0x1D649 => array(0x6E), 0x1D64A => array(0x6F), 0x1D64B => array(0x70)
1465                      ,0x1D64C => array(0x71), 0x1D64D => array(0x72), 0x1D64E => array(0x73)
1466                      ,0x1D64F => array(0x74), 0x1D650 => array(0x75), 0x1D651 => array(0x76)
1467                      ,0x1D652 => array(0x77), 0x1D653 => array(0x78), 0x1D654 => array(0x79)
1468                      ,0x1D655 => array(0x7A), 0x1D670 => array(0x61), 0x1D671 => array(0x62)
1469                      ,0x1D672 => array(0x63), 0x1D673 => array(0x64), 0x1D674 => array(0x65)
1470                      ,0x1D675 => array(0x66), 0x1D676 => array(0x67), 0x1D677 => array(0x68)
1471                      ,0x1D678 => array(0x69), 0x1D679 => array(0x6A), 0x1D67A => array(0x6B)
1472                      ,0x1D67B => array(0x6C), 0x1D67C => array(0x6D), 0x1D67D => array(0x6E)
1473                      ,0x1D67E => array(0x6F), 0x1D67F => array(0x70), 0x1D680 => array(0x71)
1474                      ,0x1D681 => array(0x72), 0x1D682 => array(0x73), 0x1D683 => array(0x74)
1475                      ,0x1D684 => array(0x75), 0x1D685 => array(0x76), 0x1D686 => array(0x77)
1476                      ,0x1D687 => array(0x78), 0x1D688 => array(0x79), 0x1D689 => array(0x7A)
1477                      ,0x1D6A8 => array(0x3B1), 0x1D6A9 => array(0x3B2), 0x1D6AA => array(0x3B3)
1478                      ,0x1D6AB => array(0x3B4), 0x1D6AC => array(0x3B5), 0x1D6AD => array(0x3B6)
1479                      ,0x1D6AE => array(0x3B7), 0x1D6AF => array(0x3B8), 0x1D6B0 => array(0x3B9)
1480                      ,0x1D6B1 => array(0x3BA), 0x1D6B2 => array(0x3BB), 0x1D6B3 => array(0x3BC)
1481                      ,0x1D6B4 => array(0x3BD), 0x1D6B5 => array(0x3BE), 0x1D6B6 => array(0x3BF)
1482                      ,0x1D6B7 => array(0x3C0), 0x1D6B8 => array(0x3C1), 0x1D6B9 => array(0x3B8)
1483                      ,0x1D6BA => array(0x3C3), 0x1D6BB => array(0x3C4), 0x1D6BC => array(0x3C5)
1484                      ,0x1D6BD => array(0x3C6), 0x1D6BE => array(0x3C7), 0x1D6BF => array(0x3C8)
1485                      ,0x1D6C0 => array(0x3C9), 0x1D6D3 => array(0x3C3), 0x1D6E2 => array(0x3B1)
1486                      ,0x1D6E3 => array(0x3B2), 0x1D6E4 => array(0x3B3), 0x1D6E5 => array(0x3B4)
1487                      ,0x1D6E6 => array(0x3B5), 0x1D6E7 => array(0x3B6), 0x1D6E8 => array(0x3B7)
1488                      ,0x1D6E9 => array(0x3B8), 0x1D6EA => array(0x3B9), 0x1D6EB => array(0x3BA)
1489                      ,0x1D6EC => array(0x3BB), 0x1D6ED => array(0x3BC), 0x1D6EE => array(0x3BD)
1490                      ,0x1D6EF => array(0x3BE), 0x1D6F0 => array(0x3BF), 0x1D6F1 => array(0x3C0)
1491                      ,0x1D6F2 => array(0x3C1), 0x1D6F3 => array(0x3B8) ,0x1D6F4 => array(0x3C3)
1492                      ,0x1D6F5 => array(0x3C4), 0x1D6F6 => array(0x3C5), 0x1D6F7 => array(0x3C6)
1493                      ,0x1D6F8 => array(0x3C7), 0x1D6F9 => array(0x3C8) ,0x1D6FA => array(0x3C9)
1494                      ,0x1D70D => array(0x3C3), 0x1D71C => array(0x3B1), 0x1D71D => array(0x3B2)
1495                      ,0x1D71E => array(0x3B3), 0x1D71F => array(0x3B4), 0x1D720 => array(0x3B5)
1496                      ,0x1D721 => array(0x3B6), 0x1D722 => array(0x3B7), 0x1D723 => array(0x3B8)
1497                      ,0x1D724 => array(0x3B9), 0x1D725 => array(0x3BA), 0x1D726 => array(0x3BB)
1498                      ,0x1D727 => array(0x3BC), 0x1D728 => array(0x3BD), 0x1D729 => array(0x3BE)
1499                      ,0x1D72A => array(0x3BF), 0x1D72B => array(0x3C0), 0x1D72C => array(0x3C1)
1500                      ,0x1D72D => array(0x3B8), 0x1D72E => array(0x3C3), 0x1D72F => array(0x3C4)
1501                      ,0x1D730 => array(0x3C5), 0x1D731 => array(0x3C6), 0x1D732 => array(0x3C7)
1502                      ,0x1D733 => array(0x3C8), 0x1D734 => array(0x3C9), 0x1D747 => array(0x3C3)
1503                      ,0x1D756 => array(0x3B1), 0x1D757 => array(0x3B2), 0x1D758 => array(0x3B3)
1504                      ,0x1D759 => array(0x3B4), 0x1D75A => array(0x3B5), 0x1D75B => array(0x3B6)
1505                      ,0x1D75C => array(0x3B7), 0x1D75D => array(0x3B8), 0x1D75E => array(0x3B9)
1506                      ,0x1D75F => array(0x3BA), 0x1D760 => array(0x3BB), 0x1D761 => array(0x3BC)
1507                      ,0x1D762 => array(0x3BD), 0x1D763 => array(0x3BE), 0x1D764 => array(0x3BF)
1508                      ,0x1D765 => array(0x3C0), 0x1D766 => array(0x3C1), 0x1D767 => array(0x3B8)
1509                      ,0x1D768 => array(0x3C3), 0x1D769 => array(0x3C4), 0x1D76A => array(0x3C5)
1510                      ,0x1D76B => array(0x3C6), 0x1D76C => array(0x3C7), 0x1D76D => array(0x3C8)
1511                      ,0x1D76E => array(0x3C9), 0x1D781 => array(0x3C3), 0x1D790 => array(0x3B1)
1512                      ,0x1D791 => array(0x3B2), 0x1D792 => array(0x3B3), 0x1D793 => array(0x3B4)
1513                      ,0x1D794 => array(0x3B5), 0x1D795 => array(0x3B6), 0x1D796 => array(0x3B7)
1514                      ,0x1D797 => array(0x3B8), 0x1D798 => array(0x3B9), 0x1D799 => array(0x3BA)
1515                      ,0x1D79A => array(0x3BB), 0x1D79B => array(0x3BC), 0x1D79C => array(0x3BD)
1516                      ,0x1D79D => array(0x3BE), 0x1D79E => array(0x3BF), 0x1D79F => array(0x3C0)
1517                      ,0x1D7A0 => array(0x3C1), 0x1D7A1 => array(0x3B8), 0x1D7A2 => array(0x3C3)
1518                      ,0x1D7A3 => array(0x3C4), 0x1D7A4 => array(0x3C5), 0x1D7A5 => array(0x3C6)
1519                      ,0x1D7A6 => array(0x3C7), 0x1D7A7 => array(0x3C8), 0x1D7A8 => array(0x3C9)
1520                      ,0x1D7BB => array(0x3C3), 0x3F9   => array(0x3C3), 0x1D2C  => array(0x61)
1521                      ,0x1D2D  => array(0xE6), 0x1D2E  => array(0x62), 0x1D30  => array(0x64)
1522                      ,0x1D31  => array(0x65), 0x1D32  => array(0x1DD), 0x1D33  => array(0x67)
1523                      ,0x1D34  => array(0x68), 0x1D35  => array(0x69), 0x1D36  => array(0x6A)
1524                      ,0x1D37  => array(0x6B), 0x1D38  => array(0x6C), 0x1D39  => array(0x6D)
1525                      ,0x1D3A  => array(0x6E), 0x1D3C  => array(0x6F), 0x1D3D  => array(0x223)
1526                      ,0x1D3E  => array(0x70), 0x1D3F  => array(0x72), 0x1D40  => array(0x74)
1527                      ,0x1D41  => array(0x75), 0x1D42  => array(0x77), 0x213B  => array(0x66, 0x61, 0x78)
1528                      ,0x3250  => array(0x70, 0x74, 0x65), 0x32CC  => array(0x68, 0x67)
1529                      ,0x32CE  => array(0x65, 0x76), 0x32CF  => array(0x6C, 0x74, 0x64)
1530                      ,0x337A  => array(0x69, 0x75), 0x33DE  => array(0x76, 0x2215, 0x6D)
1531                      ,0x33DF  => array(0x61, 0x2215, 0x6D)
1532                      )
1533              ,'norm_combcls' => array(0x334   => 1,   0x335   => 1,   0x336   => 1,   0x337   => 1
1534                      ,0x338   => 1,   0x93C   => 7,   0x9BC   => 7,   0xA3C   => 7,   0xABC   => 7
1535                      ,0xB3C   => 7,   0xCBC   => 7,   0x1037  => 7,   0x3099  => 8,   0x309A  => 8
1536                      ,0x94D   => 9,   0x9CD   => 9,   0xA4D   => 9,   0xACD   => 9,   0xB4D   => 9
1537                      ,0xBCD   => 9,   0xC4D   => 9,   0xCCD   => 9,   0xD4D   => 9,   0xDCA   => 9
1538                      ,0xE3A   => 9,   0xF84   => 9,   0x1039  => 9,   0x1714  => 9,   0x1734  => 9
1539                      ,0x17D2  => 9,   0x5B0   => 10,  0x5B1   => 11,  0x5B2   => 12,  0x5B3   => 13
1540                      ,0x5B4   => 14,  0x5B5   => 15,  0x5B6   => 16,  0x5B7   => 17,  0x5B8   => 18
1541                      ,0x5B9   => 19,  0x5BB   => 20,  0x5Bc   => 21,  0x5BD   => 22,  0x5BF   => 23
1542                      ,0x5C1   => 24,  0x5C2   => 25,  0xFB1E  => 26,  0x64B   => 27,  0x64C   => 28
1543                      ,0x64D   => 29,  0x64E   => 30,  0x64F   => 31,  0x650   => 32,  0x651   => 33
1544                      ,0x652   => 34,  0x670   => 35,  0x711   => 36,  0xC55   => 84,  0xC56   => 91
1545                      ,0xE38   => 103, 0xE39   => 103, 0xE48   => 107, 0xE49   => 107, 0xE4A   => 107
1546                      ,0xE4B   => 107, 0xEB8   => 118, 0xEB9   => 118, 0xEC8   => 122, 0xEC9   => 122
1547                      ,0xECA   => 122, 0xECB   => 122, 0xF71   => 129, 0xF72   => 130, 0xF7A   => 130
1548                      ,0xF7B   => 130, 0xF7C   => 130, 0xF7D   => 130, 0xF80   => 130, 0xF74   => 132
1549                      ,0x321   => 202, 0x322   => 202, 0x327   => 202, 0x328   => 202, 0x31B   => 216
1550                      ,0xF39   => 216, 0x1D165 => 216, 0x1D166 => 216, 0x1D16E => 216, 0x1D16F => 216
1551                      ,0x1D170 => 216, 0x1D171 => 216, 0x1D172 => 216, 0x302A  => 218, 0x316   => 220
1552                      ,0x317   => 220, 0x318   => 220, 0x319   => 220, 0x31C   => 220, 0x31D   => 220
1553                      ,0x31E   => 220, 0x31F   => 220, 0x320   => 220, 0x323   => 220, 0x324   => 220
1554                      ,0x325   => 220, 0x326   => 220, 0x329   => 220, 0x32A   => 220, 0x32B   => 220
1555                      ,0x32C   => 220, 0x32D   => 220, 0x32E   => 220, 0x32F   => 220, 0x330   => 220
1556                      ,0x331   => 220, 0x332   => 220, 0x333   => 220, 0x339   => 220, 0x33A   => 220
1557                      ,0x33B   => 220, 0x33C   => 220, 0x347   => 220, 0x348   => 220, 0x349   => 220
1558                      ,0x34D   => 220, 0x34E   => 220, 0x353   => 220, 0x354   => 220, 0x355   => 220
1559                      ,0x356   => 220, 0x591   => 220, 0x596   => 220, 0x59B   => 220, 0x5A3   => 220
1560                      ,0x5A4   => 220, 0x5A5   => 220, 0x5A6   => 220, 0x5A7   => 220, 0x5AA   => 220
1561                      ,0x655   => 220, 0x656   => 220, 0x6E3   => 220, 0x6EA   => 220, 0x6ED   => 220
1562                      ,0x731   => 220, 0x734   => 220, 0x737   => 220, 0x738   => 220, 0x739   => 220
1563                      ,0x73B   => 220, 0x73C   => 220, 0x73E   => 220, 0x742   => 220, 0x744   => 220
1564                      ,0x746   => 220, 0x748   => 220, 0x952   => 220, 0xF18   => 220, 0xF19   => 220
1565                      ,0xF35   => 220, 0xF37   => 220, 0xFC6   => 220, 0x193B  => 220, 0x20E8  => 220
1566                      ,0x1D17B => 220, 0x1D17C => 220, 0x1D17D => 220, 0x1D17E => 220, 0x1D17F => 220
1567                      ,0x1D180 => 220, 0x1D181 => 220, 0x1D182 => 220, 0x1D18A => 220, 0x1D18B => 220
1568                      ,0x59A   => 222, 0x5AD   => 222, 0x1929  => 222, 0x302D  => 222, 0x302E  => 224
1569                      ,0x302F  => 224, 0x1D16D => 226, 0x5AE   => 228, 0x18A9  => 228, 0x302B  => 228
1570                      ,0x300   => 230, 0x301   => 230, 0x302   => 230, 0x303   => 230, 0x304   => 230
1571                      ,0x305   => 230, 0x306   => 230, 0x307   => 230, 0x308   => 230, 0x309   => 230
1572                      ,0x30A   => 230, 0x30B   => 230, 0x30C   => 230, 0x30D   => 230, 0x30E   => 230
1573                      ,0x30F   => 230, 0x310   => 230, 0x311   => 230, 0x312   => 230, 0x313   => 230
1574                      ,0x314   => 230, 0x33D   => 230, 0x33E   => 230, 0x33F   => 230, 0x340   => 230
1575                      ,0x341   => 230, 0x342   => 230, 0x343   => 230, 0x344   => 230, 0x346   => 230
1576                      ,0x34A   => 230, 0x34B   => 230, 0x34C   => 230, 0x350   => 230, 0x351   => 230
1577                      ,0x352   => 230, 0x357   => 230, 0x363   => 230, 0x364   => 230, 0x365   => 230
1578                      ,0x366   => 230, 0x367   => 230, 0x368   => 230, 0x369   => 230, 0x36A   => 230
1579                      ,0x36B   => 230, 0x36C   => 230, 0x36D   => 230, 0x36E   => 230, 0x36F   => 230
1580                      ,0x483   => 230, 0x484   => 230, 0x485   => 230, 0x486   => 230, 0x592   => 230
1581                      ,0x593   => 230, 0x594   => 230, 0x595   => 230, 0x597   => 230, 0x598   => 230
1582                      ,0x599   => 230, 0x59C   => 230, 0x59D   => 230, 0x59E   => 230, 0x59F   => 230
1583                      ,0x5A0   => 230, 0x5A1   => 230, 0x5A8   => 230, 0x5A9   => 230, 0x5AB   => 230
1584                      ,0x5AC   => 230, 0x5AF   => 230, 0x5C4   => 230, 0x610   => 230, 0x611   => 230
1585                      ,0x612   => 230, 0x613   => 230, 0x614   => 230, 0x615   => 230, 0x653   => 230
1586                      ,0x654   => 230, 0x657   => 230, 0x658   => 230, 0x6D6   => 230, 0x6D7   => 230
1587                      ,0x6D8   => 230, 0x6D9   => 230, 0x6DA   => 230, 0x6DB   => 230, 0x6DC   => 230
1588                      ,0x6DF   => 230, 0x6E0   => 230, 0x6E1   => 230, 0x6E2   => 230, 0x6E4   => 230
1589                      ,0x6E7   => 230, 0x6E8   => 230, 0x6EB   => 230, 0x6EC   => 230, 0x730   => 230
1590                      ,0x732   => 230, 0x733   => 230, 0x735   => 230, 0x736   => 230, 0x73A   => 230
1591                      ,0x73D   => 230, 0x73F   => 230, 0x740   => 230, 0x741   => 230, 0x743   => 230
1592                      ,0x745   => 230, 0x747   => 230, 0x749   => 230, 0x74A   => 230, 0x951   => 230
1593                      ,0x953   => 230, 0x954   => 230, 0xF82   => 230, 0xF83   => 230, 0xF86   => 230
1594                      ,0xF87   => 230, 0x170D  => 230, 0x193A  => 230, 0x20D0  => 230, 0x20D1  => 230
1595                      ,0x20D4  => 230, 0x20D5  => 230, 0x20D6  => 230, 0x20D7  => 230, 0x20DB  => 230
1596                      ,0x20DC  => 230, 0x20E1  => 230, 0x20E7  => 230, 0x20E9  => 230, 0xFE20  => 230
1597                      ,0xFE21  => 230, 0xFE22  => 230, 0xFE23  => 230, 0x1D185 => 230, 0x1D186 => 230
1598                      ,0x1D187 => 230, 0x1D189 => 230, 0x1D188 => 230, 0x1D1AA => 230, 0x1D1AB => 230
1599                      ,0x1D1AC => 230, 0x1D1AD => 230, 0x315   => 232, 0x31A   => 232, 0x302C  => 232
1600                      ,0x35F   => 233, 0x362   => 233, 0x35D   => 234, 0x35E   => 234, 0x360   => 234
1601                      ,0x361   => 234, 0x345   => 240
1602                      )
1603              );
1604  }
1605  ?>


Generated: Sun Jan 29 16:31:14 2012 Cross-referenced by PHPXref 0.7.1