<? // lump.php - Lightweight Unicode Map/Picker by CJB
$copy=2006$auth="Christian van den Bosch"$lic="GPLv2";
$title="Lump (Lightweight Unicode Map/Picker)";
// generate char tables on client, getting char names from server via XML if possible.
// fail over to server-side generated table if js is absent.
header('Cache-Control: max-age:86400');
if(isset(
$_GET['P'])) // are we generating XML character name list?
{    preg_match('/[0-9]+/',$p=$_GET['P']) or die;
    
$maxch=$minch=$p*512;
    
header('Content-Type: text/xml');
    require 
'project/db.php';
    
$result=mysql_query("SELECT * FROM unichars WHERE num>=$minch AND num<=$minch+511 ORDER BY num ASC;") or die;
    while( 
$row=mysql_fetch_assoc$result ) )
        
$descrs[$maxch=$row['num']] = $row['desc'];
    echo 
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<root>\n";
    
// output up to 512 descs in sequence. stop at last non-empty one.
    
for($i=$minch;$i<=$maxch;++$i)
        echo isset(
$descrs[$i]) ? ('<c>'.htmlentities($descrs[$i])."</c>\n") : "<c/>\n";
    die(
"</root>\n");// XML all done
}
// fall through to generate HTML
header(($ct='Content-Type').': '.($cs='text/html; charset=utf-8')); // absolutely vital for this page!
$ssn=$_SERVER['SCRIPT_NAME'];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="<?echo$ct;?>" content="<?echo$cs;?>" />
<meta name="author" content="<?echo$auth;?>" />
<meta name="copyright" content="(c) <?echo$copy.' '.$auth;?>" />
<meta name="licence" content="<?echo$lic;?>" />
<meta name="description" content="<?echo$title;?>" />
<meta name="generator" content="vi+PHP" />
<link rel="stylesheet" href="u.css" type="text/css" />
<script type="text/javascript"><!--
var hr, tdl, thl, p;
function a(e)
{    var o=et(e), c, n, h;
    //try{ o=e.target } catch(m) {o=e.srcElement};
    if(o.tagName!='TD')//konq/safari go one obj too deep
        o=o.parentNode;
    df(0).txt.focus();
    df(0).txt.value+=(c=String.fromCharCode(n=eval('0x'+(h=o.title.substring(0,4)))));//all this, just to make amp, lt, gt work!
    df(0).txt.select();
    gi('j').innerHTML='';
    gi('x').innerHTML='Character description'+(o.title.length>6?(': '+o.title.substring(6)):' not available.');
    gi('w').innerHTML='HTML: &amp;#x'+h+'; &nbsp; UTF-8:'+he(c,' ')+' &nbsp; Decimal: '+n;
}
function ol()
{    var i;
    tdl=document.getElementsByTagName('td');
    thl=document.getElementsByTagName('th');
    for(i=0;i<512;++i)//assume first 512 TDs on page are entries in char table
        tdl[i].onclick=a;
    gi('f').innerHTML='';
    gi('g').disabled=gi('c').disabled=false;
    hr=false;
    try { hr=new XMLHttpRequest(); } catch (e)
    {    try { hr=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e)
        {     try { hr=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { }
        }
    }
    np();
}
function np()
{    var i, j, k;
    p=df(0).p.selectedIndex;
    gi('j').innerHTML='Javascript click-to-copy enabled.';
    if(hr)
    {    hr.onreadystatechange=ac;
        hr.open('GET','<?echo$ssn;?>?P='+p,true);
        hr.send(null);
        gi('x').innerHTML='Character descriptions requested...';
    }
    gi('t').href='<?echo$ssn;?>?p='+p;
    gi('t').title=df(0).p.options[p].text;
    gi('t').innerHTML=df(0).p.options[p].text.substring(0,5);
    p*=512;
    for(i=0;i<32;++i) // change column headings
    {    j=h(4,16*i+p);
        thl[i+1].innerHTML=(j.substr(0,2)+'<br>'+j.substr(2,1)+"_");
    }
    for(i=0;i<512;++i) // change table content
    {    tc(i).title=j=h(4,i+p);
        tc(i).innerHTML=(((i+p)&0xff7f)<=32)|(i+p==127)?'':'&#x'+j+';';
    }
    gi('w').innerHTML=p?'<?echo$wnz="Note: browser settings determine character appearance.";?>':'<?echo$wz="Nonportable control characters hidden.";?>';
}
function gi(n) { return document.getElementById(n); }
function df(n) { return document.forms[n]; }
function h(d,n) { var h; h=n.toString(16).toUpperCase(); return "000".substring(0,d-h.length)+h; }
function tc(i) { return tdl[((i&15)<<5)|((i&496)>>4)]; }

function ac()
{    var i, j, n=0;
    if (hr.readyState==4)
    {    if (hr.status==200)
        {    var xd=hr.responseXML.getElementsByTagName('c');
            for(i=0;i<512;++i)
            {    try
                {    tc(i).title='';
                    tc(i).title=h(4,p+i)+': '+xd[i].firstChild.data;
                    ++n;// write fresh title - strange results in IE if we append to what's there.
                }
                catch(e)
                {    tc(i).title=h(4,p+i);
                }
            }
        }
        gi('x').innerHTML='Character descriptions '+(n?'loaded: '+n:'not found :(');
    }
}
function u8(n)
{    if(n<128)    return String.fromCharCode(n);
    if(n<2048)    return String.fromCharCode((n>>6)+192,(n&63)+128);
    if(n<65536)    return String.fromCharCode((n>>12)+224,((n>>6)&63)+128,(n&63)+128);
    if(n<2097152)    return String.fromCharCode((n>>18)+240,((n>>12)&63)+128,((n>>6)&63)+128,(n&63)+128);
}
function he(s,d)
{    var i, j, n, c, e='';
    for(i=0;i<s.length;++i)
    {    c=u8(s.charCodeAt(i));
        for(j=0;j<c.length;++j)
            e+=''+d+h(2,c.charCodeAt(j));
    }
    return e;
}
function gg(t)
{    window.open("http://www.google.com/search?ie=UTF-8&oe=UTF-8&q="+he(t,'%'));
}
function et(e)
{    if(!e)    e = event;
    return e.target||e.srcElement;
}
// --></script>
<?
function u8($c// utf-8 <= 3 bytes for unicode-16, hex html entities are 7: saves 2k when transferring 512 chars!
{    if($c<32)    return ''// hide nonportable 0-31
    
if($c<127)    return sprintf('&#x%02x;',$c);    // avoid issues with lt, gt, amp.
    
if($c<160)    return ''// hide nonportable 127-159
    
if($c<2048)    return chr(($c>>6)+192).chr(($c&63)+128);
    if(
$c<65536)    return chr(($c>>12)+224).chr((($c>>6)&63)+128).chr(($c&63)+128);
    if(
$c<2097152)    return chr(($c>>18)+240).chr((($c>>12)&63)+128).chr((($c>>6)&63)+128).chr(($c&63)+128);
}

$cjk 'CJK Unif Ideog';
$cjkA$cjk.' Ext A';
$cjkC'CJK Comp';
$yis 'Yi Syllables';
$yir 'Yi Radicals';
$hgs 'Hangul Syllables';
$pua 'PUA'// Private Use Area
$apf 'Arabic Pres Forms';

$pages=array(
    
'Latin, Ext-1, Ext-A, Ext-B'// 0000
    
'Latin Ext-B, IPA, Modifiers, Greek (Ελληνικά), Coptic'// 0200
    
'Cyrillic (Кириллица), Hebrew (עברית)',    // 0400
    
'Arabic (العربية), Syriac, Thaana'// 0600
    
'Devanagari, Bengali'// 0800
    
'Gurmukhi, Gujarati, Oriya, Tamil'// 0A00
    
'Telugu, Kannada, Malayalam, Sinhala'// 0C00
    
'Thai, Lao, Tibetan'// 0E00
    
'Myanmar, Georgian, Hangul Jamo'// 1000
    
'Ethiopic, Cherokee'// 1200
    
'Canadian Aboriginal'// 1400
    
'Can Abor, Ogham, Runic, Tagalog, Hanunoo, Buhid, Tagbanwa, Khmer'// 1600
    
'Mongolian, Limbu, Tai Le, New Tai Le, Khmer Symbols'// 1800
    
'Buginese'// 1A00
    
'Phonetic Extensions, Supp, Diacrit Supp'// 1C00
    
'Latin Ext Additional, Greek Ext'// 1E00
    
"Gen'l Punct, Super/Sub, Currency, Comb Diacr, Ltrlike, Num Forms, Arrows"// 2000
    
'Mathematical Operators, Misc Tech Sym'// 2200
    
'Control Pictures, OCR, Enclosed Alphanum, Box Drawing'// 2400
    
'Miscellaneous, Dingbats, Misc Math Sym A, Supp Arrows A'// 2600
    
'Braille Patterns, Supp Arrows B, Misc Math Sym B'// 2800
    
'Supp Math Operators, Misc Sym + Arrows'// 2A00
    
'Glagolitic, Coptic, Georgian Supp, Tifinagh, Ethiopic Extended'// 2C00
    
'Supp Punct, Kangxi Radicals, Ideographic Description'// 2E00
    
'CJK Sym+Punct, Hiragana, Katakana, Bopomoto, HangulCompJamo, Kanbun,...'// 3000-31ff
    
'Enclosed CJK Letters + Months, '.$cjkC// 3200-33ff
            
$cjkA,    $cjkA,    $cjkA,    $cjkA,    $cjkA,    $cjkA// 3400-43ff
    
$cjkA,    $cjkA,    $cjkA,    $cjkA,    $cjkA,    $cjkA,    $cjkA ', Yijing Hexagram Symbols'// 4400-4dff
                                
$cjk,    // 4e00-4fff
    
$cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    // 5000-5fff
    
$cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    // 6000-6fff
    
$cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    // 7000-7fff
    
$cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    // 8000-8fff
    
$cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,    $cjk,     // 9000-9fff
    
$yis,    $yis,    $yis.', '.$yir,    $yir.', Modifier Tone Letters',    // a000-a7ff
                    
'Syloti Nagri',    '(unallocated)',// a800-a9ff
                            
$hgs,    $hgs,    // aa00-afff
    
$hgs,    $hgs,    $hgs,    $hgs,    $hgs,    $hgs,    $hgs,    $hgs,    // b000-bfff
    
$hgs,    $hgs,    $hgs,    $hgs,    $hgs,    $hgs,    $hgs,    $hgs,    // c000-cfff
    
$hgs,    $hgs,    $hgs,    $hgs,    'HSA',    'HSA',    'LSA',    'LSA',    // d000-dfff
    
$pua,    $pua,    $pua,    $pua,    $pua,    $pua,    $pua,    $pua,    // e000-efff
    
$pua,    $pua,    $pua,    $pua,    $pua.', '.$cjkC,        // f000-f9ff
        
$cjkC.', Alphabetic Pres Forms, '.$apf.'-A'$apf.'-A',    // fa00-fdff
    
'VarSel, CombHalf, '.$cjkC.', Sml, '.$apf.'-B, Half/Full Width, Specials' // fe00-ffff
);

$g=0;
if( isset( 
$_GET['p'] ) )
    if( 
preg_match'/^[0-9]+$/'$_GET['p'] ) )
        
$g=0+($_GET['p']);
?>
<title><?echo$title,': ',$pages[$g];?></title></head>
<body onload="javascript:ol();">
<form action="<?echo$ssn;?>" method="get" accept-charset="utf-8"><p>
<select name="p" onchange="javascript:np();">
<?
foreach( $pages as $k => $v )
{    
printf('<option value="%d"%s>%02X/%02X: %s</option>'."\n"$k, ($k==$g?' selected="selected"':''),$k*2,$k*2+1,$v);
}
?>
</select>
<span id="f"><input type="submit" value="Go!" /></span>

</p>
<table class="c">
<tr>
    <th></th><?
$h
=$g*512;
for( 
$k=0$k<512$k+=16 // columns
    
printf('<th>%02X<br/>%X_</th>',($h+$k)/256,(($h+$k)/0x10)&15);

for( 
$i=0$i<0x10; ++$i // content
{    echo "\n</tr><tr align=\"center\">\n";
    
printf("    <th align=\"right\">%X</th>",$i&15);
    for(
$k=0;$k<512;$k+=16)
        echo 
'<td>'.u8($h+$i+$k).'</td>';
}
?>

</tr></table>
<table><tr>
<td>
<a href="http://validator.w3.org/check/referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Strict" title="Valid XHTML 1.0 Strict" /></a>
<br />
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" title="Valid CSS!" /></a>
</td><td>
<p>
<input type="text" name="txt" size="50" value="<?echo htmlspecialchars($_GET['txt'], ENT_NOQUOTES );?>" />
<input type="button" id="c" value="Clear" disabled="disabled" onclick="javascript:df(0).txt.value='';" />
<input type="button" id="g" value="Google" disabled="disabled" onclick="javascript:gg(df(0).txt.value);" />
<br />
<?echo$title;?>: <a href="u.php.txt">open source software</a> (<a href="u.phps">phps</a>) by <a href="http://cjb.ie/" title="<?echo$auth;?>">CJB</a>.
<br />
<span id="j">Javascript and</span>
<span id="x">Ajax not detected - functionality reduced!</span>
<br />
Link to table <a id="t" href="<?echo"$ssn?p=$g";?>"><?printf("%02X/%02X",$g*2,$g*2+1);?></a>.
<span id="w"><?echo$g?$wnz:$wz;?></span>
<?
$ua
=$_SERVER['HTTP_USER_AGENT'];
if(
preg_match('/MSIE/',$ua)&!preg_match('/Opera/',$ua))
    echo 
"<br />\nThis is a standards-compliant webpage. It works well with\n<br />\nstandards-compliant web browsers like <a href=\"http://getfirefox.com\">Firefox</a> and <a href=\"http://opera.com\">Opera</a>.\n";
?>
</p>
</td></tr></table>
</form>
</body></html>