home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Net / IDNA / php4.php next >
Encoding:
PHP Script  |  2008-07-02  |  96.3 KB  |  3,012 lines

  1. <?php
  2. /* ------------------------------------------------------------------------- */
  3. /* based on:                                                                 */
  4. /* idna_convert.class.php - Encode / Decode Internationalized Domain Names   */
  5. /* (c) 2004-2005 phlyLabs, Berlin (http://phlylabs.de)                       */
  6. /* All rights reserved                                                       */
  7. /* v0.4.0                                                                    */
  8. /* ------------------------------------------------------------------------- */
  9.  
  10. // {{{ license
  11.  
  12. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  13. //
  14. // +----------------------------------------------------------------------+
  15. // | This library is free software; you can redistribute it and/or modify |
  16. // | it under the terms of the GNU Lesser General Public License as       |
  17. // | published by the Free Software Foundation; either version 2.1 of the |
  18. // | License, or (at your option) any later version.                      |
  19. // |                                                                      |
  20. // | This library is distributed in the hope that it will be useful, but  |
  21. // | WITHOUT ANY WARRANTY; without even the implied warranty of           |
  22. // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
  23. // | Lesser General Public License for more details.                      |
  24. // |                                                                      |
  25. // | You should have received a copy of the GNU Lesser General Public     |
  26. // | License along with this library; if not, write to the Free Software  |
  27. // | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 |
  28. // | USA.                                                                 |
  29. // +----------------------------------------------------------------------+
  30. //
  31.  
  32. // }}}
  33.  
  34. /**
  35.  * Encode/decode Internationalized Domain Names.
  36.  *
  37.  * The class allows to convert internationalized domain names
  38.  * (see RFC 3490 for details) as they can be used with various registries worldwide
  39.  * to be translated between their original (localized) form and their encoded form
  40.  * as it will be used in the DNS (Domain Name System).
  41.  *
  42.  * The class provides two public methods, encode() and decode(), which do exactly
  43.  * what you would expect them to do. You are allowed to use complete domain names,
  44.  * simple strings and complete email addresses as well. That means, that you might
  45.  * use any of the following notations:
  46.  *
  47.  * - www.n∩┐╜rgler.com
  48.  * - xn--nrgler-wxa
  49.  * - xn--brse-5qa.xn--knrz-1ra.info
  50.  *
  51.  * Unicode input might be given as either UTF-8 string, UCS-4 string or UCS-4
  52.  * array. Unicode output is available in the same formats.
  53.  * You can select your preferred format via {@link set_paramter()}.
  54.  *
  55.  * ACE input and output is always expected to be ASCII.
  56.  *
  57.  * @author  Markus Nix <mnix@docuverse.de>
  58.  * @author  Matthias Sommerfeld <mso@phlylabs.de>
  59.  * @author  Stefan Neufeind <pear.neufeind@speedpartner.de>
  60.  * @package Net
  61.  * @version $Id: php4.php,v 1.3 2008/03/22 15:24:17 neufeind Exp $
  62.  */
  63.  
  64. class Net_IDNA_php4
  65. {
  66.     // {{{ npdata
  67.     /**
  68.      * These Unicode codepoints are mapped to nothing,
  69.      * See RFC3454 for details
  70.      *
  71.      * @static
  72.      * @var array
  73.      * @access private
  74.      */
  75.     var $_np_map_nothing = array(
  76.         0xAD,
  77.         0x34F,
  78.         0x1806,
  79.         0x180B,
  80.         0x180C,
  81.         0x180D,
  82.         0x200B,
  83.         0x200C,
  84.         0x200D,
  85.         0x2060,
  86.         0xFE00,
  87.         0xFE01,
  88.         0xFE02,
  89.         0xFE03,
  90.         0xFE04,
  91.         0xFE05,
  92.         0xFE06,
  93.         0xFE07,
  94.         0xFE08,
  95.         0xFE09,
  96.         0xFE0A,
  97.         0xFE0B,
  98.         0xFE0C,
  99.         0xFE0D,
  100.         0xFE0E,
  101.         0xFE0F,
  102.         0xFEFF
  103.     );
  104.  
  105.     /**
  106.      * @static
  107.      * @var array
  108.      * @access private
  109.      */
  110.     var $_general_prohibited = array(
  111.         0,
  112.         1,
  113.         2,
  114.         3,
  115.         4,
  116.         5,
  117.         6,
  118.         7,
  119.         8,
  120.         9,
  121.         0xA,
  122.         0xB,
  123.         0xC,
  124.         0xD,
  125.         0xE,
  126.         0xF,
  127.         0x10,
  128.         0x11,
  129.         0x12,
  130.         0x13,
  131.         0x14,
  132.         0x15,
  133.         0x16,
  134.         0x17,
  135.         0x18,
  136.         0x19,
  137.         0x1A,
  138.         0x1B,
  139.         0x1C,
  140.         0x1D,
  141.         0x1E,
  142.         0x1F,
  143.         0x20,
  144.         0x21,
  145.         0x22,
  146.         0x23,
  147.         0x24,
  148.         0x25,
  149.         0x26,
  150.         0x27,
  151.         0x28,
  152.         0x29,
  153.         0x2A,
  154.         0x2B,
  155.         0x2C,
  156.         0x2F,
  157.         0x3B,
  158.         0x3C,
  159.         0x3D,
  160.         0x3E,
  161.         0x3F,
  162.         0x40,
  163.         0x5B,
  164.         0x5C,
  165.         0x5D,
  166.         0x5E,
  167.         0x5F,
  168.         0x60,
  169.         0x7B,
  170.         0x7C,
  171.         0x7D,
  172.         0x7E,
  173.         0x7F,
  174.         0x3002
  175.     );
  176.  
  177.     /**
  178.      * @static
  179.      * @var array
  180.      * @access private
  181.      */
  182.     var $_np_prohibit = array(
  183.         0xA0,
  184.         0x1680,
  185.         0x2000,
  186.         0x2001,
  187.         0x2002,
  188.         0x2003,
  189.         0x2004,
  190.         0x2005,
  191.         0x2006,
  192.         0x2007,
  193.         0x2008,
  194.         0x2009,
  195.         0x200A,
  196.         0x200B,
  197.         0x202F,
  198.         0x205F,
  199.         0x3000,
  200.         0x6DD,
  201.         0x70F,
  202.         0x180E,
  203.         0x200C,
  204.         0x200D,
  205.         0x2028,
  206.         0x2029,
  207.         0xFEFF,
  208.         0xFFF9,
  209.         0xFFFA,
  210.         0xFFFB,
  211.         0xFFFC,
  212.         0xFFFE,
  213.         0xFFFF,
  214.         0x1FFFE,
  215.         0x1FFFF,
  216.         0x2FFFE,
  217.         0x2FFFF,
  218.         0x3FFFE,
  219.         0x3FFFF,
  220.         0x4FFFE,
  221.         0x4FFFF,
  222.         0x5FFFE,
  223.         0x5FFFF,
  224.         0x6FFFE,
  225.         0x6FFFF,
  226.         0x7FFFE,
  227.         0x7FFFF,
  228.         0x8FFFE,
  229.         0x8FFFF,
  230.         0x9FFFE,
  231.         0x9FFFF,
  232.         0xAFFFE,
  233.         0xAFFFF,
  234.         0xBFFFE,
  235.         0xBFFFF,
  236.         0xCFFFE,
  237.         0xCFFFF,
  238.         0xDFFFE,
  239.         0xDFFFF,
  240.         0xEFFFE,
  241.         0xEFFFF,
  242.         0xFFFFE,
  243.         0xFFFFF,
  244.         0x10FFFE,
  245.         0x10FFFF,
  246.         0xFFF9,
  247.         0xFFFA,
  248.         0xFFFB,
  249.         0xFFFC,
  250.         0xFFFD,
  251.         0x340,
  252.         0x341,
  253.         0x200E,
  254.         0x200F,
  255.         0x202A,
  256.         0x202B,
  257.         0x202C,
  258.         0x202D,
  259.         0x202E,
  260.         0x206A,
  261.         0x206B,
  262.         0x206C,
  263.         0x206D,
  264.         0x206E,
  265.         0x206F,
  266.         0xE0001
  267.     );
  268.  
  269.     /**
  270.      * @static
  271.      * @var array
  272.      * @access private
  273.      */
  274.     var $_np_prohibit_ranges = array(
  275.         array(0x80,     0x9F    ),
  276.         array(0x2060,   0x206F  ),
  277.         array(0x1D173,  0x1D17A ),
  278.         array(0xE000,   0xF8FF  ),
  279.         array(0xF0000,  0xFFFFD ),
  280.         array(0x100000, 0x10FFFD),
  281.         array(0xFDD0,   0xFDEF  ),
  282.         array(0xD800,   0xDFFF  ),
  283.         array(0x2FF0,   0x2FFB  ),
  284.         array(0xE0020,  0xE007F )
  285.     );
  286.  
  287.     /**
  288.      * @static
  289.      * @var array
  290.      * @access private
  291.      */
  292.     var $_np_replacemaps = array(
  293.         0x41    => array(0x61),
  294.         0x42    => array(0x62),
  295.         0x43    => array(0x63),
  296.         0x44    => array(0x64),
  297.         0x45    => array(0x65),
  298.         0x46    => array(0x66),
  299.         0x47    => array(0x67),
  300.         0x48    => array(0x68),
  301.         0x49    => array(0x69),
  302.         0x4A    => array(0x6A),
  303.         0x4B    => array(0x6B),
  304.         0x4C    => array(0x6C),
  305.         0x4D    => array(0x6D),
  306.         0x4E    => array(0x6E),
  307.         0x4F    => array(0x6F),
  308.         0x50    => array(0x70),
  309.         0x51    => array(0x71),
  310.         0x52    => array(0x72),
  311.         0x53    => array(0x73),
  312.         0x54    => array(0x74),
  313.         0x55    => array(0x75),
  314.         0x56    => array(0x76),
  315.         0x57    => array(0x77),
  316.         0x58    => array(0x78),
  317.         0x59    => array(0x79),
  318.         0x5A    => array(0x7A),
  319.         0xB5    => array(0x3BC),
  320.         0xC0    => array(0xE0),
  321.         0xC1    => array(0xE1),
  322.         0xC2    => array(0xE2),
  323.         0xC3    => array(0xE3),
  324.         0xC4    => array(0xE4),
  325.         0xC5    => array(0xE5),
  326.         0xC6    => array(0xE6),
  327.         0xC7    => array(0xE7),
  328.         0xC8    => array(0xE8),
  329.         0xC9    => array(0xE9),
  330.         0xCA    => array(0xEA),
  331.         0xCB    => array(0xEB),
  332.         0xCC    => array(0xEC),
  333.         0xCD    => array(0xED),
  334.         0xCE    => array(0xEE),
  335.         0xCF    => array(0xEF),
  336.         0xD0    => array(0xF0),
  337.         0xD1    => array(0xF1),
  338.         0xD2    => array(0xF2),
  339.         0xD3    => array(0xF3),
  340.         0xD4    => array(0xF4),
  341.         0xD5    => array(0xF5),
  342.         0xD6    => array(0xF6),
  343.         0xD8    => array(0xF8),
  344.         0xD9    => array(0xF9),
  345.         0xDA    => array(0xFA),
  346.         0xDB    => array(0xFB),
  347.         0xDC    => array(0xFC),
  348.         0xDD    => array(0xFD),
  349.         0xDE    => array(0xFE),
  350.         0xDF    => array(0x73, 0x73),
  351.         0x100   => array(0x101),
  352.         0x102   => array(0x103),
  353.         0x104   => array(0x105),
  354.         0x106   => array(0x107),
  355.         0x108   => array(0x109),
  356.         0x10A   => array(0x10B),
  357.         0x10C   => array(0x10D),
  358.         0x10E   => array(0x10F),
  359.         0x110   => array(0x111),
  360.         0x112   => array(0x113),
  361.         0x114   => array(0x115),
  362.         0x116   => array(0x117),
  363.         0x118   => array(0x119),
  364.         0x11A   => array(0x11B),
  365.         0x11C   => array(0x11D),
  366.         0x11E   => array(0x11F),
  367.         0x120   => array(0x121),
  368.         0x122   => array(0x123),
  369.         0x124   => array(0x125),
  370.         0x126   => array(0x127),
  371.         0x128   => array(0x129),
  372.         0x12A   => array(0x12B),
  373.         0x12C   => array(0x12D),
  374.         0x12E   => array(0x12F),
  375.         0x130   => array(0x69, 0x307),
  376.         0x132   => array(0x133),
  377.         0x134   => array(0x135),
  378.         0x136   => array(0x137),
  379.         0x139   => array(0x13A),
  380.         0x13B   => array(0x13C),
  381.         0x13D   => array(0x13E),
  382.         0x13F   => array(0x140),
  383.         0x141   => array(0x142),
  384.         0x143   => array(0x144),
  385.         0x145   => array(0x146),
  386.         0x147   => array(0x148),
  387.         0x149   => array(0x2BC, 0x6E),
  388.         0x14A   => array(0x14B),
  389.         0x14C   => array(0x14D),
  390.         0x14E   => array(0x14F),
  391.         0x150   => array(0x151),
  392.         0x152   => array(0x153),
  393.         0x154   => array(0x155),
  394.         0x156   => array(0x157),
  395.         0x158   => array(0x159),
  396.         0x15A   => array(0x15B),
  397.         0x15C   => array(0x15D),
  398.         0x15E   => array(0x15F),
  399.         0x160   => array(0x161),
  400.         0x162   => array(0x163),
  401.         0x164   => array(0x165),
  402.         0x166   => array(0x167),
  403.         0x168   => array(0x169),
  404.         0x16A   => array(0x16B),
  405.         0x16C   => array(0x16D),
  406.         0x16E   => array(0x16F),
  407.         0x170   => array(0x171),
  408.         0x172   => array(0x173),
  409.         0x174   => array(0x175),
  410.         0x176   => array(0x177),
  411.         0x178   => array(0xFF),
  412.         0x179   => array(0x17A),
  413.         0x17B   => array(0x17C),
  414.         0x17D   => array(0x17E),
  415.         0x17F   => array(0x73),
  416.         0x181   => array(0x253),
  417.         0x182   => array(0x183),
  418.         0x184   => array(0x185),
  419.         0x186   => array(0x254),
  420.         0x187   => array(0x188),
  421.         0x189   => array(0x256),
  422.         0x18A   => array(0x257),
  423.         0x18B   => array(0x18C),
  424.         0x18E   => array(0x1DD),
  425.         0x18F   => array(0x259),
  426.         0x190   => array(0x25B),
  427.         0x191   => array(0x192),
  428.         0x193   => array(0x260),
  429.         0x194   => array(0x263),
  430.         0x196   => array(0x269),
  431.         0x197   => array(0x268),
  432.         0x198   => array(0x199),
  433.         0x19C   => array(0x26F),
  434.         0x19D   => array(0x272),
  435.         0x19F   => array(0x275),
  436.         0x1A0   => array(0x1A1),
  437.         0x1A2   => array(0x1A3),
  438.         0x1A4   => array(0x1A5),
  439.         0x1A6   => array(0x280),
  440.         0x1A7   => array(0x1A8),
  441.         0x1A9   => array(0x283),
  442.         0x1AC   => array(0x1AD),
  443.         0x1AE   => array(0x288),
  444.         0x1AF   => array(0x1B0),
  445.         0x1B1   => array(0x28A),
  446.         0x1B2   => array(0x28B),
  447.         0x1B3   => array(0x1B4),
  448.         0x1B5   => array(0x1B6),
  449.         0x1B7   => array(0x292),
  450.         0x1B8   => array(0x1B9),
  451.         0x1BC   => array(0x1BD),
  452.         0x1C4   => array(0x1C6),
  453.         0x1C5   => array(0x1C6),
  454.         0x1C7   => array(0x1C9),
  455.         0x1C8   => array(0x1C9),
  456.         0x1CA   => array(0x1CC),
  457.         0x1CB   => array(0x1CC),
  458.         0x1CD   => array(0x1CE),
  459.         0x1CF   => array(0x1D0),
  460.         0x1D1   => array(0x1D2),
  461.         0x1D3   => array(0x1D4),
  462.         0x1D5   => array(0x1D6),
  463.         0x1D7   => array(0x1D8),
  464.         0x1D9   => array(0x1DA),
  465.         0x1DB   => array(0x1DC),
  466.         0x1DE   => array(0x1DF),
  467.         0x1E0   => array(0x1E1),
  468.         0x1E2   => array(0x1E3),
  469.         0x1E4   => array(0x1E5),
  470.         0x1E6   => array(0x1E7),
  471.         0x1E8   => array(0x1E9),
  472.         0x1EA   => array(0x1EB),
  473.         0x1EC   => array(0x1ED),
  474.         0x1EE   => array(0x1EF),
  475.         0x1F0   => array(0x6A, 0x30C),
  476.         0x1F1   => array(0x1F3),
  477.         0x1F2   => array(0x1F3),
  478.         0x1F4   => array(0x1F5),
  479.         0x1F6   => array(0x195),
  480.         0x1F7   => array(0x1BF),
  481.         0x1F8   => array(0x1F9),
  482.         0x1FA   => array(0x1FB),
  483.         0x1FC   => array(0x1FD),
  484.         0x1FE   => array(0x1FF),
  485.         0x200   => array(0x201),
  486.         0x202   => array(0x203),
  487.         0x204   => array(0x205),
  488.         0x206   => array(0x207),
  489.         0x208   => array(0x209),
  490.         0x20A   => array(0x20B),
  491.         0x20C   => array(0x20D),
  492.         0x20E   => array(0x20F),
  493.         0x210   => array(0x211),
  494.         0x212   => array(0x213),
  495.         0x214   => array(0x215),
  496.         0x216   => array(0x217),
  497.         0x218   => array(0x219),
  498.         0x21A   => array(0x21B),
  499.         0x21C   => array(0x21D),
  500.         0x21E   => array(0x21F),
  501.         0x220   => array(0x19E),
  502.         0x222   => array(0x223),
  503.         0x224   => array(0x225),
  504.         0x226   => array(0x227),
  505.         0x228   => array(0x229),
  506.         0x22A   => array(0x22B),
  507.         0x22C   => array(0x22D),
  508.         0x22E   => array(0x22F),
  509.         0x230   => array(0x231),
  510.         0x232   => array(0x233),
  511.         0x345   => array(0x3B9),
  512.         0x37A   => array(0x20, 0x3B9),
  513.         0x386   => array(0x3AC),
  514.         0x388   => array(0x3AD),
  515.         0x389   => array(0x3AE),
  516.         0x38A   => array(0x3AF),
  517.         0x38C   => array(0x3CC),
  518.         0x38E   => array(0x3CD),
  519.         0x38F   => array(0x3CE),
  520.         0x390   => array(0x3B9, 0x308, 0x301),
  521.         0x391   => array(0x3B1),
  522.         0x392   => array(0x3B2),
  523.         0x393   => array(0x3B3),
  524.         0x394   => array(0x3B4),
  525.         0x395   => array(0x3B5),
  526.         0x396   => array(0x3B6),
  527.         0x397   => array(0x3B7),
  528.         0x398   => array(0x3B8),
  529.         0x399   => array(0x3B9),
  530.         0x39A   => array(0x3BA),
  531.         0x39B   => array(0x3BB),
  532.         0x39C   => array(0x3BC),
  533.         0x39D   => array(0x3BD),
  534.         0x39E   => array(0x3BE),
  535.         0x39F   => array(0x3BF),
  536.         0x3A0   => array(0x3C0),
  537.         0x3A1   => array(0x3C1),
  538.         0x3A3   => array(0x3C3),
  539.         0x3A4   => array(0x3C4),
  540.         0x3A5   => array(0x3C5),
  541.         0x3A6   => array(0x3C6),
  542.         0x3A7   => array(0x3C7),
  543.         0x3A8   => array(0x3C8),
  544.         0x3A9   => array(0x3C9),
  545.         0x3AA   => array(0x3CA),
  546.         0x3AB   => array(0x3CB),
  547.         0x3B0   => array(0x3C5, 0x308, 0x301),
  548.         0x3C2   => array(0x3C3),
  549.         0x3D0   => array(0x3B2),
  550.         0x3D1   => array(0x3B8),
  551.         0x3D2   => array(0x3C5),
  552.         0x3D3   => array(0x3CD),
  553.         0x3D4   => array(0x3CB),
  554.         0x3D5   => array(0x3C6),
  555.         0x3D6   => array(0x3C0),
  556.         0x3D8   => array(0x3D9),
  557.         0x3DA   => array(0x3DB),
  558.         0x3DC   => array(0x3DD),
  559.         0x3DE   => array(0x3DF),
  560.         0x3E0   => array(0x3E1),
  561.         0x3E2   => array(0x3E3),
  562.         0x3E4   => array(0x3E5),
  563.         0x3E6   => array(0x3E7),
  564.         0x3E8   => array(0x3E9),
  565.         0x3EA   => array(0x3EB),
  566.         0x3EC   => array(0x3ED),
  567.         0x3EE   => array(0x3EF),
  568.         0x3F0   => array(0x3BA),
  569.         0x3F1   => array(0x3C1),
  570.         0x3F2   => array(0x3C3),
  571.         0x3F4   => array(0x3B8),
  572.         0x3F5   => array(0x3B5),
  573.         0x400   => array(0x450),
  574.         0x401   => array(0x451),
  575.         0x402   => array(0x452),
  576.         0x403   => array(0x453),
  577.         0x404   => array(0x454),
  578.         0x405   => array(0x455),
  579.         0x406   => array(0x456),
  580.         0x407   => array(0x457),
  581.         0x408   => array(0x458),
  582.         0x409   => array(0x459),
  583.         0x40A   => array(0x45A),
  584.         0x40B   => array(0x45B),
  585.         0x40C   => array(0x45C),
  586.         0x40D   => array(0x45D),
  587.         0x40E   => array(0x45E),
  588.         0x40F   => array(0x45F),
  589.         0x410   => array(0x430),
  590.         0x411   => array(0x431),
  591.         0x412   => array(0x432),
  592.         0x413   => array(0x433),
  593.         0x414   => array(0x434),
  594.         0x415   => array(0x435),
  595.         0x416   => array(0x436),
  596.         0x417   => array(0x437),
  597.         0x418   => array(0x438),
  598.         0x419   => array(0x439),
  599.         0x41A   => array(0x43A),
  600.         0x41B   => array(0x43B),
  601.         0x41C   => array(0x43C),
  602.         0x41D   => array(0x43D),
  603.         0x41E   => array(0x43E),
  604.         0x41F   => array(0x43F),
  605.         0x420   => array(0x440),
  606.         0x421   => array(0x441),
  607.         0x422   => array(0x442),
  608.         0x423   => array(0x443),
  609.         0x424   => array(0x444),
  610.         0x425   => array(0x445),
  611.         0x426   => array(0x446),
  612.         0x427   => array(0x447),
  613.         0x428   => array(0x448),
  614.         0x429   => array(0x449),
  615.         0x42A   => array(0x44A),
  616.         0x42B   => array(0x44B),
  617.         0x42C   => array(0x44C),
  618.         0x42D   => array(0x44D),
  619.         0x42E   => array(0x44E),
  620.         0x42F   => array(0x44F),
  621.         0x460   => array(0x461),
  622.         0x462   => array(0x463),
  623.         0x464   => array(0x465),
  624.         0x466   => array(0x467),
  625.         0x468   => array(0x469),
  626.         0x46A   => array(0x46B),
  627.         0x46C   => array(0x46D),
  628.         0x46E   => array(0x46F),
  629.         0x470   => array(0x471),
  630.         0x472   => array(0x473),
  631.         0x474   => array(0x475),
  632.         0x476   => array(0x477),
  633.         0x478   => array(0x479),
  634.         0x47A   => array(0x47B),
  635.         0x47C   => array(0x47D),
  636.         0x47E   => array(0x47F),
  637.         0x480   => array(0x481),
  638.         0x48A   => array(0x48B),
  639.         0x48C   => array(0x48D),
  640.         0x48E   => array(0x48F),
  641.         0x490   => array(0x491),
  642.         0x492   => array(0x493),
  643.         0x494   => array(0x495),
  644.         0x496   => array(0x497),
  645.         0x498   => array(0x499),
  646.         0x49A   => array(0x49B),
  647.         0x49C   => array(0x49D),
  648.         0x49E   => array(0x49F),
  649.         0x4A0   => array(0x4A1),
  650.         0x4A2   => array(0x4A3),
  651.         0x4A4   => array(0x4A5),
  652.         0x4A6   => array(0x4A7),
  653.         0x4A8   => array(0x4A9),
  654.         0x4AA   => array(0x4AB),
  655.         0x4AC   => array(0x4AD),
  656.         0x4AE   => array(0x4AF),
  657.         0x4B0   => array(0x4B1),
  658.         0x4B2   => array(0x4B3),
  659.         0x4B4   => array(0x4B5),
  660.         0x4B6   => array(0x4B7),
  661.         0x4B8   => array(0x4B9),
  662.         0x4BA   => array(0x4BB),
  663.         0x4BC   => array(0x4BD),
  664.         0x4BE   => array(0x4BF),
  665.         0x4C1   => array(0x4C2),
  666.         0x4C3   => array(0x4C4),
  667.         0x4C5   => array(0x4C6),
  668.         0x4C7   => array(0x4C8),
  669.         0x4C9   => array(0x4CA),
  670.         0x4CB   => array(0x4CC),
  671.         0x4CD   => array(0x4CE),
  672.         0x4D0   => array(0x4D1),
  673.         0x4D2   => array(0x4D3),
  674.         0x4D4   => array(0x4D5),
  675.         0x4D6   => array(0x4D7),
  676.         0x4D8   => array(0x4D9),
  677.         0x4DA   => array(0x4DB),
  678.         0x4DC   => array(0x4DD),
  679.         0x4DE   => array(0x4DF),
  680.         0x4E0   => array(0x4E1),
  681.         0x4E2   => array(0x4E3),
  682.         0x4E4   => array(0x4E5),
  683.         0x4E6   => array(0x4E7),
  684.         0x4E8   => array(0x4E9),
  685.         0x4EA   => array(0x4EB),
  686.         0x4EC   => array(0x4ED),
  687.         0x4EE   => array(0x4EF),
  688.         0x4F0   => array(0x4F1),
  689.         0x4F2   => array(0x4F3),
  690.         0x4F4   => array(0x4F5),
  691.         0x4F8   => array(0x4F9),
  692.         0x500   => array(0x501),
  693.         0x502   => array(0x503),
  694.         0x504   => array(0x505),
  695.         0x506   => array(0x507),
  696.         0x508   => array(0x509),
  697.         0x50A   => array(0x50B),
  698.         0x50C   => array(0x50D),
  699.         0x50E   => array(0x50F),
  700.         0x531   => array(0x561),
  701.         0x532   => array(0x562),
  702.         0x533   => array(0x563),
  703.         0x534   => array(0x564),
  704.         0x535   => array(0x565),
  705.         0x536   => array(0x566),
  706.         0x537   => array(0x567),
  707.         0x538   => array(0x568),
  708.         0x539   => array(0x569),
  709.         0x53A   => array(0x56A),
  710.         0x53B   => array(0x56B),
  711.         0x53C   => array(0x56C),
  712.         0x53D   => array(0x56D),
  713.         0x53E   => array(0x56E),
  714.         0x53F   => array(0x56F),
  715.         0x540   => array(0x570),
  716.         0x541   => array(0x571),
  717.         0x542   => array(0x572),
  718.         0x543   => array(0x573),
  719.         0x544   => array(0x574),
  720.         0x545   => array(0x575),
  721.         0x546   => array(0x576),
  722.         0x547   => array(0x577),
  723.         0x548   => array(0x578),
  724.         0x549   => array(0x579),
  725.         0x54A   => array(0x57A),
  726.         0x54B   => array(0x57B),
  727.         0x54C   => array(0x57C),
  728.         0x54D   => array(0x57D),
  729.         0x54E   => array(0x57E),
  730.         0x54F   => array(0x57F),
  731.         0x550   => array(0x580),
  732.         0x551   => array(0x581),
  733.         0x552   => array(0x582),
  734.         0x553   => array(0x583),
  735.         0x554   => array(0x584),
  736.         0x555   => array(0x585),
  737.         0x556   => array(0x586),
  738.         0x587   => array(0x565, 0x582),
  739.         0x1E00  => array(0x1E01),
  740.         0x1E02  => array(0x1E03),
  741.         0x1E04  => array(0x1E05),
  742.         0x1E06  => array(0x1E07),
  743.         0x1E08  => array(0x1E09),
  744.         0x1E0A  => array(0x1E0B),
  745.         0x1E0C  => array(0x1E0D),
  746.         0x1E0E  => array(0x1E0F),
  747.         0x1E10  => array(0x1E11),
  748.         0x1E12  => array(0x1E13),
  749.         0x1E14  => array(0x1E15),
  750.         0x1E16  => array(0x1E17),
  751.         0x1E18  => array(0x1E19),
  752.         0x1E1A  => array(0x1E1B),
  753.         0x1E1C  => array(0x1E1D),
  754.         0x1E1E  => array(0x1E1F),
  755.         0x1E20  => array(0x1E21),
  756.         0x1E22  => array(0x1E23),
  757.         0x1E24  => array(0x1E25),
  758.         0x1E26  => array(0x1E27),
  759.         0x1E28  => array(0x1E29),
  760.         0x1E2A  => array(0x1E2B),
  761.         0x1E2C  => array(0x1E2D),
  762.         0x1E2E  => array(0x1E2F),
  763.         0x1E30  => array(0x1E31),
  764.         0x1E32  => array(0x1E33),
  765.         0x1E34  => array(0x1E35),
  766.         0x1E36  => array(0x1E37),
  767.         0x1E38  => array(0x1E39),
  768.         0x1E3A  => array(0x1E3B),
  769.         0x1E3C  => array(0x1E3D),
  770.         0x1E3E  => array(0x1E3F),
  771.         0x1E40  => array(0x1E41),
  772.         0x1E42  => array(0x1E43),
  773.         0x1E44  => array(0x1E45),
  774.         0x1E46  => array(0x1E47),
  775.         0x1E48  => array(0x1E49),
  776.         0x1E4A  => array(0x1E4B),
  777.         0x1E4C  => array(0x1E4D),
  778.         0x1E4E  => array(0x1E4F),
  779.         0x1E50  => array(0x1E51),
  780.         0x1E52  => array(0x1E53),
  781.         0x1E54  => array(0x1E55),
  782.         0x1E56  => array(0x1E57),
  783.         0x1E58  => array(0x1E59),
  784.         0x1E5A  => array(0x1E5B),
  785.         0x1E5C  => array(0x1E5D),
  786.         0x1E5E  => array(0x1E5F),
  787.         0x1E60  => array(0x1E61),
  788.         0x1E62  => array(0x1E63),
  789.         0x1E64  => array(0x1E65),
  790.         0x1E66  => array(0x1E67),
  791.         0x1E68  => array(0x1E69),
  792.         0x1E6A  => array(0x1E6B),
  793.         0x1E6C  => array(0x1E6D),
  794.         0x1E6E  => array(0x1E6F),
  795.         0x1E70  => array(0x1E71),
  796.         0x1E72  => array(0x1E73),
  797.         0x1E74  => array(0x1E75),
  798.         0x1E76  => array(0x1E77),
  799.         0x1E78  => array(0x1E79),
  800.         0x1E7A  => array(0x1E7B),
  801.         0x1E7C  => array(0x1E7D),
  802.         0x1E7E  => array(0x1E7F),
  803.         0x1E80  => array(0x1E81),
  804.         0x1E82  => array(0x1E83),
  805.         0x1E84  => array(0x1E85),
  806.         0x1E86  => array(0x1E87),
  807.         0x1E88  => array(0x1E89),
  808.         0x1E8A  => array(0x1E8B),
  809.         0x1E8C  => array(0x1E8D),
  810.         0x1E8E  => array(0x1E8F),
  811.         0x1E90  => array(0x1E91),
  812.         0x1E92  => array(0x1E93),
  813.         0x1E94  => array(0x1E95),
  814.         0x1E96  => array(0x68, 0x331),
  815.         0x1E97  => array(0x74, 0x308),
  816.         0x1E98  => array(0x77, 0x30A),
  817.         0x1E99  => array(0x79, 0x30A),
  818.         0x1E9A  => array(0x61, 0x2BE),
  819.         0x1E9B  => array(0x1E61),
  820.         0x1EA0  => array(0x1EA1),
  821.         0x1EA2  => array(0x1EA3),
  822.         0x1EA4  => array(0x1EA5),
  823.         0x1EA6  => array(0x1EA7),
  824.         0x1EA8  => array(0x1EA9),
  825.         0x1EAA  => array(0x1EAB),
  826.         0x1EAC  => array(0x1EAD),
  827.         0x1EAE  => array(0x1EAF),
  828.         0x1EB0  => array(0x1EB1),
  829.         0x1EB2  => array(0x1EB3),
  830.         0x1EB4  => array(0x1EB5),
  831.         0x1EB6  => array(0x1EB7),
  832.         0x1EB8  => array(0x1EB9),
  833.         0x1EBA  => array(0x1EBB),
  834.         0x1EBC  => array(0x1EBD),
  835.         0x1EBE  => array(0x1EBF),
  836.         0x1EC0  => array(0x1EC1),
  837.         0x1EC2  => array(0x1EC3),
  838.         0x1EC4  => array(0x1EC5),
  839.         0x1EC6  => array(0x1EC7),
  840.         0x1EC8  => array(0x1EC9),
  841.         0x1ECA  => array(0x1ECB),
  842.         0x1ECC  => array(0x1ECD),
  843.         0x1ECE  => array(0x1ECF),
  844.         0x1ED0  => array(0x1ED1),
  845.         0x1ED2  => array(0x1ED3),
  846.         0x1ED4  => array(0x1ED5),
  847.         0x1ED6  => array(0x1ED7),
  848.         0x1ED8  => array(0x1ED9),
  849.         0x1EDA  => array(0x1EDB),
  850.         0x1EDC  => array(0x1EDD),
  851.         0x1EDE  => array(0x1EDF),
  852.         0x1EE0  => array(0x1EE1),
  853.         0x1EE2  => array(0x1EE3),
  854.         0x1EE4  => array(0x1EE5),
  855.         0x1EE6  => array(0x1EE7),
  856.         0x1EE8  => array(0x1EE9),
  857.         0x1EEA  => array(0x1EEB),
  858.         0x1EEC  => array(0x1EED),
  859.         0x1EEE  => array(0x1EEF),
  860.         0x1EF0  => array(0x1EF1),
  861.         0x1EF2  => array(0x1EF3),
  862.         0x1EF4  => array(0x1EF5),
  863.         0x1EF6  => array(0x1EF7),
  864.         0x1EF8  => array(0x1EF9),
  865.         0x1F08  => array(0x1F00),
  866.         0x1F09  => array(0x1F01),
  867.         0x1F0A  => array(0x1F02),
  868.         0x1F0B  => array(0x1F03),
  869.         0x1F0C  => array(0x1F04),
  870.         0x1F0D  => array(0x1F05),
  871.         0x1F0E  => array(0x1F06),
  872.         0x1F0F  => array(0x1F07),
  873.         0x1F18  => array(0x1F10),
  874.         0x1F19  => array(0x1F11),
  875.         0x1F1A  => array(0x1F12),
  876.         0x1F1B  => array(0x1F13),
  877.         0x1F1C  => array(0x1F14),
  878.         0x1F1D  => array(0x1F15),
  879.         0x1F28  => array(0x1F20),
  880.         0x1F29  => array(0x1F21),
  881.         0x1F2A  => array(0x1F22),
  882.         0x1F2B  => array(0x1F23),
  883.         0x1F2C  => array(0x1F24),
  884.         0x1F2D  => array(0x1F25),
  885.         0x1F2E  => array(0x1F26),
  886.         0x1F2F  => array(0x1F27),
  887.         0x1F38  => array(0x1F30),
  888.         0x1F39  => array(0x1F31),
  889.         0x1F3A  => array(0x1F32),
  890.         0x1F3B  => array(0x1F33),
  891.         0x1F3C  => array(0x1F34),
  892.         0x1F3D  => array(0x1F35),
  893.         0x1F3E  => array(0x1F36),
  894.         0x1F3F  => array(0x1F37),
  895.         0x1F48  => array(0x1F40),
  896.         0x1F49  => array(0x1F41),
  897.         0x1F4A  => array(0x1F42),
  898.         0x1F4B  => array(0x1F43),
  899.         0x1F4C  => array(0x1F44),
  900.         0x1F4D  => array(0x1F45),
  901.         0x1F50  => array(0x3C5, 0x313),
  902.         0x1F52  => array(0x3C5, 0x313, 0x300),
  903.         0x1F54  => array(0x3C5, 0x313, 0x301),
  904.         0x1F56  => array(0x3C5, 0x313, 0x342),
  905.         0x1F59  => array(0x1F51),
  906.         0x1F5B  => array(0x1F53),
  907.         0x1F5D  => array(0x1F55),
  908.         0x1F5F  => array(0x1F57),
  909.         0x1F68  => array(0x1F60),
  910.         0x1F69  => array(0x1F61),
  911.         0x1F6A  => array(0x1F62),
  912.         0x1F6B  => array(0x1F63),
  913.         0x1F6C  => array(0x1F64),
  914.         0x1F6D  => array(0x1F65),
  915.         0x1F6E  => array(0x1F66),
  916.         0x1F6F  => array(0x1F67),
  917.         0x1F80  => array(0x1F00, 0x3B9),
  918.         0x1F81  => array(0x1F01, 0x3B9),
  919.         0x1F82  => array(0x1F02, 0x3B9),
  920.         0x1F83  => array(0x1F03, 0x3B9),
  921.         0x1F84  => array(0x1F04, 0x3B9),
  922.         0x1F85  => array(0x1F05, 0x3B9),
  923.         0x1F86  => array(0x1F06, 0x3B9),
  924.         0x1F87  => array(0x1F07, 0x3B9),
  925.         0x1F88  => array(0x1F00, 0x3B9),
  926.         0x1F89  => array(0x1F01, 0x3B9),
  927.         0x1F8A  => array(0x1F02, 0x3B9),
  928.         0x1F8B  => array(0x1F03, 0x3B9),
  929.         0x1F8C  => array(0x1F04, 0x3B9),
  930.         0x1F8D  => array(0x1F05, 0x3B9),
  931.         0x1F8E  => array(0x1F06, 0x3B9),
  932.         0x1F8F  => array(0x1F07, 0x3B9),
  933.         0x1F90  => array(0x1F20, 0x3B9),
  934.         0x1F91  => array(0x1F21, 0x3B9),
  935.         0x1F92  => array(0x1F22, 0x3B9),
  936.         0x1F93  => array(0x1F23, 0x3B9),
  937.         0x1F94  => array(0x1F24, 0x3B9),
  938.         0x1F95  => array(0x1F25, 0x3B9),
  939.         0x1F96  => array(0x1F26, 0x3B9),
  940.         0x1F97  => array(0x1F27, 0x3B9),
  941.         0x1F98  => array(0x1F20, 0x3B9),
  942.         0x1F99  => array(0x1F21, 0x3B9),
  943.         0x1F9A  => array(0x1F22, 0x3B9),
  944.         0x1F9B  => array(0x1F23, 0x3B9),
  945.         0x1F9C  => array(0x1F24, 0x3B9),
  946.         0x1F9D  => array(0x1F25, 0x3B9),
  947.         0x1F9E  => array(0x1F26, 0x3B9),
  948.         0x1F9F  => array(0x1F27, 0x3B9),
  949.         0x1FA0  => array(0x1F60, 0x3B9),
  950.         0x1FA1  => array(0x1F61, 0x3B9),
  951.         0x1FA2  => array(0x1F62, 0x3B9),
  952.         0x1FA3  => array(0x1F63, 0x3B9),
  953.         0x1FA4  => array(0x1F64, 0x3B9),
  954.         0x1FA5  => array(0x1F65, 0x3B9),
  955.         0x1FA6  => array(0x1F66, 0x3B9),
  956.         0x1FA7  => array(0x1F67, 0x3B9),
  957.         0x1FA8  => array(0x1F60, 0x3B9),
  958.         0x1FA9  => array(0x1F61, 0x3B9),
  959.         0x1FAA  => array(0x1F62, 0x3B9),
  960.         0x1FAB  => array(0x1F63, 0x3B9),
  961.         0x1FAC  => array(0x1F64, 0x3B9),
  962.         0x1FAD  => array(0x1F65, 0x3B9),
  963.         0x1FAE  => array(0x1F66, 0x3B9),
  964.         0x1FAF  => array(0x1F67, 0x3B9),
  965.         0x1FB2  => array(0x1F70, 0x3B9),
  966.         0x1FB3  => array(0x3B1, 0x3B9),
  967.         0x1FB4  => array(0x3AC, 0x3B9),
  968.         0x1FB6  => array(0x3B1, 0x342),
  969.         0x1FB7  => array(0x3B1, 0x342, 0x3B9),
  970.         0x1FB8  => array(0x1FB0),
  971.         0x1FB9  => array(0x1FB1),
  972.         0x1FBA  => array(0x1F70),
  973.         0x1FBB  => array(0x1F71),
  974.         0x1FBC  => array(0x3B1, 0x3B9),
  975.         0x1FBE  => array(0x3B9),
  976.         0x1FC2  => array(0x1F74, 0x3B9),
  977.         0x1FC3  => array(0x3B7, 0x3B9),
  978.         0x1FC4  => array(0x3AE, 0x3B9),
  979.         0x1FC6  => array(0x3B7, 0x342),
  980.         0x1FC7  => array(0x3B7, 0x342, 0x3B9),
  981.         0x1FC8  => array(0x1F72),
  982.         0x1FC9  => array(0x1F73),
  983.         0x1FCA  => array(0x1F74),
  984.         0x1FCB  => array(0x1F75),
  985.         0x1FCC  => array(0x3B7, 0x3B9),
  986.         0x1FD2  => array(0x3B9, 0x308, 0x300),
  987.         0x1FD3  => array(0x3B9, 0x308, 0x301),
  988.         0x1FD6  => array(0x3B9, 0x342),
  989.         0x1FD7  => array(0x3B9, 0x308, 0x342),
  990.         0x1FD8  => array(0x1FD0),
  991.         0x1FD9  => array(0x1FD1),
  992.         0x1FDA  => array(0x1F76),
  993.         0x1FDB  => array(0x1F77),
  994.         0x1FE2  => array(0x3C5, 0x308, 0x300),
  995.         0x1FE3  => array(0x3C5, 0x308, 0x301),
  996.         0x1FE4  => array(0x3C1, 0x313),
  997.         0x1FE6  => array(0x3C5, 0x342),
  998.         0x1FE7  => array(0x3C5, 0x308, 0x342),
  999.         0x1FE8  => array(0x1FE0),
  1000.         0x1FE9  => array(0x1FE1),
  1001.         0x1FEA  => array(0x1F7A),
  1002.         0x1FEB  => array(0x1F7B),
  1003.         0x1FEC  => array(0x1FE5),
  1004.         0x1FF2  => array(0x1F7C, 0x3B9),
  1005.         0x1FF3  => array(0x3C9, 0x3B9),
  1006.         0x1FF4  => array(0x3CE, 0x3B9),
  1007.         0x1FF6  => array(0x3C9, 0x342),
  1008.         0x1FF7  => array(0x3C9, 0x342, 0x3B9),
  1009.         0x1FF8  => array(0x1F78),
  1010.         0x1FF9  => array(0x1F79),
  1011.         0x1FFA  => array(0x1F7C),
  1012.         0x1FFB  => array(0x1F7D),
  1013.         0x1FFC  => array(0x3C9, 0x3B9),
  1014.         0x20A8  => array(0x72, 0x73),
  1015.         0x2102  => array(0x63),
  1016.         0x2103  => array(0xB0, 0x63),
  1017.         0x2107  => array(0x25B),
  1018.         0x2109  => array(0xB0, 0x66),
  1019.         0x210B  => array(0x68),
  1020.         0x210C  => array(0x68),
  1021.         0x210D  => array(0x68),
  1022.         0x2110  => array(0x69),
  1023.         0x2111  => array(0x69),
  1024.         0x2112  => array(0x6C),
  1025.         0x2115  => array(0x6E),
  1026.         0x2116  => array(0x6E, 0x6F),
  1027.         0x2119  => array(0x70),
  1028.         0x211A  => array(0x71),
  1029.         0x211B  => array(0x72),
  1030.         0x211C  => array(0x72),
  1031.         0x211D  => array(0x72),
  1032.         0x2120  => array(0x73, 0x6D),
  1033.         0x2121  => array(0x74, 0x65, 0x6C),
  1034.         0x2122  => array(0x74, 0x6D),
  1035.         0x2124  => array(0x7A),
  1036.         0x2126  => array(0x3C9),
  1037.         0x2128  => array(0x7A),
  1038.         0x212A  => array(0x6B),
  1039.         0x212B  => array(0xE5),
  1040.         0x212C  => array(0x62),
  1041.         0x212D  => array(0x63),
  1042.         0x2130  => array(0x65),
  1043.         0x2131  => array(0x66),
  1044.         0x2133  => array(0x6D),
  1045.         0x213E  => array(0x3B3),
  1046.         0x213F  => array(0x3C0),
  1047.         0x2145  => array(0x64),
  1048.         0x2160  => array(0x2170),
  1049.         0x2161  => array(0x2171),
  1050.         0x2162  => array(0x2172),
  1051.         0x2163  => array(0x2173),
  1052.         0x2164  => array(0x2174),
  1053.         0x2165  => array(0x2175),
  1054.         0x2166  => array(0x2176),
  1055.         0x2167  => array(0x2177),
  1056.         0x2168  => array(0x2178),
  1057.         0x2169  => array(0x2179),
  1058.         0x216A  => array(0x217A),
  1059.         0x216B  => array(0x217B),
  1060.         0x216C  => array(0x217C),
  1061.         0x216D  => array(0x217D),
  1062.         0x216E  => array(0x217E),
  1063.         0x216F  => array(0x217F),
  1064.         0x24B6  => array(0x24D0),
  1065.         0x24B7  => array(0x24D1),
  1066.         0x24B8  => array(0x24D2),
  1067.         0x24B9  => array(0x24D3),
  1068.         0x24BA  => array(0x24D4),
  1069.         0x24BB  => array(0x24D5),
  1070.         0x24BC  => array(0x24D6),
  1071.         0x24BD  => array(0x24D7),
  1072.         0x24BE  => array(0x24D8),
  1073.         0x24BF  => array(0x24D9),
  1074.         0x24C0  => array(0x24DA),
  1075.         0x24C1  => array(0x24DB),
  1076.         0x24C2  => array(0x24DC),
  1077.         0x24C3  => array(0x24DD),
  1078.         0x24C4  => array(0x24DE),
  1079.         0x24C5  => array(0x24DF),
  1080.         0x24C6  => array(0x24E0),
  1081.         0x24C7  => array(0x24E1),
  1082.         0x24C8  => array(0x24E2),
  1083.         0x24C9  => array(0x24E3),
  1084.         0x24CA  => array(0x24E4),
  1085.         0x24CB  => array(0x24E5),
  1086.         0x24CC  => array(0x24E6),
  1087.         0x24CD  => array(0x24E7),
  1088.         0x24CE  => array(0x24E8),
  1089.         0x24CF  => array(0x24E9),
  1090.         0x3371  => array(0x68, 0x70, 0x61),
  1091.         0x3373  => array(0x61, 0x75),
  1092.         0x3375  => array(0x6F, 0x76),
  1093.         0x3380  => array(0x70, 0x61),
  1094.         0x3381  => array(0x6E, 0x61),
  1095.         0x3382  => array(0x3BC, 0x61),
  1096.         0x3383  => array(0x6D, 0x61),
  1097.         0x3384  => array(0x6B, 0x61),
  1098.         0x3385  => array(0x6B, 0x62),
  1099.         0x3386  => array(0x6D, 0x62),
  1100.         0x3387  => array(0x67, 0x62),
  1101.         0x338A  => array(0x70, 0x66),
  1102.         0x338B  => array(0x6E, 0x66),
  1103.         0x338C  => array(0x3BC, 0x66),
  1104.         0x3390  => array(0x68, 0x7A),
  1105.         0x3391  => array(0x6B, 0x68, 0x7A),
  1106.         0x3392  => array(0x6D, 0x68, 0x7A),
  1107.         0x3393  => array(0x67, 0x68, 0x7A),
  1108.         0x3394  => array(0x74, 0x68, 0x7A),
  1109.         0x33A9  => array(0x70, 0x61),
  1110.         0x33AA  => array(0x6B, 0x70, 0x61),
  1111.         0x33AB  => array(0x6D, 0x70, 0x61),
  1112.         0x33AC  => array(0x67, 0x70, 0x61),
  1113.         0x33B4  => array(0x70, 0x76),
  1114.         0x33B5  => array(0x6E, 0x76),
  1115.         0x33B6  => array(0x3BC, 0x76),
  1116.         0x33B7  => array(0x6D, 0x76),
  1117.         0x33B8  => array(0x6B, 0x76),
  1118.         0x33B9  => array(0x6D, 0x76),
  1119.         0x33BA  => array(0x70, 0x77),
  1120.         0x33BB  => array(0x6E, 0x77),
  1121.         0x33BC  => array(0x3BC, 0x77),
  1122.         0x33BD  => array(0x6D, 0x77),
  1123.         0x33BE  => array(0x6B, 0x77),
  1124.         0x33BF  => array(0x6D, 0x77),
  1125.         0x33C0  => array(0x6B, 0x3C9),
  1126.         0x33C1  => array(0x6D, 0x3C9), /*
  1127.         0x33C2  => array(0x61, 0x2E, 0x6D, 0x2E), */
  1128.         0x33C3  => array(0x62, 0x71),
  1129.         0x33C6  => array(0x63, 0x2215, 0x6B, 0x67),
  1130.         0x33C7  => array(0x63, 0x6F, 0x2E),
  1131.         0x33C8  => array(0x64, 0x62),
  1132.         0x33C9  => array(0x67, 0x79),
  1133.         0x33CB  => array(0x68, 0x70),
  1134.         0x33CD  => array(0x6B, 0x6B),
  1135.         0x33CE  => array(0x6B, 0x6D),
  1136.         0x33D7  => array(0x70, 0x68),
  1137.         0x33D9  => array(0x70, 0x70, 0x6D),
  1138.         0x33DA  => array(0x70, 0x72),
  1139.         0x33DC  => array(0x73, 0x76),
  1140.         0x33DD  => array(0x77, 0x62),
  1141.         0xFB00  => array(0x66, 0x66),
  1142.         0xFB01  => array(0x66, 0x69),
  1143.         0xFB02  => array(0x66, 0x6C),
  1144.         0xFB03  => array(0x66, 0x66, 0x69),
  1145.         0xFB04  => array(0x66, 0x66, 0x6C),
  1146.         0xFB05  => array(0x73, 0x74),
  1147.         0xFB06  => array(0x73, 0x74),
  1148.         0xFB13  => array(0x574, 0x576),
  1149.         0xFB14  => array(0x574, 0x565),
  1150.         0xFB15  => array(0x574, 0x56B),
  1151.         0xFB16  => array(0x57E, 0x576),
  1152.         0xFB17  => array(0x574, 0x56D),
  1153.         0xFF21  => array(0xFF41),
  1154.         0xFF22  => array(0xFF42),
  1155.         0xFF23  => array(0xFF43),
  1156.         0xFF24  => array(0xFF44),
  1157.         0xFF25  => array(0xFF45),
  1158.         0xFF26  => array(0xFF46),
  1159.         0xFF27  => array(0xFF47),
  1160.         0xFF28  => array(0xFF48),
  1161.         0xFF29  => array(0xFF49),
  1162.         0xFF2A  => array(0xFF4A),
  1163.         0xFF2B  => array(0xFF4B),
  1164.         0xFF2C  => array(0xFF4C),
  1165.         0xFF2D  => array(0xFF4D),
  1166.         0xFF2E  => array(0xFF4E),
  1167.         0xFF2F  => array(0xFF4F),
  1168.         0xFF30  => array(0xFF50),
  1169.         0xFF31  => array(0xFF51),
  1170.         0xFF32  => array(0xFF52),
  1171.         0xFF33  => array(0xFF53),
  1172.         0xFF34  => array(0xFF54),
  1173.         0xFF35  => array(0xFF55),
  1174.         0xFF36  => array(0xFF56),
  1175.         0xFF37  => array(0xFF57),
  1176.         0xFF38  => array(0xFF58),
  1177.         0xFF39  => array(0xFF59),
  1178.         0xFF3A  => array(0xFF5A),
  1179.         0x10400 => array(0x10428),
  1180.         0x10401 => array(0x10429),
  1181.         0x10402 => array(0x1042A),
  1182.         0x10403 => array(0x1042B),
  1183.         0x10404 => array(0x1042C),
  1184.         0x10405 => array(0x1042D),
  1185.         0x10406 => array(0x1042E),
  1186.         0x10407 => array(0x1042F),
  1187.         0x10408 => array(0x10430),
  1188.         0x10409 => array(0x10431),
  1189.         0x1040A => array(0x10432),
  1190.         0x1040B => array(0x10433),
  1191.         0x1040C => array(0x10434),
  1192.         0x1040D => array(0x10435),
  1193.         0x1040E => array(0x10436),
  1194.         0x1040F => array(0x10437),
  1195.         0x10410 => array(0x10438),
  1196.         0x10411 => array(0x10439),
  1197.         0x10412 => array(0x1043A),
  1198.         0x10413 => array(0x1043B),
  1199.         0x10414 => array(0x1043C),
  1200.         0x10415 => array(0x1043D),
  1201.         0x10416 => array(0x1043E),
  1202.         0x10417 => array(0x1043F),
  1203.         0x10418 => array(0x10440),
  1204.         0x10419 => array(0x10441),
  1205.         0x1041A => array(0x10442),
  1206.         0x1041B => array(0x10443),
  1207.         0x1041C => array(0x10444),
  1208.         0x1041D => array(0x10445),
  1209.         0x1041E => array(0x10446),
  1210.         0x1041F => array(0x10447),
  1211.         0x10420 => array(0x10448),
  1212.         0x10421 => array(0x10449),
  1213.         0x10422 => array(0x1044A),
  1214.         0x10423 => array(0x1044B),
  1215.         0x10424 => array(0x1044C),
  1216.         0x10425 => array(0x1044D),
  1217.         0x1D400 => array(0x61),
  1218.         0x1D401 => array(0x62),
  1219.         0x1D402 => array(0x63),
  1220.         0x1D403 => array(0x64),
  1221.         0x1D404 => array(0x65),
  1222.         0x1D405 => array(0x66),
  1223.         0x1D406 => array(0x67),
  1224.         0x1D407 => array(0x68),
  1225.         0x1D408 => array(0x69),
  1226.         0x1D409 => array(0x6A),
  1227.         0x1D40A => array(0x6B),
  1228.         0x1D40B => array(0x6C),
  1229.         0x1D40C => array(0x6D),
  1230.         0x1D40D => array(0x6E),
  1231.         0x1D40E => array(0x6F),
  1232.         0x1D40F => array(0x70),
  1233.         0x1D410 => array(0x71),
  1234.         0x1D411 => array(0x72),
  1235.         0x1D412 => array(0x73),
  1236.         0x1D413 => array(0x74),
  1237.         0x1D414 => array(0x75),
  1238.         0x1D415 => array(0x76),
  1239.         0x1D416 => array(0x77),
  1240.         0x1D417 => array(0x78),
  1241.         0x1D418 => array(0x79),
  1242.         0x1D419 => array(0x7A),
  1243.         0x1D434 => array(0x61),
  1244.         0x1D435 => array(0x62),
  1245.         0x1D436 => array(0x63),
  1246.         0x1D437 => array(0x64),
  1247.         0x1D438 => array(0x65),
  1248.         0x1D439 => array(0x66),
  1249.         0x1D43A => array(0x67),
  1250.         0x1D43B => array(0x68),
  1251.         0x1D43C => array(0x69),
  1252.         0x1D43D => array(0x6A),
  1253.         0x1D43E => array(0x6B),
  1254.         0x1D43F => array(0x6C),
  1255.         0x1D440 => array(0x6D),
  1256.         0x1D441 => array(0x6E),
  1257.         0x1D442 => array(0x6F),
  1258.         0x1D443 => array(0x70),
  1259.         0x1D444 => array(0x71),
  1260.         0x1D445 => array(0x72),
  1261.         0x1D446 => array(0x73),
  1262.         0x1D447 => array(0x74),
  1263.         0x1D448 => array(0x75),
  1264.         0x1D449 => array(0x76),
  1265.         0x1D44A => array(0x77),
  1266.         0x1D44B => array(0x78),
  1267.         0x1D44C => array(0x79),
  1268.         0x1D44D => array(0x7A),
  1269.         0x1D468 => array(0x61),
  1270.         0x1D469 => array(0x62),
  1271.         0x1D46A => array(0x63),
  1272.         0x1D46B => array(0x64),
  1273.         0x1D46C => array(0x65),
  1274.         0x1D46D => array(0x66),
  1275.         0x1D46E => array(0x67),
  1276.         0x1D46F => array(0x68),
  1277.         0x1D470 => array(0x69),
  1278.         0x1D471 => array(0x6A),
  1279.         0x1D472 => array(0x6B),
  1280.         0x1D473 => array(0x6C),
  1281.         0x1D474 => array(0x6D),
  1282.         0x1D475 => array(0x6E),
  1283.         0x1D476 => array(0x6F),
  1284.         0x1D477 => array(0x70),
  1285.         0x1D478 => array(0x71),
  1286.         0x1D479 => array(0x72),
  1287.         0x1D47A => array(0x73),
  1288.         0x1D47B => array(0x74),
  1289.         0x1D47C => array(0x75),
  1290.         0x1D47D => array(0x76),
  1291.         0x1D47E => array(0x77),
  1292.         0x1D47F => array(0x78),
  1293.         0x1D480 => array(0x79),
  1294.         0x1D481 => array(0x7A),
  1295.         0x1D49C => array(0x61),
  1296.         0x1D49E => array(0x63),
  1297.         0x1D49F => array(0x64),
  1298.         0x1D4A2 => array(0x67),
  1299.         0x1D4A5 => array(0x6A),
  1300.         0x1D4A6 => array(0x6B),
  1301.         0x1D4A9 => array(0x6E),
  1302.         0x1D4AA => array(0x6F),
  1303.         0x1D4AB => array(0x70),
  1304.         0x1D4AC => array(0x71),
  1305.         0x1D4AE => array(0x73),
  1306.         0x1D4AF => array(0x74),
  1307.         0x1D4B0 => array(0x75),
  1308.         0x1D4B1 => array(0x76),
  1309.         0x1D4B2 => array(0x77),
  1310.         0x1D4B3 => array(0x78),
  1311.         0x1D4B4 => array(0x79),
  1312.         0x1D4B5 => array(0x7A),
  1313.         0x1D4D0 => array(0x61),
  1314.         0x1D4D1 => array(0x62),
  1315.         0x1D4D2 => array(0x63),
  1316.         0x1D4D3 => array(0x64),
  1317.         0x1D4D4 => array(0x65),
  1318.         0x1D4D5 => array(0x66),
  1319.         0x1D4D6 => array(0x67),
  1320.         0x1D4D7 => array(0x68),
  1321.         0x1D4D8 => array(0x69),
  1322.         0x1D4D9 => array(0x6A),
  1323.         0x1D4DA => array(0x6B),
  1324.         0x1D4DB => array(0x6C),
  1325.         0x1D4DC => array(0x6D),
  1326.         0x1D4DD => array(0x6E),
  1327.         0x1D4DE => array(0x6F),
  1328.         0x1D4DF => array(0x70),
  1329.         0x1D4E0 => array(0x71),
  1330.         0x1D4E1 => array(0x72),
  1331.         0x1D4E2 => array(0x73),
  1332.         0x1D4E3 => array(0x74),
  1333.         0x1D4E4 => array(0x75),
  1334.         0x1D4E5 => array(0x76),
  1335.         0x1D4E6 => array(0x77),
  1336.         0x1D4E7 => array(0x78),
  1337.         0x1D4E8 => array(0x79),
  1338.         0x1D4E9 => array(0x7A),
  1339.         0x1D504 => array(0x61),
  1340.         0x1D505 => array(0x62),
  1341.         0x1D507 => array(0x64),
  1342.         0x1D508 => array(0x65),
  1343.         0x1D509 => array(0x66),
  1344.         0x1D50A => array(0x67),
  1345.         0x1D50D => array(0x6A),
  1346.         0x1D50E => array(0x6B),
  1347.         0x1D50F => array(0x6C),
  1348.         0x1D510 => array(0x6D),
  1349.         0x1D511 => array(0x6E),
  1350.         0x1D512 => array(0x6F),
  1351.         0x1D513 => array(0x70),
  1352.         0x1D514 => array(0x71),
  1353.         0x1D516 => array(0x73),
  1354.         0x1D517 => array(0x74),
  1355.         0x1D518 => array(0x75),
  1356.         0x1D519 => array(0x76),
  1357.         0x1D51A => array(0x77),
  1358.         0x1D51B => array(0x78),
  1359.         0x1D51C => array(0x79),
  1360.         0x1D538 => array(0x61),
  1361.         0x1D539 => array(0x62),
  1362.         0x1D53B => array(0x64),
  1363.         0x1D53C => array(0x65),
  1364.         0x1D53D => array(0x66),
  1365.         0x1D53E => array(0x67),
  1366.         0x1D540 => array(0x69),
  1367.         0x1D541 => array(0x6A),
  1368.         0x1D542 => array(0x6B),
  1369.         0x1D543 => array(0x6C),
  1370.         0x1D544 => array(0x6D),
  1371.         0x1D546 => array(0x6F),
  1372.         0x1D54A => array(0x73),
  1373.         0x1D54B => array(0x74),
  1374.         0x1D54C => array(0x75),
  1375.         0x1D54D => array(0x76),
  1376.         0x1D54E => array(0x77),
  1377.         0x1D54F => array(0x78),
  1378.         0x1D550 => array(0x79),
  1379.         0x1D56C => array(0x61),
  1380.         0x1D56D => array(0x62),
  1381.         0x1D56E => array(0x63),
  1382.         0x1D56F => array(0x64),
  1383.         0x1D570 => array(0x65),
  1384.         0x1D571 => array(0x66),
  1385.         0x1D572 => array(0x67),
  1386.         0x1D573 => array(0x68),
  1387.         0x1D574 => array(0x69),
  1388.         0x1D575 => array(0x6A),
  1389.         0x1D576 => array(0x6B),
  1390.         0x1D577 => array(0x6C),
  1391.         0x1D578 => array(0x6D),
  1392.         0x1D579 => array(0x6E),
  1393.         0x1D57A => array(0x6F),
  1394.         0x1D57B => array(0x70),
  1395.         0x1D57C => array(0x71),
  1396.         0x1D57D => array(0x72),
  1397.         0x1D57E => array(0x73),
  1398.         0x1D57F => array(0x74),
  1399.         0x1D580 => array(0x75),
  1400.         0x1D581 => array(0x76),
  1401.         0x1D582 => array(0x77),
  1402.         0x1D583 => array(0x78),
  1403.         0x1D584 => array(0x79),
  1404.         0x1D585 => array(0x7A),
  1405.         0x1D5A0 => array(0x61),
  1406.         0x1D5A1 => array(0x62),
  1407.         0x1D5A2 => array(0x63),
  1408.         0x1D5A3 => array(0x64),
  1409.         0x1D5A4 => array(0x65),
  1410.         0x1D5A5 => array(0x66),
  1411.         0x1D5A6 => array(0x67),
  1412.         0x1D5A7 => array(0x68),
  1413.         0x1D5A8 => array(0x69),
  1414.         0x1D5A9 => array(0x6A),
  1415.         0x1D5AA => array(0x6B),
  1416.         0x1D5AB => array(0x6C),
  1417.         0x1D5AC => array(0x6D),
  1418.         0x1D5AD => array(0x6E),
  1419.         0x1D5AE => array(0x6F),
  1420.         0x1D5AF => array(0x70),
  1421.         0x1D5B0 => array(0x71),
  1422.         0x1D5B1 => array(0x72),
  1423.         0x1D5B2 => array(0x73),
  1424.         0x1D5B3 => array(0x74),
  1425.         0x1D5B4 => array(0x75),
  1426.         0x1D5B5 => array(0x76),
  1427.         0x1D5B6 => array(0x77),
  1428.         0x1D5B7 => array(0x78),
  1429.         0x1D5B8 => array(0x79),
  1430.         0x1D5B9 => array(0x7A),
  1431.         0x1D5D4 => array(0x61),
  1432.         0x1D5D5 => array(0x62),
  1433.         0x1D5D6 => array(0x63),
  1434.         0x1D5D7 => array(0x64),
  1435.         0x1D5D8 => array(0x65),
  1436.         0x1D5D9 => array(0x66),
  1437.         0x1D5DA => array(0x67),
  1438.         0x1D5DB => array(0x68),
  1439.         0x1D5DC => array(0x69),
  1440.         0x1D5DD => array(0x6A),
  1441.         0x1D5DE => array(0x6B),
  1442.         0x1D5DF => array(0x6C),
  1443.         0x1D5E0 => array(0x6D),
  1444.         0x1D5E1 => array(0x6E),
  1445.         0x1D5E2 => array(0x6F),
  1446.         0x1D5E3 => array(0x70),
  1447.         0x1D5E4 => array(0x71),
  1448.         0x1D5E5 => array(0x72),
  1449.         0x1D5E6 => array(0x73),
  1450.         0x1D5E7 => array(0x74),
  1451.         0x1D5E8 => array(0x75),
  1452.         0x1D5E9 => array(0x76),
  1453.         0x1D5EA => array(0x77),
  1454.         0x1D5EB => array(0x78),
  1455.         0x1D5EC => array(0x79),
  1456.         0x1D5ED => array(0x7A),
  1457.         0x1D608 => array(0x61),
  1458.         0x1D609 => array(0x62),
  1459.         0x1D60A => array(0x63),
  1460.         0x1D60B => array(0x64),
  1461.         0x1D60C => array(0x65),
  1462.         0x1D60D => array(0x66),
  1463.         0x1D60E => array(0x67),
  1464.         0x1D60F => array(0x68),
  1465.         0x1D610 => array(0x69),
  1466.         0x1D611 => array(0x6A),
  1467.         0x1D612 => array(0x6B),
  1468.         0x1D613 => array(0x6C),
  1469.         0x1D614 => array(0x6D),
  1470.         0x1D615 => array(0x6E),
  1471.         0x1D616 => array(0x6F),
  1472.         0x1D617 => array(0x70),
  1473.         0x1D618 => array(0x71),
  1474.         0x1D619 => array(0x72),
  1475.         0x1D61A => array(0x73),
  1476.         0x1D61B => array(0x74),
  1477.         0x1D61C => array(0x75),
  1478.         0x1D61D => array(0x76),
  1479.         0x1D61E => array(0x77),
  1480.         0x1D61F => array(0x78),
  1481.         0x1D620 => array(0x79),
  1482.         0x1D621 => array(0x7A),
  1483.         0x1D63C => array(0x61),
  1484.         0x1D63D => array(0x62),
  1485.         0x1D63E => array(0x63),
  1486.         0x1D63F => array(0x64),
  1487.         0x1D640 => array(0x65),
  1488.         0x1D641 => array(0x66),
  1489.         0x1D642 => array(0x67),
  1490.         0x1D643 => array(0x68),
  1491.         0x1D644 => array(0x69),
  1492.         0x1D645 => array(0x6A),
  1493.         0x1D646 => array(0x6B),
  1494.         0x1D647 => array(0x6C),
  1495.         0x1D648 => array(0x6D),
  1496.         0x1D649 => array(0x6E),
  1497.         0x1D64A => array(0x6F),
  1498.         0x1D64B => array(0x70),
  1499.         0x1D64C => array(0x71),
  1500.         0x1D64D => array(0x72),
  1501.         0x1D64E => array(0x73),
  1502.         0x1D64F => array(0x74),
  1503.         0x1D650 => array(0x75),
  1504.         0x1D651 => array(0x76),
  1505.         0x1D652 => array(0x77),
  1506.         0x1D653 => array(0x78),
  1507.         0x1D654 => array(0x79),
  1508.         0x1D655 => array(0x7A),
  1509.         0x1D670 => array(0x61),
  1510.         0x1D671 => array(0x62),
  1511.         0x1D672 => array(0x63),
  1512.         0x1D673 => array(0x64),
  1513.         0x1D674 => array(0x65),
  1514.         0x1D675 => array(0x66),
  1515.         0x1D676 => array(0x67),
  1516.         0x1D677 => array(0x68),
  1517.         0x1D678 => array(0x69),
  1518.         0x1D679 => array(0x6A),
  1519.         0x1D67A => array(0x6B),
  1520.         0x1D67B => array(0x6C),
  1521.         0x1D67C => array(0x6D),
  1522.         0x1D67D => array(0x6E),
  1523.         0x1D67E => array(0x6F),
  1524.         0x1D67F => array(0x70),
  1525.         0x1D680 => array(0x71),
  1526.         0x1D681 => array(0x72),
  1527.         0x1D682 => array(0x73),
  1528.         0x1D683 => array(0x74),
  1529.         0x1D684 => array(0x75),
  1530.         0x1D685 => array(0x76),
  1531.         0x1D686 => array(0x77),
  1532.         0x1D687 => array(0x78),
  1533.         0x1D688 => array(0x79),
  1534.         0x1D689 => array(0x7A),
  1535.         0x1D6A8 => array(0x3B1),
  1536.         0x1D6A9 => array(0x3B2),
  1537.         0x1D6AA => array(0x3B3),
  1538.         0x1D6AB => array(0x3B4),
  1539.         0x1D6AC => array(0x3B5),
  1540.         0x1D6AD => array(0x3B6),
  1541.         0x1D6AE => array(0x3B7),
  1542.         0x1D6AF => array(0x3B8),
  1543.         0x1D6B0 => array(0x3B9),
  1544.         0x1D6B1 => array(0x3BA),
  1545.         0x1D6B2 => array(0x3BB),
  1546.         0x1D6B3 => array(0x3BC),
  1547.         0x1D6B4 => array(0x3BD),
  1548.         0x1D6B5 => array(0x3BE),
  1549.         0x1D6B6 => array(0x3BF),
  1550.         0x1D6B7 => array(0x3C0),
  1551.         0x1D6B8 => array(0x3C1),
  1552.         0x1D6B9 => array(0x3B8),
  1553.         0x1D6BA => array(0x3C3),
  1554.         0x1D6BB => array(0x3C4),
  1555.         0x1D6BC => array(0x3C5),
  1556.         0x1D6BD => array(0x3C6),
  1557.         0x1D6BE => array(0x3C7),
  1558.         0x1D6BF => array(0x3C8),
  1559.         0x1D6C0 => array(0x3C9),
  1560.         0x1D6D3 => array(0x3C3),
  1561.         0x1D6E2 => array(0x3B1),
  1562.         0x1D6E3 => array(0x3B2),
  1563.         0x1D6E4 => array(0x3B3),
  1564.         0x1D6E5 => array(0x3B4),
  1565.         0x1D6E6 => array(0x3B5),
  1566.         0x1D6E7 => array(0x3B6),
  1567.         0x1D6E8 => array(0x3B7),
  1568.         0x1D6E9 => array(0x3B8),
  1569.         0x1D6EA => array(0x3B9),
  1570.         0x1D6EB => array(0x3BA),
  1571.         0x1D6EC => array(0x3BB),
  1572.         0x1D6ED => array(0x3BC),
  1573.         0x1D6EE => array(0x3BD),
  1574.         0x1D6EF => array(0x3BE),
  1575.         0x1D6F0 => array(0x3BF),
  1576.         0x1D6F1 => array(0x3C0),
  1577.         0x1D6F2 => array(0x3C1),
  1578.         0x1D6F3 => array(0x3B8),
  1579.         0x1D6F4 => array(0x3C3),
  1580.         0x1D6F5 => array(0x3C4),
  1581.         0x1D6F6 => array(0x3C5),
  1582.         0x1D6F7 => array(0x3C6),
  1583.         0x1D6F8 => array(0x3C7),
  1584.         0x1D6F9 => array(0x3C8),
  1585.         0x1D6FA => array(0x3C9),
  1586.         0x1D70D => array(0x3C3),
  1587.         0x1D71C => array(0x3B1),
  1588.         0x1D71D => array(0x3B2),
  1589.         0x1D71E => array(0x3B3),
  1590.         0x1D71F => array(0x3B4),
  1591.         0x1D720 => array(0x3B5),
  1592.         0x1D721 => array(0x3B6),
  1593.         0x1D722 => array(0x3B7),
  1594.         0x1D723 => array(0x3B8),
  1595.         0x1D724 => array(0x3B9),
  1596.         0x1D725 => array(0x3BA),
  1597.         0x1D726 => array(0x3BB),
  1598.         0x1D727 => array(0x3BC),
  1599.         0x1D728 => array(0x3BD),
  1600.         0x1D729 => array(0x3BE),
  1601.         0x1D72A => array(0x3BF),
  1602.         0x1D72B => array(0x3C0),
  1603.         0x1D72C => array(0x3C1),
  1604.         0x1D72D => array(0x3B8),
  1605.         0x1D72E => array(0x3C3),
  1606.         0x1D72F => array(0x3C4),
  1607.         0x1D730 => array(0x3C5),
  1608.         0x1D731 => array(0x3C6),
  1609.         0x1D732 => array(0x3C7),
  1610.         0x1D733 => array(0x3C8),
  1611.         0x1D734 => array(0x3C9),
  1612.         0x1D747 => array(0x3C3),
  1613.         0x1D756 => array(0x3B1),
  1614.         0x1D757 => array(0x3B2),
  1615.         0x1D758 => array(0x3B3),
  1616.         0x1D759 => array(0x3B4),
  1617.         0x1D75A => array(0x3B5),
  1618.         0x1D75B => array(0x3B6),
  1619.         0x1D75C => array(0x3B7),
  1620.         0x1D75D => array(0x3B8),
  1621.         0x1D75E => array(0x3B9),
  1622.         0x1D75F => array(0x3BA),
  1623.         0x1D760 => array(0x3BB),
  1624.         0x1D761 => array(0x3BC),
  1625.         0x1D762 => array(0x3BD),
  1626.         0x1D763 => array(0x3BE),
  1627.         0x1D764 => array(0x3BF),
  1628.         0x1D765 => array(0x3C0),
  1629.         0x1D766 => array(0x3C1),
  1630.         0x1D767 => array(0x3B8),
  1631.         0x1D768 => array(0x3C3),
  1632.         0x1D769 => array(0x3C4),
  1633.         0x1D76A => array(0x3C5),
  1634.         0x1D76B => array(0x3C6),
  1635.         0x1D76C => array(0x3C7),
  1636.         0x1D76D => array(0x3C8),
  1637.         0x1D76E => array(0x3C9),
  1638.         0x1D781 => array(0x3C3),
  1639.         0x1D790 => array(0x3B1),
  1640.         0x1D791 => array(0x3B2),
  1641.         0x1D792 => array(0x3B3),
  1642.         0x1D793 => array(0x3B4),
  1643.         0x1D794 => array(0x3B5),
  1644.         0x1D795 => array(0x3B6),
  1645.         0x1D796 => array(0x3B7),
  1646.         0x1D797 => array(0x3B8),
  1647.         0x1D798 => array(0x3B9),
  1648.         0x1D799 => array(0x3BA),
  1649.         0x1D79A => array(0x3BB),
  1650.         0x1D79B => array(0x3BC),
  1651.         0x1D79C => array(0x3BD),
  1652.         0x1D79D => array(0x3BE),
  1653.         0x1D79E => array(0x3BF),
  1654.         0x1D79F => array(0x3C0),
  1655.         0x1D7A0 => array(0x3C1),
  1656.         0x1D7A1 => array(0x3B8),
  1657.         0x1D7A2 => array(0x3C3),
  1658.         0x1D7A3 => array(0x3C4),
  1659.         0x1D7A4 => array(0x3C5),
  1660.         0x1D7A5 => array(0x3C6),
  1661.         0x1D7A6 => array(0x3C7),
  1662.         0x1D7A7 => array(0x3C8),
  1663.         0x1D7A8 => array(0x3C9),
  1664.         0x1D7BB => array(0x3C3),
  1665.         0x3F9   => array(0x3C3),
  1666.         0x1D2C  => array(0x61),
  1667.         0x1D2D  => array(0xE6),
  1668.         0x1D2E  => array(0x62),
  1669.         0x1D30  => array(0x64),
  1670.         0x1D31  => array(0x65),
  1671.         0x1D32  => array(0x1DD),
  1672.         0x1D33  => array(0x67),
  1673.         0x1D34  => array(0x68),
  1674.         0x1D35  => array(0x69),
  1675.         0x1D36  => array(0x6A),
  1676.         0x1D37  => array(0x6B),
  1677.         0x1D38  => array(0x6C),
  1678.         0x1D39  => array(0x6D),
  1679.         0x1D3A  => array(0x6E),
  1680.         0x1D3C  => array(0x6F),
  1681.         0x1D3D  => array(0x223),
  1682.         0x1D3E  => array(0x70),
  1683.         0x1D3F  => array(0x72),
  1684.         0x1D40  => array(0x74),
  1685.         0x1D41  => array(0x75),
  1686.         0x1D42  => array(0x77),
  1687.         0x213B  => array(0x66, 0x61, 0x78),
  1688.         0x3250  => array(0x70, 0x74, 0x65),
  1689.         0x32CC  => array(0x68, 0x67),
  1690.         0x32CE  => array(0x65, 0x76),
  1691.         0x32CF  => array(0x6C, 0x74, 0x64),
  1692.         0x337A  => array(0x69, 0x75),
  1693.         0x33DE  => array(0x76, 0x2215, 0x6D),
  1694.         0x33DF  => array(0x61, 0x2215, 0x6D)
  1695.     );
  1696.  
  1697.     /**
  1698.      * Normalization Combining Classes; Code Points not listed
  1699.      * got Combining Class 0.
  1700.      *
  1701.      * @static
  1702.      * @var array
  1703.      * @access private
  1704.      */
  1705.     var $_np_norm_combcls = array(
  1706.         0x334   => 1,
  1707.         0x335   => 1,
  1708.         0x336   => 1,
  1709.         0x337   => 1,
  1710.         0x338   => 1,
  1711.         0x93C   => 7,
  1712.         0x9BC   => 7,
  1713.         0xA3C   => 7,
  1714.         0xABC   => 7,
  1715.         0xB3C   => 7,
  1716.         0xCBC   => 7,
  1717.         0x1037  => 7,
  1718.         0x3099  => 8,
  1719.         0x309A  => 8,
  1720.         0x94D   => 9,
  1721.         0x9CD   => 9,
  1722.         0xA4D   => 9,
  1723.         0xACD   => 9,
  1724.         0xB4D   => 9,
  1725.         0xBCD   => 9,
  1726.         0xC4D   => 9,
  1727.         0xCCD   => 9,
  1728.         0xD4D   => 9,
  1729.         0xDCA   => 9,
  1730.         0xE3A   => 9,
  1731.         0xF84   => 9,
  1732.         0x1039  => 9,
  1733.         0x1714  => 9,
  1734.         0x1734  => 9,
  1735.         0x17D2  => 9,
  1736.         0x5B0   => 10,
  1737.         0x5B1   => 11,
  1738.         0x5B2   => 12,
  1739.         0x5B3   => 13,
  1740.         0x5B4   => 14,
  1741.         0x5B5   => 15,
  1742.         0x5B6   => 16,
  1743.         0x5B7   => 17,
  1744.         0x5B8   => 18,
  1745.         0x5B9   => 19,
  1746.         0x5BB   => 20,
  1747.         0x5Bc   => 21,
  1748.         0x5BD   => 22,
  1749.         0x5BF   => 23,
  1750.         0x5C1   => 24,
  1751.         0x5C2   => 25,
  1752.         0xFB1E  => 26,
  1753.         0x64B   => 27,
  1754.         0x64C   => 28,
  1755.         0x64D   => 29,
  1756.         0x64E   => 30,
  1757.         0x64F   => 31,
  1758.         0x650   => 32,
  1759.         0x651   => 33,
  1760.         0x652   => 34,
  1761.         0x670   => 35,
  1762.         0x711   => 36,
  1763.         0xC55   => 84,
  1764.         0xC56   => 91,
  1765.         0xE38   => 103,
  1766.         0xE39   => 103,
  1767.         0xE48   => 107,
  1768.         0xE49   => 107,
  1769.         0xE4A   => 107,
  1770.         0xE4B   => 107,
  1771.         0xEB8   => 118,
  1772.         0xEB9   => 118,
  1773.         0xEC8   => 122,
  1774.         0xEC9   => 122,
  1775.         0xECA   => 122,
  1776.         0xECB   => 122,
  1777.         0xF71   => 129,
  1778.         0xF72   => 130,
  1779.         0xF7A   => 130,
  1780.         0xF7B   => 130,
  1781.         0xF7C   => 130,
  1782.         0xF7D   => 130,
  1783.         0xF80   => 130,
  1784.         0xF74   => 132,
  1785.         0x321   => 202,
  1786.         0x322   => 202,
  1787.         0x327   => 202,
  1788.         0x328   => 202,
  1789.         0x31B   => 216,
  1790.         0xF39   => 216,
  1791.         0x1D165 => 216,
  1792.         0x1D166 => 216,
  1793.         0x1D16E => 216,
  1794.         0x1D16F => 216,
  1795.         0x1D170 => 216,
  1796.         0x1D171 => 216,
  1797.         0x1D172 => 216,
  1798.         0x302A  => 218,
  1799.         0x316   => 220,
  1800.         0x317   => 220,
  1801.         0x318   => 220,
  1802.         0x319   => 220,
  1803.         0x31C   => 220,
  1804.         0x31D   => 220,
  1805.         0x31E   => 220,
  1806.         0x31F   => 220,
  1807.         0x320   => 220,
  1808.         0x323   => 220,
  1809.         0x324   => 220,
  1810.         0x325   => 220,
  1811.         0x326   => 220,
  1812.         0x329   => 220,
  1813.         0x32A   => 220,
  1814.         0x32B   => 220,
  1815.         0x32C   => 220,
  1816.         0x32D   => 220,
  1817.         0x32E   => 220,
  1818.         0x32F   => 220,
  1819.         0x330   => 220,
  1820.         0x331   => 220,
  1821.         0x332   => 220,
  1822.         0x333   => 220,
  1823.         0x339   => 220,
  1824.         0x33A   => 220,
  1825.         0x33B   => 220,
  1826.         0x33C   => 220,
  1827.         0x347   => 220,
  1828.         0x348   => 220,
  1829.         0x349   => 220,
  1830.         0x34D   => 220,
  1831.         0x34E   => 220,
  1832.         0x353   => 220,
  1833.         0x354   => 220,
  1834.         0x355   => 220,
  1835.         0x356   => 220,
  1836.         0x591   => 220,
  1837.         0x596   => 220,
  1838.         0x59B   => 220,
  1839.         0x5A3   => 220,
  1840.         0x5A4   => 220,
  1841.         0x5A5   => 220,
  1842.         0x5A6   => 220,
  1843.         0x5A7   => 220,
  1844.         0x5AA   => 220,
  1845.         0x655   => 220,
  1846.         0x656   => 220,
  1847.         0x6E3   => 220,
  1848.         0x6EA   => 220,
  1849.         0x6ED   => 220,
  1850.         0x731   => 220,
  1851.         0x734   => 220,
  1852.         0x737   => 220,
  1853.         0x738   => 220,
  1854.         0x739   => 220,
  1855.         0x73B   => 220,
  1856.         0x73C   => 220,
  1857.         0x73E   => 220,
  1858.         0x742   => 220,
  1859.         0x744   => 220,
  1860.         0x746   => 220,
  1861.         0x748   => 220,
  1862.         0x952   => 220,
  1863.         0xF18   => 220,
  1864.         0xF19   => 220,
  1865.         0xF35   => 220,
  1866.         0xF37   => 220,
  1867.         0xFC6   => 220,
  1868.         0x193B  => 220,
  1869.         0x20E8  => 220,
  1870.         0x1D17B => 220,
  1871.         0x1D17C => 220,
  1872.         0x1D17D => 220,
  1873.         0x1D17E => 220,
  1874.         0x1D17F => 220,
  1875.         0x1D180 => 220,
  1876.         0x1D181 => 220,
  1877.         0x1D182 => 220,
  1878.         0x1D18A => 220,
  1879.         0x1D18B => 220,
  1880.         0x59A   => 222,
  1881.         0x5AD   => 222,
  1882.         0x1929  => 222,
  1883.         0x302D  => 222,
  1884.         0x302E  => 224,
  1885.         0x302F  => 224,
  1886.         0x1D16D => 226,
  1887.         0x5AE   => 228,
  1888.         0x18A9  => 228,
  1889.         0x302B  => 228,
  1890.         0x300   => 230,
  1891.         0x301   => 230,
  1892.         0x302   => 230,
  1893.         0x303   => 230,
  1894.         0x304   => 230,
  1895.         0x305   => 230,
  1896.         0x306   => 230,
  1897.         0x307   => 230,
  1898.         0x308   => 230,
  1899.         0x309   => 230,
  1900.         0x30A   => 230,
  1901.         0x30B   => 230,
  1902.         0x30C   => 230,
  1903.         0x30D   => 230,
  1904.         0x30E   => 230,
  1905.         0x30F   => 230,
  1906.         0x310   => 230,
  1907.         0x311   => 230,
  1908.         0x312   => 230,
  1909.         0x313   => 230,
  1910.         0x314   => 230,
  1911.         0x33D   => 230,
  1912.         0x33E   => 230,
  1913.         0x33F   => 230,
  1914.         0x340   => 230,
  1915.         0x341   => 230,
  1916.         0x342   => 230,
  1917.         0x343   => 230,
  1918.         0x344   => 230,
  1919.         0x346   => 230,
  1920.         0x34A   => 230,
  1921.         0x34B   => 230,
  1922.         0x34C   => 230,
  1923.         0x350   => 230,
  1924.         0x351   => 230,
  1925.         0x352   => 230,
  1926.         0x357   => 230,
  1927.         0x363   => 230,
  1928.         0x364   => 230,
  1929.         0x365   => 230,
  1930.         0x366   => 230,
  1931.         0x367   => 230,
  1932.         0x368   => 230,
  1933.         0x369   => 230,
  1934.         0x36A   => 230,
  1935.         0x36B   => 230,
  1936.         0x36C   => 230,
  1937.         0x36D   => 230,
  1938.         0x36E   => 230,
  1939.         0x36F   => 230,
  1940.         0x483   => 230,
  1941.         0x484   => 230,
  1942.         0x485   => 230,
  1943.         0x486   => 230,
  1944.         0x592   => 230,
  1945.         0x593   => 230,
  1946.         0x594   => 230,
  1947.         0x595   => 230,
  1948.         0x597   => 230,
  1949.         0x598   => 230,
  1950.         0x599   => 230,
  1951.         0x59C   => 230,
  1952.         0x59D   => 230,
  1953.         0x59E   => 230,
  1954.         0x59F   => 230,
  1955.         0x5A0   => 230,
  1956.         0x5A1   => 230,
  1957.         0x5A8   => 230,
  1958.         0x5A9   => 230,
  1959.         0x5AB   => 230,
  1960.         0x5AC   => 230,
  1961.         0x5AF   => 230,
  1962.         0x5C4   => 230,
  1963.         0x610   => 230,
  1964.         0x611   => 230,
  1965.         0x612   => 230,
  1966.         0x613   => 230,
  1967.         0x614   => 230,
  1968.         0x615   => 230,
  1969.         0x653   => 230,
  1970.         0x654   => 230,
  1971.         0x657   => 230,
  1972.         0x658   => 230,
  1973.         0x6D6   => 230,
  1974.         0x6D7   => 230,
  1975.         0x6D8   => 230,
  1976.         0x6D9   => 230,
  1977.         0x6DA   => 230,
  1978.         0x6DB   => 230,
  1979.         0x6DC   => 230,
  1980.         0x6DF   => 230,
  1981.         0x6E0   => 230,
  1982.         0x6E1   => 230,
  1983.         0x6E2   => 230,
  1984.         0x6E4   => 230,
  1985.         0x6E7   => 230,
  1986.         0x6E8   => 230,
  1987.         0x6EB   => 230,
  1988.         0x6EC   => 230,
  1989.         0x730   => 230,
  1990.         0x732   => 230,
  1991.         0x733   => 230,
  1992.         0x735   => 230,
  1993.         0x736   => 230,
  1994.         0x73A   => 230,
  1995.         0x73D   => 230,
  1996.         0x73F   => 230,
  1997.         0x740   => 230,
  1998.         0x741   => 230,
  1999.         0x743   => 230,
  2000.         0x745   => 230,
  2001.         0x747   => 230,
  2002.         0x749   => 230,
  2003.         0x74A   => 230,
  2004.         0x951   => 230,
  2005.         0x953   => 230,
  2006.         0x954   => 230,
  2007.         0xF82   => 230,
  2008.         0xF83   => 230,
  2009.         0xF86   => 230,
  2010.         0xF87   => 230,
  2011.         0x170D  => 230,
  2012.         0x193A  => 230,
  2013.         0x20D0  => 230,
  2014.         0x20D1  => 230,
  2015.         0x20D4  => 230,
  2016.         0x20D5  => 230,
  2017.         0x20D6  => 230,
  2018.         0x20D7  => 230,
  2019.         0x20DB  => 230,
  2020.         0x20DC  => 230,
  2021.         0x20E1  => 230,
  2022.         0x20E7  => 230,
  2023.         0x20E9  => 230,
  2024.         0xFE20  => 230,
  2025.         0xFE21  => 230,
  2026.         0xFE22  => 230,
  2027.         0xFE23  => 230,
  2028.         0x1D185 => 230,
  2029.         0x1D186 => 230,
  2030.         0x1D187 => 230,
  2031.         0x1D189 => 230,
  2032.         0x1D188 => 230,
  2033.         0x1D1AA => 230,
  2034.         0x1D1AB => 230,
  2035.         0x1D1AC => 230,
  2036.         0x1D1AD => 230,
  2037.         0x315   => 232,
  2038.         0x31A   => 232,
  2039.         0x302C  => 232,
  2040.         0x35F   => 233,
  2041.         0x362   => 233,
  2042.         0x35D   => 234,
  2043.         0x35E   => 234,
  2044.         0x360   => 234,
  2045.         0x361   => 234,
  2046.         0x345   => 240
  2047.     );
  2048.     // }}}
  2049.  
  2050.  
  2051.     // Internal settings, do not mess with them
  2052.     var $_punycode_prefix = 'xn--';
  2053.     var $_invalid_ucs =     0x80000000;
  2054.     var $_max_ucs =         0x10FFFF;
  2055.     var $_base =            36;
  2056.     var $_tmin =            1;
  2057.     var $_tmax =            26;
  2058.     var $_skew =            38;
  2059.     var $_damp =            700;
  2060.     var $_initial_bias =    72;
  2061.     var $_initial_n =       0x80;
  2062.     var $_sbase =           0xAC00;
  2063.     var $_lbase =           0x1100;
  2064.     var $_vbase =           0x1161;
  2065.     var $_tbase =           0x11a7;
  2066.     var $_lcount =          19;
  2067.     var $_vcount =          21;
  2068.     var $_tcount =          28;
  2069.     var $_ncount =          588;   // _vcount * _tcount
  2070.     var $_scount =          11172; // _lcount * _tcount * _vcount
  2071.     var $_error =           false;
  2072.  
  2073.     // See set_parameter() for details of how to change the following settings
  2074.     // from within your script / application
  2075.     var $_api_encoding   =  'utf8'; // Default input charset is UTF-8
  2076.     var $_allow_overlong =  false;  // Overlong UTF-8 encodings are forbidden
  2077.     var $_strict_mode    =  false;  // Behave strict or not
  2078.  
  2079.     // The constructor
  2080.     function Net_IDNA_php4($options = false)
  2081.     {
  2082.         $this->slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount;
  2083.         // If parameters are given, pass these to the respective method
  2084.         if (is_array($options)) {
  2085.             return $this->set_parameter($options);
  2086.         }
  2087.         return true;
  2088.     }
  2089.  
  2090.     /**
  2091.     * Sets a new option value. Available options and values:
  2092.     * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8,
  2093.     *         'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8]
  2094.     * [overlong - Unicode does not allow unnecessarily long encodings of chars,
  2095.     *             to allow this, set this parameter to true, else to false;
  2096.     *             default is false.]
  2097.     * [strict - true: strict mode, good for registration purposes - Causes errors
  2098.     *           on failures; false: loose mode, ideal for "wildlife" applications
  2099.     *           by silently ignoring errors and returning the original input instead
  2100.     *
  2101.     * @param    mixed     Parameter to set (string: single parameter; array of Parameter => Value pairs)
  2102.     * @param    string    Value to use (if parameter 1 is a string)
  2103.     * @return   boolean   true on success, false otherwise
  2104.     * @access   public
  2105.     */
  2106.     function set_parameter($option, $value = false)
  2107.     {
  2108.         if (!is_array($option)) {
  2109.             $option = array($option => $value);
  2110.         }
  2111.         foreach ($option as $k => $v) {
  2112.             switch ($k) {
  2113.             case 'encoding':
  2114.                 switch ($v) {
  2115.                 case 'utf8':
  2116.                 case 'ucs4_string':
  2117.                 case 'ucs4_array':
  2118.                     $this->_api_encoding = $v;
  2119.                     break;
  2120.                 default:
  2121.                     $this->_error('Set Parameter: Unknown parameter '.$v.' for option '.$k);
  2122.                     return false;
  2123.                 }
  2124.                 break;
  2125.             case 'overlong':
  2126.                 $this->_allow_overlong = ($v) ? true : false;
  2127.                 break;
  2128.             case 'strict':
  2129.                 $this->_strict_mode = ($v) ? true : false;
  2130.                 break;
  2131.             default:
  2132.                 $this->_error('Set Parameter: Unknown option '.$k);
  2133.                 return false;
  2134.             }
  2135.         }
  2136.         return true;
  2137.     }
  2138.  
  2139.     /**
  2140.     * Decode a given ACE domain name
  2141.     * @param    string   Domain name (ACE string)
  2142.     * [@param    string   Desired output encoding, see {@link set_parameter}]
  2143.     * @return   string   Decoded Domain name (UTF-8 or UCS-4)
  2144.     * @access   public
  2145.     */
  2146.     function decode($input, $one_time_encoding = false)
  2147.     {
  2148.         // Optionally set
  2149.         if ($one_time_encoding) {
  2150.             switch ($one_time_encoding) {
  2151.             case 'utf8':
  2152.             case 'ucs4_string':
  2153.             case 'ucs4_array':
  2154.                 break;
  2155.             default:
  2156.                 $this->_error('Unknown encoding '.$one_time_encoding);
  2157.                 return false;
  2158.             }
  2159.         }
  2160.         // Make sure to drop any newline characters around
  2161.         $input = trim($input);
  2162.  
  2163.         // Negotiate input and try to determine, wether it is a plain string,
  2164.         // an email address or something like a complete URL
  2165.         if (strpos($input, '@')) { // Maybe it is an email address
  2166.             // No no in strict mode
  2167.             if ($this->_strict_mode) {
  2168.                 $this->_error('Only simple domain name parts can be handled in strict mode');
  2169.                 return false;
  2170.             }
  2171.             list($email_pref, $input) = explode('@', $input, 2);
  2172.             $arr = explode('.', $input);
  2173.             foreach ($arr as $k => $v) {
  2174.                 $conv = $this->_decode($v);
  2175.                 if ($conv) $arr[$k] = $conv;
  2176.             }
  2177.             $return = $email_pref . '@' . join('.', $arr);
  2178.         } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters)
  2179.             // No no in strict mode
  2180.             if ($this->_strict_mode) {
  2181.                 $this->_error('Only simple domain name parts can be handled in strict mode');
  2182.                 return false;
  2183.             }
  2184.             $parsed = parse_url($input);
  2185.             if (isset($parsed['host'])) {
  2186.                 $arr = explode('.', $parsed['host']);
  2187.                 foreach ($arr as $k => $v) {
  2188.                     $conv = $this->_decode($v);
  2189.                     if ($conv) $arr[$k] = $conv;
  2190.                 }
  2191.                 $parsed['host'] = join('.', $arr);
  2192.                 if (isset($parsed['scheme'])) {
  2193.                     $parsed['scheme'] .= (strtolower($parsed['scheme']) == 'mailto') ? ':' : '://';
  2194.                 }
  2195.                 $return = join('', $parsed);
  2196.             } else { // parse_url seems to have failed, try without it
  2197.                 $arr = explode('.', $input);
  2198.                 foreach ($arr as $k => $v) {
  2199.                     $conv = $this->_decode($v);
  2200.                     if ($conv) $arr[$k] = $conv;
  2201.                 }
  2202.                 $return = join('.', $arr);
  2203.             }
  2204.         } else { // Otherwise we consider it being a pure domain name string
  2205.             $return = $this->_decode($input);
  2206.         }
  2207.         // The output is UTF-8 by default, other output formats need conversion here
  2208.         // If one time encoding is given, use this, else the objects property
  2209.         switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) {
  2210.         case 'utf8':
  2211.             return $return;
  2212.             break;
  2213.         case 'ucs4_string':
  2214.            return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return));
  2215.            break;
  2216.         case 'ucs4_array':
  2217.             return $this->_utf8_to_ucs4($return);
  2218.             break;
  2219.         default:
  2220.             $this->_error('Unsupported output format');
  2221.             return false;
  2222.         }
  2223.     }
  2224.  
  2225.     /**
  2226.     * Encode a given UTF-8 domain name
  2227.     * @param    string   Domain name (UTF-8 or UCS-4)
  2228.     * [@param    string   Desired input encoding, see {@link set_parameter}]
  2229.     * @return   string   Encoded Domain name (ACE string)
  2230.     * @access   public
  2231.     */
  2232.     function encode($decoded, $one_time_encoding = false)
  2233.     {
  2234.         // Forcing conversion of input to UCS4 array
  2235.         // If one time encoding is given, use this, else the objects property
  2236.         switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) {
  2237.         case 'utf8':
  2238.             $decoded = $this->_utf8_to_ucs4($decoded);
  2239.             break;
  2240.         case 'ucs4_string':
  2241.            $decoded = $this->_ucs4_string_to_ucs4($decoded);
  2242.         case 'ucs4_array':
  2243.            break;
  2244.         default:
  2245.             // $this->_error('Unsupported input format: '.$this->_api_encoding);
  2246.             $this->_error('Unsupported input format');
  2247.             return false;
  2248.         }
  2249.  
  2250.         // No input, no output, what else did you expect?
  2251.         if (empty($decoded)) return '';
  2252.  
  2253.         // Anchors for iteration
  2254.         $last_begin = 0;
  2255.         // Output string
  2256.         $output = '';
  2257.         foreach ($decoded as $k => $v) {
  2258.             // Make sure to use just the plain dot
  2259.             switch($v) {
  2260.             case 0x3002:
  2261.             case 0xFF0E:
  2262.             case 0xFF61:
  2263.                 $decoded[$k] = 0x2E;
  2264.                 // It's right, no break here
  2265.                 // The codepoints above have to be converted to dots anyway
  2266.  
  2267.             // Stumbling across an anchoring character
  2268.             case 0x2E:
  2269.             case 0x2F:
  2270.             case 0x3A:
  2271.             case 0x3F:
  2272.             case 0x40:
  2273.                 // Neither email addresses nor URLs allowed in strict mode
  2274.                 if ($this->_strict_mode) {
  2275.                    $this->_error('Neither email addresses nor URLs are allowed in strict mode.');
  2276.                    return false;
  2277.                 } else {
  2278.                     // Skip first char
  2279.                     if ($k) {
  2280.                         $encoded = '';
  2281.                         $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin)));
  2282.                         if ($encoded) {
  2283.                             $output .= $encoded;
  2284.                         } else {
  2285.                             $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin)));
  2286.                         }
  2287.                         $output .= chr($decoded[$k]);
  2288.                     }
  2289.                     $last_begin = $k + 1;
  2290.                 }
  2291.             }
  2292.         }
  2293.         // Catch the rest of the string
  2294.         if ($last_begin) {
  2295.             $inp_len = sizeof($decoded);
  2296.             $encoded = '';
  2297.             $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
  2298.             if ($encoded) {
  2299.                 $output .= $encoded;
  2300.             } else {
  2301.                 $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
  2302.             }
  2303.             return $output;
  2304.         } else {
  2305.             if ($output = $this->_encode($decoded)) {
  2306.                 return $output;
  2307.             } else {
  2308.                 return $this->_ucs4_to_utf8($decoded);
  2309.             }
  2310.         }
  2311.     }
  2312.  
  2313.     /**
  2314.     * Use this method to get the last error ocurred
  2315.     * @param    void
  2316.     * @return   string   The last error, that occured
  2317.     * @access   public
  2318.     */
  2319.     function get_last_error()
  2320.     {
  2321.         return $this->_error;
  2322.     }
  2323.  
  2324.     /**
  2325.     * The actual decoding algorithm
  2326.     * @access   private
  2327.     */
  2328.     function _decode($encoded)
  2329.     {
  2330.         // We do need to find the Punycode prefix
  2331.         if (!preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $encoded)) {
  2332.             $this->_error('This is not a punycode string');
  2333.             return false;
  2334.         }
  2335.         $encode_test = preg_replace('!^'.preg_quote($this->_punycode_prefix, '!').'!', '', $encoded);
  2336.         // If nothing left after removing the prefix, it is hopeless
  2337.         if (!$encode_test) {
  2338.             $this->_error('The given encoded string was empty');
  2339.             return false;
  2340.         }
  2341.         // Find last occurence of the delimiter
  2342.         $delim_pos = strrpos($encoded, '-');
  2343.         if ($delim_pos > strlen($this->_punycode_prefix)) {
  2344.             for ($k = strlen($this->_punycode_prefix); $k < $delim_pos; ++$k) {
  2345.                 $decoded[] = ord($encoded{$k});
  2346.             }
  2347.         } else {
  2348.             $decoded = array();
  2349.         }
  2350.         $deco_len = count($decoded);
  2351.         $enco_len = strlen($encoded);
  2352.  
  2353.         // Wandering through the strings; init
  2354.         $is_first = true;
  2355.         $bias     = $this->_initial_bias;
  2356.         $idx      = 0;
  2357.         $char     = $this->_initial_n;
  2358.  
  2359.         for ($enco_idx = ($delim_pos) ? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) {
  2360.             for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) {
  2361.                 $digit = $this->_decode_digit($encoded{$enco_idx++});
  2362.                 $idx += $digit * $w;
  2363.                 $t = ($k <= $bias) ? $this->_tmin :
  2364.                         (($k >= $bias + $this->_tmax) ? $this->_tmax : ($k - $bias));
  2365.                 if ($digit < $t) break;
  2366.                 $w = (int) ($w * ($this->_base - $t));
  2367.             }
  2368.             $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first);
  2369.             $is_first = false;
  2370.             $char += (int) ($idx / ($deco_len + 1));
  2371.             $idx %= ($deco_len + 1);
  2372.             if ($deco_len > 0) {
  2373.                 // Make room for the decoded char
  2374.                 for ($i = $deco_len; $i > $idx; $i--) {
  2375.                     $decoded[$i] = $decoded[($i - 1)];
  2376.                 }
  2377.             }
  2378.             $decoded[$idx++] = $char;
  2379.         }
  2380.         return $this->_ucs4_to_utf8($decoded);
  2381.     }
  2382.  
  2383.     /**
  2384.     * The actual encoding algorithm
  2385.     * @access   private
  2386.     */
  2387.     function _encode($decoded)
  2388.     {
  2389.         // We cannot encode a domain name containing the Punycode prefix
  2390.         $extract = strlen($this->_punycode_prefix);
  2391.         $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix);
  2392.         $check_deco = array_slice($decoded, 0, $extract);
  2393.  
  2394.         if ($check_pref == $check_deco) {
  2395.             $this->_error('This is already a punycode string');
  2396.             return false;
  2397.         }
  2398.         // We will not try to encode strings consisting of basic code points only
  2399.         $encodable = false;
  2400.         foreach ($decoded as $k => $v) {
  2401.             if ($v > 0x7a) {
  2402.                 $encodable = true;
  2403.                 break;
  2404.             }
  2405.         }
  2406.         if (!$encodable) {
  2407.             $this->_error('The given string does not contain encodable chars');
  2408.             return false;
  2409.         }
  2410.  
  2411.         // Do NAMEPREP
  2412.         $decoded = $this->_nameprep($decoded);
  2413.         if (!$decoded || !is_array($decoded)) return false; // NAMEPREP failed
  2414.  
  2415.         $deco_len  = count($decoded);
  2416.         if (!$deco_len) return false; // Empty array
  2417.  
  2418.         $codecount = 0; // How many chars have been consumed
  2419.  
  2420.         $encoded = '';
  2421.         // Copy all basic code points to output
  2422.         for ($i = 0; $i < $deco_len; ++$i) {
  2423.             $test = $decoded[$i];
  2424.             // Will match [0-9a-zA-Z-]
  2425.             if ((0x2F < $test && $test < 0x40)
  2426.                     || (0x40 < $test && $test < 0x5B)
  2427.                     || (0x60 < $test && $test <= 0x7B)
  2428.                     || (0x2D == $test)) {
  2429.                 $encoded .= chr($decoded[$i]);
  2430.                 $codecount++;
  2431.             }
  2432.         }
  2433.  
  2434.         // All codepoints were basic ones
  2435.         if ($codecount == $deco_len) {
  2436.             return $encoded;
  2437.         }
  2438.  
  2439.         // Start with the prefix; copy it to output
  2440.         $encoded = $this->_punycode_prefix.$encoded;
  2441.  
  2442.         // If we have basic code points in output, add an hyphen to the end
  2443.         if ($codecount) $encoded .= '-';
  2444.  
  2445.         // Now find and encode all non-basic code points
  2446.         $is_first  = true;
  2447.         $cur_code  = $this->_initial_n;
  2448.         $bias      = $this->_initial_bias;
  2449.         $delta     = 0;
  2450.         while ($codecount < $deco_len) {
  2451.             // Find the smallest code point >= the current code point and
  2452.             // remember the last ouccrence of it in the input
  2453.             for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) {
  2454.                 if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) {
  2455.                     $next_code = $decoded[$i];
  2456.                 }
  2457.             }
  2458.  
  2459.             $delta += ($next_code - $cur_code) * ($codecount + 1);
  2460.             $cur_code = $next_code;
  2461.  
  2462.             // Scan input again and encode all characters whose code point is $cur_code
  2463.             for ($i = 0; $i < $deco_len; $i++) {
  2464.                 if ($decoded[$i] < $cur_code) {
  2465.                     $delta++;
  2466.                 } elseif ($decoded[$i] == $cur_code) {
  2467.                     for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) {
  2468.                         $t = ($k <= $bias) ? $this->_tmin :
  2469.                                 (($k >= $bias + $this->_tmax) ? $this->_tmax : $k - $bias);
  2470.                         if ($q < $t) break;
  2471.                         $encoded .= $this->_encode_digit(ceil($t + (($q - $t) % ($this->_base - $t))));
  2472.                         $q = ($q - $t) / ($this->_base - $t);
  2473.                     }
  2474.                     $encoded .= $this->_encode_digit($q);
  2475.                     $bias = $this->_adapt($delta, $codecount+1, $is_first);
  2476.                     $codecount++;
  2477.                     $delta = 0;
  2478.                     $is_first = false;
  2479.                 }
  2480.             }
  2481.             $delta++;
  2482.             $cur_code++;
  2483.         }
  2484.         return $encoded;
  2485.     }
  2486.  
  2487.     /**
  2488.     * Adapt the bias according to the current code point and position
  2489.     * @access   private
  2490.     */
  2491.     function _adapt($delta, $npoints, $is_first)
  2492.     {
  2493.         $delta = (int) ($is_first ? ($delta / $this->_damp) : ($delta / 2));
  2494.         $delta += (int) ($delta / $npoints);
  2495.         for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) {
  2496.             $delta = (int) ($delta / ($this->_base - $this->_tmin));
  2497.         }
  2498.         return (int) ($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew));
  2499.     }
  2500.  
  2501.     /**
  2502.     * Encoding a certain digit
  2503.     * @access   private
  2504.     */
  2505.     function _encode_digit($d)
  2506.     {
  2507.         return chr($d + 22 + 75 * ($d < 26));
  2508.     }
  2509.  
  2510.     /**
  2511.     * Decode a certain digit
  2512.     * @access   private
  2513.     */
  2514.     function _decode_digit($cp)
  2515.     {
  2516.         $cp = ord($cp);
  2517.         return ($cp - 48 < 10) ? $cp - 22 : (($cp - 65 < 26) ? $cp - 65 : (($cp - 97 < 26) ? $cp - 97 : $this->_base));
  2518.     }
  2519.  
  2520.     /**
  2521.     * Internal error handling method
  2522.     * @access   private
  2523.     */
  2524.     function _error($error = '')
  2525.     {
  2526.         $this->_error = $error;
  2527.     }
  2528.  
  2529.     /**
  2530.     * Do Nameprep according to RFC3491 and RFC3454
  2531.     * @param    array    Unicode Characters
  2532.     * @return   string   Unicode Characters, Nameprep'd
  2533.     * @access   private
  2534.     */
  2535.     function _nameprep($input)
  2536.     {
  2537.         $output = array();
  2538.         $error = false;
  2539.         //
  2540.         // Mapping
  2541.         // Walking through the input array, performing the required steps on each of
  2542.         // the input chars and putting the result into the output array
  2543.         // While mapping required chars we apply the cannonical ordering
  2544.  
  2545.         // $this->_show_hex($input);
  2546.         foreach ($input as $v) {
  2547.             // Map to nothing == skip that code point
  2548.             if (in_array($v, $this->_np_map_nothing)) continue;
  2549.  
  2550.             // Try to find prohibited input
  2551.             if (in_array($v, $this->_np_prohibit) || in_array($v, $this->_general_prohibited)) {
  2552.                 $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v));
  2553.                 return false;
  2554.             }
  2555.             foreach ($this->_np_prohibit_ranges as $range) {
  2556.                 if ($range[0] <= $v && $v <= $range[1]) {
  2557.                     $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v));
  2558.                     return false;
  2559.                 }
  2560.             }
  2561.             //
  2562.             // Hangul syllable decomposition
  2563.             if (0xAC00 <= $v && $v <= 0xD7AF) {
  2564.                 foreach ($this->_hangul_decompose($v) as $out) {
  2565.                     $output[] = $out;
  2566.                 }
  2567.             // There's a decomposition mapping for that code point
  2568.             } elseif (isset($this->_np_replacemaps[$v])) {
  2569.                 foreach ($this->_apply_cannonical_ordering($this->_np_replacemaps[$v]) as $out) {
  2570.                     $output[] = $out;
  2571.                 }
  2572.             } else {
  2573.                 $output[] = $v;
  2574.             }
  2575.         }
  2576.         //
  2577.         // Combine code points
  2578.         //
  2579.         $last_class   = 0;
  2580.         $last_starter = 0;
  2581.         $out_len      = count($output);
  2582.         for ($i = 0; $i < $out_len; ++$i) {
  2583.             $class = $this->_get_combining_class($output[$i]);
  2584.             if ((!$last_class || $last_class != $class) && $class) {
  2585.                 // Try to match
  2586.                 $seq_len = $i - $last_starter;
  2587.                 $out = $this->_combine(array_slice($output, $last_starter, $seq_len));
  2588.                 // On match: Replace the last starter with the composed character and remove
  2589.                 // the now redundant non-starter(s)
  2590.                 if ($out) {
  2591.                     $output[$last_starter] = $out;
  2592.                     if (count($out) != $seq_len) {
  2593.                         for ($j = $i+1; $j < $out_len; ++$j) {
  2594.                             $output[$j-1] = $output[$j];
  2595.                         }
  2596.                         unset($output[$out_len]);
  2597.                     }
  2598.                     // Rewind the for loop by one, since there can be more possible compositions
  2599.                     $i--;
  2600.                     $out_len--;
  2601.                     $last_class = ($i == $last_starter) ? 0 : $this->_get_combining_class($output[$i-1]);
  2602.                     continue;
  2603.                 }
  2604.             }
  2605.             if (!$class) { // The current class is 0
  2606.                 $last_starter = $i;
  2607.             }
  2608.             $last_class = $class;
  2609.         }
  2610.         return $output;
  2611.     }
  2612.  
  2613.     /**
  2614.     * Decomposes a Hangul syllable
  2615.     * (see http://www.unicode.org/unicode/reports/tr15/#Hangul
  2616.     * @param    integer  32bit UCS4 code point
  2617.     * @return   array    Either Hangul Syllable decomposed or original 32bit value as one value array
  2618.     * @access   private
  2619.     */
  2620.     function _hangul_decompose($char)
  2621.     {
  2622.         $sindex = $char - $this->_sbase;
  2623.         if ($sindex < 0 || $sindex >= $this->_scount) {
  2624.             return array($char);
  2625.         }
  2626.         $result = array();
  2627.         $T = $this->_tbase + $sindex % $this->_tcount;
  2628.         $result[] = (int) ($this->_lbase + $sindex / $this->_ncount);
  2629.         $result[] = (int) ($this->_vbase + ($sindex % $this->_ncount) / $this->_tcount);
  2630.         if ($T != $this->_tbase) $result[] = $T;
  2631.         return $result;
  2632.     }
  2633.  
  2634.     /**
  2635.     * Ccomposes a Hangul syllable
  2636.     * (see http://www.unicode.org/unicode/reports/tr15/#Hangul
  2637.     * @param    array    Decomposed UCS4 sequence
  2638.     * @return   array    UCS4 sequence with syllables composed
  2639.     * @access   private
  2640.     */
  2641.     function _hangul_compose($input)
  2642.     {
  2643.         $inp_len = count($input);
  2644.         if (!$inp_len) return array();
  2645.         $result = array();
  2646.         $last = $input[0];
  2647.         $result[] = $last; // copy first char from input to output
  2648.  
  2649.         for ($i = 1; $i < $inp_len; ++$i) {
  2650.             $char = $input[$i];
  2651.  
  2652.             // Find out, wether two current characters from L and V
  2653.             $lindex = $last - $this->_lbase;
  2654.             if (0 <= $lindex && $lindex < $this->_lcount) {
  2655.                 $vindex = $char - $this->_vbase;
  2656.                 if (0 <= $vindex && $vindex < $this->_vcount) {
  2657.                     // create syllable of form LV
  2658.                     $last = ($this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount);
  2659.                     $out_off = count($result) - 1;
  2660.                     $result[$out_off] = $last; // reset last
  2661.                     continue; // discard char
  2662.                 }
  2663.             }
  2664.  
  2665.             // Find out, wether two current characters are LV and T
  2666.             $sindex = $last - $this->_sbase;
  2667.             if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount) == 0) {
  2668.                 $tindex = $char - $this->_tbase;
  2669.                 if (0 <= $tindex && $tindex <= $this->_tcount) {
  2670.                     // create syllable of form LVT
  2671.                     $last += $tindex;
  2672.                     $out_off = count($result) - 1;
  2673.                     $result[$out_off] = $last; // reset last
  2674.                     continue; // discard char
  2675.                 }
  2676.             }
  2677.             // if neither case was true, just add the character
  2678.             $last = $char;
  2679.             $result[] = $char;
  2680.         }
  2681.         return $result;
  2682.     }
  2683.  
  2684.     /**
  2685.     * Returns the combining class of a certain wide char
  2686.     * @param    integer    Wide char to check (32bit integer)
  2687.     * @return   integer    Combining class if found, else 0
  2688.     * @access   private
  2689.     */
  2690.     function _get_combining_class($char)
  2691.     {
  2692.         return isset($this->np_norm_combcls[$char]) ? $this->np_norm_combcls[$char] : 0;
  2693.     }
  2694.  
  2695.     /**
  2696.     * Apllies the cannonical ordering of a decomposed UCS4 sequence
  2697.     * @param    array      Decomposed UCS4 sequence
  2698.     * @return   array      Ordered USC4 sequence
  2699.     * @access   private
  2700.     */
  2701.     function _apply_cannonical_ordering($input)
  2702.     {
  2703.         $swap = true;
  2704.         $size = count($input);
  2705.         while ($swap) {
  2706.             $swap = false;
  2707.             $last = $this->_get_combining_class($input[0]);
  2708.             for ($i = 0; $i < $size - 1; ++$i) {
  2709.                 $next = $this->_get_combining_class($input[$i+1]);
  2710.                 if ($next != 0 && $last > $next) {
  2711.                     // Move item leftward until it fits
  2712.                     for ($j = $i + 1; $j > 0; --$j) {
  2713.                         if ($this->_get_combining_class($input[$j - 1]) <= $next) break;
  2714.                         $t = $input[$j];
  2715.                         $input[$j] = $input[$j - 1];
  2716.                         $input[$j - 1] = $t;
  2717.                         $swap = 1;
  2718.                     }
  2719.                     // Reentering the loop looking at the old character again
  2720.                     $next = $last;
  2721.                 }
  2722.                 $last = $next;
  2723.             }
  2724.         }
  2725.         return $input;
  2726.     }
  2727.  
  2728.     /**
  2729.     * Do composition of a sequence of starter and non-starter
  2730.     * @param    array      UCS4 Decomposed sequence
  2731.     * @return   array      Ordered USC4 sequence
  2732.     * @access   private
  2733.     */
  2734.     function _combine($input)
  2735.     {
  2736.         $inp_len = count($input);
  2737.         // Is it a Hangul syllable?
  2738.         if (1 != $inp_len) {
  2739.             $hangul = $this->_hangul_compose($input);
  2740.             if (count($hangul) != $inp_len) return $hangul; // This place is probably wrong
  2741.         }
  2742.         foreach ($this->np_casemap as $np_src => $np_target) {
  2743.             if ($np_target[0] != $input[0]) continue;
  2744.             if (count($np_target) != $inp_len) continue;
  2745.             $hit = false;
  2746.             foreach ($input as $k2 => $v2) {
  2747.                 if ($v2 == $np_target[$k2]) {
  2748.                     $hit = true;
  2749.                 } else {
  2750.                     $hit = false;
  2751.                     break;
  2752.                 }
  2753.             }
  2754.             if ($hit) return $np_src;
  2755.         }
  2756.         return false;
  2757.     }
  2758.  
  2759.     /**
  2760.     * This converts an UTF-8 encoded string to its UCS-4 representation
  2761.     * By talking about UCS-4 "strings" we mean arrays of 32bit integers representing
  2762.     * each of the "chars". This is due to PHP not being able to handle strings with
  2763.     * bit depth different from 8. This apllies to the reverse method _ucs4_to_utf8(), too.
  2764.     * The following UTF-8 encodings are supported:
  2765.     * bytes bits  representation
  2766.     * 1        7  0xxxxxxx
  2767.     * 2       11  110xxxxx 10xxxxxx
  2768.     * 3       16  1110xxxx 10xxxxxx 10xxxxxx
  2769.     * 4       21  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  2770.     * 5       26  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  2771.     * 6       31  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  2772.     * Each x represents a bit that can be used to store character data.
  2773.     * The five and six byte sequences are part of Annex D of ISO/IEC 10646-1:2000
  2774.     * @access   private
  2775.     */
  2776.     function _utf8_to_ucs4($input)
  2777.     {
  2778.         $output = array();
  2779.         $out_len = 0;
  2780.         $inp_len = strlen($input);
  2781.         $mode = 'next';
  2782.         $test = 'none';
  2783.         for ($k = 0; $k < $inp_len; ++$k) {
  2784.             $v = ord($input{$k}); // Extract byte from input string
  2785.  
  2786.             if ($v < 128) { // We found an ASCII char - put into stirng as is
  2787.                 $output[$out_len] = $v;
  2788.                 ++$out_len;
  2789.                 if ('add' == $mode) {
  2790.                     $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
  2791.                     return false;
  2792.                 }
  2793.                 continue;
  2794.             }
  2795.             if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char
  2796.                 $start_byte = $v;
  2797.                 $mode = 'add';
  2798.                 $test = 'range';
  2799.                 if ($v >> 5 == 6) { // &110xxxxx 10xxxxx
  2800.                     $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left
  2801.                     $v = ($v - 192) << 6;
  2802.                 } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx
  2803.                     $next_byte = 1;
  2804.                     $v = ($v - 224) << 12;
  2805.                 } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
  2806.                     $next_byte = 2;
  2807.                     $v = ($v - 240) << 18;
  2808.                 } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  2809.                     $next_byte = 3;
  2810.                     $v = ($v - 248) << 24;
  2811.                 } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  2812.                     $next_byte = 4;
  2813.                     $v = ($v - 252) << 30;
  2814.                 } else {
  2815.                     $this->_error('This might be UTF-8, but I don\'t understand it at byte '.$k);
  2816.                     return false;
  2817.                 }
  2818.                 if ('add' == $mode) {
  2819.                     $output[$out_len] = (int) $v;
  2820.                     ++$out_len;
  2821.                     continue;
  2822.                 }
  2823.             }
  2824.             if ('add' == $mode) {
  2825.                 if (!$this->_allow_overlong && $test == 'range') {
  2826.                     $test = 'none';
  2827.                     if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) {
  2828.                         $this->_error('Bogus UTF-8 character detected (out of legal range) at byte '.$k);
  2829.                         return false;
  2830.                     }
  2831.                 }
  2832.                 if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx
  2833.                     $v = ($v - 128) << ($next_byte * 6);
  2834.                     $output[($out_len - 1)] += $v;
  2835.                     --$next_byte;
  2836.                 } else {
  2837.                     $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
  2838.                     return false;
  2839.                 }
  2840.                 if ($next_byte < 0) {
  2841.                     $mode = 'next';
  2842.                 }
  2843.             }
  2844.         } // for
  2845.         return $output;
  2846.     }
  2847.  
  2848.     /**
  2849.     * Convert UCS-4 string into UTF-8 string
  2850.     * See _utf8_to_ucs4() for details
  2851.     * @access   private
  2852.     */
  2853.     function _ucs4_to_utf8($input)
  2854.     {
  2855.         $output = '';
  2856.         foreach ($input as $v) {
  2857.             // $v = ord($v);
  2858.             if ($v < 128) { // 7bit are transferred literally
  2859.                 $output .= chr($v);
  2860.             } elseif ($v < (1 << 11)) { // 2 bytes
  2861.                 $output .= chr(192 + ($v >> 6)) . chr(128 + ($v & 63));
  2862.             } elseif ($v < (1 << 16)) { // 3 bytes
  2863.                 $output .= chr(224 + ($v >> 12)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63));
  2864.             } elseif ($v < (1 << 21)) { // 4 bytes
  2865.                 $output .= chr(240 + ($v >> 18)) . chr(128 + (($v >> 12) & 63))
  2866.                          . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63));
  2867.             } elseif ($v < (1 << 26)) { // 5 bytes
  2868.                 $output .= chr(248 + ($v >> 24)) . chr(128 + (($v >> 18) & 63))
  2869.                          . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63))
  2870.                          . chr(128 + ($v & 63));
  2871.             } elseif ($v < (1 << 31)) { // 6 bytes
  2872.                 $output .= chr(252 + ($v >> 30)) . chr(128 + (($v >> 24) & 63))
  2873.                          . chr(128 + (($v >> 18) & 63)) . chr(128 + (($v >> 12) & 63))
  2874.                          . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63));
  2875.             } else {
  2876.                 $this->_error('Conversion from UCS-4 to UTF-8 failed: malformed input at byte '.$k);
  2877.                 return false;
  2878.             }
  2879.         }
  2880.         return $output;
  2881.     }
  2882.  
  2883.     /**
  2884.      * Convert UCS-4 array into UCS-4 string
  2885.      *
  2886.      * @access   private
  2887.      */
  2888.     function _ucs4_to_ucs4_string($input)
  2889.     {
  2890.         $output = '';
  2891.         // Take array values and split output to 4 bytes per value
  2892.         // The bit mask is 255, which reads &11111111
  2893.         foreach ($input as $v) {
  2894.             $output .= chr(($v >> 24) & 255)
  2895.                      . chr(($v >> 16) & 255)
  2896.                      . chr(($v >> 8) & 255)
  2897.                      . chr($v & 255);
  2898.         }
  2899.         return $output;
  2900.     }
  2901.  
  2902.     /**
  2903.      * Convert UCS-4 strin into UCS-4 garray
  2904.      *
  2905.      * @access   private
  2906.      */
  2907.     function _ucs4_string_to_ucs4($input)
  2908.     {
  2909.         $output = array();
  2910.  
  2911.         $inp_len = strlen($input);
  2912.         // Input length must be dividable by 4
  2913.         if ($inp_len % 4) {
  2914.             $this->_error('Input UCS4 string is broken');
  2915.             return false;
  2916.         }
  2917.  
  2918.         // Empty input - return empty output
  2919.         if (!$inp_len) return $output;
  2920.  
  2921.         for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) {
  2922.             // Increment output position every 4 input bytes
  2923.             if (!($i % 4)) {
  2924.                 $out_len++;
  2925.                 $output[$out_len] = 0;
  2926.             }
  2927.             $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) );
  2928.         }
  2929.         return $output;
  2930.     }
  2931.  
  2932.     /**
  2933.     * Gives you a bit representation of given Byte (8 bits), Word (16 bits) or DWord (32 bits)
  2934.     * Output width is automagically determined
  2935.     * @access   private
  2936.     */
  2937.     function show_bitmask($octet)
  2938.     {
  2939.         if ($octet >= (1 << 16)) $w = 31;
  2940.         elseif ($octet >= (1 << 8)) $w = 15;
  2941.         else $w = 7;
  2942.         $return = '';
  2943.         for ($i = $w; $i > -1; $i--) {
  2944.             $return .= ($octet & (1 << $i)) ? 1 : '0';
  2945.         }
  2946.         return $return;
  2947.     }
  2948.  
  2949.     /**
  2950.     * echo hex represnatation of UCS4 sequence to STDOUT
  2951.     * @param    array      UCS4 sequence
  2952.     * @param    boolean    include bitmask in output
  2953.     * @return   void
  2954.     * @access   private
  2955.     */
  2956.     function _show_hex($input, $include_bit = false)
  2957.     {
  2958.         foreach ($input as $k => $v) {
  2959.             echo '[', $k, '] => ', sprintf('%X', $v);
  2960.             if ($include_bit) {
  2961.                 echo ' (', $this->show_bitmask($v), ')';
  2962.             }
  2963.             echo "\n";
  2964.         }
  2965.     }
  2966. }
  2967.  
  2968. /**
  2969. * Adapter class for aligning the API of Net_IDNA_php4 with that of
  2970. * Net_IDNA
  2971. * @author  Matthias Sommerfeld <mso@phlylabs.de>
  2972. */
  2973. class Net_IDNA extends Net_IDNA_php4
  2974. {
  2975.     /**
  2976.     * Constructor
  2977.     *
  2978.     * @param  array  $options
  2979.     * @access public
  2980.     * @see    setParams()
  2981.     */
  2982.     function Net_IDNA($options = false)
  2983.     {
  2984.         $this->IC = new idna_convert($options);
  2985.         return $this->IC;
  2986.     }
  2987.  
  2988.     /**
  2989.      * Sets a new option value. Available options and values:
  2990.      *
  2991.      * [utf8 -     Use either UTF-8 or ISO-8859-1 as input (true for UTF-8, false
  2992.      *             otherwise); The output is always UTF-8]
  2993.      * [overlong - Unicode does not allow unnecessarily long encodings of chars,
  2994.      *             to allow this, set this parameter to true, else to false;
  2995.      *             default is false.]
  2996.      * [strict -   true: strict mode, good for registration purposes - Causes errors
  2997.      *             on failures; false: loose mode, ideal for "wildlife" applications
  2998.      *             by silently ignoring errors and returning the original input instead]
  2999.      *
  3000.      * @param    mixed     $option      Parameter to set (string: single parameter; array of Parameter => Value pairs)
  3001.      * @param    string    $value       Value to use (if parameter 1 is a string)
  3002.      * @return   boolean                true on success, false otherwise
  3003.      * @access   public
  3004.      */
  3005.     function setParams($option, $param = false)
  3006.     {
  3007.         return $this->IC->set_parameters($option, $param);
  3008.     }
  3009. }
  3010.  
  3011. ?>
  3012.