Index: /trunk/devel/run
===================================================================
--- /trunk/devel/run	(revision 1052)
+++ /trunk/devel/run	(revision 1053)
@@ -198,8 +198,8 @@
 	;;
 dc)
-	exec ./php-cli -c devel.ini ./mod_disassembler/bin/phpdc.phpr "${args[@]}" | tee decompiled.php
+	exec ./php-cli -c devel.ini ./bin/phpdc.phpr "${args[@]}" | tee decompiled.php
 	;;
 dop)
-	exec ./php-cli -c devel.ini ./mod_disassembler/bin/phpdop.phpr "${args[@]}"
+	exec ./php-cli -c devel.ini ./bin/phpdop.phpr "${args[@]}"
 	;;
 retest)
Index: /trunk/htdocs/cacher/cacher-en.lang.php
===================================================================
--- /trunk/htdocs/cacher/cacher-en.lang.php	(revision 1053)
+++ /trunk/htdocs/cacher/cacher-en.lang.php	(revision 1053)
@@ -0,0 +1,81 @@
+<?php
+
+$GLOBALS['config']['show_todo_strings'] = false;
+
+$strings = array(
+		'cache.cache'
+		=> 'Cache|',
+		'cache.slots'
+		=> 'Slots|Number of hash slots. the setting from your php.ini',
+		'cache.size'
+		=> 'Size|Cache Size, Size of the cache (or cache chunk), in bytes',
+		'cache.avail'
+		=> 'Avail|Available Memory, free memory in bytes of this cache',
+		'cache.used'
+		=> 'Used|Used Memory, used memory in bytes of this cache',
+		'cache.blocksgraph'
+		=> 'Percent Graph|Shows how much memory available in percent, and memory blocks status in graph',
+		'cache.operations'
+		=> 'Operations|Press the clear button to clean this cache',
+		'cache.compiling'
+		=> 'Comp.|Compiling flag, "yes" if the cache is busy compiling php script',
+		'cache.hits'
+		=> 'Hits|Cache Hits, hit=a var/php is loaded from this cache',
+		'cache.hits_avg_h'
+		=> 'Hits/H|Average Hits per Hour. Only last 24 hours is logged',
+		'cache.hits_graph'
+		=> 'Hits*24H|Hits graph of last 24 hours',
+		'cache.hits_avg_s'
+		=> 'Hits/S|Average Hits per Second. Only last 5 seconds is logged',
+		'cache.updates'
+		=> 'Updates|Cache Updates',
+		'cache.clogs'
+		=> 'Clogs|Compiling Clogs, clog=compiling is needed but avoided to wait(be blocked) when the cache is busy compiling already',
+		'cache.ooms'
+		=> 'OOMs|Out Of Memory, how many times a new item should be stored but there isn\'t enough memory in the cache, think of increasing the xcache.size or xcache.var_size',
+		'cache.errors'
+		=> 'Errs|Compiler errors, how many times your script is compiled but failed. You should really check what is happening if you see this value increase. (See Help for more information)',
+		'cache.readonly_protected'
+		=> 'Protected|Whether readonly_protection is available and enable on this cache (See help for more information)',
+		'cache.cached'
+		=> 'Cached|Number of entries stored in this cache',
+		'cache.deleted'
+		=> 'Deleted|Number of entries is pending in delete list (expired but referenced)',
+		'cache.gc_timer'
+		=> 'GC|Seconds count down of Garbage Collection',
+		'entry.id'
+		=> 'Id|',
+		'entry.name'
+		=> 'Entry name|The entry name or filename',
+		'entry.hits'
+		=> 'Hits|Times this entry is hit (loaded from this cache)',
+		'entry.size'
+		=> 'Size|Size in bytes of this entry in the cache',
+		'entry.refcount'
+		=> 'Refs|Reference count of this entry is holded by a php request',
+		'entry.phprefcount'
+		=> 'Shares|Count of entry sharing this php data',
+		'entry.file_size'
+		=> 'Src Size|Size of the source file',
+		'entry.file_mtime'
+		=> 'Modified|Last modified time of the source file',
+		'entry.file_device'
+		=> 'dev|device number of the source file',
+		'entry.file_inode'
+		=> 'ino|inode number of the source file',
+		'entry.class_cnt'
+		=> 'Cls.|Count of classes',
+		'entry.function_cnt'
+		=> 'Funcs|Count of functions',
+		'entry.hash'
+		=> 'Hash|Hash value of this entry',
+		'entry.atime'
+		=> 'Access|Last time when this entry is accessed',
+		'entry.ctime'
+		=> 'Create|The time when this entry is stored',
+		'entry.delete'
+		=> 'Delete|The time when this entry is deleted',
+		'entry.remove'
+		=> 'Remove|',
+);
+
Index: /trunk/htdocs/cacher/cacher-zh-simplified.lang.php
===================================================================
--- /trunk/htdocs/cacher/cacher-zh-simplified.lang.php	(revision 1053)
+++ /trunk/htdocs/cacher/cacher-zh-simplified.lang.php	(revision 1053)
@@ -0,0 +1,131 @@
+<?php
+
+$strings = array(
+		'XCache Help'
+		=> 'XCache 帮助信息',
+		'Help'
+		=> '帮助',
+		'Clear'
+		=> '清除',
+		'Sure to clear?'
+		=> '确认要清除吗?',
+		'% Free'
+		=> '% 剩余',
+		'% Used'
+		=> '% 已用',
+		'Hits'
+		=> '命中',
+		'Modify'
+		=> '修改',
+		'See also'
+		=> '建议参考',
+		'Legends:'
+		=> '图例:',
+		'Used Blocks'
+		=> '已用块',
+		'Free Blocks'
+		=> '未用块',
+		'Total'
+		=> '总共',
+		'Caches'
+		=> '缓存区',
+		'php Cached'
+		=> '缓存的 php 脚本',
+		'php Deleted'
+		=> '待删 php 缓存',
+		'var Cached'
+		=> '缓存的变量',
+		'var Deleted'
+		=> '待删变量',
+		'Statistics'
+		=> '统计信息',
+		'List PHP'
+		=> '列出PHP',
+		'List Var Data'
+		=> '列变量数据',
+		'XCache %s Administration'
+		=> 'XCache %s 管理页面',
+		'Module Info'
+		=> '模块信息',
+		'Remove Selected'
+		=> '删除所选',
+		'Editing Variable %s'
+		=> '正在编辑变量 %s',
+		'Set %s in config to enable'
+		=> '请在配置文件中设置 %s 启用本功能',
+		'cache.cache'
+		=> '缓存|',
+		'cache.slots'
+		=> '槽|Hash 槽个数, 对应 php.ini 里的设置',
+		'cache.size'
+		=> '大小|共享内存区大小, 单位: 字节',
+		'cache.avail'
+		=> '剩余|可用内存, 对应共享内存区的剩余内存字节数',
+		'cache.used'
+		=> '已用|已用内存, 对应共享内存区的已用内存字节数',
+		'cache.blocksgraph'
+		=> '百分比图|条状显示可用内存的比例, 以及显示分配块状态',
+		'cache.operations'
+		=> '操作|点击按钮清除对应共享内存区的数据',
+		'cache.compiling'
+		=> '编译中|编译标记, 当共享内存区正在编译 php 脚本时标记为 "yes"',
+		'cache.hits'
+		=> '命中|共享内存命中次数, 命中=从该共享内存载入php或者变量',
+		'cache.hits_avg_h'
+		=> '命中/H|每小时命中次数. 只统计最后 24 小时',
+		'cache.hits_graph'
+		=> '24H 分布|24 小时命中分布图. 图表现是最后 24 小时的命中次数',
+		'cache.hits_avg_s'
+		=> '命中/S|每秒命中次数. 只统计最后 5 秒',
+		'cache.updates'
+		=> '更新|共享内存更新次数',
+		'cache.clogs'
+		=> '阻塞|编译阻塞跳过, 阻塞=当需该共享内存区负责编译时, 其他进程/现成无法访问此共享内存. 跳过=XCache 自动判断阻塞的共享内存区自动跳过阻塞等待, 直接使用非共享内存方式继续处理请求',
+		'cache.ooms'
+		=> '内存不足|内存不足次数, 显示需要存储新数据但是共享内存区内存不足的次数. 如果出现太频繁请考虑加大配置中的 xcache.size 或者 xcache.var_size',
+		'cache.errors'
+		=> '错误|编译错误, 显示您的脚本被编译时出错的次数. 如果您发现这个数字不断增长, 您应该检查什么脚本产生错误. 参考 帮助 获取更多信息',
+		'cache.readonly_protected'
+		=> '保护|显示该 Cache 是否支持并启用 readonly_protection. 参考 帮助 获取更多信息',
+		'cache.cached'
+		=> '缓存|共享内存于该共享内存区的项目条数',
+		'cache.deleted'
+		=> '待删|共享内存区内将要删除的项目 (已经删除但是还被某些进程占用)',
+		'cache.gc_timer'
+		=> 'GC|垃圾回收的倒计时',
+		'entry.id'
+		=> 'Id|',
+		'entry.name'
+		=> '项目名/文件名|项目名或者文件名',
+		'entry.hits'
+		=> '命中|该项目被命中的次数 (从共享内存区载入)',
+		'entry.size'
+		=> '大小|项目在共享内存里占用字节数',
+		'entry.refcount'
+		=> '引用数|项目依然被其他进程占据的引用次数',
+		'entry.phprefcount'
+		=> '共享数|与本项目相同 PHP 代码的个数',
+		'entry.file_size'
+		=> '源大小|源文件大小',
+		'entry.file_mtime'
+		=> '修改|源文件最后修改时间',
+		'entry.file_device'
+		=> 'dev|源文件所在设备ID',
+		'entry.file_inode'
+		=> 'ino|源文件的 inode',
+		'entry.class_cnt'
+		=> '类|类个数',
+		'entry.function_cnt'
+		=> '函数|函数个数',
+		'entry.hash'
+		=> '哈希|该项目的哈希值',
+		'entry.atime'
+		=> '访问|最后访问该项目的时间',
+		'entry.ctime'
+		=> '创建|该项目被创建于共享内的时间',
+		'entry.delete'
+		=> '删除|该项目被决定删除的时间',
+		'entry.remove'
+		=> '删除|',
+);
+
Index: /trunk/htdocs/cacher/cacher-zh-traditional.lang.php
===================================================================
--- /trunk/htdocs/cacher/cacher-zh-traditional.lang.php	(revision 1053)
+++ /trunk/htdocs/cacher/cacher-zh-traditional.lang.php	(revision 1053)
@@ -0,0 +1,131 @@
+<?php
+
+$strings = array(
+		'XCache Help'
+		=> 'XCache 說明訊息',
+		'Help'
+		=> '說明',
+		'Clear'
+		=> '清除',
+		'Sure to clear?'
+		=> '確認要清除嗎?',
+		'% Free'
+		=> '% 剩余',
+		'% Used'
+		=> '% 已用',
+		'Hits'
+		=> '命中',
+		'Modify'
+		=> '修改',
+		'See also'
+		=> '建議參考',
+		'Legends:'
+		=> '图例:',
+		'Used Blocks'
+		=> '已用块',
+		'Free Blocks'
+		=> '未用块',
+		'Total'
+		=> '总共',
+		'Caches'
+		=> '快取',
+		'php Cached'
+		=> '快取的 php 指令',
+		'php Deleted'
+		=> '待刪 php 指令',
+		'var Cached'
+		=> '快取的變數',
+		'var Deleted'
+		=> '待刪變數',
+		'Statistics'
+		=> '統計訊息',
+		'List PHP'
+		=> '列出PHP',
+		'List Var Data'
+		=> '列變數資料',
+		'XCache %s Administration'
+		=> 'XCache %s 管理頁面',
+		'Module Info'
+		=> '組元訊息',
+		'Remove Selected'
+		=> '移除所选',
+		'Editing Variable %s'
+		=> '正在编辑变量 %s',
+		'Set %s in config to enable'
+		=> '請在配置文件中設置 %s 啟用本功能',
+		'cache.cache'
+		=> '快取|',
+		'cache.slots'
+		=> '槽|Hash 槽個數，對應 php.ini 裡的設置',
+		'cache.size'
+		=> '大小|共享記憶體區大小，單位：位元',
+		'cache.avail'
+		=> '剩餘|可用記憶體，對應共享記憶體區的剩餘記憶體位元數',
+		'cache.used'
+		=> '已用|已用内存, 对应共享内存区的已用内存字节数',
+		'cache.blocksgraph'
+		=> '百分比图|條狀顯示可用記憶體的比例',
+		'cache.operations'
+		=> '操作按鈕|點擊按鈕清除對應共享記憶體區的資料',
+		'cache.compiling'
+		=> '編譯中|編譯標記，當共享記憶體區正在編譯 php 指令時標記為 "yes"',
+		'cache.hits'
+		=> '命中|共享記憶體命中次數，命中=從該共享記憶體載入php或者變數',
+		'cache.hits_avg_h'
+		=> '命中/H|每小时命中次数. 只统计最后 24 小时',
+		'cache.hits_graph'
+		=> '24H 分布|24 小时命中分布图. 图表现是最后 24 小时的命中次数',
+		'cache.hits_avg_s'
+		=> '命中/S|每秒命中次数. 只统计最后 5 秒',
+		'cache.updates'
+		=> '更新|共享記憶更新過次數',
+		'cache.clogs'
+		=> '阻塞|編譯阻塞跳過，阻塞=當需該共享記憶體區負責編譯時，其他程序/現成無法存取此共享記憶體. 跳過=XCache 自動判斷阻塞的共享記憶體區自動跳過阻塞等待，直接使用非共享記憶體方式繼續處理請求',
+		'cache.ooms'
+		=> '記憶體不足|記憶體不足次數，顯示需要儲存新資料但是共享記憶體區記憶體不足的次數. 如果出現太頻繁請考慮加大配置中的 xcache.size 或者 xcache.var_size',
+		'cache.errors'
+		=> '错误|编译错误, 显示您的脚本被编译时出错的次数. 如果您发现这个数字不断增长, 您应该检查什么脚本产生错误. 参考 說明',
+		'cache.readonly_protected'
+		=> 'Protected|顯示該 Cache 是否支援並啟用 readonly_protection. 参考 說明',
+		'cache.cached'
+		=> '快取|共享記憶體於該共享記憶體區的項目個數',
+		'cache.deleted'
+		=> '待刪|共享記憶體區內將要刪除的項目 (已經刪除但是還被某些程序佔用)',
+		'cache.gc_timer'
+		=> 'GC|垃圾回收的倒數計時',
+		'entry.id'
+		=> 'Id|',
+		'entry.name'
+		=> '項目名稱/檔案名稱|項目名稱或者檔案名稱',
+		'entry.hits'
+		=> '命中|該項目被命中的次數 (從共享記憶體區載入)',
+		'entry.size'
+		=> '大小|項目在共享記憶體裡佔用位元數',
+		'entry.refcount'
+		=> '引用數|項目依然被其他程序佔用的引用次數',
+		'entry.phprefcount'
+		=> '共享|與本項目相同 PHP 內容的个數',
+		'entry.file_size'
+		=> '源大小|原始檔案大小',
+		'entry.file_mtime'
+		=> '修改|原始檔案最後修改時間',
+		'entry.file_device'
+		=> 'dev|原始檔案所在設備ID',
+		'entry.file_inode'
+		=> 'ino|原始檔案的inode',
+		'entry.class_cnt'
+		=> '类|类个数',
+		'entry.function_cnt'
+		=> '函数|函数个数',
+		'entry.hash'
+		=> 'Hash|Hash',
+		'entry.atime'
+		=> '存取|最後存取該項目的時間',
+		'entry.ctime'
+		=> '建立|該項目被建立於共享內的時間',
+		'entry.delete'
+		=> '移除|該項目被移除於共享內的時間',
+		'entry.remove'
+		=> '移除|',
+);
+
Index: /trunk/htdocs/cacher/cacher.css
===================================================================
--- /trunk/htdocs/cacher/cacher.css	(revision 1053)
+++ /trunk/htdocs/cacher/cacher.css	(revision 1053)
@@ -0,0 +1,35 @@
+td, th { white-space: pre; }
+.phpinfo table { border: 1px solid black; margin-bottom: 1px; }
+.phpinfo table th, .phpinfo table td { border: 1px solid black; }
+.phpinfo table th { font-weight: bold; }
+.phpinfo .e {background-color: #ccccff; font-weight: bold; color: #000000;}
+.phpinfo .h {background-color: #9999cc; font-weight: bold; color: #000000;}
+.phpinfo .v {background-color: #cccccc; color: #000000;}
+.button { }
+span.sortarrow { color: white; text-decoration: none; }
+form {margin: 0; padding: 0}
+
+.percent { height: 3px; margin-bottom: 1px; border: 1px solid gray; }
+.percent div { float: left; height: 100%; }
+.pvalue { background: limegreen; }
+
+.blocksgraph { height: 16px; }
+.blocksgraph div { float: left; height: 3px; width: 4px; border: solid gray; border-width: 0 0px 1px 0; }
+.blocksgraph { border: 1px solid gray; border-bottom: 0px; }
+
+.hitsgraph { height: 20px; margin: auto; }
+.hitsgraph div { float: left; width: 2px; height: 100%; }
+.hitsgraph div:hover { background: gray; }
+.hitsgraph div div { float: none; width: 100%; }
+.hitsgraph div div.barf { border: 0px solid gray; border-width: 1px 0 0 0; }
+.hitsgraph div div.barv { border: 0px solid gray; border-width: 0 0 1px 0; }
+.hitsgraph div div.barf.active { border-color: yellow; }
+.hitsgraph div div.barv.active { border-color: yellow; }
+
+#help { display: block; float: right; }
+dl { overflow: hidden; }
+dt { font-weight: bold; clear: both; float: left; width: 100px; text-align: right; margin: 0; }
+dd { margin: 0; }
+.blockarea { overflow: hidden; _width: 1px; }
+div.legend { float: left; border: 1px solid gray; font: 12px/12px monospace; }
+div.legendtitle { float: left; padding: 2px; padding-right: 10px; font: 12px/12px monospace; }
Index: /trunk/htdocs/cacher/cacher.php
===================================================================
--- /trunk/htdocs/cacher/cacher.php	(revision 1053)
+++ /trunk/htdocs/cacher/cacher.php	(revision 1053)
@@ -0,0 +1,308 @@
+<?php
+
+include("./common.php");
+
+function freeblock_to_graph($freeblocks, $size)
+{
+	global $config;
+
+	// cached in static variable
+	static $graph_initial;
+	if (!isset($graph_initial)) {
+		$graph_initial = array_fill(0, $config['percent_graph_width'], 0);
+	}
+	$graph = $graph_initial;
+	foreach ($freeblocks as $b) {
+		$begin = $b['offset'] / $size * $config['percent_graph_width'];
+		$end = ($b['offset'] + $b['size']) / $size * $config['percent_graph_width'];
+
+		if ((int) $begin == (int) $end) {
+			$v = $end - $begin;
+			$graph[(int) $v] += $v - (int) $v;
+		}
+		else {
+			$graph[(int) $begin] += 1 - ($begin - (int) $begin);
+			$graph[(int) $end] += $end - (int) $end;
+			for ($i = (int) $begin + 1, $e = (int) $end; $i < $e; $i ++) {
+				$graph[$i] += 1;
+			}
+		}
+	}
+	$html = array();
+	$c = 255;
+	foreach ($graph as $k => $v) {
+		if ($config['percent_graph_type'] != 'free') {
+			$v = 1 - $v;
+		}
+		$v = (int) ($v * $c);
+		$r = $g = $c - $v;
+		$b = $c;
+		$html[] = '<div style="background: rgb(' . "$r,$g,$b" . ')"></div>';
+	}
+	return implode('', $html);
+}
+
+function calc_total(&$total, $data)
+{
+	foreach ($data as $k => $v) {
+		switch ($k) {
+		case 'type':
+		case 'cache_name':
+		case 'cacheid':
+		case 'free_blocks':
+			continue 2;
+		}
+		if (!isset($total[$k])) {
+			$total[$k] = $v;
+		}
+		else {
+			switch ($k) {
+			case 'hits_by_hour':
+			case 'hits_by_second':
+				foreach ($data[$k] as $kk => $vv) {
+					$total[$k][$kk] += $vv;
+				}
+				break;
+
+			default:
+				$total[$k] += $v;
+			}
+		}
+	}
+}
+
+function array_avg($a)
+{
+	if (count($a) == 0) {
+		return '';
+	}
+	return array_sum($a) / count($a);
+}
+
+function bar_hits_percent($v, $percent, $active)
+{
+	$r = 220 + (int) ($percent * 25);
+	$g = $b = 220 - (int) ($percent * 220);
+	$percent = (int) ($percent * 100);
+	$a = $active ? ' active' : '';
+	return '<div title="' . $v . '">'
+		. '<div class="barf' . $a . '" style="height: ' . (100 - $percent) . '%"></div>'
+		. '<div class="barv' . $a . '" style="background: rgb(' . "$r,$g,$b" . '); height: ' . $percent . '%"></div>'
+		. '</div>';
+}
+
+function hits_to_graph($hits)
+{
+	$max = 0;
+	foreach ($hits as $v) {
+		if ($max < $v) {
+			$max = $v;
+		}
+	}
+	if (!$max) {
+		return '';
+	}
+	$t = (time() / (60 * 60)) % 24;
+	$html = array();
+	foreach ($hits as $i => $v) {
+		$html[] = bar_hits_percent($v, $v / $max, $i == $t);
+	}
+	return implode('', $html);
+}
+
+$module = "cacher";
+if (!extension_loaded('XCache')) {
+	include("../common/header.tpl.php");
+	echo '<h1>XCache is not loaded</h1>';
+	ob_start();
+	phpinfo(INFO_GENERAL);
+	$info = ob_get_clean();
+	if (preg_match_all("!<tr>[^<]*<td[^>]*>[^<]*(?:Configuration|ini|Server API)[^<]*</td>[^<]*<td[^>]*>[^<]*</td>[^<]*</tr>!s", $info, $m)) {
+		echo '<div class="phpinfo">';
+		echo 'PHP Info';
+		echo '<table>';
+		echo implode('', $m[0]);
+		echo '</table>';
+		echo '</div>';
+	}
+	if (preg_match('!<td class="v">(.*?\\.ini)!', $info, $m)) {
+		echo "Please check $m[1]";
+	}
+	else if (preg_match('!Configuration File \\(php.ini\\) Path *</td><td class="v">([^<]+)!', $info, $m)) {
+		echo "Please put a php.ini in $m[1] and load XCache extension";
+	}
+	else {
+		echo "You don't even have a php.ini yet?";
+	}
+	echo "(See above)";
+	include("../common/footer.tpl.php");
+	exit;
+}
+$pcnt = xcache_count(XC_TYPE_PHP);
+$vcnt = xcache_count(XC_TYPE_VAR);
+
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+	$remove = @ $_POST['remove'];
+	if ($remove && is_array($remove)) {
+		foreach ($remove as $name) {
+			xcache_unset($name);
+		}
+	}
+}
+
+$moduleinfo = null;
+$type_none = -1;
+if (!isset($_GET['type'])) {
+	$_GET['type'] = $type_none;
+}
+$_GET['type'] = $type = (int) $_GET['type'];
+
+// {{{ process clear
+function processClear()
+{
+	$type = isset($_POST['type']) ? $_POST['type'] : null;
+	if ($type != XC_TYPE_PHP && $type != XC_TYPE_VAR) {
+		$type = null;
+	}
+	if (isset($type)) {
+		$cacheid = (int) (isset($_POST['cacheid']) ? $_POST['cacheid'] : 0);
+		if (isset($_POST['clearcache'])) {
+			$count = xcache_count($type);
+			if ($cacheid >= 0) {
+				for ($cacheid = 0; $cacheid < $count; $cacheid ++) {
+					xcache_clear_cache($type, $cacheid);
+				}
+			}
+			else {
+				xcache_clear_cache($type);
+			}
+		}
+	}
+}
+processClear();
+// }}}
+// {{{ load info/list
+$cacheinfos = array();
+$total = array();
+for ($i = 0; $i < $pcnt; $i ++) {
+	$data = xcache_info(XC_TYPE_PHP, $i);
+	if ($type === XC_TYPE_PHP) {
+		$data += xcache_list(XC_TYPE_PHP, $i);
+	}
+	$data['type'] = XC_TYPE_PHP;
+	$data['cache_name'] = "php#$i";
+	$data['cacheid'] = $i;
+	$cacheinfos[] = $data;
+	if ($pcnt >= 2) {
+		calc_total($total, $data);
+	}
+}
+
+if ($pcnt >= 2) {
+	$total['type'] = XC_TYPE_PHP;
+	$total['cache_name'] = _('Total');
+	$total['cacheid'] = -1;
+	$total['gc'] = null;
+	$total['istotal'] = true;
+	$cacheinfos[] = $total;
+}
+
+$total = array();
+for ($i = 0; $i < $vcnt; $i ++) {
+	$data = xcache_info(XC_TYPE_VAR, $i);
+	if ($type === XC_TYPE_VAR) {
+		$data += xcache_list(XC_TYPE_VAR, $i);
+	}
+	$data['type'] = XC_TYPE_VAR;
+	$data['cache_name'] = "var#$i";
+	$data['cacheid'] = $i;
+	$cacheinfos[] = $data;
+	if ($vcnt >= 2) {
+		calc_total($total, $data);
+	}
+}
+
+if ($vcnt >= 2) {
+	$total['type'] = XC_TYPE_VAR;
+	$total['cache_name'] = _('Total');
+	$total['cacheid'] = -1;
+	$total['gc'] = null;
+	$total['istotal'] = true;
+	$cacheinfos[] = $total;
+}
+// }}}
+// {{{ merge the list
+switch ($type) {
+case XC_TYPE_PHP:
+case XC_TYPE_VAR:
+	$cachelist = array('type' => $type, 'cache_list' => array(), 'deleted_list' => array());
+	if ($type == XC_TYPE_VAR) {
+		$cachelist['type_name'] = 'var';
+	}
+	else {
+		$cachelist['type_name'] = 'php';
+	}
+	foreach ($cacheinfos as $i => $c) {
+		if (!empty($c['istotal'])) {
+			continue;
+		}
+		if ($c['type'] == $type && isset($c['cache_list'])) {
+			foreach ($c['cache_list'] as $e) {
+				$e['cache_name'] = $c['cache_name'];
+				$cachelist['cache_list'][] = $e;
+			}
+			foreach ($c['deleted_list'] as $e) {
+				$e['cache_name'] = $c['cache_name'];
+				$cachelist['deleted_list'][] = $e;
+			}
+		}
+	}
+	if ($type == XC_TYPE_PHP) {
+		$inodes = array();
+		$haveinode = false;
+		foreach ($cachelist['cache_list'] as $e) {
+			if (isset($e['file_inode'])) {
+				$haveinode = true;
+				break;
+			}
+		}
+		if (!$haveinode) {
+			foreach ($cachelist['deleted_list'] as $e) {
+				if (isset($e['file_inode'])) {
+					$haveinode = true;
+					break;
+				}
+			}
+		}
+	}
+	unset($data);
+	break;
+
+default:
+	$_GET['type'] = $type_none;
+	$cachelist = array();
+	ob_start();
+	phpinfo(INFO_MODULES);
+	$moduleinfo = ob_get_clean();
+	if (preg_match_all('!(XCache[^<>]*)</a></h2>(.*?)<h2>!is', $moduleinfo, $m)) {
+		$moduleinfo = array();
+		foreach ($m[1] as $i => $dummy) {
+			$moduleinfo[] = '<h3>' . trim($m[1][$i]) . '</h3>';
+			$moduleinfo[] = str_replace('<br />', '', trim($m[2][$i]));
+		}
+		$moduleinfo = implode('', $moduleinfo);
+	}
+	else {
+		$moduleinfo = null;
+	}
+	break;
+}
+// }}}
+
+$type_php = XC_TYPE_PHP;
+$type_var = XC_TYPE_VAR;
+$listTypes = array($type_none => _('Statistics'), $type_php => _('List PHP'), $type_var => _('List Var Data'));
+
+include("cacher.tpl.php");
+
+?>
Index: /trunk/htdocs/cacher/cacher.tpl.php
===================================================================
--- /trunk/htdocs/cacher/cacher.tpl.php	(revision 1053)
+++ /trunk/htdocs/cacher/cacher.tpl.php	(revision 1053)
@@ -0,0 +1,303 @@
+<?php include("../common/header.tpl.php"); ?>
+<div class="switcher"><?php echo switcher("type", $listTypes); ?></div>
+<div id="help">
+	<a href="help.php"><?php echo _("Help") ?> &raquo;</a>
+</div>
+<?php
+$a = new Cycle('class="col1"', 'class="col2"');
+$b = new Cycle('class="col1"', 'class="col2"');
+?>
+<table cellspacing="0" cellpadding="4" class="cycles caches">
+	<caption><?php echo _('Caches'); ?></caption>
+	<col />
+	<col align="right" />
+	<col align="right" />
+	<col align="right" />
+	<col />
+	<col />
+	<col align="right" />
+	<col align="right" />
+	<col align="right" />
+	<col />
+	<col align="right" />
+	<col align="right" />
+	<col align="right" />
+	<col align="right" />
+	<col align="right" />
+	<col align="right" />
+	<col align="right" />
+	<col />
+	<tr <?php echo $a->next(); ?>>
+	<?php echo
+		th(N_("cache.cache"))
+		, th(N_("cache.size"))
+		, th(N_("cache.avail"))
+		, th(N_("cache.used"))
+		, th(N_("cache.blocksgraph"))
+		, th(N_("cache.operations"))
+		, th(N_("cache.compiling"))
+		, th(N_("cache.hits"))
+		, th(N_("cache.hits_graph"))
+		, th(N_("cache.hits_avg_h"))
+		, th(N_("cache.hits_avg_s"))
+		, th(N_("cache.updates"))
+		, th(N_("cache.clogs"))
+		, th(N_("cache.ooms"))
+		, th(N_("cache.errors"))
+		, th(N_("cache.readonly_protected"))
+		, th(N_("cache.cached"))
+		, th(N_("cache.deleted"))
+		, th(N_("cache.gc_timer"))
+		;
+	?>
+	</tr>
+	<?php
+	$numkeys = explode(',', 'slots,size,avail,hits,updates,clogs,ooms,errors,cached,deleted');
+	$l_clear = _('Clear');
+	$l_clear_confirm = _('Sure to clear?');
+	foreach ($cacheinfos as $i => $ci) {
+		echo "
+		<tr ", $a->next(), ">";
+		$pvalue = (int) ($ci['avail'] / $ci['size'] * 100);
+		$pempty = 100 - $pvalue;
+		if ($config['percent_graph_type'] == 'used') {
+			// swap
+			$tmp = $pvalue;
+			$pvalue = $pempty;
+			$pempty = $tmp;
+		}
+
+		$w = $config['percent_graph_width'];
+		if (empty($ci['istotal'])) {
+			$graph = freeblock_to_graph($ci['free_blocks'], $ci['size']);
+			$blocksgraph = "<div class=\"blocksgraph\" style=\"width: {$w}px\">{$graph}</div>";
+		}
+		else {
+			$blocksgraph = '';
+		}
+
+		$ci_slots = size($ci['slots']);
+		$ci_size  = size($ci['size']);
+		$ci_avail = size($ci['avail']);
+		$ci = number_formats($ci, $numkeys);
+
+		$hits_avg_h     = number_format(array_avg($ci['hits_by_hour']), 2);
+		$hits_avg_s     = number_format(array_avg($ci['hits_by_second']), 2);
+		$hits_graph_h   = hits_to_graph($ci['hits_by_hour']);
+		$hits_graph_h_w = count($ci['hits_by_hour']) * 2;
+
+		if (!empty($ci['istotal'])) {
+			$ci['compiling']    = '-';
+			$ci['can_readonly'] = '-';
+		}
+		else {
+			$ci['compiling']    = $ci['type'] == $type_php ? ($ci['compiling'] ? 'yes' : 'no') : '-';
+			$ci['can_readonly'] = $ci['can_readonly'] ? 'yes' : 'no';
+		}
+		echo <<<EOS
+		<th>{$ci['cache_name']}</th>
+		<td title="{$ci['slots']}">{$ci_slots}</td>
+		<td title="{$ci['size']}">{$ci_size}</td>
+		<td title="{$ci['avail']}">{$ci_avail}</td>
+		<td title="{$pvalue} %"
+			><div class="percent" style="width: {$w}px"
+				><div style="width: {$pvalue}%" class="pvalue"></div
+				><div style="width: {$pempty}%" class="pempty"></div
+			></div
+		>{$blocksgraph}</td>
+		<td
+			><form method="post" action=""
+				><div
+					><input type="hidden" name="type" value="{$ci['type']}"
+					/><input type="hidden" name="cacheid" value="{$ci['cacheid']}"
+					/><input type="submit" name="clearcache" value="{$l_clear}" class="submit" onclick="return confirm('{$l_clear_confirm}');"
+				/></div
+			></form
+		></td>
+		<td>{$ci['compiling']}</td>
+		<td>{$ci['hits']}</td>
+		<td><div class="hitsgraph" style="width: {$hits_graph_h_w}px">{$hits_graph_h}</div></td>
+		<td>{$hits_avg_h}</td>
+		<td>{$hits_avg_s}</td>
+		<td>{$ci['updates']}</td>
+		<td>{$ci['clogs']}</td>
+		<td>{$ci['ooms']}</td>
+		<td>{$ci['errors']}</td>
+		<td>{$ci['can_readonly']}</td>
+		<td>{$ci['cached']}</td>
+		<td>{$ci['deleted']}</td>
+		<td>{$ci['gc']}</td>
+EOS;
+
+			$b->reset();
+			?>
+	</tr>
+	<?php } ?>
+</table>
+<div class="blockarea legends">
+	<div class="legendtitle"><?php echo _('Legends:'); ?></div>
+	<div class="legend pvalue">&nbsp;&nbsp;</div>
+	<div class="legendtitle"><?php echo _($config['percent_graph_type'] == 'free' ? '% Free' : '% Used'); ?></div>
+	<div class="legend" style="background: rgb(0,0,255)">&nbsp;&nbsp;</div>
+	<div class="legendtitle"><?php echo _($config['percent_graph_type'] == 'free' ? 'Free Blocks' : 'Used Blocks'); ?></div>
+	<div class="legend" style="background: rgb(255,0,0)">&nbsp;&nbsp;</div>
+	<div class="legendtitle"><?php echo _('Hits'); ?></div>
+</div>
+<?php
+
+if ($cachelist) {
+	$isphp = $cachelist['type'] == $type_php;
+	ob_start($config['path_nicer']);
+	foreach (array('Cached' => $cachelist['cache_list'], 'Deleted' => $cachelist['deleted_list']) as $listname => $entries) {
+		$a->reset();
+		?>
+
+	<form action="" method="post">
+	<table cellspacing="0" cellpadding="4" class="cycles entries" width="100%">
+		<caption><?php echo _("{$cachelist['type_name']} $listname"); ?></caption>
+		<?php
+		echo "
+		<tr ", $a->next(), ">";
+		?>
+
+			<?php
+			if ($isphp) {
+				echo
+					th("entry.id")
+					;
+			}
+			else {
+				echo
+					th("entry.remove", 'width="20"')
+					;
+			}
+
+			echo
+				th(N_("entry.name"))
+				, th(N_("entry.hits"))
+				, th(N_("entry.size"))
+				;
+
+			if ($isphp) {
+				echo
+					th(N_("entry.refcount"))
+					, th(N_("entry.phprefcount"))
+					, th(N_("entry.class_cnt"))
+					, th(N_("entry.function_cnt"))
+					, th(N_("entry.file_size"))
+					, th(N_("entry.file_mtime"))
+					;
+				if ($haveinode) {
+					echo
+						th(N_("entry.file_device"))
+						, th(N_("entry.file_inode"))
+						;
+				}
+			}
+			echo
+				th(N_("entry.hash"))
+				, th(N_("entry.atime"))
+				, th(N_("entry.ctime"))
+				;
+
+			if ($listname == 'Deleted') {
+				echo
+					th(N_("entry.delete"))
+					;
+			}
+			?>
+		</tr>
+		<?php
+		foreach ($entries as $i => $entry) {
+			echo "
+			<tr ", $a->next(), ">";
+			$name     = htmlspecialchars($entry['name']);
+			$hits     = number_format($entry['hits']);
+			$size     = size($entry['size']);
+			if ($isphp) {
+				$class_cnt    = number_format($entry['class_cnt']);
+				$function_cnt = number_format($entry['function_cnt']);
+				$phprefcount  = number_format($entry['phprefcount']);
+				$file_size    = size($entry['file_size']);
+			}
+
+			if ($isphp) {
+				$file_mtime = age($entry['file_mtime']);
+			}
+			$ctime = age($entry['ctime']);
+			$atime = age($entry['atime']);
+			if ($listname == 'Deleted') {
+				$dtime = age($entry['dtime']);
+			}
+
+			if ($isphp) {
+				$namelink = $name;
+				echo <<<ENTRY
+				<td>{$entry['cache_name']} {$i}</td>
+ENTRY;
+			}
+			else {
+				echo <<<ENTRY
+					<td><label><input type="checkbox" name="remove[]" value="{$name}"/>{$entry['cache_name']} {$i}</label></td>
+ENTRY;
+				$uname = urlencode($entry['name']);
+				$namelink = "<a href=\"edit.php?name=$uname\">$name</a>";
+			}
+
+			echo <<<ENTRY
+			<td>{$namelink}</td>
+			<td align="right" int="{$entry['hits']}">{$entry['hits']}</td>
+			<td align="right" int="{$entry['size']}">{$size}</td>
+ENTRY;
+			if ($isphp) {
+				$refcount = number_format($entry['refcount']);
+				echo <<<ENTRY
+				<td align="right" int="{$entry['refcount']}">{$entry['refcount']}</td>
+				<td align="right" int="{$entry['phprefcount']}">{$phprefcount}</td>
+				<td align="right" int="{$entry['class_cnt']}">{$class_cnt}</td>
+				<td align="right" int="{$entry['function_cnt']}">{$function_cnt}</td>
+				<td align="right" int="{$entry['file_size']}">{$file_size}</td>
+				<td align="right" int="{$entry['file_mtime']}">{$file_mtime}</td>
+ENTRY;
+				if (isset($entry['file_inode'])) {
+					echo <<<ENTRY
+					<td align="right" int="{$entry['file_device']}">{$entry['file_device']}</td>
+					<td align="right" int="{$entry['file_inode']}">{$entry['file_inode']}</td>
+ENTRY;
+				}
+			}
+			echo <<<ENTRY
+			<td align="right" int="{$entry['hvalue']}">{$entry['hvalue']}</td>
+			<td align="right" int="{$entry['atime']}">{$atime}</td>
+			<td align="right" int="{$entry['ctime']}">{$ctime}</td>
+ENTRY;
+			if ($listname == 'Deleted') {
+			echo <<<ENTRY
+				<td align="right" int="{$entry['dtime']}">{$dtime}</td>
+ENTRY;
+			}
+
+			echo "
+		</tr>
+			";
+		}
+		?>
+
+	</table>
+	<?php if (!$isphp) { ?>
+	<input type="submit" value="<?php echo _("Remove Selected"); ?>">
+	<?php } ?>
+	</form>
+<?php
+	}
+	ob_end_flush();
+}
+if ($moduleinfo) {
+	$t_moduleinfo = _("Module Info");
+	echo <<<HTML
+<h2>$t_moduleinfo</h2>
+<div class="phpinfo">$moduleinfo</div>
+HTML;
+}
+?>
+<?php include("../common/footer.tpl.php"); ?>
Index: unk/htdocs/cacher/common-en.lang.php
===================================================================
--- /trunk/htdocs/cacher/common-en.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,81 +1,0 @@
-<?php
-
-$GLOBALS['config']['show_todo_strings'] = false;
-
-$strings = array(
-		'cache.cache'
-		=> 'Cache|',
-		'cache.slots'
-		=> 'Slots|Number of hash slots. the setting from your php.ini',
-		'cache.size'
-		=> 'Size|Cache Size, Size of the cache (or cache chunk), in bytes',
-		'cache.avail'
-		=> 'Avail|Available Memory, free memory in bytes of this cache',
-		'cache.used'
-		=> 'Used|Used Memory, used memory in bytes of this cache',
-		'cache.blocksgraph'
-		=> 'Percent Graph|Shows how much memory available in percent, and memory blocks status in graph',
-		'cache.operations'
-		=> 'Operations|Press the clear button to clean this cache',
-		'cache.compiling'
-		=> 'Comp.|Compiling flag, "yes" if the cache is busy compiling php script',
-		'cache.hits'
-		=> 'Hits|Cache Hits, hit=a var/php is loaded from this cache',
-		'cache.hits_avg_h'
-		=> 'Hits/H|Average Hits per Hour. Only last 24 hours is logged',
-		'cache.hits_graph'
-		=> 'Hits*24H|Hits graph of last 24 hours',
-		'cache.hits_avg_s'
-		=> 'Hits/S|Average Hits per Second. Only last 5 seconds is logged',
-		'cache.updates'
-		=> 'Updates|Cache Updates',
-		'cache.clogs'
-		=> 'Clogs|Compiling Clogs, clog=compiling is needed but avoided to wait(be blocked) when the cache is busy compiling already',
-		'cache.ooms'
-		=> 'OOMs|Out Of Memory, how many times a new item should be stored but there isn\'t enough memory in the cache, think of increasing the xcache.size or xcache.var_size',
-		'cache.errors'
-		=> 'Errs|Compiler errors, how many times your script is compiled but failed. You should really check what is happening if you see this value increase. (See Help for more information)',
-		'cache.readonly_protected'
-		=> 'Protected|Whether readonly_protection is available and enable on this cache (See help for more information)',
-		'cache.cached'
-		=> 'Cached|Number of entries stored in this cache',
-		'cache.deleted'
-		=> 'Deleted|Number of entries is pending in delete list (expired but referenced)',
-		'cache.gc_timer'
-		=> 'GC|Seconds count down of Garbage Collection',
-		'entry.id'
-		=> 'Id|',
-		'entry.name'
-		=> 'Entry name|The entry name or filename',
-		'entry.hits'
-		=> 'Hits|Times this entry is hit (loaded from this cache)',
-		'entry.size'
-		=> 'Size|Size in bytes of this entry in the cache',
-		'entry.refcount'
-		=> 'Refs|Reference count of this entry is holded by a php request',
-		'entry.phprefcount'
-		=> 'Shares|Count of entry sharing this php data',
-		'entry.file_size'
-		=> 'Src Size|Size of the source file',
-		'entry.file_mtime'
-		=> 'Modified|Last modified time of the source file',
-		'entry.file_device'
-		=> 'dev|device number of the source file',
-		'entry.file_inode'
-		=> 'ino|inode number of the source file',
-		'entry.class_cnt'
-		=> 'Cls.|Count of classes',
-		'entry.function_cnt'
-		=> 'Funcs|Count of functions',
-		'entry.hash'
-		=> 'Hash|Hash value of this entry',
-		'entry.atime'
-		=> 'Access|Last time when this entry is accessed',
-		'entry.ctime'
-		=> 'Create|The time when this entry is stored',
-		'entry.delete'
-		=> 'Delete|The time when this entry is deleted',
-		'entry.remove'
-		=> 'Remove|',
-);
-
Index: unk/htdocs/cacher/common-zh-simplified-utf-8.lang.php
===================================================================
--- /trunk/htdocs/cacher/common-zh-simplified-utf-8.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,131 +1,0 @@
-<?php
-
-$strings = array(
-		'XCache Help'
-		=> 'XCache 帮助信息',
-		'Help'
-		=> '帮助',
-		'Clear'
-		=> '清除',
-		'Sure to clear?'
-		=> '确认要清除吗?',
-		'% Free'
-		=> '% 剩余',
-		'% Used'
-		=> '% 已用',
-		'Hits'
-		=> '命中',
-		'Modify'
-		=> '修改',
-		'See also'
-		=> '建议参考',
-		'Legends:'
-		=> '图例:',
-		'Used Blocks'
-		=> '已用块',
-		'Free Blocks'
-		=> '未用块',
-		'Total'
-		=> '总共',
-		'Caches'
-		=> '缓存区',
-		'php Cached'
-		=> '缓存的 php 脚本',
-		'php Deleted'
-		=> '待删 php 缓存',
-		'var Cached'
-		=> '缓存的变量',
-		'var Deleted'
-		=> '待删变量',
-		'Statistics'
-		=> '统计信息',
-		'List PHP'
-		=> '列出PHP',
-		'List Var Data'
-		=> '列变量数据',
-		'XCache %s Administration'
-		=> 'XCache %s 管理页面',
-		'Module Info'
-		=> '模块信息',
-		'Remove Selected'
-		=> '删除所选',
-		'Editing Variable %s'
-		=> '正在编辑变量 %s',
-		'Set %s in config to enable'
-		=> '请在配置文件中设置 %s 启用本功能',
-		'cache.cache'
-		=> '缓存|',
-		'cache.slots'
-		=> '槽|Hash 槽个数, 对应 php.ini 里的设置',
-		'cache.size'
-		=> '大小|共享内存区大小, 单位: 字节',
-		'cache.avail'
-		=> '剩余|可用内存, 对应共享内存区的剩余内存字节数',
-		'cache.used'
-		=> '已用|已用内存, 对应共享内存区的已用内存字节数',
-		'cache.blocksgraph'
-		=> '百分比图|条状显示可用内存的比例, 以及显示分配块状态',
-		'cache.operations'
-		=> '操作|点击按钮清除对应共享内存区的数据',
-		'cache.compiling'
-		=> '编译中|编译标记, 当共享内存区正在编译 php 脚本时标记为 "yes"',
-		'cache.hits'
-		=> '命中|共享内存命中次数, 命中=从该共享内存载入php或者变量',
-		'cache.hits_avg_h'
-		=> '命中/H|每小时命中次数. 只统计最后 24 小时',
-		'cache.hits_graph'
-		=> '24H 分布|24 小时命中分布图. 图表现是最后 24 小时的命中次数',
-		'cache.hits_avg_s'
-		=> '命中/S|每秒命中次数. 只统计最后 5 秒',
-		'cache.updates'
-		=> '更新|共享内存更新次数',
-		'cache.clogs'
-		=> '阻塞|编译阻塞跳过, 阻塞=当需该共享内存区负责编译时, 其他进程/现成无法访问此共享内存. 跳过=XCache 自动判断阻塞的共享内存区自动跳过阻塞等待, 直接使用非共享内存方式继续处理请求',
-		'cache.ooms'
-		=> '内存不足|内存不足次数, 显示需要存储新数据但是共享内存区内存不足的次数. 如果出现太频繁请考虑加大配置中的 xcache.size 或者 xcache.var_size',
-		'cache.errors'
-		=> '错误|编译错误, 显示您的脚本被编译时出错的次数. 如果您发现这个数字不断增长, 您应该检查什么脚本产生错误. 参考 帮助 获取更多信息',
-		'cache.readonly_protected'
-		=> '保护|显示该 Cache 是否支持并启用 readonly_protection. 参考 帮助 获取更多信息',
-		'cache.cached'
-		=> '缓存|共享内存于该共享内存区的项目条数',
-		'cache.deleted'
-		=> '待删|共享内存区内将要删除的项目 (已经删除但是还被某些进程占用)',
-		'cache.gc_timer'
-		=> 'GC|垃圾回收的倒计时',
-		'entry.id'
-		=> 'Id|',
-		'entry.name'
-		=> '项目名/文件名|项目名或者文件名',
-		'entry.hits'
-		=> '命中|该项目被命中的次数 (从共享内存区载入)',
-		'entry.size'
-		=> '大小|项目在共享内存里占用字节数',
-		'entry.refcount'
-		=> '引用数|项目依然被其他进程占据的引用次数',
-		'entry.phprefcount'
-		=> '共享数|与本项目相同 PHP 代码的个数',
-		'entry.file_size'
-		=> '源大小|源文件大小',
-		'entry.file_mtime'
-		=> '修改|源文件最后修改时间',
-		'entry.file_device'
-		=> 'dev|源文件所在设备ID',
-		'entry.file_inode'
-		=> 'ino|源文件的 inode',
-		'entry.class_cnt'
-		=> '类|类个数',
-		'entry.function_cnt'
-		=> '函数|函数个数',
-		'entry.hash'
-		=> '哈希|该项目的哈希值',
-		'entry.atime'
-		=> '访问|最后访问该项目的时间',
-		'entry.ctime'
-		=> '创建|该项目被创建于共享内的时间',
-		'entry.delete'
-		=> '删除|该项目被决定删除的时间',
-		'entry.remove'
-		=> '删除|',
-);
-
Index: unk/htdocs/cacher/common-zh-traditional-utf-8.lang.php
===================================================================
--- /trunk/htdocs/cacher/common-zh-traditional-utf-8.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,131 +1,0 @@
-<?php
-
-$strings = array(
-		'XCache Help'
-		=> 'XCache 說明訊息',
-		'Help'
-		=> '說明',
-		'Clear'
-		=> '清除',
-		'Sure to clear?'
-		=> '確認要清除嗎?',
-		'% Free'
-		=> '% 剩余',
-		'% Used'
-		=> '% 已用',
-		'Hits'
-		=> '命中',
-		'Modify'
-		=> '修改',
-		'See also'
-		=> '建議參考',
-		'Legends:'
-		=> '图例:',
-		'Used Blocks'
-		=> '已用块',
-		'Free Blocks'
-		=> '未用块',
-		'Total'
-		=> '总共',
-		'Caches'
-		=> '快取',
-		'php Cached'
-		=> '快取的 php 指令',
-		'php Deleted'
-		=> '待刪 php 指令',
-		'var Cached'
-		=> '快取的變數',
-		'var Deleted'
-		=> '待刪變數',
-		'Statistics'
-		=> '統計訊息',
-		'List PHP'
-		=> '列出PHP',
-		'List Var Data'
-		=> '列變數資料',
-		'XCache %s Administration'
-		=> 'XCache %s 管理頁面',
-		'Module Info'
-		=> '組元訊息',
-		'Remove Selected'
-		=> '移除所选',
-		'Editing Variable %s'
-		=> '正在编辑变量 %s',
-		'Set %s in config to enable'
-		=> '請在配置文件中設置 %s 啟用本功能',
-		'cache.cache'
-		=> '快取|',
-		'cache.slots'
-		=> '槽|Hash 槽個數，對應 php.ini 裡的設置',
-		'cache.size'
-		=> '大小|共享記憶體區大小，單位：位元',
-		'cache.avail'
-		=> '剩餘|可用記憶體，對應共享記憶體區的剩餘記憶體位元數',
-		'cache.used'
-		=> '已用|已用内存, 对应共享内存区的已用内存字节数',
-		'cache.blocksgraph'
-		=> '百分比图|條狀顯示可用記憶體的比例',
-		'cache.operations'
-		=> '操作按鈕|點擊按鈕清除對應共享記憶體區的資料',
-		'cache.compiling'
-		=> '編譯中|編譯標記，當共享記憶體區正在編譯 php 指令時標記為 "yes"',
-		'cache.hits'
-		=> '命中|共享記憶體命中次數，命中=從該共享記憶體載入php或者變數',
-		'cache.hits_avg_h'
-		=> '命中/H|每小时命中次数. 只统计最后 24 小时',
-		'cache.hits_graph'
-		=> '24H 分布|24 小时命中分布图. 图表现是最后 24 小时的命中次数',
-		'cache.hits_avg_s'
-		=> '命中/S|每秒命中次数. 只统计最后 5 秒',
-		'cache.updates'
-		=> '更新|共享記憶更新過次數',
-		'cache.clogs'
-		=> '阻塞|編譯阻塞跳過，阻塞=當需該共享記憶體區負責編譯時，其他程序/現成無法存取此共享記憶體. 跳過=XCache 自動判斷阻塞的共享記憶體區自動跳過阻塞等待，直接使用非共享記憶體方式繼續處理請求',
-		'cache.ooms'
-		=> '記憶體不足|記憶體不足次數，顯示需要儲存新資料但是共享記憶體區記憶體不足的次數. 如果出現太頻繁請考慮加大配置中的 xcache.size 或者 xcache.var_size',
-		'cache.errors'
-		=> '错误|编译错误, 显示您的脚本被编译时出错的次数. 如果您发现这个数字不断增长, 您应该检查什么脚本产生错误. 参考 說明',
-		'cache.readonly_protected'
-		=> 'Protected|顯示該 Cache 是否支援並啟用 readonly_protection. 参考 說明',
-		'cache.cached'
-		=> '快取|共享記憶體於該共享記憶體區的項目個數',
-		'cache.deleted'
-		=> '待刪|共享記憶體區內將要刪除的項目 (已經刪除但是還被某些程序佔用)',
-		'cache.gc_timer'
-		=> 'GC|垃圾回收的倒數計時',
-		'entry.id'
-		=> 'Id|',
-		'entry.name'
-		=> '項目名稱/檔案名稱|項目名稱或者檔案名稱',
-		'entry.hits'
-		=> '命中|該項目被命中的次數 (從共享記憶體區載入)',
-		'entry.size'
-		=> '大小|項目在共享記憶體裡佔用位元數',
-		'entry.refcount'
-		=> '引用數|項目依然被其他程序佔用的引用次數',
-		'entry.phprefcount'
-		=> '共享|與本項目相同 PHP 內容的个數',
-		'entry.file_size'
-		=> '源大小|原始檔案大小',
-		'entry.file_mtime'
-		=> '修改|原始檔案最後修改時間',
-		'entry.file_device'
-		=> 'dev|原始檔案所在設備ID',
-		'entry.file_inode'
-		=> 'ino|原始檔案的inode',
-		'entry.class_cnt'
-		=> '类|类个数',
-		'entry.function_cnt'
-		=> '函数|函数个数',
-		'entry.hash'
-		=> 'Hash|Hash',
-		'entry.atime'
-		=> '存取|最後存取該項目的時間',
-		'entry.ctime'
-		=> '建立|該項目被建立於共享內的時間',
-		'entry.delete'
-		=> '移除|該項目被移除於共享內的時間',
-		'entry.remove'
-		=> '移除|',
-);
-
Index: unk/htdocs/cacher/common.php
===================================================================
--- /trunk/htdocs/cacher/common.php	(revision 1052)
+++ 	(revision )
@@ -1,152 +1,0 @@
-<?php
-
-function xcache_validateFileName($name)
-{
-	return preg_match('!^[a-zA-Z0-9._-]+$!', $name);
-}
-
-function get_language_file_ex($name, $l, $s)
-{
-	static $lmap = array(
-			'zh'    => 'zh-simplified',
-			'zh-hk' => 'zh-traditional',
-			'zh-tw' => 'zh-traditional',
-			);
-	static $smap = array(
-			'gbk'     => 'gb2312',
-			'gb18030' => 'gb2312',
-			);
-
-	if (isset($lmap[$l])) {
-		$l = $lmap[$l];
-	}
-	$file = "$name-$l-$s.lang.php";
-	if (xcache_validateFileName($file) && file_exists($file)) {
-		return $file;
-	}
-	if (isset($smap[$s])) {
-		$s = $smap[$s];
-		$file = "$name-$l-$s.lang.php";
-		if (xcache_validateFileName($file) && file_exists($file)) {
-			return $file;
-		}
-	}
-	$file = "$name-$l.lang.php";
-	if (xcache_validateFileName($file) && file_exists($file)) {
-		return $file;
-	}
-	return null;
-}
-
-function get_language_file($name)
-{
-	global $config;
-	$s = strtolower($config['charset']);
-	if (!empty($config['lang'])) {
-		$l = strtolower($config['lang']);
-		$file = get_language_file_ex($name, $l, $s);
-		if (!isset($file)) {
-			$l = strtok($l, ':-');
-			$file = get_language_file_ex($name, $l, $s);
-		}
-	}
-	else if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
-		foreach (explode(',', str_replace(' ', '', $_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $l) {
-			$l = strtok($l, ':;');
-			$file = get_language_file_ex($name, $l, $s);
-			if (isset($file)) {
-				$config['lang'] = $l;
-				break;
-			}
-			if (strpos($l, '-') !== false) {
-				$ll = strtok($l, ':-');
-				$file = get_language_file_ex($name, $ll, $s);
-				if (isset($file)) {
-					$config['lang'] = $l;
-					break;
-				}
-			}
-		}
-	}
-	return isset($file) ? $file : "$name-en.lang.php";
-}
-
-function _($str)
-{
-	if (isset($GLOBALS['strings'][$str])) {
-		return $GLOBALS['strings'][$str];
-	}
-	if (!empty($GLOBALS['config']['show_todo_strings'])) {
-		return '<span style="color:red">' . htmlspecialchars($str) . '</span>|';
-	}
-	return $str;
-}
-
-function __($str)
-{
-	return _($str);
-}
-
-function N_($str)
-{
-	return $str;
-}
-
-function stripaddslashes_array($value, $mqs = false)
-{
-	if (is_array($value)) {
-		foreach($value as $k => $v) {
-			$value[$k] = stripaddslashes_array($v, $mqs);
-		}
-	}
-	else if(is_string($value)) {
-		$value = $mqs ? str_replace('\'\'', '\'', $value) : stripslashes($value);
-	}
-	return $value;
-}
-
-function ob_filter_path_nicer_default($list_html)
-{
-	$sep = DIRECTORY_SEPARATOR;
-	$docRoot = $_SERVER['DOCUMENT_ROOT'];
-	if ($sep != '/') {
-		$docRoot = str_replace('/', $sep, $docRoot);
-	}
-	$list_html = str_replace(">$docRoot",  ">{DOCROOT}" . (substr($docRoot, -1) == $sep ? $sep : ""), $list_html);
-	$xcachedir = realpath(dirname(__FILE__) . "$sep..$sep");
-	$list_html = str_replace(">$xcachedir$sep", ">{XCache}$sep", $list_html);
-	if ($sep == '/') {
-		$list_html = str_replace(">/home/", ">{H}/", $list_html);
-	}
-	return $list_html;
-}
-
-
-error_reporting(E_ALL);
-ini_set('display_errors', 'On');
-define('REQUEST_TIME', time());
-
-if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc()) {
-	$mqs = (bool) ini_get('magic_quotes_sybase');
-	$_GET = stripaddslashes_array($_GET, $mqs);
-	$_POST = stripaddslashes_array($_POST, $mqs);
-	$_REQUEST = stripaddslashes_array($_REQUEST, $mqs);
-	unset($mqs);
-}
-ini_set('magic_quotes_runtime', '0');
-
-$config = array();
-include("./config.default.php");
-if (file_exists("./config.php")) {
-	include("./config.php");
-}
-
-include(get_language_file("common"));
-if (empty($config['lang'])) {
-	$config['lang'] = 'en-us';
-}
-
-header("Cache-Control: no-cache, must-revalidate");
-header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
-
-?>
Index: /trunk/htdocs/cacher/config.default.php
===================================================================
--- /trunk/htdocs/cacher/config.default.php	(revision 1052)
+++ /trunk/htdocs/cacher/config.default.php	(revision 1053)
@@ -1,15 +1,8 @@
 <?php
 
-// this is default config
-// DO NOT rename/delete/modify this file
-// see config.example.php
+// [default config]
+// DO NOT rename/delete/modify this file which will be overwritten when upgrade
+// See config.example.php instead
 
-// detected by browser
-// $config['lang'] = 'en-us';
-
-$config['charset'] = "UTF-8";
-
-// translators only
-$config['show_todo_strings'] = false;
 
 // width of graph for free or usage blocks
@@ -21,6 +14,2 @@
 $config['enable_eval'] = false;
 
-// this ob filter is applied for the cache list, not the whole page
-$config['path_nicer'] = 'ob_filter_path_nicer_default';
-
-?>
Index: /trunk/htdocs/cacher/config.example.php
===================================================================
--- /trunk/htdocs/cacher/config.example.php	(revision 1052)
+++ /trunk/htdocs/cacher/config.example.php	(revision 1053)
@@ -1,16 +1,13 @@
 <?php
 
-// this is example config
-// DO NOT rename/delete/modify this file
-// if you want to customize config, copy this file and name it as config.php
-// upgrading your config.php when config.example.php were upgraded
-
-// leave this setting unset to auto detect using browser request header
-// $config['lang'] = 'en-us';
-
-$config['charset'] = "UTF-8";
-
-// enable this for translators only
-$config['show_todo_strings'] = false;
+// DO NOT rename/delete/modify example file which will be overwritten when upgrade
+// How To Custom Config:
+// 1. copy config.example.php config.php; edit config.php
+// 2. upgrading your config.php when config.example.php were upgraded
+// XCache will load
+// 1. ../config.default.php
+// 2. ./config.default.php
+// 3. ../config.php
+// 4. ./config.php
 
 // width of graph for free or usage blocks
@@ -22,53 +19,2 @@
 $config['enable_eval'] = false;
 
-// this ob filter is applied for the cache list, not the whole page
-function custom_ob_filter_path_nicer($list_html)
-{
-	$list_html = ob_filter_path_nicer_default($list_html); // this function is from common.php
-	return $list_html;
-}
-$config['path_nicer'] = 'custom_ob_filter_path_nicer';
-
-// XCache builtin http auth is enforce for security reason
-// if http auth is disabled, any vhost user that can upload *.php, will see all variable data cached in XCache
-
-// but if you have your own login/permission system, you can use the following example
-// {{{ login example
-// this is an example only, it's won't work for you without your implemention.
-/*
-function check_admin_and_by_pass_xcache_http_auth()
-{
-	require("/path/to/user-login-and-permission-lib.php");
-	session_start();
-
-	if (user_logined()) {
-		user_load_permissions();
-		if (user_is_admin()) {
-			// user is trusted after permission checks above.
-			// tell XCache about it (the only secure way to by pass XCache http auth)
-			$_SERVER["PHP_AUTH_USER"] = "moo";
-			$_SERVER["PHP_AUTH_PW"] = "your-xcache-password-before-md5";
-		}
-		else {
-			die("Permission denied");
-		}
-	}
-	else {
-		if (!ask_the_user_to_login()) {
-			exit;
-		}
-	}
-
-	return true;
-}
-
-check_admin_and_by_pass_xcache_http_auth();
-*/
-// }}}
-
-/* by pass XCache http auth
-$_SERVER["PHP_AUTH_USER"] = "moo";
-$_SERVER["PHP_AUTH_PW"] = "your-xcache-password-before-md5";
-*/
-
-?>
Index: /trunk/htdocs/cacher/edit.php
===================================================================
--- /trunk/htdocs/cacher/edit.php	(revision 1052)
+++ /trunk/htdocs/cacher/edit.php	(revision 1053)
@@ -37,7 +37,5 @@
 }
 
-$php_version = phpversion();
-$xcache_version = XCACHE_VERSION;
-$xcache_modules = XCACHE_MODULES;
+$module = "cacher";
 
 include("edit.tpl.php");
Index: /trunk/htdocs/cacher/edit.tpl.php
===================================================================
--- /trunk/htdocs/cacher/edit.tpl.php	(revision 1052)
+++ /trunk/htdocs/cacher/edit.tpl.php	(revision 1053)
@@ -1,3 +1,3 @@
-<?php include("header.tpl.php"); ?>
+<?php include("../common/header.tpl.php"); ?>
 <?php
 $h_name = htmlspecialchars($name);
@@ -16,3 +16,3 @@
 	</fieldset>
 </form>
-<?php include("footer.tpl.php"); ?>
+<?php include("../common/footer.tpl.php"); ?>
Index: unk/htdocs/cacher/footer.tpl.php
===================================================================
--- /trunk/htdocs/cacher/footer.tpl.php	(revision 1052)
+++ 	(revision )
@@ -1,9 +1,0 @@
-<div class="footnote">
-<?php echo <<<EOS
-PHP {$php_version} Powered By: XCache {$xcache_version}, {$xcache_modules}
-EOS;
-?>
-</div>
-
-</body>
-</html>
Index: unk/htdocs/cacher/header.tpl.php
===================================================================
--- /trunk/htdocs/cacher/header.tpl.php	(revision 1052)
+++ 	(revision )
@@ -1,17 +1,0 @@
-<!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>
-<?php
-echo <<<HEAD
-	<meta http-equiv="Content-Type" content="text/html; charset=$config[charset]" />
-	<meta http-equiv="Content-Language" content="$config[lang]" />
-	<script type="text/javascript" src="tablesort.js" charset="$config[charset]"></script>
-HEAD;
-?>
-
-	<link rel="stylesheet" type="text/css" href="xcache.css" />
-	<title><?php echo sprintf(_("XCache %s Administration"), $xcache_version); ?></title>
-</head>
-
-<body>
-<h1><?php echo sprintf(_("XCache %s Administration"), $xcache_version); ?></h1>
Index: unk/htdocs/cacher/help-zh-simplified-utf-8.lang.php
===================================================================
--- /trunk/htdocs/cacher/help-zh-simplified-utf-8.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,4 +1,0 @@
-<dl>
-<dt>编译错误: </dt> <dd><a href="http://www.php.net/manual/en/ref.errorfunc.php#ini.error-log">ini.error-log</a> and <a href="http://cn2.php.net/manual/en/ref.errorfunc.php#ini.display-errors">ini.display-errors</a></dd>
-<dt>只读保护: </dt> <dd><a href="http://xcache.lighttpd.net/wiki/ReadonlyProtection">ReadonlyProtection</a></dd>
-</dl>
Index: /trunk/htdocs/cacher/help-zh-simplified.lang.php
===================================================================
--- /trunk/htdocs/cacher/help-zh-simplified.lang.php	(revision 1053)
+++ /trunk/htdocs/cacher/help-zh-simplified.lang.php	(revision 1053)
@@ -0,0 +1,4 @@
+<dl>
+<dt>编译错误: </dt> <dd><a href="http://www.php.net/manual/en/ref.errorfunc.php#ini.error-log">ini.error-log</a> and <a href="http://cn2.php.net/manual/en/ref.errorfunc.php#ini.display-errors">ini.display-errors</a></dd>
+<dt>只读保护: </dt> <dd><a href="http://xcache.lighttpd.net/wiki/ReadonlyProtection">ReadonlyProtection</a></dd>
+</dl>
Index: unk/htdocs/cacher/help-zh-traditional-utf-8.lang.php
===================================================================
--- /trunk/htdocs/cacher/help-zh-traditional-utf-8.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,4 +1,0 @@
-<dl>
-<dt>编译错误: </dt> <dd><a href="http://www.php.net/manual/en/ref.errorfunc.php#ini.error-log">ini.error-log</a> and <a href="http://cn2.php.net/manual/en/ref.errorfunc.php#ini.display-errors">ini.display-errors</a></dd>
-<dt>只读保护: </dt> <dd><a href="http://xcache.lighttpd.net/wiki/ReadonlyProtection">ReadonlyProtection</a></dd>
-</dl>
Index: /trunk/htdocs/cacher/help-zh-traditional.lang.php
===================================================================
--- /trunk/htdocs/cacher/help-zh-traditional.lang.php	(revision 1053)
+++ /trunk/htdocs/cacher/help-zh-traditional.lang.php	(revision 1053)
@@ -0,0 +1,4 @@
+<dl>
+<dt>编译错误: </dt> <dd><a href="http://www.php.net/manual/en/ref.errorfunc.php#ini.error-log">ini.error-log</a> and <a href="http://cn2.php.net/manual/en/ref.errorfunc.php#ini.display-errors">ini.display-errors</a></dd>
+<dt>只读保护: </dt> <dd><a href="http://xcache.lighttpd.net/wiki/ReadonlyProtection">ReadonlyProtection</a></dd>
+</dl>
Index: /trunk/htdocs/cacher/index.php
===================================================================
--- /trunk/htdocs/cacher/index.php	(revision 1052)
+++ /trunk/htdocs/cacher/index.php	(revision 1053)
@@ -1,3 +1,3 @@
 <?php
 
-include("xcache.php");
+include("cacher.php");
Index: unk/htdocs/cacher/xcache.css
===================================================================
--- /trunk/htdocs/cacher/xcache.css	(revision 1052)
+++ 	(revision )
@@ -1,55 +1,0 @@
-input, table { font-family: sans-serif; }
-input { font-size: 12px; }
-table { border-collapse: collapse; font-size: 11px; margin: 0; }
-table caption, h2, h3 { font-size: 16px; font-weight: bold; text-align: left; padding-top: 20px; margin-bottom: 2px; }
-h3 { font-size: 14px; padding-top: 2px; margin-bottom: 0px; }
-td, th { white-space: pre; }
-table.cycles { border: 1px solid black; margin-top: 5px; margin-bottom: 5px; }
-table.cycles .col1 { background-color: #f5f5f5; }
-table.cycles .col2 { background-color: #e0e0e0; }
-table.cycles th, table.cycles td { border: 1px solid black; font-family: monospace; }
-table.cycles th { background-color: #9999cc; color: black; font-weight: bold; height: 20px; line-height: 20px; font-family: serif; }
-th a { color: black; font-weight: bold; display: block; width: 100%; height: 100%; }
-th { font-size: 12px; }
-.phpinfo table { border: 1px solid black; margin-bottom: 1px; }
-.phpinfo table th, .phpinfo table td { border: 1px solid black; }
-.phpinfo table th { font-weight: bold; }
-.phpinfo .e {background-color: #ccccff; font-weight: bold; color: #000000;}
-.phpinfo .h {background-color: #9999cc; font-weight: bold; color: #000000;}
-.phpinfo .v {background-color: #cccccc; color: #000000;}
-.button { }
-span.sortarrow { color: white; text-decoration: none; }
-form {margin: 0; padding: 0}
-
-.percent { height: 3px; margin-bottom: 1px; border: 1px solid gray; }
-.percent div { float: left; height: 100%; }
-.pvalue { background: limegreen; }
-
-.blocksgraph { height: 16px; }
-.blocksgraph div { float: left; height: 3px; width: 4px; border: solid gray; border-width: 0 0px 1px 0; }
-.blocksgraph { border: 1px solid gray; border-bottom: 0px; }
-
-.hitsgraph { height: 20px; margin: auto; }
-.hitsgraph div { float: left; width: 2px; height: 100%; }
-.hitsgraph div:hover { background: gray; }
-.hitsgraph div div { float: none; width: 100%; }
-.hitsgraph div div.barf { border: 0px solid gray; border-width: 1px 0 0 0; }
-.hitsgraph div div.barv { border: 0px solid gray; border-width: 0 0 1px 0; }
-.hitsgraph div div.barf.active { border-color: yellow; }
-.hitsgraph div div.barv.active { border-color: yellow; }
-
-.switcher, h1 { text-align: center; display: block; }
-.switcher a { color: blue; padding: 1px 8px 1px 8px; border: 1px solid white; border-bottom-color: black; text-decoration: none; }
-.switcher a:hover.active
-, .switcher a:active.active
-, .switcher a.active { color: black; background: #99C; border-color: #99C; border-left-color: black; border-right-color: black; }
-.switcher a:hover { background: #f0f0f0; }
-.switcher a:active { background: #e0e0e0; }
-#help { display: block; float: right; }
-.footnote { text-align: right; font-size: 12px; }
-dl { overflow: hidden; }
-dt { font-weight: bold; clear: both; float: left; width: 100px; text-align: right; margin: 0; }
-dd { margin: 0; }
-.blockarea { overflow: hidden; _width: 1px; }
-div.legend { float: left; border: 1px solid gray; font: 12px/12px monospace; }
-div.legendtitle { float: left; padding: 2px; padding-right: 10px; font: 12px/12px monospace; }
Index: unk/htdocs/cacher/xcache.php
===================================================================
--- /trunk/htdocs/cacher/xcache.php	(revision 1052)
+++ 	(revision )
@@ -1,407 +1,0 @@
-<?php
-
-include("./common.php");
-
-class Cycle
-{
-	var $values;
-	var $i;
-	var $count;
-
-	function Cycle($v)
-	{
-		$this->values = func_get_args();
-		$this->i = -1;
-		$this->count = count($this->values);
-	}
-
-	function next()
-	{
-		$this->i = ($this->i + 1) % $this->count;
-		return $this->values[$this->i];
-	}
-
-	function cur()
-	{
-		return $this->values[$this->i];
-	}
-
-	function reset()
-	{
-		$this->i = -1;
-	}
-}
-
-function number_formats($a, $keys)
-{
-	foreach ($keys as $k) {
-		$a[$k] = number_format($a[$k]);
-	}
-	return $a;
-}
-
-function size($size)
-{
-	$size = (int) $size;
-	if ($size < 1024)
-		return number_format($size, 2) . ' b';
-
-	if ($size < 1048576)
-		return number_format($size / 1024, 2) . ' K';
-
-	return number_format($size / 1048576, 2) . ' M';
-}
-
-function age($time)
-{
-	if (!$time) return '';
-	$delta = REQUEST_TIME - $time;
-
-	if ($delta < 0) {
-		$delta = -$delta;
-	}
-	
-  	static $seconds = array(1, 60, 3600, 86400, 604800, 2678400, 31536000);
-	static $name = array('s', 'm', 'h', 'd', 'w', 'M', 'Y');
-
-	for ($i = 6; $i >= 0; $i --) {
-		if ($delta >= $seconds[$i]) {
-			$ret = (int) ($delta / $seconds[$i]);
-			return $ret . ' ' . $name[$i];
-		}
-	}
-
-	return '0 s';
-}
-
-function freeblock_to_graph($freeblocks, $size)
-{
-	global $config;
-
-	// cached in static variable
-	static $graph_initial;
-	if (!isset($graph_initial)) {
-		$graph_initial = array_fill(0, $config['percent_graph_width'], 0);
-	}
-	$graph = $graph_initial;
-	foreach ($freeblocks as $b) {
-		$begin = $b['offset'] / $size * $config['percent_graph_width'];
-		$end = ($b['offset'] + $b['size']) / $size * $config['percent_graph_width'];
-
-		if ((int) $begin == (int) $end) {
-			$v = $end - $begin;
-			$graph[(int) $v] += $v - (int) $v;
-		}
-		else {
-			$graph[(int) $begin] += 1 - ($begin - (int) $begin);
-			$graph[(int) $end] += $end - (int) $end;
-			for ($i = (int) $begin + 1, $e = (int) $end; $i < $e; $i ++) {
-				$graph[$i] += 1;
-			}
-		}
-	}
-	$html = array();
-	$c = 255;
-	foreach ($graph as $k => $v) {
-		if ($config['percent_graph_type'] != 'free') {
-			$v = 1 - $v;
-		}
-		$v = (int) ($v * $c);
-		$r = $g = $c - $v;
-		$b = $c;
-		$html[] = '<div style="background: rgb(' . "$r,$g,$b" . ')"></div>';
-	}
-	return implode('', $html);
-}
-
-function calc_total(&$total, $data)
-{
-	foreach ($data as $k => $v) {
-		switch ($k) {
-		case 'type':
-		case 'cache_name':
-		case 'cacheid':
-		case 'free_blocks':
-			continue 2;
-		}
-		if (!isset($total[$k])) {
-			$total[$k] = $v;
-		}
-		else {
-			switch ($k) {
-			case 'hits_by_hour':
-			case 'hits_by_second':
-				foreach ($data[$k] as $kk => $vv) {
-					$total[$k][$kk] += $vv;
-				}
-				break;
-
-			default:
-				$total[$k] += $v;
-			}
-		}
-	}
-}
-
-function array_avg($a)
-{
-	if (count($a) == 0) {
-		return '';
-	}
-	return array_sum($a) / count($a);
-}
-
-function bar_hits_percent($v, $percent, $active)
-{
-	$r = 220 + (int) ($percent * 25);
-	$g = $b = 220 - (int) ($percent * 220);
-	$percent = (int) ($percent * 100);
-	$a = $active ? ' active' : '';
-	return '<div title="' . $v . '">'
-		. '<div class="barf' . $a . '" style="height: ' . (100 - $percent) . '%"></div>'
-		. '<div class="barv' . $a . '" style="background: rgb(' . "$r,$g,$b" . '); height: ' . $percent . '%"></div>'
-		. '</div>';
-}
-
-function hits_to_graph($hits)
-{
-	$max = 0;
-	foreach ($hits as $v) {
-		if ($max < $v) {
-			$max = $v;
-		}
-	}
-	if (!$max) {
-		return '';
-	}
-	$t = (time() / (60 * 60)) % 24;
-	$html = array();
-	foreach ($hits as $i => $v) {
-		$html[] = bar_hits_percent($v, $v / $max, $i == $t);
-	}
-	return implode('', $html);
-}
-
-function switcher($name, $options)
-{
-	$n = isset($_GET[$name]) ? $_GET[$name] : null;
-	$html = array();
-	foreach ($options as $k => $v) {
-		$html[] = sprintf('<a href="?%s=%s"%s>%s</a>', $name, $k, $k == $n ? ' class="active"' : '', $v);
-	}
-	return implode('', $html);
-}
-
-function th($name, $attrs = null)
-{
-	$translated = __($name);
-	if ($translated == $name) {
-		$translated = "$name|$name";
-	}
-	list($text, $title) = explode('|', $translated, 2);
-	return sprintf('%s<th%s id="%s" title="%s"><a href="javascript:" onclick="resort(this); return false">%s</a></th>%s'
-			, "\t"
-			, $attrs ? " $attrs" : ""
-			, $name, htmlspecialchars(trim($title)), trim($text)
-			, "\n");
-}
-
-$php_version = phpversion();
-$xcache_version = XCACHE_VERSION;
-$xcache_modules = XCACHE_MODULES;
-
-if (!extension_loaded('XCache')) {
-	include("header.tpl.php");
-	echo '<h1>XCache is not loaded</h1>';
-	ob_start();
-	phpinfo(INFO_GENERAL);
-	$info = ob_get_clean();
-	if (preg_match_all("!<tr>[^<]*<td[^>]*>[^<]*(?:Configuration|ini|Server API)[^<]*</td>[^<]*<td[^>]*>[^<]*</td>[^<]*</tr>!s", $info, $m)) {
-		echo '<div class="phpinfo">';
-		echo 'PHP Info';
-		echo '<table>';
-		echo implode('', $m[0]);
-		echo '</table>';
-		echo '</div>';
-	}
-	if (preg_match('!<td class="v">(.*?\\.ini)!', $info, $m)) {
-		echo "Please check $m[1]";
-	}
-	else if (preg_match('!Configuration File \\(php.ini\\) Path *</td><td class="v">([^<]+)!', $info, $m)) {
-		echo "Please put a php.ini in $m[1] and load XCache extension";
-	}
-	else {
-		echo "You don't even have a php.ini yet?";
-	}
-	echo "(See above)";
-	include("footer.tpl.php");
-	exit;
-}
-$pcnt = xcache_count(XC_TYPE_PHP);
-$vcnt = xcache_count(XC_TYPE_VAR);
-
-if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-	$remove = @ $_POST['remove'];
-	if ($remove && is_array($remove)) {
-		foreach ($remove as $name) {
-			xcache_unset($name);
-		}
-	}
-}
-
-$moduleinfo = null;
-$type_none = -1;
-if (!isset($_GET['type'])) {
-	$_GET['type'] = $type_none;
-}
-$_GET['type'] = $type = (int) $_GET['type'];
-
-// {{{ process clear
-function processClear()
-{
-	$type = isset($_POST['type']) ? $_POST['type'] : null;
-	if ($type != XC_TYPE_PHP && $type != XC_TYPE_VAR) {
-		$type = null;
-	}
-	if (isset($type)) {
-		$cacheid = (int) (isset($_POST['cacheid']) ? $_POST['cacheid'] : 0);
-		if (isset($_POST['clearcache'])) {
-			$count = xcache_count($type);
-			if ($cacheid >= 0) {
-				for ($cacheid = 0; $cacheid < $count; $cacheid ++) {
-					xcache_clear_cache($type, $cacheid);
-				}
-			}
-			else {
-				xcache_clear_cache($type);
-			}
-		}
-	}
-}
-processClear();
-// }}}
-// {{{ load info/list
-$cacheinfos = array();
-$total = array();
-for ($i = 0; $i < $pcnt; $i ++) {
-	$data = xcache_info(XC_TYPE_PHP, $i);
-	if ($type === XC_TYPE_PHP) {
-		$data += xcache_list(XC_TYPE_PHP, $i);
-	}
-	$data['type'] = XC_TYPE_PHP;
-	$data['cache_name'] = "php#$i";
-	$data['cacheid'] = $i;
-	$cacheinfos[] = $data;
-	if ($pcnt >= 2) {
-		calc_total($total, $data);
-	}
-}
-
-if ($pcnt >= 2) {
-	$total['type'] = XC_TYPE_PHP;
-	$total['cache_name'] = _('Total');
-	$total['cacheid'] = -1;
-	$total['gc'] = null;
-	$total['istotal'] = true;
-	$cacheinfos[] = $total;
-}
-
-$total = array();
-for ($i = 0; $i < $vcnt; $i ++) {
-	$data = xcache_info(XC_TYPE_VAR, $i);
-	if ($type === XC_TYPE_VAR) {
-		$data += xcache_list(XC_TYPE_VAR, $i);
-	}
-	$data['type'] = XC_TYPE_VAR;
-	$data['cache_name'] = "var#$i";
-	$data['cacheid'] = $i;
-	$cacheinfos[] = $data;
-	if ($vcnt >= 2) {
-		calc_total($total, $data);
-	}
-}
-
-if ($vcnt >= 2) {
-	$total['type'] = XC_TYPE_VAR;
-	$total['cache_name'] = _('Total');
-	$total['cacheid'] = -1;
-	$total['gc'] = null;
-	$total['istotal'] = true;
-	$cacheinfos[] = $total;
-}
-// }}}
-// {{{ merge the list
-switch ($type) {
-case XC_TYPE_PHP:
-case XC_TYPE_VAR:
-	$cachelist = array('type' => $type, 'cache_list' => array(), 'deleted_list' => array());
-	if ($type == XC_TYPE_VAR) {
-		$cachelist['type_name'] = 'var';
-	}
-	else {
-		$cachelist['type_name'] = 'php';
-	}
-	foreach ($cacheinfos as $i => $c) {
-		if (!empty($c['istotal'])) {
-			continue;
-		}
-		if ($c['type'] == $type && isset($c['cache_list'])) {
-			foreach ($c['cache_list'] as $e) {
-				$e['cache_name'] = $c['cache_name'];
-				$cachelist['cache_list'][] = $e;
-			}
-			foreach ($c['deleted_list'] as $e) {
-				$e['cache_name'] = $c['cache_name'];
-				$cachelist['deleted_list'][] = $e;
-			}
-		}
-	}
-	if ($type == XC_TYPE_PHP) {
-		$inodes = array();
-		$haveinode = false;
-		foreach ($cachelist['cache_list'] as $e) {
-			if (isset($e['file_inode'])) {
-				$haveinode = true;
-				break;
-			}
-		}
-		if (!$haveinode) {
-			foreach ($cachelist['deleted_list'] as $e) {
-				if (isset($e['file_inode'])) {
-					$haveinode = true;
-					break;
-				}
-			}
-		}
-	}
-	unset($data);
-	break;
-
-default:
-	$_GET['type'] = $type_none;
-	$cachelist = array();
-	ob_start();
-	phpinfo(INFO_MODULES);
-	$moduleinfo = ob_get_clean();
-	if (preg_match_all('!(XCache[^<>]*)</a></h2>(.*?)<h2>!is', $moduleinfo, $m)) {
-		$moduleinfo = array();
-		foreach ($m[1] as $i => $dummy) {
-			$moduleinfo[] = '<h3>' . trim($m[1][$i]) . '</h3>';
-			$moduleinfo[] = str_replace('<br />', '', trim($m[2][$i]));
-		}
-		$moduleinfo = implode('', $moduleinfo);
-	}
-	else {
-		$moduleinfo = null;
-	}
-	break;
-}
-// }}}
-
-$type_php = XC_TYPE_PHP;
-$type_var = XC_TYPE_VAR;
-$types = array($type_none => _('Statistics'), $type_php => _('List PHP'), $type_var => _('List Var Data'));
-
-include("xcache.tpl.php");
-
-?>
Index: unk/htdocs/cacher/xcache.tpl.php
===================================================================
--- /trunk/htdocs/cacher/xcache.tpl.php	(revision 1052)
+++ 	(revision )
@@ -1,301 +1,0 @@
-<?php include("header.tpl.php"); ?>
-<div id="help">
-	<a href="help.php"><?php echo _("Help") ?> &raquo;</a>
-</div>
-<div class="switcher"><?php echo switcher("type", $types); ?></div>
-<?php
-$a = new Cycle('class="col1"', 'class="col2"');
-$b = new Cycle('class="col1"', 'class="col2"');
-?>
-<table cellspacing="0" cellpadding="4" class="cycles caches">
-	<caption><?php echo _('Caches'); ?></caption>
-	<col />
-	<col align="right" />
-	<col align="right" />
-	<col align="right" />
-	<col />
-	<col />
-	<col align="right" />
-	<col align="right" />
-	<col align="right" />
-	<col />
-	<col align="right" />
-	<col align="right" />
-	<col align="right" />
-	<col align="right" />
-	<col align="right" />
-	<col align="right" />
-	<col align="right" />
-	<col />
-	<tr <?php echo $a->next(); ?>>
-	<?php echo
-		th(N_("cache.cache"))
-		, th(N_("cache.size"))
-		, th(N_("cache.avail"))
-		, th(N_("cache.used"))
-		, th(N_("cache.blocksgraph"))
-		, th(N_("cache.operations"))
-		, th(N_("cache.compiling"))
-		, th(N_("cache.hits"))
-		, th(N_("cache.hits_graph"))
-		, th(N_("cache.hits_avg_h"))
-		, th(N_("cache.hits_avg_s"))
-		, th(N_("cache.updates"))
-		, th(N_("cache.clogs"))
-		, th(N_("cache.ooms"))
-		, th(N_("cache.errors"))
-		, th(N_("cache.readonly_protected"))
-		, th(N_("cache.cached"))
-		, th(N_("cache.deleted"))
-		, th(N_("cache.gc_timer"))
-		;
-	?>
-	</tr>
-	<?php
-	$numkeys = explode(',', 'slots,size,avail,hits,updates,clogs,ooms,errors,cached,deleted');
-	$l_clear = _('Clear');
-	$l_clear_confirm = _('Sure to clear?');
-	foreach ($cacheinfos as $i => $ci) {
-		echo "
-		<tr ", $a->next(), ">";
-		$pvalue = (int) ($ci['avail'] / $ci['size'] * 100);
-		$pempty = 100 - $pvalue;
-		if ($config['percent_graph_type'] == 'used') {
-			// swap
-			$tmp = $pvalue;
-			$pvalue = $pempty;
-			$pempty = $tmp;
-		}
-
-		$w = $config['percent_graph_width'];
-		if (empty($ci['istotal'])) {
-			$graph = freeblock_to_graph($ci['free_blocks'], $ci['size']);
-			$blocksgraph = "<div class=\"blocksgraph\" style=\"width: {$w}px\">{$graph}</div>";
-		}
-		else {
-			$blocksgraph = '';
-		}
-
-		$ci_slots = size($ci['slots']);
-		$ci_size  = size($ci['size']);
-		$ci_avail = size($ci['avail']);
-		$ci = number_formats($ci, $numkeys);
-
-		$hits_avg_h     = number_format(array_avg($ci['hits_by_hour']), 2);
-		$hits_avg_s     = number_format(array_avg($ci['hits_by_second']), 2);
-		$hits_graph_h   = hits_to_graph($ci['hits_by_hour']);
-		$hits_graph_h_w = count($ci['hits_by_hour']) * 2;
-
-		if (!empty($ci['istotal'])) {
-			$ci['compiling']    = '-';
-			$ci['can_readonly'] = '-';
-		}
-		else {
-			$ci['compiling']    = $ci['type'] == $type_php ? ($ci['compiling'] ? 'yes' : 'no') : '-';
-			$ci['can_readonly'] = $ci['can_readonly'] ? 'yes' : 'no';
-		}
-		echo <<<EOS
-		<th>{$ci['cache_name']}</th>
-		<td title="{$ci['slots']}">{$ci_slots}</td>
-		<td title="{$ci['size']}">{$ci_size}</td>
-		<td title="{$ci['avail']}">{$ci_avail}</td>
-		<td title="{$pvalue} %"
-			><div class="percent" style="width: {$w}px"
-				><div style="width: {$pvalue}%" class="pvalue"></div
-				><div style="width: {$pempty}%" class="pempty"></div
-			></div
-		>{$blocksgraph}</td>
-		<td
-			><form method="post" action=""
-				><div
-					><input type="hidden" name="type" value="{$ci['type']}"
-					/><input type="hidden" name="cacheid" value="{$ci['cacheid']}"
-					/><input type="submit" name="clearcache" value="{$l_clear}" class="submit" onclick="return confirm('{$l_clear_confirm}');"
-				/></div
-			></form
-		></td>
-		<td>{$ci['compiling']}</td>
-		<td>{$ci['hits']}</td>
-		<td><div class="hitsgraph" style="width: {$hits_graph_h_w}px">{$hits_graph_h}</div></td>
-		<td>{$hits_avg_h}</td>
-		<td>{$hits_avg_s}</td>
-		<td>{$ci['updates']}</td>
-		<td>{$ci['clogs']}</td>
-		<td>{$ci['ooms']}</td>
-		<td>{$ci['errors']}</td>
-		<td>{$ci['can_readonly']}</td>
-		<td>{$ci['cached']}</td>
-		<td>{$ci['deleted']}</td>
-		<td>{$ci['gc']}</td>
-EOS;
-
-			$b->reset();
-			?>
-	</tr>
-	<?php } ?>
-</table>
-<div class="blockarea legends">
-	<div class="legendtitle"><?php echo _('Legends:'); ?></div>
-	<div class="legend pvalue">&nbsp;&nbsp;</div>
-	<div class="legendtitle"><?php echo _($config['percent_graph_type'] == 'free' ? '% Free' : '% Used'); ?></div>
-	<div class="legend" style="background: rgb(0,0,255)">&nbsp;&nbsp;</div>
-	<div class="legendtitle"><?php echo _($config['percent_graph_type'] == 'free' ? 'Free Blocks' : 'Used Blocks'); ?></div>
-	<div class="legend" style="background: rgb(255,0,0)">&nbsp;&nbsp;</div>
-	<div class="legendtitle"><?php echo _('Hits'); ?></div>
-</div>
-<?php
-
-if ($cachelist) {
-	$isphp = $cachelist['type'] == $type_php;
-	ob_start($config['path_nicer']);
-	foreach (array('Cached' => $cachelist['cache_list'], 'Deleted' => $cachelist['deleted_list']) as $listname => $entries) {
-		$a->reset();
-		?>
-
-	<form action="" method="post">
-	<table cellspacing="0" cellpadding="4" class="cycles entries" width="100%">
-		<caption><?php echo _("{$cachelist['type_name']} $listname"); ?></caption>
-		<?php
-		echo "
-		<tr ", $a->next(), ">";
-		?>
-
-			<?php
-			if ($isphp) {
-				echo
-					th("entry.id")
-					;
-			}
-			else {
-				echo
-					th("entry.remove", 'width="20"')
-					;
-			}
-
-			echo
-				th(N_("entry.name"))
-				, th(N_("entry.hits"))
-				, th(N_("entry.size"))
-				;
-
-			if ($isphp) {
-				echo
-					th(N_("entry.refcount"))
-					, th(N_("entry.phprefcount"))
-					, th(N_("entry.class_cnt"))
-					, th(N_("entry.function_cnt"))
-					, th(N_("entry.file_size"))
-					, th(N_("entry.file_mtime"))
-					;
-				if ($haveinode) {
-					echo
-						th(N_("entry.file_device"))
-						, th(N_("entry.file_inode"))
-						;
-				}
-			}
-			echo
-				th(N_("entry.hash"))
-				, th(N_("entry.atime"))
-				, th(N_("entry.ctime"))
-				;
-
-			if ($listname == 'Deleted') {
-				echo
-					th(N_("entry.delete"))
-					;
-			}
-			?>
-		</tr>
-		<?php
-		foreach ($entries as $i => $entry) {
-			echo "
-			<tr ", $a->next(), ">";
-			$name     = htmlspecialchars($entry['name']);
-			$hits     = number_format($entry['hits']);
-			$size     = size($entry['size']);
-			$class_cnt = number_format($entry['class_cnt']);
-			$function_cnt = number_format($entry['function_cnt']);
-			if ($isphp) {
-				$phprefcount = number_format($entry['phprefcount']);
-				$file_size   = size($entry['file_size']);
-			}
-
-			if ($isphp) {
-				$file_mtime = age($entry['file_mtime']);
-			}
-			$ctime = age($entry['ctime']);
-			$atime = age($entry['atime']);
-			if ($listname == 'Deleted') {
-				$dtime = age($entry['dtime']);
-			}
-
-			if (!$isphp) {
-				echo <<<ENTRY
-					<td><input type="checkbox" name="remove[]" value="{$name}"/></td>
-ENTRY;
-				$uname = urlencode($entry['name']);
-				$namelink = "<a href=\"edit.php?name=$uname\">$name</a>";
-			}
-			else {
-				$namelink = $name;
-			}
-
-			echo <<<ENTRY
-			<td>{$entry['cache_name']} {$i}</td>
-			<td>{$namelink}</td>
-			<td align="right" int="{$entry['hits']}">{$entry['hits']}</td>
-			<td align="right" int="{$entry['size']}">{$size}</td>
-ENTRY;
-			if ($isphp) {
-				$refcount = number_format($entry['refcount']);
-				echo <<<ENTRY
-				<td align="right" int="{$entry['refcount']}">{$entry['refcount']}</td>
-				<td align="right" int="{$entry['phprefcount']}">{$phprefcount}</td>
-				<td align="right" int="{$entry['class_cnt']}">{$class_cnt}</td>
-				<td align="right" int="{$entry['function_cnt']}">{$function_cnt}</td>
-				<td align="right" int="{$entry['file_size']}">{$file_size}</td>
-				<td align="right" int="{$entry['file_mtime']}">{$file_mtime}</td>
-ENTRY;
-				if (isset($entry['file_inode'])) {
-					echo <<<ENTRY
-					<td align="right" int="{$entry['file_device']}">{$entry['file_device']}</td>
-					<td align="right" int="{$entry['file_inode']}">{$entry['file_inode']}</td>
-ENTRY;
-				}
-			}
-			echo <<<ENTRY
-			<td align="right" int="{$entry['hvalue']}">{$entry['hvalue']}</td>
-			<td align="right" int="{$entry['atime']}">{$atime}</td>
-			<td align="right" int="{$entry['ctime']}">{$ctime}</td>
-ENTRY;
-			if ($listname == 'Deleted') {
-			echo <<<ENTRY
-				<td align="right" int="{$entry['dtime']}">{$dtime}</td>
-ENTRY;
-			}
-
-			echo "
-		</tr>
-			";
-		}
-		?>
-
-	</table>
-	<?php if (!$isphp) { ?>
-	<input type="submit" value="<?php echo _("Remove Selected"); ?>">
-	<?php } ?>
-	</form>
-<?php
-	}
-	ob_end_flush();
-}
-if ($moduleinfo) {
-	$t_moduleinfo = _("Module Info");
-	echo <<<HTML
-<h2>$t_moduleinfo</h2>
-<div class="phpinfo">$moduleinfo</div>
-HTML;
-}
-?>
-<?php include("footer.tpl.php"); ?>
Index: /trunk/htdocs/common/common-en.lang.php
===================================================================
--- /trunk/htdocs/common/common-en.lang.php	(revision 1053)
+++ /trunk/htdocs/common/common-en.lang.php	(revision 1053)
@@ -0,0 +1,4 @@
+<?php
+
+$strings = array();
+
Index: /trunk/htdocs/common/common.php
===================================================================
--- /trunk/htdocs/common/common.php	(revision 1053)
+++ /trunk/htdocs/common/common.php	(revision 1053)
@@ -0,0 +1,250 @@
+<?php
+
+class Cycle
+{
+	var $values;
+	var $i;
+	var $count;
+
+	function Cycle($v)
+	{
+		$this->values = func_get_args();
+		$this->i = -1;
+		$this->count = count($this->values);
+	}
+
+	function next()
+	{
+		$this->i = ($this->i + 1) % $this->count;
+		return $this->values[$this->i];
+	}
+
+	function cur()
+	{
+		return $this->values[$this->i];
+	}
+
+	function reset()
+	{
+		$this->i = -1;
+	}
+}
+
+function switcher($name, $options)
+{
+	$n = isset($_GET[$name]) ? $_GET[$name] : null;
+	$html = array();
+	foreach ($options as $k => $v) {
+		$html[] = sprintf('<a href="?%s=%s"%s>%s</a>', $name, $k, $k == $n ? ' class="active"' : '', $v);
+	}
+	return implode('', $html);
+}
+
+function moduleswitcher()
+{
+	global $module, $modules;
+	$html = array();
+	foreach ($modules as $k => $v) {
+		$html[] = sprintf('<a href="../%s/"%s>%s</a>', $k, $k == $module ? ' class="active"' : '', $v);
+	}
+	return implode('', $html);
+}
+
+function th($name, $attrs = null)
+{
+	$translated = __($name);
+	if ($translated == $name) {
+		$translated = "$name|$name";
+	}
+	list($text, $title) = explode('|', $translated, 2);
+	return sprintf('%s<th%s id="%s" title="%s"><a href="javascript:" onclick="resort(this); return false">%s</a></th>%s'
+			, "\t"
+			, $attrs ? " $attrs" : ""
+			, $name, htmlspecialchars(trim($title)), trim($text)
+			, "\n");
+}
+
+function xcache_validateFileName($name)
+{
+	return preg_match('!^[a-zA-Z0-9._-]+$!', $name);
+}
+
+function get_language_file_ex($name, $lang)
+{
+	static $langMap = array(
+			'zh'    => 'zh-simplified',
+			'zh-hk' => 'zh-traditional',
+			'zh-tw' => 'zh-traditional',
+			);
+
+	if (isset($langMap[$lang])) {
+		$lang = $langMap[$lang];
+	}
+	$file = "$name-$lang.lang.php";
+	if (xcache_validateFileName($file) && file_exists($file)) {
+		return $file;
+	}
+	return null;
+}
+
+function get_language_file($name)
+{
+	global $config;
+	if (!empty($config['lang'])) {
+		$lang = strtolower($config['lang']);
+		$file = get_language_file_ex($name, $lang);
+		if (!isset($file)) {
+			$lang = strtok($lang, ':-');
+			$file = get_language_file_ex($name, $lang);
+		}
+	}
+	else if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+		foreach (explode(',', str_replace(' ', '', $_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $lang) {
+			$lang = strtok($lang, ':;');
+			$file = get_language_file_ex($name, $lang);
+			if (isset($file)) {
+				$config['lang'] = $lang;
+				break;
+			}
+			if (strpos($lang, '-') !== false) {
+				$file = get_language_file_ex($name, strtok($lang, ':-'));
+				if (isset($file)) {
+					$config['lang'] = $lang;
+					break;
+				}
+			}
+		}
+	}
+	return isset($file) ? $file : "$name-en.lang.php";
+}
+
+function _($str)
+{
+	if (isset($GLOBALS['strings'][$str])) {
+		return $GLOBALS['strings'][$str];
+	}
+	if (!empty($GLOBALS['config']['show_todo_strings'])) {
+		return '<span style="color:red">' . htmlspecialchars($str) . '</span>|';
+	}
+	return $str;
+}
+
+function __($str)
+{
+	return _($str);
+}
+
+function N_($str)
+{
+	return $str;
+}
+
+function number_formats($a, $keys)
+{
+	foreach ($keys as $k) {
+		$a[$k] = number_format($a[$k]);
+	}
+	return $a;
+}
+
+function size($size)
+{
+	$size = (int) $size;
+	if ($size < 1024)
+		return number_format($size, 2) . ' b';
+
+	if ($size < 1048576)
+		return number_format($size / 1024, 2) . ' K';
+
+	return number_format($size / 1048576, 2) . ' M';
+}
+
+function age($time)
+{
+	if (!$time) return '';
+	$delta = REQUEST_TIME - $time;
+
+	if ($delta < 0) {
+		$delta = -$delta;
+	}
+	
+  	static $seconds = array(1, 60, 3600, 86400, 604800, 2678400, 31536000);
+	static $name = array('s', 'm', 'h', 'd', 'w', 'M', 'Y');
+
+	for ($i = 6; $i >= 0; $i --) {
+		if ($delta >= $seconds[$i]) {
+			$ret = (int) ($delta / $seconds[$i]);
+			return $ret . ' ' . $name[$i];
+		}
+	}
+
+	return '0 s';
+}
+
+function stripaddslashes_array($value, $mqs = false)
+{
+	if (is_array($value)) {
+		foreach($value as $k => $v) {
+			$value[$k] = stripaddslashes_array($v, $mqs);
+		}
+	}
+	else if(is_string($value)) {
+		$value = $mqs ? str_replace('\'\'', '\'', $value) : stripslashes($value);
+	}
+	return $value;
+}
+
+function ob_filter_path_nicer_default($list_html)
+{
+	$sep = DIRECTORY_SEPARATOR;
+	$docRoot = $_SERVER['DOCUMENT_ROOT'];
+	if ($sep != '/') {
+		$docRoot = str_replace('/', $sep, $docRoot);
+	}
+	$list_html = str_replace(">$docRoot",  ">{DOCROOT}" . (substr($docRoot, -1) == $sep ? $sep : ""), $list_html);
+	$xcachedir = realpath(dirname(__FILE__) . "$sep..$sep");
+	$list_html = str_replace(">$xcachedir$sep", ">{XCache}$sep", $list_html);
+	if ($sep == '/') {
+		$list_html = str_replace(">/home/", ">{H}/", $list_html);
+	}
+	return $list_html;
+}
+
+error_reporting(E_ALL);
+ini_set('display_errors', 'On');
+define('REQUEST_TIME', time());
+
+if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc()) {
+	$mqs = (bool) ini_get('magic_quotes_sybase');
+	$_GET = stripaddslashes_array($_GET, $mqs);
+	$_POST = stripaddslashes_array($_POST, $mqs);
+	$_REQUEST = stripaddslashes_array($_REQUEST, $mqs);
+	unset($mqs);
+}
+ini_set('magic_quotes_runtime', '0');
+
+$config = array();
+if (file_exists("./config.default.php")) {
+	include("./config.default.php");
+}
+include("../config.default.php");
+if (file_exists("../config.php")) {
+	include("../config.php");
+}
+if (file_exists("./config.php")) {
+	include("./config.php");
+}
+
+include(get_language_file("common"));
+
+$modules = array();
+if (file_exists("../cacher/index.php")) {
+	$modules["cacher"] = _("Cacher");
+}
+if (file_exists("../coverager/index.php")) {
+	$modules["coverager"] = _("Coverager");
+}
+header("Cache-Control: no-cache, must-revalidate");
+header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
+
+?>
Index: /trunk/htdocs/common/footer.tpl.php
===================================================================
--- /trunk/htdocs/common/footer.tpl.php	(revision 1053)
+++ /trunk/htdocs/common/footer.tpl.php	(revision 1053)
@@ -0,0 +1,13 @@
+<div class="footnote">
+PHP <?php
+	echo phpversion();
+?> Powered By: XCache <?php
+	echo defined('XCACHE_VERSION') ? XCACHE_VERSION : '';
+?>, <?php
+	echo defined('XCACHE_MODULES') ? XCACHE_MODULES : '';
+?>
+
+</div>
+
+</body>
+</html>
Index: /trunk/htdocs/common/header.tpl.php
===================================================================
--- /trunk/htdocs/common/header.tpl.php	(revision 1053)
+++ /trunk/htdocs/common/header.tpl.php	(revision 1053)
@@ -0,0 +1,15 @@
+<!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="Content-Type" content="text/html; charset=<?php echo $GLOBALS['config']['charset']; ?>" />
+	<meta http-equiv="Content-Language" content="<?php echo $GLOBALS['config']['charset']; ?>" />
+	<script type="text/javascript" src="tablesort.js"></script>
+
+	<link rel="stylesheet" type="text/css" href="../common/common.css" />
+	<link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['module']; ?>.css" />
+	<title><?php echo $title = sprintf("XCache %s", $xcache_version = defined('XCACHE_VERSION') ? XCACHE_VERSION : '') . " - " . ucfirst($GLOBALS['module']); ?></title>
+</head>
+
+<body>
+<h1><?php echo $title; ?></h1>
+<div class="switcher"><?php echo moduleswitcher(); ?></div>
Index: /trunk/htdocs/config.default.php
===================================================================
--- /trunk/htdocs/config.default.php	(revision 1053)
+++ /trunk/htdocs/config.default.php	(revision 1053)
@@ -0,0 +1,17 @@
+<?php
+
+// [default config]
+// DO NOT rename/delete/modify this file which will be overwritten when upgrade
+// See config.example.php instead
+
+// detected by browser
+// $config['lang'] = 'en-us';
+
+$config['charset'] = "UTF-8";
+
+// translators only
+$config['show_todo_strings'] = false;
+
+// this ob filter function is applied for the list with paths, not the whole page
+$config['path_nicer'] = 'ob_filter_path_nicer_default';
+
Index: /trunk/htdocs/config.example.php
===================================================================
--- /trunk/htdocs/config.example.php	(revision 1053)
+++ /trunk/htdocs/config.example.php	(revision 1053)
@@ -0,0 +1,65 @@
+<?php
+
+// DO NOT rename/delete/modify example file which will be overwritten when upgrade
+// How To Custom Config:
+// 1. copy config.example.php config.php; edit config.php
+// 2. upgrading your config.php when config.example.php were upgraded
+
+// leave this setting unset to auto detect using browser request header
+// $config['lang'] = 'en-us';
+
+$config['charset'] = "UTF-8";
+
+// enable this for translators only
+$config['show_todo_strings'] = false;
+
+// this ob filter is applied for the cache list, not the whole page
+function custom_ob_filter_path_nicer($list_html)
+{
+	$list_html = ob_filter_path_nicer_default($list_html); // this function is from common.php
+	return $list_html;
+}
+$config['path_nicer'] = 'custom_ob_filter_path_nicer';
+
+// "XCache Cacher" http auth for is enforced for security reason
+// if http auth is disabled, any vhost user who can upload *.php will see all variable data cached in XCache
+
+/*// but if you have your own login/permission system, you can integerate it using the following example
+// {{{ login example
+// this is an example only, it's won't work for you without your implemention.
+
+function check_admin_and_by_pass_xcache_http_auth()
+{
+	require("/path/to/user-login-and-permission-lib.php");
+	session_start();
+
+	if (user_logined()) {
+		user_load_permissions();
+		if (user_is_admin()) {
+			// user is trusted after permission checks above.
+			// tell XCache about it (the only secure way to by pass XCache http auth)
+			$_SERVER["PHP_AUTH_USER"] = "moo";
+			$_SERVER["PHP_AUTH_PW"] = "your-xcache-password-before-md5";
+		}
+		else {
+			die("Permission denied");
+		}
+	}
+	else {
+		if (!ask_the_user_to_login()) {
+			exit;
+		}
+	}
+
+	return true;
+}
+
+check_admin_and_by_pass_xcache_http_auth();
+*/
+// }}}
+
+/* by pass XCache http auth
+$_SERVER["PHP_AUTH_USER"] = "moo";
+$_SERVER["PHP_AUTH_PW"] = "your-xcache-password-before-md5";
+*/
+
Index: unk/htdocs/coverager/common-en.lang.php
===================================================================
--- /trunk/htdocs/coverager/common-en.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,5 +1,0 @@
-<?php
-
-$GLOBALS['show_todo_strings'] = false;
-
-?>
Index: unk/htdocs/coverager/common-zh-simplified-gb2312.lang.php
===================================================================
--- /trunk/htdocs/coverager/common-zh-simplified-gb2312.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,25 +1,0 @@
-<?php
-
-$strings = array(
-		'root'
-		=> '¿ªÊ¼',
-		'Directory'
-		=> 'Ä¿Â¼',
-		'File'
-		=> 'ÎÄ¼þ',
-		'Percent'
-		=> '¸²¸ÇÂÊ',
-		'Hits'
-		=> 'ÃüÖÐ',
-		'Lines'
-		=> 'ÐÐÊý',
-		'TODO'
-		=> 'ÏÐÖÃÎÄ¼þ',
-		'XCache PHP Code Coverage Viewer'
-		=> 'XCache PHP ´úÂë¸²¸Ç²é¿´Æ÷',
-		'module'
-		=> 'Ä£¿é',
-		''
-		=> '',
-		);
-
Index: unk/htdocs/coverager/common-zh-simplified-utf-8.lang.php
===================================================================
--- /trunk/htdocs/coverager/common-zh-simplified-utf-8.lang.php	(revision 1052)
+++ 	(revision )
@@ -1,25 +1,0 @@
-<?php
-
-$strings = array(
-		'root'
-		=> '开始',
-		'Directory'
-		=> '目录',
-		'File'
-		=> '文件',
-		'Percent'
-		=> '覆盖率',
-		'Hits'
-		=> '命中',
-		'Lines'
-		=> '行数',
-		'TODO'
-		=> '闲置文件',
-		'XCache PHP Code Coverage Viewer'
-		=> 'XCache PHP 代码覆盖查看器',
-		'module'
-		=> '模块',
-		''
-		=> '',
-		);
-
Index: /trunk/htdocs/coverager/common.php
===================================================================
--- /trunk/htdocs/coverager/common.php	(revision 1052)
+++ /trunk/htdocs/coverager/common.php	(revision 1053)
@@ -1,112 +1,7 @@
 <?php
 
-function get_language_file_ex($name, $l, $s)
-{
-	static $lmap = array(
-			'zh'    => 'zh-simplified',
-			'zh-hk' => 'zh-traditional',
-			'zh-tw' => 'zh-traditional',
-			);
-	static $smap = array(
-			'gbk'     => 'gb2312',
-			'gb18030' => 'gb2312',
-			);
+require_once "../common/common.php";
 
-	if (isset($lmap[$l])) {
-		$l = $lmap[$l];
-	}
-	if (file_exists($file = "$name-$l-$s.lang.php")) {
-		return $file;
-	}
-	if (isset($smap[$s])) {
-		$s = $smap[$s];
-		if (file_exists($file = "$name-$l-$s.lang.php")) {
-			return $file;
-		}
-	}
-	if (file_exists($file = "$name-$l.lang.php")) {
-		return $file;
-	}
-	return null;
-}
+include(get_language_file("coverager"));
+$module = "coverager";
 
-function get_language_file($name)
-{
-	global $charset, $lang;
-	$s = strtolower($charset);
-	if (isset($lang)) {
-		$l = strtolower($lang);
-		$file = get_language_file_ex($name, $l, $s);
-		if (!isset($file)) {
-			$l = strtok($l, '-');
-			$file = get_language_file_ex($name, $l, $s);
-		}
-	}
-	else if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
-		foreach (explode(',', str_replace(' ', '', $_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $l) {
-			$l = strtok($l, ';');
-			$file = get_language_file_ex($name, $l, $s);
-			if (isset($file)) {
-				$lang = $l;
-				break;
-			}
-			if (strpos($l, '-') !== false) {
-				$ll = strtok($l, '-');
-				$file = get_language_file_ex($name, $ll, $s);
-				if (isset($file)) {
-					$lang = $l;
-					break;
-				}
-			}
-		}
-	}
-	return isset($file) ? $file : "$name-en.lang.php";
-}
-
-function _T($str)
-{
-	if (isset($GLOBALS['strings'][$str])) {
-		return $GLOBALS['strings'][$str];
-	}
-	if (!empty($GLOBALS['show_todo_strings'])) {
-		return '<span style="color:red">' . htmlspecialchars($str) . '</span>';
-	}
-	return $str;
-}
-
-function stripaddslashes_array($value, $mqs = false)
-{
-	if (is_array($value)) {
-		foreach($value as $k => $v) {
-			$value[$k] = stripaddslashes_array($v, $mqs);
-		}
-	}
-	else if(is_string($value)) {
-		$value = $mqs ? str_replace('\'\'', '\'', $value) : stripslashes($value);
-	}
-	return $value;
-}
-
-error_reporting(E_ALL);
-ini_set('display_errors', 'On');
-define('REQUEST_TIME', time());
-
-if (get_magic_quotes_gpc()) {
-	$mqs = (bool) ini_get('magic_quotes_sybase');
-	$_GET = stripaddslashes_array($_GET, $mqs);
-	$_POST = stripaddslashes_array($_POST, $mqs);
-	$_REQUEST = stripaddslashes_array($_REQUEST, $mqs);
-}
-ini_set('magic_quotes_runtime', '0');
-
-$charset = "UTF-8";
-if (file_exists("./config.php")) {
-	include("./config.php");
-}
-
-include(get_language_file("common"));
-if (!isset($lang)) {
-	$lang = 'en-us';
-}
-
-?>
Index: /trunk/htdocs/coverager/config.example.php
===================================================================
--- /trunk/htdocs/coverager/config.example.php	(revision 1053)
+++ /trunk/htdocs/coverager/config.example.php	(revision 1053)
@@ -0,0 +1,19 @@
+<?php
+
+// DO NOT rename/delete/modify example file which will be overwritten when upgrade
+// How To Custom Config:
+// 1. copy config.example.php config.php; edit config.php
+// 2. upgrading your config.php when config.example.php were upgraded
+// XCache will load
+// 1. ../config.default.php
+// 2. ./config.default.php
+// 3. ../config.php
+// 4. ./config.php
+
+// $config['include_paths = array("/www/my-php-project/");
+// $config['exclude_paths = array("/www/my-php-project/tmp/");
+$config['syntax_higlight'] = true;
+$config['use_cache'] = false;
+//// $config['datadir'] is default to ini_get("xcache.coveragedump_directory")
+// $config['datadir'] = '';
+
Index: unk/htdocs/coverager/config.php.example
===================================================================
--- /trunk/htdocs/coverager/config.php.example	(revision 1052)
+++ 	(revision )
@@ -1,59 +1,0 @@
-<?php
-
-// this is an example only
-// write your own config and name it as config.php
-
-// detected by browser
-// $lang = 'en-us';
-
-$charset = "UTF-8";
-
-// developers only
-$show_todo_strings = false;
-
-// $include_paths = array("/www/my-php-project/");
-// $exclude_paths = array("/www/my-php-project/tmp/");
-$syntaxhiglight = true;
-$usecache = false;
-//// $datadir is default to ini_get("xcache.coveragedump_directory")
-// $datadir = '';
-
-function ob_filter_path_nicer($o)
-{
-	$sep = DIRECTORY_SEPARATOR;
-	$o = str_replace($_SERVER['DOCUMENT_ROOT'],  "{DOCROOT}" . (substr($d, -1) == $sep ? $sep : ""), $o);
-	$xcachedir = realpath(dirname(__FILE__) . "$sep..$sep");
-	$o = str_replace($xcachedir . $sep, "{XCache}$sep", $o);
-	if ($sep == '/') {
-		$o = str_replace("/home/", "{H}/", $o);
-	}
-	return $o;
-}
-
-// implement your auth here if needed
-// {{{ home made login example
-// this is an example only, it's won't work for you without your implemention.
-function check_admin_auth()
-{
-	require("/path/to/user-login-and-permission-lib.php");
-	session_start();
-
-	if (!user_logined()) {
-		if (!ask_the_user_to_login()) {
-			exit;
-		}
-	}
-
-	user_load_permissions();
-	if (!user_is_admin()) {
-		die("Permission denied");
-	}
-
-	return true;
-}
-
-// uncomment:
-// check_admin_auth()
-// }}}
-
-?>
Index: /trunk/htdocs/coverager/coverager-en.lang.php
===================================================================
--- /trunk/htdocs/coverager/coverager-en.lang.php	(revision 1053)
+++ /trunk/htdocs/coverager/coverager-en.lang.php	(revision 1053)
@@ -0,0 +1,5 @@
+<?php
+
+$GLOBALS['show_todo_strings'] = false;
+
+?>
Index: /trunk/htdocs/coverager/coverager-zh-simplified.lang.php
===================================================================
--- /trunk/htdocs/coverager/coverager-zh-simplified.lang.php	(revision 1053)
+++ /trunk/htdocs/coverager/coverager-zh-simplified.lang.php	(revision 1053)
@@ -0,0 +1,25 @@
+<?php
+
+$strings += array(
+		'root'
+		=> '开始',
+		'Directory'
+		=> '目录',
+		'File'
+		=> '文件',
+		'Percent'
+		=> '覆盖率',
+		'Hits'
+		=> '命中',
+		'Lines'
+		=> '行数',
+		'TODO'
+		=> '闲置文件',
+		'XCache PHP Code Coverage Viewer'
+		=> 'XCache PHP 代码覆盖查看器',
+		'module'
+		=> '模块',
+		''
+		=> '',
+		);
+
Index: /trunk/htdocs/coverager/coverager.css
===================================================================
--- /trunk/htdocs/coverager/coverager.css	(revision 1052)
+++ /trunk/htdocs/coverager/coverager.css	(revision 1053)
@@ -1,14 +1,4 @@
-h1 { text-align: center; display: block; }
-input, table { font-family: sans-serif; font-size: 11px; }
-th { font-size: 12px; }
-table { border-collapse: collapse; }
 table.center { margin-left: auto; margin-right: auto; }
 table\-center { text-align: center; }
-table.cycles { border: 1px solid black; margin-top: 5px; margin-bottom: 5px; }
-table.cycles .col1 { background-color: #f5f5f5; }
-table.cycles .col2 { background-color: #e0e0e0; }
-table.cycles th, table.cycles td { border: 1px solid black; font-family: monospace; }
-table.cycles th { background-color: #9999cc; color: black; font-weight: bold; height: 20px; line-height: 20px; font-family: serif; }
-th a { color: black; font-weight: bold; display: block; width: 100%; height: 100%; }
 
 .coverFile {
@@ -68,4 +58,3 @@
 }
 
-.footnote { text-align: right; font-size: 12px; }
 .error { color: red; }
Index: /trunk/htdocs/coverager/coverager.php
===================================================================
--- /trunk/htdocs/coverager/coverager.php	(revision 1052)
+++ /trunk/htdocs/coverager/coverager.php	(revision 1053)
@@ -2,39 +2,9 @@
 
 include("./common.php");
-
-class Cycle
-{
-	var $values;
-	var $i;
-	var $count;
-
-	function Cycle($v)
-	{
-		$this->values = func_get_args();
-		$this->i = -1;
-		$this->count = count($this->values);
-	}
-
-	function next()
-	{
-		$this->i = ($this->i + 1) % $this->count;
-		return $this->values[$this->i];
-	}
-
-	function cur()
-	{
-		return $this->values[$this->i];
-	}
-
-	function reset()
-	{
-		$this->i = -1;
-	}
-}
 
 class XcacheCoverageViewer
 {
-	var $syntaxhiglight = true;
-	var $usecache = false;
+	var $syntax_higlight = true;
+	var $use_cache = false;
 	var $include_paths = array();
 	var $exclude_paths = array();
@@ -50,8 +20,8 @@
 		$this->datadir = ini_get('xcache.coveragedump_directory');
 
-		// copy config
-		foreach (array('charset', 'include_paths', 'exclude_paths', 'syntaxhiglight', 'usecache', 'datadir', 'lang') as $k) {
-			if (isset($GLOBALS[$k])) {
-				$this->{$k} = $GLOBALS[$k];
+		global $config;
+		foreach (array('charset', 'include_paths', 'exclude_paths', 'syntax_higlight', 'use_cache', 'datadir', 'lang') as $k) {
+			if (isset($config[$k])) {
+				$this->{$k} = $config[$k];
 			}
 		}
@@ -79,5 +49,5 @@
 			$prefix_len = strlen($path) + 1;
 			$dirinfo = $this->loadDir($this->outpath);
-			if (!$this->usecache) {
+			if (!$this->use_cache) {
 				ksort($dirinfo['subdirs']);
 				ksort($dirinfo['files']);
@@ -104,5 +74,5 @@
 				}
 			}
-			if ($this->syntaxhiglight) {
+			if ($this->syntax_higlight) {
 				$source = implode('', $lines);
 				ob_start();
@@ -130,5 +100,5 @@
 		else if (!$this->datadir) {
 			$action = 'error';
-			$error  = 'require `ini:xcache.coveragedump_directory` or `config:$datadir` to be set';
+			$error  = 'require `xcache.coveragedump_directory` in ini or `$datadir` in config to be set';
 		}
 		else {
@@ -137,5 +107,5 @@
 		}
 
-		$xcache_version = defined('XCACHE_VERSION') ? XCACHE_VERSION : '';
+		global $config;
 		include("coverager.tpl.php");
 	}
@@ -143,5 +113,5 @@
 	function loadDir($outdir, $addtodo = null)
 	{
-		if ($this->usecache) {
+		if ($this->use_cache) {
 			$cachefile = $outdir . "/.pcovcache";
 			if (file_exists($cachefile)) {
@@ -210,5 +180,5 @@
 		}
 
-		if ($this->usecache) {
+		if ($this->use_cache) {
 			ksort($subdirs);
 			ksort($files);
@@ -223,5 +193,5 @@
 				);
 
-		if ($this->usecache) {
+		if ($this->use_cache) {
 			$fp = fopen($cachefile, "wb");
 			fwrite($fp, serialize($info));
@@ -233,5 +203,5 @@
 	function loadFile($file)
 	{
-		if ($this->usecache) {
+		if ($this->use_cache) {
 			$cachefile = $file . "cache";
 			if (file_exists($cachefile)) {
@@ -243,5 +213,5 @@
 		unset($info['cov']);
 
-		if ($this->usecache) {
+		if ($this->use_cache) {
 			$fp = fopen($cachefile, "wb");
 			fwrite($fp, serialize($info));
Index: /trunk/htdocs/coverager/coverager.tpl.php
===================================================================
--- /trunk/htdocs/coverager/coverager.tpl.php	(revision 1052)
+++ /trunk/htdocs/coverager/coverager.tpl.php	(revision 1053)
@@ -1,18 +1,3 @@
-<!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>
-<?php
-echo <<<HEAD
-	<meta http-equiv="Content-Type" content="text/html; charset=$this->charset" />
-	<meta http-equiv="Content-Language" content="{$this->lang}" />
-	<script type="text/javascript" src="tablesort.js" charset="$this->charset"></script>
-HEAD;
-?>
-
-	<link rel="stylesheet" type="text/css" href="coverager.css" />
-	<title><?php echo _T("XCache PHP Code Coverage Viewer"); ?></title>
-</head>
-<body>
-<h1><?php echo _T("XCache PHP Code Coverage Viewer"); ?></h1>
+<?php include "../common/header.tpl.php"; ?>
 
 <?php
@@ -50,9 +35,9 @@
 	global $cycle;
 	$cycle = new Cycle('class="col1"', 'class="col2"');
-	$l_dir = _T("Directory");
-	$l_per = _T("Percent");
-	$l_hit = _T("Hits");
-	$l_lns = _T("Lines");
-	$l_tds = _T("TODO");
+	$l_dir = _("Directory");
+	$l_per = _("Percent");
+	$l_hit = _("Hits");
+	$l_lns = _("Lines");
+	$l_tds = _("TODO");
 	return <<<EOS
 <div class="table-center">
@@ -114,8 +99,8 @@
 	global $cycle;
 	$cycle = new Cycle('class="col1"', 'class="col2"');
-	$l_fil = _T("File");
-	$l_per = _T("Percent");
-	$l_hit = _T("Hits");
-	$l_lns = _T("Lines");
+	$l_fil = _("File");
+	$l_per = _("Percent");
+	$l_hit = _("Hits");
+	$l_lns = _("Lines");
 	return <<<EOS
 <div class="center-table">
@@ -168,5 +153,5 @@
 }
 
-$l_root = _T("root");
+$l_root = _("root");
 if ($action == 'dir') {
 	if (function_exists('ob_filter_path_nicer')) {
@@ -246,8 +231,4 @@
 ?>
 
-<div class="footnote">
-Powered By: XCache <?php echo $xcache_version; ?> coverager <?php echo _T("module"); ?>
-</div>
-
-</body>
-</html>
+<?php include "../common/footer.tpl.php"; ?>
+
