{@Replace(<,<)}html());
	}
	
	public function lock($mark){
		$mark = strtolower($mark);
		$this->locked = $mark;
	}
	
	public function unlock($mark){
		$mark = strtolower($mark);
		foreach($this->temp as $_key => $_val){
			if(strpos($_key, $mark .'$')!==false){
				$_tmp = substr($_key, strpos($_key, '$'));
				$this->mark[$_tmp] = $_val;
				unset($this->temp[$_key]);
			}
		}
		$this->locked = '';
	}
	
	public function skindir(){
		return $this->cdir($this->dir . $this->name .'/');
	}
	
	public function item($key, $val=null){
		$key = strtolower($key);
		if(is_null($val)){
			return $this->mark[$key];
		}else{
			$this->mark[$key] = $val;
		}
		return $val;
	}
	
	public function html(){
		if(!headers_sent()){
			ob_end_clean();
			header('Content-type: text/html; charset='. $this->charset);
		}
		$this->item('$Charset', $this->charset);
		$this->item('$SkinDir', $this->skindir());
		$_html = $this->parse($this->load($this->file));
		$_time = (microtime(true)-$this->stime) * 1000;
		$this->item('$XmarkTimer', number_format($_time, 3, '.', ''));
		$this->item('$XmarkTimes', $this->times + 1);
		$this->item('$XmarkEvals', $this->evals + 1);
		$this->item('$XmarkLogs', $this->logs);
		$_html .= $this->xsign;
		$_html = $this->parse($_html);
		return $_html;
	}
	
	public function load($tpl){
		$_file = $this->skindir() . $tpl . $this->ext;
		if(!($_data=@file_get_contents($_file))){
			$_data = 'Cannot find the template file '. $tpl . $this->ext;
		}
		return $_data;
	}
	
	public function parse($html){
		if(is_null($html)) return;

		$html = $this->parseCtrlFree($html);
		$html = $this->parseCtrlFunc($html);
		$html = $this->parseFuncFree($html);
		$html = $this->parseFunction($html);
		$html = $this->parseVariable($html);
		$html = $this->parseVariable($html);
		$this->times += 1;
		return $html;
	}
	
	private function parseCtrlFree($html){
		// {@If.Free(fact)}{/If.Free} ...
		preg_match_all('/{@(([_a-z0-9]+?\.)([^{]*?))\(([^{]*?)\)}([\s\S]+?){\/\1}/ui', $html, $matchs);
		for($i=0; $i< count($matchs[0]); $i++){
			$_mark = strtolower('@'. $matchs[2][$i]);
			$_free = $matchs[3][$i];
			$_pars = $matchs[4][$i];
			$_html = $matchs[5][$i];
			if(isset($this->mark[$_mark])){
				$_func = $this->mark[$_mark];
				if(function_exists($_func)){
					$_pars = $this->parsePars($_pars);
					try{eval('$_value = '. $_func .'('. $_pars .', $_free, $_html);');}
					catch(Exception $e){$_value = $this->parseDebug($_mark, $e);}
					if(!empty($_value)){
						$html = str_replace($matchs[0][$i], $this->parse($_value), $html);
					}
					$this->logs .= ', '. $_mark;
					$this->evals += 1;
				}
			}
		}
		return $html;
	}
	
	private function parseCtrlFunc($html){
		// {@If(fact)}{/If} ...
		preg_match_all('/{@([_a-z0-9]+?)\(([^{]*?)\)}([\s\S]*?){\/\1}/ui', $html, $matchs);
		for($i=0; $i< count($matchs[0]); $i++){
			$_mark = strtolower('@'. $matchs[1][$i]);
			$_pars = $matchs[2][$i];
			$_html = $matchs[3][$i];
			if(isset($this->mark[$_mark])){
				$_func = $this->mark[$_mark];
				if(function_exists($_func)){
					$_pars = $this->parsePars($_pars);
					try{eval('$_value = '. $_func .'('. $_pars .', $_html);');}
					catch(Exception $e){$_value = $this->parseDebug($_mark, $e);}
					if(!empty($_value)){
						$html = str_replace($matchs[0][$i], $this->parse($_value), $html);
					}
					$this->logs .= ', '. $_mark;
					$this->evals += 1;
				}
			}
		}
		return $html;
	}
	
	private function parseFuncFree($html){
		// {@Include.Free(inc)/} ...
		preg_match_all('/{(@[_a-z0-9]+?\.)([^{]*?)\(([^{]*?)\)\/}/ui', $html, $matchs);
		for($i=0; $i< count($matchs[0]); $i++){
			$_mark = strtolower($matchs[1][$i]);
			$_free = $matchs[2][$i];
			$_pars = $matchs[3][$i];
			if(isset($this->mark[$_mark])){
				$_func = $this->mark[$_mark];
				if(function_exists($_func)){
					$_pars = $this->parsePars($_pars);
					try{eval('$_value = '. $_func .'('. $_pars .', $_free);');}
					catch(Exception $e){$_value = $this->parseDebug($_mark, $e);}
					if(!empty($_value)){
						$html = str_replace($matchs[0][$i], $this->parse($_value), $html);
					}
					$this->logs .= ', '. $_mark;
					$this->evals += 1;
				}
			}
		}
		return $html;
	}
	
	private function parseFunction($html){
		// {@Include(inc)/} ...
		preg_match_all('/{(@[_a-z0-9]+?)\(([^{]*?)\)\/}/ui', $html, $matchs);
		for($i=0; $i< count($matchs[0]); $i++){
			$_mark = strtolower($matchs[1][$i]);
			$_pars = $matchs[2][$i];
			if(isset($this->mark[$_mark])){
				$_func = $this->mark[$_mark];
				if(function_exists($_func)){
					$_pars = $this->parsePars($_pars);
					try{eval('$_value = '. $_func .'('. $_pars .');');}
					catch(Exception $e){$_value = $this->parseDebug($_mark, $e);}
					if(!empty($_value)){
						$html = str_replace($matchs[0][$i], $this->parse($_value), $html);
					}
					$this->logs .= ', '. $_mark;
					$this->evals += 1;
				}
			}
		}
		return $html;
	}
	
	private function parseVariable($html){
		// {$SkinDir} ...
		preg_match_all('/{(\$[_a-z0-9.]+?)}/ui', $html, $matchs);
		for($i=0; $i< count($matchs[0]); $i++){
			$_mark = strtolower($matchs[1][$i]);
			if(isset($this->mark[$_mark])){
				$_value = $this->mark[$_mark];
				if(is_null($_value)) $_value = '';
				if(!empty($_value)){
					$html = str_replace($matchs[0][$i], $_value, $html);
				}
				$this->logs .= ', '. $_mark;
				$this->evals += 1;
			}
		}
		return $html;
	}
	
	private function parsePars($pars){
		$_parn = 1; $_pars = '';
		if(trim($pars)=='') $pars = ' ';
		$_parr = explode(',', $pars);
		foreach($_parr as $_parm){
			preg_match_all('/(\$[_a-z0-9.]+)/ui', $_parm, $matchs);
			for($i=0; $i< count($matchs[0]); $i++){
				$_mark = strtolower($matchs[1][$i]);
				$_value = $this->quotstr($this->mark[$_mark]);
				$_parm = str_replace($matchs[0][$i], $_value, $_parm);
				$this->evals += 1;
			}
			$_pars .= $this->quotstr($_parm);
			if($_parndebug){
			$_debug = '';
			$_debug .= '[Xmark'. $mark .']('. $err->getCode() .')'. $err->getMessage();
			$_debug .= '';
		}
		return $_debug;
	}

	private function lockMark($key){
		$_key = $this->locked . $key;
		if(!isset($this->temp[$_key])){
			$this->temp[$_key] = $this->mark[$key];
		}
	}
	
	private function cdir($sdir){
		return str_replace('//', '/', str_replace('\\', '/', $sdir .'/'));
	}
	
	private function quotstr($str){
		if(strtolower($str)=='true' || strtolower($str)=='false') return $str;
		if(!is_numeric($str)){
			if((substr($str,0,1)=='\'' && substr($str,-1)=='\'')
			  ||(substr($str,0,1)=='"' && substr($str,-1)=='"')){
				$str = substr($str, 1, -1);
			}
			$str = str_replace('\'', '\\\'', $str);
			$str = '\''. $str .'\'';
		}
		if(trim($str)=='') $str = '\'\'';
		return $str;
	}
	
	private function filename(){
		$_file = basename($_SERVER['PHP_SELF']);
		if($_file=='') return 'index';
		return current(explode('.', $_file));
	}
	
	private function CXmark(){
		ob_start();
		$this->ext = '.html';
		$this->dir = 'template/';
		$this->name = 'default';
		$this->file = $this->filename();
		$this->version = '1.1.0';
		if(!defined('X_DEBUG')){
			$this->debug = false;
		}else{
			$this->debug = X_DEBUG;
		}
		if(!defined('X_CHARSET')){
			$this->charset = 'UTF-8';
		}else{
			$this->charset = X_CHARSET;
		}
		
		$this->temp = array();
		$this->mark = array();
		$this->logs = 'Xmark';
		$this->times = 0;
		$this->evals = 0;
		$this->stime = microtime(true);
		$this->locked = '';
		$this->item('$SkinDir', $this->skindir());
		$this->item('$Software', 'Xmark Template Engine Version '. $this->version);
		$this->xsign = '';
	}
	
	function __construct(){
		$this->CXmark();
	}
	function __destruct(){
		
	}
}

function XmarkClose(){
	if(isset($GLOBALS['Xmark'])){
		unset($GLOBALS['Xmark']);
	}
}

function XmarkHtml(){
	$_html = '';
	if(isset($GLOBALS['Xmark'])){
		$_html = $GLOBALS['Xmark']->html();
		unset($GLOBALS['Xmark']);
	}
	return $_html;
}

function XmarkShow(){
	if(isset($GLOBALS['Xmark'])){
		$GLOBALS['Xmark']->show();
		unset($GLOBALS['Xmark']);
	}
}
?>
{/Replace}