Location: PHPKode > scripts > LinkEX - Free Link EXchange manager by linkex.dk > linkex/index.php
<?php

error_reporting(E_ALL);
@set_time_limit( 60 );

$_SERVER['SCRIPT_NAME'] = substr( 
	linkex::get( 'PHP_SELF', $_SERVER, '' ), 
	0, 
	( strlen( linkex::get( 'PHP_SELF', $_SERVER, '' ) ) - strlen( linkex::get( 'PATH_INFO', $_SERVER, '' ) ) ) );
$_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . rtrim( '?' . linkex::get( 'QUERY_STRING', $_SERVER, '' ), '?' );
$errors = array();
if ( !function_exists( 'session_start' ) ) {
	die( '[Error: Sessions is not available on your server, please enable them since LinkEX relies on sessions]' );
}

session_name( 'sid' );
session_start();

srand( (float)microtime() * 10000 );
mt_srand( (float)microtime() * 10000 );
define( 'BASEDIR', dirname( __FILE__ ) );

define( 'BASEURI', basename( __FILE__ ) );
define( 'BASEFOLDER', basename( dirname( __FILE__ ) ) );
define( 'BASEFILE', basename( __FILE__ ) );

$templatecolumns = array(
	'added' => 'Date added',
	'lastchecked' => 'Date checked',
	'rpagerank' => 'Inbound Pagerank',
	'rdom' => 'Inbound Domain',
	'rdomip' => 'Inbound IP',
	'rindexed' => 'Inbound Indexed Pages',
	'lpagerank' => 'Outbound Pagerank',
	'ldom' => 'Outbound Domain',
	'ldomip' =>	'Outbound IP',
	'lindexed' => 'Outbound Indexed Pages',
	'link' => 'Link',
	'anchor' => 'Anchor',
	'title' => 'Title',
	'status' => 'Status'
);

// {{{ Session hijack check
$myuid = md5( linkex::get( 'REMOTE_ADDR', $_SERVER ) . linkex::get( 'HTTP_USER_AGENT', $_SERVER ) );
if ( ( $hash = linkex::get( 'hash', $_SESSION, false ) ) !== false ) {
	if ( 
		( $hash != $myuid ) || 
		( ( ( $ss = linkex::get( 'sid', $_GET, false ) ) !== false ) && ( $ss != session_id() ) )
	) {
		session_destroy();
		session_id( md5( uniqid() ) );
		setcookie( 'sid', '', time() - 1, '/' );
		linkex::redirect( BASEURI );
	}
}
// }}}
// {{{ Strip slashes from userinput
if ( get_magic_quotes_gpc() ) {
	function stripslashes_deep( $value ) {
		if( is_array( $value ) ) {
			$value = linkex::map( 'stripslashes_deep', $value );
		} elseif ( !empty( $value ) && is_string( $value ) ) {
			$value = stripslashes( $value );
		}
		return $value;
	}
	$_POST = stripslashes_deep($_POST);
	$_GET = stripslashes_deep($_GET);
	$_COOKIE = stripslashes_deep($_COOKIE);
} // }}}
// {{{ Std. includes

class linkex {
	function arraychunk( $array, $size, $fill=false ) { // {{{
		$i = $j = 0;
		$retval=array();

		if ( is_array( $size ) ) {
			$i = $k = 0;
			foreach( $size AS $s ) {
				$s = ( $s == '' ) ? ( sizeof($array)-$i ) : intval( $s );
				for( $n=0; $n<$s; $n++, $i++ ) {
					$retval[$k][] = $array[$i];
				}
				$k++;
			}
		} else {
			if ( $fill !== false ) {
				$count = ceil(sizeof($array)/$size)*$size;
			} else {
				$count = sizeof( $array );
			}

			for ($i=0; $i<$count;$i++) {
				if ($i>0 && ($i%$size)==0) {
					$j++;
				}
				$retval[$j][$i%$size] = (empty($array[$i])) ? $fill : $array[$i];
			}
		}
		return $retval;
	} // }}}
	function authorized() { // {{{
		global $config;
		$r=$u=$p=$a=false;
		$remember = ( linkex::get( 'remember', $_REQUEST, 0 ) == 1 );
		if ( ( $u = linkex::get( 'username', $_POST, false ) ) && ( $p = linkex::get( 'password', $_POST, false ) ) ) {
			$r=true;
		} else if ( $a = linkex::get( '_authcookie', $_SESSION, false ) ) {
			$r=false;
		} else if ( $a = linkex::get( '_authcookie', $_COOKIE, false ) ) {
			$remember=true;
			$r=false;
		}

		$path = dirname( linkex::get( 'SCRIPT_NAME', $_SERVER, '/' ) );
		if ( ( $u !== false && $p !== false ) || ( $a !== false ) ) {
			if ( md5( $u .'---'. $p ) == $config->password || $a == $config->password ) {
				$_SESSION['_authcookie'] = $config->password;
				
				if ( $remember ) {
					setcookie( '_authcookie', $config->password, time()+60*60*24*30, $path );
				}
				if ( $r ) {
					linkex::redirect( $_SERVER['REQUEST_URI'] );
				}
				return true;
			} else {
				setcookie( '_authcookie', '', time() - 3600, $path );
				unset( $_SESSION['_authcookie'] );
				return false;
			}
		} else {
			setcookie( '_authcookie', '', time() - 3600, $path );
			unset( $_SESSION['_authcookie'] );
			return false;
		}
	} // }}}
	function buildquery( $array ) { // {{{
		$retval = array();
		foreach( $array AS $k=>$v ) {
			$retval[] = urlencode( $k ).'='.urlencode( $v );
		}
		return join( '&', $retval );
	} // }}}
	function categories( $all = false, $checkslots=false ) { // {{{
		$categories = array();
		$cids = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR );
		foreach( $cids AS $cid ) {
			$c = new category( $cid );
			if ( ( $all || $c->public == 1 ) && ( !$checkslots || ( $checkslots && $c->slots > 0 && $c->links() < $c->slots ) ) ) {
				$categories{ $cid } = $c->name;
			}
			unset( $c );
		}
		return $categories;
	} // }}}
	function compareIPs( $a, $b ) { // {{{ a can be 127., 127.0, 127.0.0, 127.0.0.1, or a hostname
		if ( !preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $a ) ) {
			$a = linkex::gethostbyname( $a );
		}
		if ( !preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $b ) ) {
			$b = linkex::gethostbyname( $b );
		}
		$a = explode( '.', $a );
		$b = explode( '.', $b );
		for( $i=0; $i<sizeof( $a ); $i++ ) {
			if ( intval( $a[$i] ) != intval( $b[$i] ) ) {
				return $a[$i] - $b[$i];
			}
		}
		return 0;
	} // }}}
	function compareURLs( $a, $b ) { // {{{
		// returns 0 if equal
		global $config;
		$a = strtolower( $a );
		$b = strtolower( $b );
		if ( strlen( $a ) == 0 || strlen( $b ) == 0 ) {
			return 1;
		}
		if ( $config->linkbotdisregardwww == 1 ) {
			$a = str_replace( 'www.', '', $a );
			$b = str_replace( 'www.', '', $b );
		}
		if ( $config->linkbotignoretrailingslash == 1 ) {
			$a = rtrim( $a, '/' );
			$b = rtrim( $b, '/' );
		}
		return strcmp( $a, $b );
	} // }}}
	function checkbox( $val ) { // {{{
		return ( intval( $val ) != 0 ) ? 'checked="checked"':'';
	} // }}}
	function du( $dir ) { // {{{
		$s = @stat( $dir );
		$space = linkex::get( 'size', $s, 0 );
		if ( is_dir( $dir ) ) {
			$dh = opendir( $dir );
			while ( ( $file = readdir( $dh ) ) !== false ) {
				if ( !in_array( $file, array( '.', '..' ) ) ) {
					$space += linkex::du( rtrim( $dir, '/' ) .'/'. $file );
				}
			}
			closedir( $dh );
		}
		return $space;
	} // }}}
	function elapsed( $seconds ) { // {{{
		$retval = array(
			'Y' => 0,
			'm' => 0,
			'd' => 0,
			'H' => 0,
			'i' => 0,
			's' => 0,
			'nice' => ''
		);
		// Years ( 60*60*24*365 ) = 31536000 seconds
		if ( $seconds > 31536000 ) {
			$retval{'Y'} = floor( $seconds / 31536000 );
			$seconds = $seconds - ( $retval{'Y'} * 31536000 );
			$retval{'nice'} = $retval{'Y'} . ' year' . ( $retval{'Y'}>1?'s':'' );
		}

		// Months ( 60*60*24*30 ) = 2592000
		if ( $seconds > 2592000 ) {
			$retval{'m'} = floor( $seconds / 2592000 );
			$seconds = $seconds - ( $retval{'m'} * 2592000 );
			$retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . 
				$retval{'m'} . ' month' . ( $retval{'m'}>1?'s':'' );
		}
		// Days ( 60*60*24 ) = 86400
		if ( $seconds > 86400 ) {
			$retval{'d'} = floor( $seconds / 86400 );
			$seconds = $seconds - ( $retval{'d'} * 86400 );
			$retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . 
				$retval{'d'} . ' day' . ( $retval{'d'}>1?'s':'' );
		}
		// Hours ( 60*60 ) = 3600
		if ( $seconds > 3600 ) {
			$retval{'H'} = floor( $seconds / 3600 );
			$seconds = $seconds - ( $retval{'H'} * 3600 );
			$retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . 
				$retval{'H'} . ' hour' . ( $retval{'H'}>1?'s':'' );
		}
		// Minutes ( 60 ) = 60
		if ( $seconds > 60 ) {
			$retval{'i'} = floor( $seconds / 60 );
			$seconds = $seconds - ( $retval{'i'} * 60 );
			$retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . 
				$retval{'i'} . ' minute' . ( $retval{'i'} > 1 ? 's':'' );
		}
		// Seconds 0
		if ( $seconds >= 0 ) {
			$retval{'s'} = $seconds;
			$retval{'nice'} .= ( strlen( $retval{'nice'} ) > 0 ? ', ':'' ) . 
				$retval{'s'} . ' second' . ( $retval{'s'}>1?'s':'' );
		}
		return $retval;
	} // }}}
	function expandlink( $link, $baseurl ) { // {{{
			preg_match( "'^[^\?]+'", $baseurl.'/', $res );
			$res = preg_replace( "|/[^\/\.]+\.[^\/\.]+$|", '', $res[0] );
			$res = rtrim( $res, '/' );

			if ( ( $root = @parse_url( $res ) ) ) {
				$root = $root['scheme'] .'://'. $root['host'];
			} else {
				// fixme
				// die( 'Unable to parse: '.$res );
				$root = 'http://';
			}

			$search = array(
				"|^(\/)|i",
				"|^(?!http://)(?!mailto:)|i",
				"|/\./|",
				"|/[^\/]+/\.\./|"
			);
			$replace = array(
				$root .'/',
				$res . '/',
				'/',
				'/'
			);

			return preg_replace( $search, $replace, $link );
		} // }}}
	function fetch( $url, $params=array() ) { // {{{
		global $config;
		if ( ( $host = @parse_url( $url ) ) && linkex::get( 'host', $host, false ) !== false ) {
			$po = linkex::get( 'port', $host, '80' );
			$ho = linkex::get( 'host', $host, '' );
			$pa = linkex::get( 'path', $host );
			$pa = ( strlen( $pa ) == 0 ) ? '/':$pa;
			$qu = linkex::get( 'query', $host, '' );
			$pa.= ( strlen( $qu ) == 0 ) ? '':'?'.$qu;
			$cua = array_map( 'trim', explode("\n", $config->linkbotagent ) );
			shuffle($cua);
			$cua = $cua[0];
			$ua = linkex::get( 'agent', $params, $cua );

			$h  = array();
			$h[]= linkex::get( 'method', $params, 'GET' ).' '.$pa.' HTTP/1.0';
			$h[]= 'Host: '.$ho;
			$h[]= 'User-Agent: '.$ua;
			$h[]= 'Connection: close';
			if ( ( $ref = linkex::get( 'referer', $params, false ) ) !== false ) {
				$h[] = 'Referer: '.$ref;
			}
			if ( linkex::get( 'method', $params, 'GET' ) == 'POST' && strlen( linkex::get( 'data', $params, '' ) ) > 0 ) {
				$h[]= 'Content-Length: '.strlen( linkex::get( 'data', $params, '' ) );
				$h[] = 'Content-Type: application/x-www-form-urlencoded';
			}
			$header = join( "\r\n", $h ) . "\r\n\r\n";
			if ( ( $data = linkex::get( 'data', $params, false ) ) !== false ) {
				$header .= $data;
			}

			$buffer = '';
			$fp = @fsockopen ( $ho, $po, $errno, $error, linkex::get( 'timeout', $params, 3 ) );
			if ( !$fp ) {
				return array( 'URL' => $url, 'error' => 'Socket error: '.$error.' ['.$errno.']' );
			} else {
				@stream_set_timeout($fp, linkex::get( 'timeout', $params, 3 ) );
				fputs( $fp, $header );
				while( !feof( $fp ) ) {
					$buffer .= fgets( $fp, 1024 );
				}
				fclose( $fp );
				/// buffer holder nu hele resultatet, incl headers etc
				if ( preg_match( '/^HTTP\/(\d+\.\d+)\s+(\d{3})\s+(.*)/i', $buffer, $res ) === false ) {
					return array( 'URL' => $url, 'error' => 'Invalid HTTP response ('.substr( $buffer,0,30).')' );
				} else {
					switch ( $res[2] ) {
					case 200:
						/// ok
						/// strip off the headers
						$res = explode( "\n\n", str_replace( chr( 13 ), '', $buffer ) );
						if ( sizeof( $res ) >= 2 ) {
							$headers = array_shift( $res );
							if ( function_exists( 'utf8_encode' ) ) {
								$contents = utf8_encode( join( "\n\n", $res ) );
							} else {
								$contents = join( "\n\n", $res );
							}
							return array( 'URL' => $url, 'headers' => $headers, 'contents' => $contents );
						} else {
							return array( 'URL' => $url, 'contents' => utf8_encode( $buffer ) );
						}								
						break;
					case 301:
					case 302:
						/// maybe redirect?
						if ( !preg_match( '/location\:\s+(.*)/i', $buffer, $redir ) ) {
							return array( 'URL' => $url, 'error' => $res[2].' but no redirect' );
						} else {
							$url = rtrim( $redir[1] );
							if ( !preg_match( '"^http"i', $url ) ) {
								$url = 'http://'.$ho.'/'.ltrim( $url, '/' );
							}
							if ( ( $h = @parse_url( $url ) ) === false ) {
								return array( 'URL' => $url, 'error' => $res[2].' but unparsable URL' );
							} else {
								if ( 
									str_replace( 'www.', '', strtolower( linkex::get( 'host', $h, '' ) ) )
								 	!= 
									str_replace( 'www.','', strtolower( $ho ) ) 
								) { 
									return array( 'URL' => $url, 
										'error' => $res[2].' but to external site ('.linkex::get( 'host', $h, '' ).')' );
								} else {
									return linkex::fetch( trim( $url ) );
								}
							}
						}
						break;
					default:
						/// not good
						return array( 'URL' => $url, 'error' => $res[2].' '.trim( $res[3] ) );
						break;
					}
				}
			}
		} else {
				return array( 'URL' => $url, 'error' => 'Unparsable URL' );
		}	
	} // }}}
	function fileget( $file, $default=null ) { // {{{
		if ( file_exists( $file ) ) {
			if ( $fp = @fopen( $file, 'r' ) ) {
				$locked = ( @flock( $fp, LOCK_EX ) ) ? true:false;
				// $default = fread( $fp, filesize( $file ) );
				$default = '';
				while ( !feof( $fp ) ) {
					$default .= fread( $fp, 1024*1024 );
				}
				if ( $locked ) { @flock( $fp, LOCK_UN ); }
				fclose( $fp );
			}
		}
		return $default;
	} // }}}
	function fileput( $file, $con ) { // {{{
		if ( $fp = @fopen( $file, 'w' ) ) {
			$locked = ( @flock( $fp, LOCK_EX ) ) ? true:false;
			$default = fwrite( $fp, $con );
			if ( $locked ) { @flock( $fp, LOCK_UN ); }
			@fclose( $fp );
			return ( intval( $default ) > 0 );
		} else {
			return false;
		}
	} // }}}
	function flush() { // {{{
		echo str_pad('',4096)."\n";	
		flush();
		usleep( 500000 );
	} // }}}
	function genID() { // {{{
		$id = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR .'uid' );
		$id++;
		linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR .'uid', $id ) or die( "[Fatal Error: Unable to write to UID file]" );
		return $id;
	} // }}}
	function get( $key, $array, $default=null ) { // {{{
		if ( is_array( $array ) && in_array( $key, array_keys( $array ) ) ) {
			$default = $array{ $key };
		}
		return $default;
	} // }}}
	function getDomain( $var ) { // {{{
		$var = strtolower( $var );
		if ( ( $pos = strpos( $var, '@' ) ) !== false ) {
			// Email
			$domain = substr( $var, $pos + 1 );
		} else {
			// URL
			$domain = @parse_url( $var );
			$domain = linkex::get( 'host', $domain, 'unparseable' );
		}
		return $domain;
	} // }}}
		function gethostbyname( $dom, $force=false ) { // {{{
			$dom = strtolower( trim( $dom ) );

			$data = array();
			if ( 
				file_exists( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'ips' ) && 
				( $data = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'ips' ) ) &&
				( $data = linkex::unserialize( $data ) )
			) {
				if (
					( $force === false ) &&
					( $ipinfo = linkex::get( $dom, $data, false ) ) !== false &&
					( time() - linkex::get( 'date', $ipinfo, 0 ) ) < 604800 &&
					( $ip = linkex::get( 'ip', $ipinfo, false ) ) !== false &&
					preg_match( '/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/', $ip ) == 1
				) {
					unset( $data );
					return $ip;
				}
			}
			$ip = @gethostbyname( $dom );
			if ( $dom != $ip ) {
				$data{ $dom } = array( 'date' => time(), 'ip' => $ip );
				linkex::fileput( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'ips', trim( serialize( $data ) ) );
				unset( $data );
			}
			return $ip;

		} // }}}
		function getLinks( $str, $baseurl ) { // {{{
			$thisdom = linkex::getDomain( $baseurl );
			preg_match_all( "'<\s*a.*>(.*)<\s*/\s*a\s*>'Umis", $str, $res );
			$links = array();
			for( $i=0; $i<sizeof( $res[0] ); $i++ ) {
				$buffer = array();
				$buffer{'raw'} = htmlentities( $res[0][$i] );
				$res[0][$i] = preg_replace( '#\s*=\s*#', '=', $res[0][$i] );
				$buffer{'href'} = linkex::getParam( 'href', $res[0][$i] );
				$buffer{'url'} = linkex::expandlink( $buffer{'href'}, $baseurl );
				$buffer{'domain'} = linkex::getDomain( $buffer{'url'} );
				$buffer{'external'} = ( $buffer{'domain'} == $thisdom ) ? 0:1;
				$rel = linkex::getParam( 'rel', $res[0][$i] );
				$buffer{'nofollow'} = ( strlen( $rel ) && ( strpos( strtolower( $rel ), 'nofollow' ) !== false ) ) ? 1:0;
				$buffer{'anchor'} = trim( $res[1][$i] );
				$links[] = $buffer;
			}
			unset( $res );
			return $links;
		} // }}}
	function getParam( $needle, $haystack, $default=null ) { /// {{{
			if ( ( $pos = strpos( strtolower( $haystack ), strtolower( $needle ) ) ) !== false ) {
				$pos += strlen( $needle ) + 1; /// +1 : "="
				if ( in_array( $haystack{$pos}, array( '"', "'" ) ) ) {
					$d=1;
					$end = array( $haystack{$pos} );
				} else {
					$d=0;
					$end = array( ' ', '>' );
				}
				$retval = '';
				for($i=$pos+$d;$i<strlen( $haystack ) && ( !in_array( $haystack{$i}, $end ) || ( in_array( $haystack{$i}, $end ) && $i>0 && $haystack{$i-1} == '\\' ) );$retval.=$haystack{$i}, $i++ ) {}
				foreach( $end AS $c ) { $retval = str_replace( '\\'.$c, $c, $retval ); }
				return $retval;
			} else {
				return $default;
			}
		} /// }}}
	function glob( $dir, $regex ) { // {{{
		$files = array();
		if ( $d = @opendir( $dir ) ) {
			while ( false !== ( $file = readdir( $d ) ) ) {
				if ( preg_match( '|' . $regex . '|i', $file ) ) {
					$files[] = $file;
				}
			}
		}
		return $files;
	} // }}}		
	function installed() { // {{{
		return (
			is_dir( BASEDIR . DIRECTORY_SEPARATOR .'data' ) &&
			is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR ) &&
			is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR ) &&
			is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR ) &&
			is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'blacklist' . DIRECTORY_SEPARATOR ) &&
			is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ) &&
			is_dir( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'output' . DIRECTORY_SEPARATOR )
		);
	} // }}}
	function listfiles( $dir, $ext=array() ) { // {{{
		$retval = array();
		if ( is_dir( $dir ) ) {
			if ( $dh = opendir( $dir ) ) {
				while ( ( $file = readdir( $dh ) ) !== false ) {
					if ( filetype( rtrim( $dir, DIRECTORY_SEPARATOR ) .DIRECTORY_SEPARATOR. $file ) == 'file' ) {
						$retval[] = $file;
					}
				}
			}
		}
		return $retval;
	} // }}}
	function log( $level, $type, $str ) { // {{{
		$file = 'linkex.log';
		$log = sprintf( "[%s] [level=%d] [%s] %s\n", date( 'Y-m-d H:i:s' ), $level, $type, $str );
		$fp = fopen( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . $file, 'a' );
		flock( $fp, LOCK_EX );
		fwrite( $fp, $log );
		fclose( $fp );
	} // }}}
	function map( $fun, $arr ) { // {{{
		$retval = array();
		foreach( $arr AS $k=>$v ) {
			$retval[ $k ] = $fun( $v );
		}
		return $retval;
	} // }}}
	function mail( $to, $sub, $body ) { // {{{
		global $config;

		$headers = array();
		$headers[] = 'X-Mailer: LinkEX/20100226';
		if ( strlen( $config->email ) > 0 ) {
			$headers[] = sprintf( 'From: LinkEX @ %s <%s>', 
				linkex::get( 'HTTP_HOST', $_SERVER, linkex::getdomain( $config->url ) ), $config->email );
			$headers[] = sprintf( 'Reply-To: %s', trim( $config->email ) );
		}
		return mail( $to, $sub, $body, join( 
			str_replace( array( '\r', '\n' ), array( "\r", "\n" ), 
			$config->emailcrlf ), $headers 
		) );
	} // }}}
	function redirect( $url, $code=301 ) { // {{{
		$resp = array(
			301 => 'HTTP/1.1 301 Moved Permanently',
			404 => 'HTTP/1.1 404 Not Found'
		);
		if ( ( $resp = linkex::get( $code, $resp, false ) ) !== false ) {
			header( $resp );
		}
		header( 'location: '.$url );
		exit;
	} // }}}
		function selector( $name, $list, $selected=null, $multiple=true, $forcetype=null, $extra=null, $sep='<br />' ) { /// {{{

			$type = ( $multiple ) ? 'checkbox':'radio';
			$type = ( sizeof( $list ) > 5 ) ? 'select':$type;
			if ( $forcetype && in_array( $forcetype, array( 'checkbox', 'radio', 'select' ) ) ) {
				$type = $forcetype;
			}
			$extra['class'] = $type.' '.linkex::get( 'class', $extra, '' );
			if ( $extra ) {
				$buffer=array();
				foreach( $extra AS $k=>$v ) {
					$buffer[] = sprintf( '%s="%s"', $k, $v );
				}
				$extra=' '.join( ' ', $buffer );
			} else {
				$extra='';
			}
			$formname = ( $multiple ) ? $name.'[]' : $name;
			$buffer = '';
			if ( $type == 'select' ) {
				$buffer .= sprintf( '<select id="%s" name="%s" size="%d" %s%s>', $name, $formname, ($multiple)?4:1, ( $multiple ) ? 'multiple ':'', $extra );
			}
			foreach ( $list AS $id=>$txt ) {
				$ck = ( ( is_array( $selected ) && in_array( $id, $selected ) ) || ( is_string( $selected ) && $id==$selected ) );
				if ( $type == 'select' ) {
					$buffer .= sprintf( '<option value="%s" %s>%s</option>', $id, ($ck)?'selected="selected"':'', $txt );
				} elseif ( $type == 'checkbox' ) {
					$buffer .= sprintf( '<label><input type="checkbox" name="%s" value="%s"%s %s/> %s</label>%s',
						$formname, $id, ($ck)?' checked="checked"':'', $extra, $txt, $sep );
				} elseif ( $type == 'radio' ) {
					$buffer .= sprintf( '<label><input type="radio" name="%s" value="%s"%s %s/> %s</label>%s',
						$formname, $id, ($ck)?' checked="checked"':'', $extra, $txt, $sep );

				}
			}
			if ( $type == 'select' ) {
				$buffer .= '</select>';
			}
		
			return $buffer;
		} /// }}}
	function serialize( $val ) { // {{{
		return serialize( $val );
	} // }}}
	function sort( &$array, $field, $order='desc' ) { // {{{
		if ( $field == 'random' ) {
			shuffle( $array );
		} else {
			$GLOBALS['sortby'] = $field;

			usort( $array, array( 'linkex', 'usort' ) );

			if ( $order == 'desc' ) {
				$array = array_reverse( $array );
			}
		}
	} // }}}
	function stripcomments( $con ) { // {{{
		$con = preg_replace( '|<!--.*-->|Umis', '', $con );
		$con = preg_replace( '|<script.*<\s*/\s*script.*>|Umis', '', $con );
		$con = preg_replace( '|<style.*<\s*/\s*style.*>|Umis', '', $con );
		return $con;
	} // }}}
	function substr( $str, $len, $pad='..' ) { // {{{
		if ( strlen( $str ) > $len ) {
			return substr( $str, 0, $len - strlen( $pad ) ) . $pad;
		} else {
			return $str;
		}
	} // }}}
	function truncate( $str, $len, $txt='..' ) { // {{{
		if ( strlen( $str ) > ( $len-strlen( $txt ) ) ) {
			return substr( $str, 0, $len-strlen( $txt ) ).$txt;
		} else {
			return $str;
		}
	} // }}}
	function unserialize( $str ) { // {{{
		$retval = @unserialize( $str );
		if ( $retval !== false ) {
			return $retval;
		} else {
			// Attempt to fix it
			$str = preg_replace('!s:(\d+):"(.*?)";!e', "'s:'.strlen('$2').':\"$2\";'", trim( $str ) );
			$retval = @unserialize( $str );
			if ( $retval !== false ) {
				return $retval;
			} else {
				echo '[Fatal error in linkex::unserialize( "'. $str .'" )]';
			}
		}
	} // }}}
	function usort( $a, $b ) { // {{{
		if ( isset( $GLOBALS['sortby'] ) && strlen( $GLOBALS['sortby'] ) > 0 ) {
			$f = $GLOBALS['sortby'];
			if ( is_object( $a ) && isset( $a->$f ) ) {
				$aa = $a->$f;
			} else if ( is_array( $a ) && isset( $a[$f] ) ) {
				$aa = $a[$f];
			} else {
				$aa = $a;
			}
			if ( is_object( $b ) && isset( $b->$f ) ) {
				$bb = $b->$f;
			} else if ( is_array( $b ) && isset( $b[$f] ) ) {
				$bb = $b[$f];
			} else {
				$bb = $b;
			}

			switch( $f ) {
			case 'ldomip':
			case 'rdomip':
				$aa = sprintf( '%u', ip2long( $aa ) );
				$bb = sprintf( '%u', ip2long( $bb ) );
				break;
			case 'ldom':
			case 'rdom':
				$aa = str_replace( 'www.', '', strtolower( $aa ) );
				$bb = str_replace( 'www.', '', strtolower( $bb ) );
				break;
			case 'title':
			case 'link':
			case 'anchor':
				$aa = strtolower( $aa );
				$bb = strtolower( $bb );
				break;
			}

			if ($aa == $bb) {
				return 0;
			}
			return ($aa < $bb) ? -1 : 1;
		} else {
			return 0;
		}
	} // }}}
	function verifybacklinks( $ids=array(), $callback=null ) { // {{{
		global $config;
		$retval = array(
			'starttime' => time(),
			'links' => array(),
			'categories' => array()
		);
		foreach( $ids AS $id ) {
			$l = new link( $id, false );
			$l->updateIPs(true);
			$buffer = array(
				'action' => 'link',
				'id' => $l->id,
				'rdom' => $l->rdom,
				'rdomip' => $l->rdomip,
				'rurl' => $l->rurl,
				'skipcheck' => $l->skipcheck,
				'skippagerank' => $l->skippagerank,
				'minpagerank' => ( $l->minpagerank != -1 ) ? $l->minpagerank : $config->minpagerank,
				'oldstatus' => $l->status,
				'oldpagerank' => $l->pagerank
			);
			if ( $l->skipcheck == 0 ) {
				$pr = $l->getRPageRank();
				$l->getLPageRank();
				$l->getRIndexedPages();
				$l->getLIndexedPages();
				$buffer{'res'} = $l->hasBacklink();
				$buffer{'code'} = ( !is_string( linkex::get( 'reason', $buffer{'res'}, null ) ) ) ? '200 OK' : $l->laststatus;
				if ( $l->status != 4 ) {
					$l->status = ( 
						( $pr >= ( ( $l->minpagerank != -1 ) ? $l->minpagerank : $config->minpagerank ) ) && 
						( linkex::get( 'res', $buffer{'res'}, -1 ) == 0 ) 
					) ? 1:2;
				}
				if ( intval( $config->disableblacklisted ) == 1 && ( ( $b = $l->blacklisted() ) !== false )) {
					$l->status = 2;
					$buffer{'res'} = 64;
					$buffer{'code'} = $b;
					$l->log[] = array( 
						'date' => time(),
						'res' => '64',
						'reason' => $b
					);
				}
			} else {
				$l->lastcheked = time();
				$l->log[] = array( 
					'date' => time(),
					'res' => '32',
					'reason' => ''
				);
			}
			$l->save( false );
			$buffer{'status'} = $l->status;
			$buffer{'pagerank'} = $l->getRPageRank(false);
			$retval{'links'}[] = $buffer;
			unset( $l );
			if ( $callback != null && function_exists( $callback ) ) {
				call_user_func( $callback, $buffer );
			}
			unset( $buffer );
		}
		// Rebuild categories
		$categories = linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'categories' . DIRECTORY_SEPARATOR );
		foreach( $categories AS $cid ) {
			$c = new category( $cid );
			$c->generate();
			$buffer = array(
				'action' => 'category',
				'id' => $cid,
				'name' => $c->name
			);
			$retval{'categories'}[] = $buffer;
			unset( $c );
			if ( $callback != null && function_exists( $callback ) ) {
				call_user_func( $callback, $buffer );
			}
			unset( $buffer );
		}
		
		$retval{'endtime'} = time();
		return $retval;
	} // }}}
	function sum( $array = array() ) { // {{{
		$retval = 0;
		foreach( $array AS $a ) {
			$retval += $a;
		}
		return $retval;
	} // }}}
	function yesno( $val ) { // {{{
		return ( $val ) ? 'Yes':'No';
	} // }}}
}

class template {
	function about() { // {{{
		global $config;
		if ( LOGGEDIN ) {
			$phpver = phpversion();
			$umask = sprintf( "%04o", umask() );
			$zendver = zend_version();
			$uname = php_uname( "s" )." ".php_uname( "r" )." ".php_uname( "m" );
			$du = round( linkex::du( BASEDIR . DIRECTORY_SEPARATOR . 'data' ) / 1024, 2 ).'KB';
			$links = sizeof( linkex::listfiles( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'links' . DIRECTORY_SEPARATOR ) );
			$installdate = date( $config->dateformat, $config->installdate );
			$precision = ini_get( 'precision' );
			if ( function_exists( 'gd_info' ) ) {
				$gd = gd_info();
				$gd = sprintf( '%s - GIF Support: %s',
					$gd{'GD Version'},
					( ( $gd{'GIF Create Support'} ) ? 'enabled':'unsupported, using plain text for CAPTCHA if used' )
				);
			} else {
				$gd = 'Not installed, using plain text for CAPTCHA if used.';
			}

			echo "<div style=\"margin:10px auto;\">
	<fieldset>
		<legend>Server info</legend>
		<table class=\"table\">
			<tr>
				<td class=\"key\">PHP version:</td>
				<td>{$phpver}</td>
			</tr>
			<tr>
				<td class=\"key\">Zend version:</td>
				<td>{$zendver}</td>
			</tr>
			<tr>
				<td class=\"key\">GD Info:</td>
				<td>{$gd}</td>
			</tr>
			<tr valign=\"top\">
				<td class=\"key\">Server OS:</td>
				<td>{$uname}</td>
			</tr>
			<tr>
				<td class=\"key\">php.precision</td>
				<td>{$precision}</td>
			</tr>
			<tr>
				<td class=\"key\">umask</td>
				<td>{$umask}</td>
			</tr>
		</table>
	</fieldset>
</div>
<div style=\"margin:10px auto;\">
	<fieldset>
		<legend>LinkEX info</legend>
		<table class=\"table\">
			<tr>
				<td class=\"key\">LinkEX version:</td>
				<td>20100226</td>
			</tr>
			<tr>
				<td class=\"key\">Current version:</td>
				<td id=\"currentversion\">stand by..</td>
			</tr>
			<tr>
				<td class=\"key\"></td>
				<td id=\"upgradeadvised\"></td>
			</tr>
			<tr>
				<td class=\"key\">Database size:</td>
				<td>{$du}</td>
			</tr>
			<tr>
				<td class=\"key\">Links:</td>
				<td>{$links}</td>
			</tr>
			<tr>
				<td class=\"key\">Install date:</td>
				<td>{$installdate}</td>
			</tr>
		</table>
	</fieldset>
</div>

<div style=\"margin:10px auto;\" id=\"changelog\">
	<fieldset class=\"expandable hidden\" id=\"fschangelog\">
		<legend>LinkEX info</legend>
		<div class=\"contractor\">
			<div id=\"changelogitems\"></div>
		</div>
	</fieldset>
</div>

<script type=\"text/javascript\">
			/*<![CDATA[*/
			\$(document).ready(function(){ \$(\"#changelog\").hide(); var url = location.href.replace( /\?.*/, '' )+'?page=rss&view=changelog'; \$.get( url,
			function(xml){ var upgradeurl=location.href.replace(/\?.*/, '')+'?page=admin&view=upgrade'; var release=\$(\"channel\", xml).attr(\"release\"); \$(\"#currentversion\").html(release+'&nbsp;(<a href=\"'+upgradeurl+'\">Force upgrade</a>)'); if(release > 20100226){ \$(\"#upgradeadvised\").html('A newer version is available. You are advised to <a href=\"'+upgradeurl+'\">upgrade</a>.<br />Check out the changes below, before upgrading.'); \$(\"div#changelog div.contractor\").hide(); \$(\"div#changelog\").show().find(\"legend:first\").html(\"Changelog 20100226 &raquo; \"+release); var url=location.href.replace(/\?.*/, '')+'?page=rss&view=changelog'; \$.get(url,
			function(xml){ var html=''; var items=\$(\"item\", xml); \$(items).each(function(){ var title=\$(this).find(\"title:first\").text(); var link=\$(this).find(\"link:first\").text(); var pubDate=\$(this).find(\"pubDate:first\").text(); var description=\$(this).find(\"description:first\").text(); html +='<div class=\"item\"><div class=\"meta\"><div class=\"title\"><a target=\"_blank\" href=\"'+link+'\">'+ title+'</a></div>Posted on '+pubDate+'</div><div class=\"contents\">'+description+'</div></div>'; }); \$(\"div#changelogitems\").html(html); }); } }); });
			/*]]>*/
		</script>

";
		} else {
			echo "<fieldset style=\"margin:10px auto;\">
	<legend>Powered by <a href=\"http://linkex.dk/\" title=\"LinkEX\">LinkEX</a></legend>
	<div class=\"article\">
		This site is powered by LinkEX, a free script that will take care of accepting link exchange requests, 
		and, if needed, making sure a link back is present.<br />
		<br />
		If you run a website, you can have this script also. Head over to <a href=\"http://linkex.dk\">linkex.dk</a>, 
		and get your free copy.<br />
		<br />
		<div class=\"bold underline\">Features</div>
		<ul>
			<li>Free! This script is free. No hidden fees, no nothing.</li>
			<li>Easy to install - upload 1 (one) file, fill out the basic settings, and you are good to go.</li>
			<li>One click updates. Update the script, just by a single click. The script will fetch the latest release, install it, making sure you are up to date at all times.</li>
			<li>Advancend link robot. You choose what sites to check for backlinks, and the bot will make sure the link is present.</li>
			<li>Google PageRank&trade; check. The script will show you the PageRank&trade; of all your link partners.</li>
			<li>And much much more..</li>
		</ul>
		Head over to <a href=\"http://linkex.dk\">linkex.dk</a> to read more
	</div>
</fieldset>
";
		}
	} // }}}
	function footer() { // {{{
		$params = array(
			'BASEURI' => BASEURI
		);
		return "			</div>
			<div id=\"footer\">
				v.20100226 &copy; <a href=\"http://linkex.dk/\" title=\"Free link exchange script\">linkex.dk</a> 2006-2010
			</div>
		</div>
	</body>
</html>
";
	} // }}}
	function header( $params = array() ) { // {{{
		global $errors, $config;
		$params = array_merge( 
			array(
				'BASEURI' => BASEURI,
				'menu' => Template::menu(),
				'title' => '',
				'onload' => '',
				'metadescription' => ''
			),
			$params
		);
		if ( isset( $params{'metarobots'} ) && strpos( $params{'metarobots'}, '<' ) === false ) {
			$params{'metarobots'} = sprintf( '<META NAME="ROBOTS" CONTENT="%s">', strtoupper( $params{'metarobots'} ) );
		} else {
			$params{'metarobots'} = '';
		}
		$error = '';
		$charset = isset( $config->charset ) ? $config->charset : 'utf-8';
		if ( linkex::get( 'noerrors', $params, true ) && sizeof( $errors ) > 0 ) {
			$error = join( '<br />', $errors );
			$error = "<div style=\"margin:10px 0px;\">
	<fieldset class=\"error\">
		<legend>Error</legend>
		<div class=\"article\">
			{$error}
		</div>
	</fieldset>
</div>
";
		}
		return "<!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\" xml:lang=\"en\" lang=\"en\">
	<head>
		<meta http-equiv=\"Content-Type\" content=\"text/html;charset={$charset}\" />
		<title>LinkEX &raquo; {$params{'title'}}</title>
		<style type=\"text/css\">div.rssnews { height:200px; overflow:auto; } div.rssnews div.item { margin:10px 25px; padding-bottom:10px; border-bottom:1px dotted #bbb; } div.rssnews div.item div.meta { border-bottom:1px solid #F3F3F3; margin-bottom:10px; color:#333; } div.rssnews div.item div.meta div.title { font-size:14px; font-weight:bold; } div.helpDiv { background-color:#fff; width:400px; height:300px; position:absolute; z-index:100; top:70px; left:150px; padding:0px; border:3px solid #aaa; } div.helpDiv .article { padding:10px;overflow:auto;height:250px; } div.helpDiv h1 { margin:0px;font-size:20px; } div.helpDivGone { display:none; top:10000000px; left:10000000px; } .center { text-align:center; } .right { text-align:right; } .pre { font-family:monospace; } .justify { text-align:justify; } .bold { font-weight:bold; } .underline { text-decoration: underline; } div.icon { width:16px; height:16px; background-image:url( '{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981' ); background-repeat:no-repeat; } div.iconinformation, div.icon4 { background-position:-32px -155px; } div.iconaccept, div.icon1 { background-position:0px -155px; } div.icondelete, div.icon2, div.icon64 { background-position:-16px -155px; } html { min-height:100.05%; } body { background-color:#f4f5f1; margin:0px; } a { color:blue; } body, td, input, select, textarea {  font-family:verdana, sans-serif; font-size:11px; } div#wrapper { width:80%; min-width:1000px; background-color:#fff; } div#topbar{ height:20px; background-color:#B91450; } div#header h1, div#header a { font-size:22px; text-align:right; color:#313129; margin:0px; text-decoration:none; }  #navbar ul { padding-left: 0; margin-left: 0; margin:0px; padding:0px; background-color: #d7d7d7; background-image:url( '{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981' ); background-repeat:repeat-x; background-position:0px -129px; color:#7f7f7f; float:left; width:100%; border:1px solid #959595; border-left:0px; border-right:0px; }  #navbar ul li { display: inline; } #navbar ul li a { padding:4px 10px 3px 7px; color:#7f7f7f; text-decoration: none; float:left; }  #navbar ul li a:hover { color: #000; }  div#footer { padding-top:0px; padding-bottom:1px; font-size:9px; text-align:right; color:#fff; background-color:#B91450; } div#footer a { color:#fff; text-decoration:none; height:13px; } div#footer a img { border:0px; width:45px; height:13px; } div#contents { padding:3px; } form { margin:0px; } select { width:150px; font-size:11px; } input.checkbox, input .radio { margin-left:0px; margin-right:0px; } input.button { width:100px; } input.text { background-color:#F4F4F4; border:1px solid #B2B2B2; border-color:#999999 rgb(204, 204, 204) rgb(204, 204, 204) rgb(153, 153, 153); padding:3px; width:400px; } textarea.text { background-color:#F4F4F4; border:1px solid #B2B2B2; padding:2px; width:402px; overflow:auto; height:55px; } input.focus, textarea.focus { background-color:#fff; border-color:#686868; } fieldset { width:90%; margin:0px auto; padding:2px 0px; border:1px solid #aaa; } fieldset legend { margin-left:15px; font-weight:bold; } fieldset.expandable legend { cursor:pointer; background-image:url('{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981'); background-repeat:no-repeat; background-position:4px -109px; padding-left:15px; margin:0px 10px; _margin:0px 2px; } fieldset.hidden legend { background-image:url('{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981'); background-position:4px -93px; } fieldset.expandable div.contractor { } span.green, div.green { color:#008000; } span.yellow, div.yellow { color:#D5A13D; } fieldset.error, span.red, div.red { color:#c00; } fieldset.error legend { background-repeat:no-repeat; background-position:-22px -202px; padding:5px 0px; padding-left:23px; margin:0px 10px; margin-right:5px; _margin:0px 2px; background-image:url('{$params{'BASEURI'}}?page=file&view=sprite'); } table { width:100%; } table tr { height:15px; } table tr.thXXX thXX { background-color:#ddd; border-bottom:1px solid #000; } table th { text-align:left; } table tr.navigation, table tr.navigation td { background-color:#ddd; } table td.key { width:130px; text-align:right; padding-right:15px; } a.help img { width:16px; height:16px; border:0px; } div.article { padding:3px 10px; line-height:15px; text-align:justify; } div.pagerank { width:55px; height:8px; background-image:url('{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981'); background-position:0px 0px; float:left; } div.pr1 { background-position:0px -8px; } div.pr2 { background-position:0px -16px; } div.pr3 { background-position:0px -24px; } div.pr4 { background-position:0px -32px; } div.pr5 { background-position:0px -40px; } div.pr6 { background-position:0px -48px; } div.pr7 { background-position:0px -56px; } div.pr8 { background-position:0px -64px; } div.pr9 { background-position:0px -72px; } div.pr10{ background-position:0px -80px; }  div.minpagerank { width:7px; height:8px; background-image:url('{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981'); background-position:-44px 0px; float:left; margin-left:5px; } div.minpr1 { background-position:-44px -8px; } div.minpr2 { background-position:-44px -16px; } div.minpr3 { background-position:-44px -24px; } div.minpr4 { background-position:-44px -32px; } div.minpr5 { background-position:-44px -40px; } div.minpr6 { background-position:-44px -48px; } div.minpr7 { background-position:-44px -56px; } div.minpr8 { background-position:-44px -64px; } div.minpr9 { background-position:-44px -72px; } div.minpr10{ background-position:-44px -80px; }   table.list { background-color:#eee;width:100%;border:1px solid #aaa;border-collapse:collapse; } table.list th a { display:block;width:100%; } table.list td { background-color:#fff;border-color:#eee;border-width:1px;border-style:inset;padding:0px 3px; } table.list td.navigation { padding:8px 0px; } table.list tr.hover, table.list tr.hover td, table.list th.hover { background-color:#ccc; } table.list th { background-color:#ddd;padding:3px;border-color:#aaa;border-style:inset;border-width:0px;border-bottom-width:1px;text-align:left; }  table.list th a.sortdesc {  padding-left:11px; background-position:0px -224px; background-repeat:no-repeat; background-image:url( '{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981' ); }  table.list th a.sortasc {  padding-left:11px; background-position:0px -239px; background-repeat:no-repeat; background-image:url('{$params{'BASEURI'}}?page=file&view=arrowdown');  background-image:url( '{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981' ); }  table.list div.imageup { background-image:url( '{$params{'BASEURI'}}?page=file&view=sprite&rand=1267173981' ); background-repeat:no-repeat; background-position:3px -206px; width:18px; height:18px; } table.list td.navigation, table.list td.navigation:hover { background-color:#fff; }  table.list td.navigation a:hover { background-color:#ccc; } table.list td.navigation a, table.list td.navigation span { text-decoration:none; color:#666; padding:2px 6px; border: solid 2px #ddd; background-color:#fff; } table.list td.navigation span { color:#ccc; }  table.pagerank { margin:0px; padding:0px; width:100px; height:10px; } table.pagerank, table.pagerank td, table.pagerank tr { border:0px solid #fff; border-style:solid; border-width:1px; } table.pagerank td.bar { width:40px; height:10px; border:0px; } table.pagerank td.bar div { border:1px solid #999; width:40px; padding:1px; height:10px; } table.pagerank td.bar div div { padding:0px; border:0px; background-color:#5EAA5E; } table.pagerank td.value { font-weight:bold; font-size:10px; text-align:right; } div#linkstable { height:15px; } div#linkstable div.linkitem { border:1px solid #666; background-color:#ddd; float:left; padding:2px 5px; cursor:pointer; height:15px; } ul.selector { width:80%; list-style-type: none;  margin: 0; min-height:200px; padding:10px 5px; background-color:#eee; } ul.selector li { cursor:move; background-color:#fff; margin:5px; padding:5px; border:1px solid #CCCCCC; font-weight:bold; outline-style:none; outline-width:medium; } ul.selector li.immutable { color:#999; cursor:default; } div#selectmsg { padding-top:5px; }</style>
		<script type=\"text/javascript\" src=\"{$params{'BASEURI'}}?page=file&view=jquery&rand=1267173981\"></script>
		<meta name=\"description\" content=\"{$params{'metadescription'}}\" />
		{$params{'metarobots'}}
	</head>
	<body>
		<div id=\"wrapper\">
			<div id=\"topbar\">
				&nbsp;
			</div>
			<div id=\"header\">
				<h1><a href=\"http://linkex.dk\" title=\"Powered by LinkEX\">Link<span style=\"color:#B91450;\">EX</span></a></h1>
			</div>

			<div id=\"navbar\">
				<ul id=\"navlist\">
					{$params{'menu'}}
				</ul>
			</div>
			<div style=\"clear:both;\"></div>

			<div id=\"contents\">

				{$error}
";
	} // }}}
	function linkdetails() { // {{{
		global $config;

		$url = $config->url;
		$anchor = $config->anchor;
		$anchor = $anchor[ mt_rand( 0, sizeof( $anchor )-1 ) ];
		$title = $config->title;
		$title = $title[ mt_rand( 0, sizeof( $title )-1 ) ];
		$description = $config->description;

		$htmlcode = str_replace(
			array( '{$URL}', '{$ANCHOR}', '{$DESCRIPTION}', '{$TITLE}' ),
			array( 
				htmlentities( $url ), 
				htmlentities( $anchor ), 
				htmlentities( $description ),
				htmlentities( $title )
			),
			$config->htmlcode
		);

		// {{{ Show the email
		if ( intval( $config->showemail ) == 1 ) {
			$email = "			<tr>
				<td class=\"key\">Email:</td>
				<td>{$config->email}</td>
			</tr>
";
		} else {
			$email = '';
		}
		// }}}
		return "<div style=\"margin:10px auto;\">
	<fieldset style=\"margin:10px auto;\">
		<legend>Our linking details</legend>
		<table class=\"table\">
{$email}
			<tr>
				<td class=\"key\">URL:</td>
				<td style=\"width:480px;\">{$url}</td>
			</tr>
			<tr>
				<td class=\"key\">Site title:</td>
				<td>{$anchor}</td>
			</tr>
			<tr valign=\"top\">
				<td class=\"key\">Site description:</td>
				<td>{$description}</td>
			</tr>
			<tr valign=\"top\">
				<td class=\"key\">HTML code:</td>
				<td></td>
			</tr>
			<tr valign=\"top\">
				<td colspan=\"2\" class=\"center pre\">{$htmlcode}</td>
			</tr>
		</table>
	</fieldset>
</div>
";
	} // }}}
	function linkform() { // {{{
		global $config;

		$_POST['email']				= htmlentities( linkex::get( 'email', $_POST, ( (LOGGEDIN)?$config->email:'') ) );
		$_POST['lurl']				= htmlentities( linkex::get( 'lurl', $_POST, '' ) );
		$_POST['rurl']				= htmlentities( linkex::get( 'rurl', $_POST, '' ) );
		$_POST['anchor']			= htmlentities( linkex::get( 'anchor', $_POST, '' ) );
		$_POST['description'] = htmlentities( linkex::get( 'description', $_POST, '' ) );

		// {{{ Show the recip field if public or loggedin
		if ( intval( $config->disablerecipfield ) == 0 || intval( $config->samedomain ) == 2 ) {
			$extra='';
			switch( intval( $config->samedomain ) ) {
			case 1: $extra = 'Must be on the same domain as above'; break;
			case 2: $extra = 'Must be on a different domain as above'; break;
			}
			$recipfield = "				<tr>
					<td class=\"key\">Reciprocal link URL:</td>
					<td><input type=\"text\" class=\"text\" name=\"rurl\" value=\"{$_POST['rurl']}\" /> {$extra}</td>
					<td class=\"help\"></td>
				</tr>

";
		} else {
			$recipfield = '';
		}
		// }}}
		// {{{ Show the categories if loggedin or public
		if ( ( $cat = linkex::get( 'categories', $_REQUEST, false ) ) !== false ) {
			if ( !is_array( $cat ) ) {
				$cat = linkex::map( 'trim', explode( ',', $cat ) );
			}
		} else {
			$cat = $config->defaultcategories;
		}
		if ( intval( $config->publiccategories ) == 1 || LOGGEDIN ) {
			$categories = linkex::categories( LOGGEDIN );
			$cats = array();
			foreach( $categories AS $cid=>$name ) {
				$cats[] = new Category( $cid );
			}
			$categories = $cats;
			unset( $cats );
			linkex::sort( $categories, 'name', 'asc' );
			$cats = array();
			foreach( $categories AS $c ) {
				$cats{ $c->id } = $c->name;
			}
			$categories = $cats;
			unset( $cats );

			$categories = linkex::selector( 'categories', $categories, 
				linkex::get( 'categories', $_POST, $cat ), LOGGEDIN, null, array( 'style' => 'width:auto;max-width:300px;' ) );
			$categories = "				<tr valign=\"top\">
					<td class=\"key\">Category:</td>
					<td>{$categories}</td>
					<td class=\"help\"></td>
				</tr>

";
		} else {
			$categories = '';
		} 
		// }}}
		// {{{ CAPTCHA html tag put into => $captcha (the class will know weathe to use img or html
		if ( intval( $config->usecaptcha ) == 1 && !LOGGEDIN ) {
			$c = new captcha;
			$captchatag = $c->html(); 
			$captcha = "				<tr>
					<td class=\"key\">Spam check:</td>
					<td>
						<table cellpadding=\"0\" cellspacing=\"0\">
							<tr>
								<td style=\"width:100px;\">{$captchatag}</td>
								<td><input type=\"text\" name=\"captcha\" value=\"\" class=\"text\" style=\"width:50px;\" /></td>
							</tr>
						</table>
					</td>
					<td class=\"help\"></td>
				</tr>

";
		} else {
			$captcha = '';
		}
		// }}}

		if ( LOGGEDIN ) {
			$skipbacklinkcheck = linkex::checkbox( linkex::get( 'skipbacklinkcheck', $_POST, 0 ) );
			$skippagerank = linkex::checkbox( linkex::get( 'skippagerank', $_POST, 0 ) );
			$skipblacklist = linkex::checkbox( linkex::get( 'skipblacklist', $_POST, 0 ) );
			$skiplengths = linkex::checkbox( linkex::get( 'skiplengths', $_POST, 0 ) );
			$skipdupes = linkex::checkbox( linkex::get( 'skipdupes', $_POST, 0 ) );
			$adminoptions = "				<tr>
					<td class=\"key\"></td>
					<td colspan=\"3\"><br />Since you are logged in, you have additional options:</td>
				</tr>
				<tr>
					<td class=\"key\"></td>
					<td><label><input type=\"checkbox\" class=\"checkbox\" name=\"skipbacklinkcheck\" value=\"1\" {$skipbacklinkcheck} /> Ignore missing backlink.</label></td>
					<td></td>
				</tr>				
				<tr>
					<td class=\"key\"></td>
					<td><label><input type=\"checkbox\" class=\"checkbox\" name=\"skippagerank\" value=\"1\" {$skippagerank} /> Ignore PageRank&trade;.</label></td>
					<td></td>
				</tr>				
				<tr>
					<td class=\"key\"></td>
					<td><label><input type=\"checkbox\" class=\"checkbox\" name=\"skipblacklist\" value=\"1\" {$skipblacklist} /> Ignore blacklist.</label></td>
					<td></td>
				</tr>
				<tr>
					<td class=\"key\"></td>
					<td><label><input type=\"checkbox\" class=\"checkbox\" name=\"skiplengths\" value=\"1\" {$skiplengths} /> Ignore max. length on title and description.</label></td>
					<td></td>
				</tr>
				<tr>
					<td class=\"key\"></td>
					<td><label><input type=\"checkbox\" class=\"checkbox\" name=\"skipdupes\" value=\"1\" {$skipdupes} /> Ignore dublicate domains/IPs.</label></td>
					<td></td>
				</tr>
";
		} else {
			$adminoptions = '';
		}

		// Lengths
		$anchorlength = ( $config->anchorlength > 0 ) ? 
			( 'max. '.$config->anchorlength.' '.(( $config->anchorlengthtype == 'w' )?'words':'characters' )) : '';
		$titlelength = ( $config->titlelength > 0 ) ? 
			( 'max. '.$config->titlelength.' '.(( $config->titlelengthtype == 'w' )?'words':'characters' )) : '';
		$descriptionlength = ( $config->descriptionlength > 0 ) ? 
			( 'max. '.$config->descriptionlength.' '.(( $config->descriptionlengthtype == 'w' )?'words':'characters' )) : '';

		return "<div style=\"margin:10px auto;\">
	<fieldset style=\"margin:10px auto;\">
		<legend>Your linking details</legend>
		<form method=\"post\" action=\"".BASEURI."\">
			<table class=\"table\">
				<tr>
					<td class=\"key\">Site title:</td>
					<td><input type=\"text\" class=\"text\" name=\"anchor\" value=\"{$_POST['anchor']}\" /> {$titlelength}</td>
				</tr>
				<tr>
					<td class=\"key\">Your URL:</td>
					<td><input type=\"text\" class=\"text\" name=\"lurl\" value=\"{$_POST['lurl']}\" /></td>
				</tr>
{$recipfield}
				<tr>
					<td class=\"key\">Your email:</td>
					<td><input type=\"text\" class=\"text\" name=\"email\" value=\"{$_POST['email']}\" /></td>
				</tr>
				<tr valign=\"top\">
					<td class=\"key\">Site description:</td>
					<td><textarea cols=\"80\" rows=\"3\" class=\"text\" name=\"description\">{$_POST['description']}</textarea> {$descriptionlength}</td>
				</tr>
{$captcha}
{$categories}
{$adminoptions}
				<tr>
					<td class=\"key\"></td>
					<td><br /><input type=\"submit\" class=\"button\" value=\"Add my link\" /></td>
					<td class=\"help\"></td>
				</tr>
			</table>
		</form>
	</fieldset>
</div>
";
	} // }}}
	function menu() { // {{{
		if ( linkex::installed() ) {
			if ( defined( 'LOGGEDIN' ) && LOGGEDIN ) {
				$menu = "				<li><a href=\"".BASEURI."\" title=\"Add link\">&raquo; Add link</a></li>
				<li><a href=\"".BASEURI."?page=admin\" title=\"Home\">&raquo; Home</a></li>
				<li><a href=\"".BASEURI."?page=admin&amp;view=tools\" title=\"Tools\">&raquo; Tools</a></li>
				<li><a href=\"".BASEURI."?page=admin&amp;view=categories\" title=\"Categories\">&raquo; Categories</a></li>
				<li><a href=\"".BASEURI."?page=admin&amp;view=blacklist\" title=\"Blacklist\">&raquo; Blacklist</a></li>
				<li><a href=\"".BASEURI."?page=admin&amp;view=settings\" title=\"Settings\">&raquo; Settings</a></li>
				<li><a href=\"".BASEURI."?page=logout\" title=\"Log out\">&raquo; Log out</a></li>
				<li><a href=\"".BASEURI."?page=about\" title=\"About LinkEX\">&raquo; About</a></li>
";
			} else {
				$menu = "				<li><a href=\"".BASEURI."\" title=\"Add link\">&raquo; Add link</a></li>
				<li><a href=\"".BASEURI."?page=admin\" title=\"Admin\">&raquo; Admin</a></li>
				<li><a href=\"".BASEURI."?page=about\" title=\"About LinkEX\">&raquo; About</a></li>
				
";
			}
		} else {
			$menu = '&nbsp;';
		}
		return $menu;
	} // }}}
	function navigation( $start, $pages, $uri ) { // {{{
		$retval = '';
		if ( $pages > 1 ) {
			if ( $start > 1 ) {
				$retval .= "<a href=\"".$uri."start=".($start-1)."\">&laquo; prev</a>";
			} else {
				$retval .= "<span>&laquo; prev</span>";
			}
			for( $i=1; $i<=$pages; $i++ ) {
				$retval .= "&nbsp;";
				if ( $i == $start ) {
					$retval .= '<span><strong>'. $i .'</strong></span>';
				} else {
					$retval .= "<a href=\"".$uri."start=".$i."\">".$i."</a>";
				}
			}
			$retval .= "&nbsp;";
			if ( $start < $pages ) {
				$retval .= "<a href=\"".$uri."start=".($start+1)."\">next &raquo;</a>";
			} else {
				$retval .= "<span>next &raquo;</span>";
			}
		}
		return $retval;
	} // }}}
	function pagerank( $pr ) { // {{{
		$pr = max( min( intval( $pr ), 10 ), 0 );
		$perc = $pr * 10;
		return "<table class=\"pagerank\">
	<tr>
		<td>
			<div class=\"pagerank\">
				<div class=\"bar\" style=\"width:{$perc}%\">&nbsp;</div>
			</div>
		</td>
		<td class=\"value\">{$pr}</td>
	</tr>
</table>
";

	} // }}}
	function progress( $progress ) { // {{{
		echo "<script type=\"text/javascript\">
			/*<![CDATA[*/
			_p('{$progress}');
			/*]]>*/
		</script>
";
		linkex::flush();
	} // }}}
	function report( $report ) { // {{{
		$startdate = date( 'Y-m-d H:i:s', $report{'starttime'} );
		$enddate = date( 'Y-m-d H:i:s', $report{'endtime'} );
		$elapsed = linkex::elapsed( $report{'endtime'} - $report{'starttime'} );
		$elapsed = $elapsed{'nice'};

		$sp = "% 6s  % -20s % -15s % 6s => % -10s % 10s => % -10s\n";
		$links = sprintf( $sp, 'ID', 'Domain', 'IP', 'Old PR', 'New PR', 'Old Status', 'New status' ) .
			"==========================================================================================\n";
		foreach( $report{'links'} AS $data ) {
			$links .= sprintf( $sp, $data{'id'}, linkex::truncate( $data{'rdom'}, 20 ),
				$data{'rdomip'},
				$data{'oldpagerank'}, $data{'pagerank'}, 
				link::statusOptions( $data{'oldstatus'} ), 
				link::statusOptions( $data{'status'} ) );
		}

		$sp = "% 6s   % -20s % -10s\n";
		$categories = sprintf( $sp, 'ID', 'Name', 'Status' ) .
			"==========================================================================================\n";
		foreach( $report{'categories'} AS $data ) {
			$categories .= sprintf( $sp, $data{'id'}, linkex::truncate( $data{'name'}, 20 ), 'done' );
		}

		return "LinkEX verification output.
===========================

verification started on: {$startdate}
verification ended on:   {$enddate}
verification elapsed:    {$elapsed}

* Verifying backlinks..

{$links}

* Rebuilding categories..

{$categories}

";
	} // }}}
	function rules() { // {{{
		global $config;
		$linkback = ( intval( $config->linkbackrequired ) == 1 ) ? 'R'.'equired':'Not r'.'equired';
		$rules = linkex::fileget( BASEDIR . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'rules', "We are constantly looking for new perm link exchanges to improve link popularity and page rank.<br />
Please remember that this is not about traffic, it's about the link.<br />
Play fair!
" );
		$maxoutboundlinks = ( $config->maxoutboundlinks>0 ) ? "			<tr>
				<td class=\"key\">Max. links:</td>
				<td>{$config->maxoutboundlinks} external links on reciprocal link URL</td>
			</tr>

" : '';
		return "<div style=\"margin:10px auto;\">
	<fieldset>
		<legend>Rules</legend>
		<table class=\"table\">
			<tr>
				<td colspan=\"2\">
					<div class=\"article\">
						{$rules}
					</div>
				</td>
			</tr>
			<tr>
				<td class=\"key\">Linkback:</td>
				<td>{$linkback}</td>
			</tr>
			<tr>
				<td class=\"key\">Min. PageRank&trade;:</td>
				<td><div class=\"pagerank pr{$config->minpagerank}\"></div></td>
			</tr>
			{$maxoutboundlinks}
		</table>
	</fieldset>
</div>
";
	} // }}}
}

if ( linkex::get( 'page', $_REQUEST ) == 'file' ) {
	switch( linkex::get( 'view', $_REQUEST ) ) {
	case 'sprite':
		$image = base64_decode('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');
		header('Content-type: image/gif');
		header('Expires: Thu, 15 Apr 2010 20:00:00 GMT');
		header('Cache-Control: private');
		header('Pragma: public');
		header('Last-Modified: ' . date( 'r', 1267173981 ) );
		header('Content-Length: ' . strlen( $image ) );
		echo $image;
		exit;
		break;
	case 'jquery':
		header('Content-type: application/javascript');
		header('Expires: Thu, 15 Apr 2010 20:00:00 GMT');
		header('Cache-Control: private');
		header('Pragma: public');
		header('Last-Modified: ' . date( 'r', 1267173981 ) );
		 ?>/*
 * jQuery JavaScript Library v1.3.2
 * http://jquery.com/
 *
 * Copyright (c) 2009 John Resig
 * Dual licensed under the MIT and GPL licenses.
 * http://docs.jquery.com/License
 *
 * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
 * Revision: 6246
 */
(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"