From 2f6b480e8b5ebe18f8117c0b2ad9b477ca0fb76f Mon Sep 17 00:00:00 2001 From: ozhozh Date: Mon, 11 May 2009 20:30:26 +0000 Subject: [PATCH] Initial commit (importing from http://svn.planetozh.com/ozhin) git-svn-id: http://yourls.googlecode.com/svn/trunk@3 12232710-3e20-11de-b438-597f59cd7555 --- .htaccess | 12 + api.php | 27 ++ css/style.css | 92 ++++ css/tablesorter.css | 57 +++ db.sql | 26 ++ go.php | 36 ++ images/asc.gif | Bin 0 -> 54 bytes images/bg.gif | Bin 0 -> 64 bytes images/desc.gif | Bin 0 -> 54 bytes images/loading.gif | Bin 0 -> 771 bytes includes/auth.php | 30 ++ includes/class-mysql.php | 393 ++++++++++++++++++ includes/config-sample.php | 41 ++ includes/functions-baseconvert.php | 163 ++++++++ includes/functions-json.php | 69 +++ includes/functions-xml.php | 57 +++ includes/functions.php | 346 +++++++++++++++ insert.php | 265 ++++++++++++ insert_ajax.php | 45 ++ js/insert.js | 167 ++++++++ js/jquery-1.3.1.min.js | 19 + js/jquery.tablesorter.min.js | 1 + pages/about.php | 5 + readme.txt | 38 ++ test-api.php | 23 + test.php | 8 + .../generate-short-urls-for-all-posts.php | 26 ++ .../ozh-plc-bridge/inc/options.php | 63 +++ .../ozh-plc-bridge/inc/twitter.php | 34 ++ wordpress-plugin/ozh-plc-bridge/plugin.php | 132 ++++++ 30 files changed, 2175 insertions(+) create mode 100644 .htaccess create mode 100644 api.php create mode 100644 css/style.css create mode 100644 css/tablesorter.css create mode 100644 db.sql create mode 100644 go.php create mode 100644 images/asc.gif create mode 100644 images/bg.gif create mode 100644 images/desc.gif create mode 100644 images/loading.gif create mode 100644 includes/auth.php create mode 100644 includes/class-mysql.php create mode 100644 includes/config-sample.php create mode 100644 includes/functions-baseconvert.php create mode 100644 includes/functions-json.php create mode 100644 includes/functions-xml.php create mode 100644 includes/functions.php create mode 100644 insert.php create mode 100644 insert_ajax.php create mode 100644 js/insert.js create mode 100644 js/jquery-1.3.1.min.js create mode 100644 js/jquery.tablesorter.min.js create mode 100644 pages/about.php create mode 100644 readme.txt create mode 100644 test-api.php create mode 100644 test.php create mode 100644 wordpress-plugin/ozh-plc-bridge/generate-short-urls-for-all-posts.php create mode 100644 wordpress-plugin/ozh-plc-bridge/inc/options.php create mode 100644 wordpress-plugin/ozh-plc-bridge/inc/twitter.php create mode 100644 wordpress-plugin/ozh-plc-bridge/plugin.php diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..9e76bea --- /dev/null +++ b/.htaccess @@ -0,0 +1,12 @@ +# BEGIN ShortURL +RewriteEngine On +#RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ^([0-9a-z]+)/?$ go.php?id=$1 [L] +# END ShortURL + + +RewriteEngine on +RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization},L] + \ No newline at end of file diff --git a/api.php b/api.php new file mode 100644 index 0000000..7843571 --- /dev/null +++ b/api.php @@ -0,0 +1,27 @@ +get_var("SELECT `url` FROM `$table` WHERE id = $id")); + +// URL found +if(!empty($url)) { + $update_clicks = $db->query("UPDATE `$table` SET `clicks` = clicks + 1 WHERE `id` = $id"); + header ('HTTP/1.1 301 Moved Permanently'); + header ('Location: '. $url); + +// URL not found. Either reserved, or page, or doesn't exist +} else { + + // Do we have a page? + if (file_exists(dirname(__FILE__)."/pages/$keyword.php")) { + yourls_page($keyword); + + // Either reserved id, or no such id + } else { + header ('HTTP/1.1 307 Temporary Redirect'); // no 404 to tell browser this might change, and also to not pollute logs + header ('Location: '. yourls_SITE); + } +} +exit(); +?> \ No newline at end of file diff --git a/images/asc.gif b/images/asc.gif new file mode 100644 index 0000000000000000000000000000000000000000..74157867f25acbc146704d43399d6c3605ba7724 GIT binary patch literal 54 zcmZ?wbhEHb6lGvxXkcJa);0M5|G(l-7DfgJMg|=QAOOiQF!A=tFW`Q0{?_dDi`go= G4AuZ#-wosd literal 0 HcmV?d00001 diff --git a/images/bg.gif b/images/bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..fac668fcf42af844a3af0a239fa638ddbc08443c GIT binary patch literal 64 zcmZ?wbhEHb6lLIKXkcJa);0M5|G(l-7DfgJMg|=QAOOiQFp2l{H=O3Yl~fU8)V1~= QTew|n!uOuePzDBT00piR0RR91 literal 0 HcmV?d00001 diff --git a/images/desc.gif b/images/desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b30b3c58eabdb47a1c420ad03c8e30b966cc858 GIT binary patch literal 54 zcmZ?wbhEHb6lGvxXkcJa);0M5|G(l-7DfgJMg|=QAOOiQF!A>EGoD<#VNP?1QCB1* GgEatI(+xQQ literal 0 HcmV?d00001 diff --git a/images/loading.gif b/images/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..e846e1d6c58796558015ffee1fdec546bc207ee8 GIT binary patch literal 771 zcmZ?wbhEHb6krfw*v!MQYQ=(yeQk4RPu{+D?cCXuwr^cCp}%d_ius2R?!0jBXnAQ) zOH<|l|Nj|aK=D7fpKD04vtxj(k)8oFBT!uNCkrbB0}q1^NDatX1{VJbCr|b)oWWMT zS%hVC ~NwO_yO%;SvZ5MdNYf|QNy-I*%yJaj+uTdt+qbZ z4E`Fzb8m}I&!N8OKmWEcCmrLs^Hs&3i)mt@hQVdcqghkaBs*D}tG_lKew4?rTjzIZ z9tSone1TS+TR7tu^CunG)Y7Jg#sw#)sG9C!c0I%LEzP)9;hqRf&)s$D8d5Db{TBs% zgl0~5QQ91luq4Q9tJgt4QLbaxZvAaKeCM9!oy85dg4k>TdBSVqjHub_PG=PO&J-rx z7oYTuF+kH|tG-UK+EkUhDjYx?zW?T|lx>+aOQm zzL$v$zBLo4Cj=G&tw{H}dW?tlTkS)SY4<#NS92z*EY-MMB6Ftp`R=*=*Ev7cS+X%W zMCur^FdlokL}1Y+&aasU2J4#EOuNlnb9CmqgLCGTSY!1BD42pkHY^XidQ5=>YQx%` z*%Pm9D!CkBu&tMWm(%-ejACVWGS2RX5=QOJ$1*tr7F}F+*-OA+Ly&Isg|AEuUYicA z#%IG6kPXkHt{zk2M6zK@Vu^4Q(1zE$?yY6M!^&jQ+2^E?!p7{g*|X6}vuRC3p@jk0 W117c83?+LXEZI4G$p&LV25SKE>nb+@ literal 0 HcmV?d00001 diff --git a/includes/auth.php b/includes/auth.php new file mode 100644 index 0000000..2cd0a76 --- /dev/null +++ b/includes/auth.php @@ -0,0 +1,30 @@ +last_error = $err_str; + // Capture all errors to an error array no matter what happens + $this->captured_errors[] = array ('error_str' => $err_str, 'query' => $this->last_query); + } + + ## Show Errors + function show_errors() { $this->show_errors = true; } + + ## Hide Errors + function hide_errors() { $this->show_errors = false; } + + ## Kill cached query results + function flush() { + // Get rid of these + $this->last_result = null; + $this->col_info = null; + $this->last_query = null; + } + + ## Get one variable from the DB - see docs for more detail + function get_var($query=null,$x=0,$y=0) { + // Log how the function was called + $this->func_call = "\$db->get_var(\"$query\",$x,$y)"; + // If there is a query then perform it if not then use cached results.. + if ($query) { + $this->query($query); + } + // Extract var out of cached results based x,y vals + if ($this->last_result[$y]){ + $values = array_values(get_object_vars($this->last_result[$y])); + } + // If there is a value return it else return null + return (isset($values[$x]) && $values[$x]!=='')?$values[$x]:null; + } + + ## Get one row from the DB - see docs for more detail + function get_row($query=null,$output=OBJECT,$y=0) { + // Log how the function was called + $this->func_call = "\$db->get_row(\"$query\",$output,$y)"; + // If there is a query then perform it if not then use cached results.. + if ($query) { + $this->query($query); + } + // If the output is an object then return object using the row offset.. + if ($output == OBJECT) { + return $this->last_result[$y]?$this->last_result[$y]:null; + // If the output is an associative array then return row as such.. + } elseif ($output == ARRAY_A) { + return $this->last_result[$y]?get_object_vars($this->last_result[$y]):null; + // If the output is an numerical array then return row as such.. + } elseif ($output == ARRAY_N) { + return $this->last_result[$y]?array_values(get_object_vars($this->last_result[$y])):null; + // If invalid output type was specified.. + } else { + $this->print_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N"); + } + } + + ## Function to get 1 column from the cached result set based in X index see docs for usage and info + function get_col($query=null,$x=0) { + // If there is a query then perform it if not then use cached results.. + if ($query) { + $this->query($query); + } + + // Extract the column values + for ($i=0; $i < count($this->last_result); $i++) { + $new_array[$i] = $this->get_var(null,$x,$i); + } + return $new_array; + } + + ## Return the the query as a result set - see docs for more details + function get_results($query=null, $output = OBJECT) { + // Log how the function was called + $this->func_call = "\$db->get_results(\"$query\", $output)"; + // If there is a query then perform it if not then use cached results.. + if ($query) { + $this->query($query); + } + // Send back array of objects. Each row is an object + if ($output == OBJECT) { + return $this->last_result; + } elseif ($output == ARRAY_A || $output == ARRAY_N) { + if ($this->last_result) { + $i=0; + foreach($this->last_result as $row) { + $new_array[$i] = get_object_vars($row); + if ($output == ARRAY_N) { + $new_array[$i] = array_values($new_array[$i]); + } + $i++; + } + return $new_array; + } else { + return null; + } + } + } + + ## Function to get column meta data info pertaining to the last query see docs for more info and usage + function get_col_info($info_type="name",$col_offset=-1) { + if ($this->col_info) { + if ($col_offset == -1) { + $i=0; + foreach($this->col_info as $col) { + $new_array[$i] = $col->{$info_type}; + $i++; + } + return $new_array; + } else { + return $this->col_info[$col_offset]->{$info_type}; + } + } + } + + ## Dumps the contents of any input variable to screen in a nicely formatted and easy to understand way - any type: Object, Var or Array + function vardump($mixed='') { + echo "

"; + echo "
";
+		if (!$this->vardump_called) {
+			echo "ezSQL (v".EZSQL_VERSION.") Variable Dump..\n\n";
+		}
+		$var_type = gettype ($mixed);
+		print_r(($mixed?$mixed:"No Value / False"));
+		echo "\n\nType: " . ucfirst($var_type) . "\n";
+		echo "Last Query [$this->num_queries]: ".($this->last_query?$this->last_query:"NULL")."\n";
+		echo "Last Function Call: " . ($this->func_call?$this->func_call:"None")."\n";
+		echo "Last Rows Returned: ".count($this->last_result)."\n";
+		echo "
".$this->donation(); + echo "\n


"; + $this->vardump_called = true; + } + + ## Alias for the above function + function dumpvar($mixed) { $this->vardump($mixed); } + + ## Displays the last query string that was sent to the database & a table listing results (if there were any). (abstracted into a seperate file to save server overhead). + function debug() { + echo "
"; + // Only show ezSQL credits once.. + if (!$this->debug_called) { + echo "ezSQL (v".EZSQL_VERSION.") Debug..

\n"; + } + if ($this->last_error) { + echo "Last Error -- [$this->last_error]

"; + } + echo "Query [$this->num_queries] -- "; + echo "[$this->last_query]

"; + echo "Query Result.."; + echo "

"; + if ($this->col_info) { + // Results top rows + echo ""; + echo ""; + for ($i=0; $i < count($this->col_info); $i++) { + echo ""; + } + echo ""; + // print main results + if ($this->last_result) { + $i=0; + foreach ($this->get_results(null,ARRAY_N) as $one_row) { + $i++; + echo ""; + foreach ($one_row as $item) { + echo ""; + } + echo ""; + } + } else { + echo ""; + } + echo "
(row){$this->col_info[$i]->type} {$this->col_info[$i]->max_length}
{$this->col_info[$i]->name}
$i$item
No Results
"; + } else { + echo "No Results"; + } + echo "
".$this->donation()."
"; + $this->debug_called = true; + } + + ## Naughty little function to ask for some remuniration! + function donation() { + return "If ezSQL has helped make a donation!?   "; + } +} + + +### ezSQL MYSQL Class Variables +$ezsql_mysql_str = array +( + 1 => 'Require $dbuser and $dbpassword to connect to a database server', + 2 => 'Error establishing mySQL database connection. Correct user/password? Correct hostname? Database server running?', + 3 => 'Require $dbname to select a database', + 4 => 'mySQL database connection is not active', + 5 => 'Unexpected error while trying to select database' +); +if ( ! function_exists ('mysql_connect') ) die('Fatal Error: ezSQL_mysql requires mySQL Lib to be compiled and or linked in to the PHP engine'); +if ( ! class_exists ('ezSQLcore') ) die('Fatal Error: ezSQL_mysql requires ezSQLcore (ez_sql_core.php) to be included/loaded before it can be used'); + + +### ezSQL MYSQL Class +class ezSQL_mysql extends ezSQLcore { + + ## Constructor - allow the user to perform a qucik connect at the same time as initialising the ezSQL_mysql class + function ezSQL_mysql($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost') { + if ($dbuser && $dbname) { + $this->quick_connect($dbuser, $dbpassword, $dbname, $dbhost); + } + } + + ## Short hand way to connect to mySQL database server and select a mySQL database at the same time + function quick_connect($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost') { + $return_val = false; + if ( ! $this->connect($dbuser, $dbpassword, $dbhost,true) ) ; + else if ( ! $this->select($dbname) ) ; + else $return_val = true; + return $return_val; + } + + ## Try to connect to mySQL database server + function connect($dbuser='', $dbpassword='', $dbhost='localhost'){ + global $ezsql_mysql_str; $return_val = false; + // Must have a user and a password + if (!$dbuser){ + $this->register_error($ezsql_mysql_str[1].' in '.__FILE__.' on line '.__LINE__); + $this->show_errors ? trigger_error($ezsql_mysql_str[1],E_USER_WARNING) : null; + // Try to establish the server database handle + } else if (!$this->dbh = @mysql_connect($dbhost,$dbuser,$dbpassword)) { + $this->register_error($ezsql_mysql_str[2].' in '.__FILE__.' on line '.__LINE__); + $this->show_errors ? trigger_error($ezsql_mysql_str[2],E_USER_WARNING) : null; + } else { + $return_val = true; + } + return $return_val; + } + + ## Try to select a mySQL database + function select($dbname='') { + global $ezsql_mysql_str; $return_val = false; + // Must have a database name + if (!$dbname) { + $this->register_error($ezsql_mysql_str[3].' in '.__FILE__.' on line '.__LINE__); + $this->show_errors ? trigger_error($ezsql_mysql_str[3],E_USER_WARNING) : null; + // Must have an active database connection + } else if (!$this->dbh) { + $this->register_error($ezsql_mysql_str[4].' in '.__FILE__.' on line '.__LINE__); + $this->show_errors ? trigger_error($ezsql_mysql_str[4],E_USER_WARNING) : null; + // Try to connect to the database + } else if (!@mysql_select_db($dbname,$this->dbh)) { + // Try to get error supplied by mysql if not use our own + if ( !$str = @mysql_error($this->dbh)) { + $str = $ezsql_mysql_str[5]; + } + $this->register_error($str.' in '.__FILE__.' on line '.__LINE__); + $this->show_errors ? trigger_error($str,E_USER_WARNING) : null; + } else { + $return_val = true; + } + return $return_val; + } + + ## Format a mySQL string correctly for safe mySQL insert (no mater if magic quotes are on or not) + function escape($str) { + return mysql_escape_string(stripslashes($str)); + } + + ## Return mySQL specific system date syntax + function sysdate() { + return 'NOW()'; + } + + ## Perform mySQL query and try to detirmin result value + function query($query) { + // For reg expressions + $query = trim($query); + // Initialise return + $return_val = 0; + // Flush cached values.. + $this->flush(); + // Log how the function was called + $this->func_call = "\$db->query(\"$query\")"; + // Keep track of the last query for debug.. + $this->last_query = $query; + // Perform the query via std mysql_query function.. + $this->result = @mysql_query($query,$this->dbh); + $this->num_queries++; + $this->all_queries .= $query.'
'; + // If there is an error then take note of it.. + if ($str = @mysql_error($this->dbh)) { + $this->register_error($str); + $this->show_errors ? trigger_error($str,E_USER_WARNING) : null; + return false; + } + // Query was an insert, delete, update, replace + if (preg_match("/^(insert|delete|update|replace)\s+/i",$query)) { + $this->rows_affected = @mysql_affected_rows(); + // Take note of the insert_id + if (preg_match("/^(insert|replace)\s+/i",$query)) { + $this->insert_id = @mysql_insert_id($this->dbh); + } + // Return number fo rows affected + $return_val = $this->rows_affected; + // Query was a select + } else { + // Take note of column info + $i=0; + while ($i < @mysql_num_fields($this->result)) { + $this->col_info[$i] = @mysql_fetch_field($this->result); + $i++; + } + // Store Query Results + $num_rows=0; + while ($row = @mysql_fetch_object($this->result)) { + // Store relults as an objects within main array + $this->last_result[$num_rows] = $row; + $num_rows++; + } + @mysql_free_result($this->result); + // Log number of rows the query returned + $this->num_rows = $num_rows; + // Return number of rows selected + $return_val = $this->num_rows; + } + // If debug ALL queries + $this->trace || $this->debug_all ? $this->debug() : null ; + return $return_val; + } +} +?> \ No newline at end of file diff --git a/includes/config-sample.php b/includes/config-sample.php new file mode 100644 index 0000000..01ce662 --- /dev/null +++ b/includes/config-sample.php @@ -0,0 +1,41 @@ + 'mypass', + 'toto' => '123' + ); // array of login/password to access the site (can be just one 'key'=>'value') + +// URL shortening method: 36 or 62. +// 36: generates case insentitive lowercase keywords (ie: 13jkm) +// 64: generate case sensitive keywords (ie: 13jKm or 13JKm) +// Stick to one setting, don't change after you've created links as it will change all your short URLs! +// Base 36 should be picked. Use 62 only if you understand what it implies. +// Using base 62 means you *need* PHP extension BCCOMP +define('YOURLS_URL_CONVERT', 36); + +// Reserved keywords (so that generated URLs won't match them) +// Define here negative, unwanted or potentially misleading keywords +$yourls_reserved_URL = array( + 'porn', 'faggot', 'sex', 'nigger', 'fuck', 'cunt', 'dick', 'gay', +); + +/******************** DO NOT EDIT ANYTHING ELSE ********************/ + +// Include everything except auth functions +require_once 'functions.php'; +require_once 'functions-baseconvert.php'; +require_once 'class-mysql.php'; + diff --git a/includes/functions-baseconvert.php b/includes/functions-baseconvert.php new file mode 100644 index 0000000..5deb6c3 --- /dev/null +++ b/includes/functions-baseconvert.php @@ -0,0 +1,163 @@ + + * http://www.pgregg.com + * + * Function: Arbitrary Number Base conversion from base 2 - 62 + * This file should be included by other php scripts + * For normal base 2 - 36 conversion use the built in base_convert function + * + * Open Source Code: If you use this code on your site for public + * access (i.e. on the Internet) then you must attribute the author and + * source web site: http://www.pgregg.com/projects/ + * You must also make this original source code available for download + * unmodified or provide a link to the source. Additionally you must provide + * the source to any modified or translated versions or derivatives. + * + */ + +/* Ozh' note: this script: + * - allows handling large integers on 32bits machines, which base_convert() does not + * - allows encoding upt to base 64 (base_convert() is limited to 36) + * - needs PHP extension BCCOMP (http://www.php.net/bccomp) + */ + +function yourls_dec2base($iNum, $iBase, $iScale=0) { // cope with base 2..62 + $LDEBUG = FALSE; + $sChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + $sResult = ''; // Store the result + + // special case for Base64 encoding + if ($iBase == 64) + $sChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; + + $sNum = is_integer($iNum) ? "$iNum" : (string)$iNum; + $iBase = yourls_intval($iBase); // incase it is a string or some weird decimal + + // Check to see if we are an integer or real number + if (strpos($sNum, '.') !== FALSE) { + list ($sNum, $sReal) = explode('.', $sNum, 2); + $sReal = '0.' . $sReal; + } else + $sReal = '0'; + + while (bccomp($sNum, 0, $iScale) != 0) { // still data to process + $sRem = bcmod($sNum, $iBase); // calc the remainder + $sNum = bcdiv( bcsub($sNum, $sRem, $iScale), $iBase, $iScale ); + $sResult = $sChars[$sRem] . $sResult; + } + if ($sReal != '0') { + $sResult .= '.'; + $fraciScale = $iScale; + while($fraciScale-- && bccomp($sReal, 0, $iScale) != 0) { // still data to process + if ($LDEBUG) print "
-> $sReal * $iBase = "; + $sReal = bcmul($sReal, $iBase, $iScale); // multiple the float part with the base + if ($LDEBUG) print "$sReal => "; + $sFrac = 0; + if (bccomp($sReal ,1, $iScale) > -1) + list($sFrac, $dummy) = explode('.', $sReal, 2); // get the yourls_intval + if ($LDEBUG) print "$sFrac\n"; + $sResult .= $sChars[$sFrac]; + $sReal = bcsub($sReal, $sFrac, $iScale); + } + } + + return $sResult; +} + + +function yourls_base2dec($sNum, $iBase=0, $iScale=0) { + $sChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + $sResult = ''; + + $iBase = yourls_intval($iBase); // incase it is a string or some weird decimal + + // special case for Base64 encoding + if ($iBase == 64) + $sChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; + + // clean up the input string if it uses particular input formats + switch ($iBase) { + case 16: // remove 0x from start of string + if (strtolower(substr($sNum, 0, 2)) == '0x') $sNum = substr($sNum, 2); + break; + case 8: // remove the 0 from the start if it exists - not really required + if (strpos($sNum, '0')===0) $sNum = substr($sNum, 1); + break; + case 2: // remove an 0b from the start if it exists + if (strtolower(substr($sNum, 0, 2)) == '0b') $sNum = substr($sNum, 2); + break; + case 64: // remove padding chars: = + $sNum = str_replace('=', '', $sNum); + break; + default: // Look for numbers in the format base#number, + // if so split it up and use the base from it + if (strpos($sNum, '#') !== false) { + list ($sBase, $sNum) = explode('#', $sNum, 2); + $iBase = yourls_intval($sBase); // take the new base + } + if ($iBase == 0) { + print("yourls_base2dec called without a base value and not in base#number format"); + return ''; + } + break; + } + + // Convert string to upper case since base36 or less is case insensitive + if ($iBase < 37) $sNum = strtoupper($sNum); + + // Check to see if we are an integer or real number + if (strpos($sNum, '.') !== FALSE) { + list ($sNum, $sReal) = explode('.', $sNum, 2); + $sReal = '0.' . $sReal; + } else + $sReal = '0'; + + + // By now we know we have a correct base and number + $iLen = strlen($sNum); + + // Now loop through each digit in the number + for ($i=$iLen-1; $i>=0; $i--) { + $sChar = $sNum[$i]; // extract the last char from the number + $iValue = strpos($sChars, $sChar); // get the decimal value + if ($iValue > $iBase) { + print("yourls_base2dec: $sNum is not a valid base $iBase number"); + return ''; + } + // Now convert the value+position to decimal + $sResult = bcadd($sResult, bcmul( $iValue, bcpow($iBase, ($iLen-$i-1))) ); + } + + // Now append the real part + if (strcmp($sReal, '0') != 0) { + $sReal = substr($sReal, 2); // Chop off the '0.' characters + $iLen = strlen($sReal); + for ($i=0; $i<$iLen; $i++) { + $sChar = $sReal[$i]; // extract the first, second, third, etc char + $iValue = strpos($sChars, $sChar); // get the decimal value + if ($iValue > $iBase) { + print("yourls_base2dec: $sNum is not a valid base $iBase number"); + return ''; + } + $sResult = bcadd($sResult, bcdiv($iValue, bcpow($iBase, ($i+1)), $iScale), $iScale); + } + } + + return $sResult; +} + +function yourls_base2base($iNum, $iBase, $oBase, $iScale=0) { + if (!function_exists('bccomp')) + return base_convert($iNum, $iBase, $oBase); + + if ($iBase != 10) $oNum = yourls_base2dec($iNum, $iBase, $iScale); + else $oNum = $iNum; + $oNum = yourls_dec2base($oNum, $oBase, $iScale); + return $oNum; +} + diff --git a/includes/functions-json.php b/includes/functions-json.php new file mode 100644 index 0000000..9df6e51 --- /dev/null +++ b/includes/functions-json.php @@ -0,0 +1,69 @@ + $value ){ + + // We first copy each key/value pair into a staging array, + // formatting each key and value properly as we go. + + // Format the key: + if( is_numeric($key) ){ + $key = "key_$key"; + } + $key = "'".addslashes($key)."'"; + + // Format the value: + if( is_array( $value )){ + $value = array_to_json( $value ); + } else if( !is_numeric( $value ) || is_string( $value ) ){ + $value = "'".addslashes($value)."'"; + } + + // Add to staging array: + $construct[] = "$key: $value"; + } + + // Then we collapse the staging array into the JSON form: + $result = "{ " . implode( ", ", $construct ) . " }"; + + } else { // If the array is a vector (not associative): + + $construct = array(); + foreach( $array as $value ){ + + // Format the value: + if( is_array( $value )){ + $value = array_to_json( $value ); + } else if( !is_numeric( $value ) || is_string( $value ) ){ + $value = "'".addslashes($value)."'"; + } + + // Add to staging array: + $construct[] = $value; + } + + // Then we collapse the staging array into the JSON form: + $result = "[ " . implode( ", ", $construct ) . " ]"; + } + + return $result; +} + +?> \ No newline at end of file diff --git a/includes/functions-xml.php b/includes/functions-xml.php new file mode 100644 index 0000000..bebfa6c --- /dev/null +++ b/includes/functions-xml.php @@ -0,0 +1,57 @@ +'. + "\n\n"; + } + foreach ($array as $key=>$value) { + $key = strtolower($key); + if (is_array($value)) { + $multi_tags = false; + foreach($value as $key2=>$value2) { + if (is_array($value2)) { + $xml .= str_repeat("\t",$level)."<$key>\n"; + $xml .= array_to_xml($value2, $level+1); + $xml .= str_repeat("\t",$level)."\n"; + $multi_tags = true; + } else { + if (trim($value2)!='') { + if (htmlspecialchars($value2)!=$value2) { + $xml .= str_repeat("\t",$level). + "<$key>". + "\n"; + } else { + $xml .= str_repeat("\t",$level). + "<$key>$value2\n"; + } + } + $multi_tags = true; + } + } + if (!$multi_tags and count($value)>0) { + $xml .= str_repeat("\t",$level)."<$key>\n"; + $xml .= array_to_xml($value, $level+1); + $xml .= str_repeat("\t",$level)."\n"; + } + } else { + if (trim($value)!='') { + if (htmlspecialchars($value)!=$value) { + $xml .= str_repeat("\t",$level)."<$key>". + "\n"; + } else { + $xml .= str_repeat("\t",$level). + "<$key>$value\n"; + } + } + } + } + if ($level==1) { + $xml .= "\n"; + } + return $xml; +} + +?> \ No newline at end of file diff --git a/includes/functions.php b/includes/functions.php new file mode 100644 index 0000000..a8473a4 --- /dev/null +++ b/includes/functions.php @@ -0,0 +1,346 @@ +1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); + $data = array(); + preg_match_all('@(\w+)=(?:([\'"])([^$2]+)$2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER); + foreach ($matches as $m) { + $data[$m[1]] = $m[3] ? trim($m[3],"\",'") : trim($m[4],"\",'"); + unset($needed_parts[$m[1]]); + } + return $needed_parts ? false : $data; +} + +// Prompt for Authentication +function yourls_auth_headers($realm = '') { + header('HTTP/1.1 401 Unauthorized'); + header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); + die('Sorry! Retry.'); +} + +// Make sure a link id (site.com/1fv) is valid. +function yourls_sanitize_string ($in) { + if (YOURLS_URL_CONVERT <= 37) + $in = strtolower($in); + return substr(preg_replace('/[^a-zAZ0-9]/', '', $in), 0, 12); +} + +// make sure there's one and only one 'http://' at the beginning (prevents omitting or pasting a URL right after the default 'http://') +function yourls_sanitize_url($url) { + return preg_replace('#^(http://)+#', 'http://', 'http://'.$url); +} + +// Make sure an id link is a valid integer (PHP's intval() limits to too small numbers) +function yourls_sanitize_int($in) { + return ( substr(preg_replace('/[^0-9]/', '', strval($in) ), 0, 20) ); +} + +// Make sure a integer is safe +// Note: this is not checking for integers, since integers on 32bits system are way too limited +// TODO: find a way to validate as integer +function yourls_intval($in) { + return mysql_real_escape_string($in); +} + + +// Check to see if a given integer id is reserved (ie reserved URL or an existing page) +// Returns bool +function yourls_is_reserved_id($id) { + global $yourls_reserved_URL; + $keyword = yourls_int2string( yourls_intval($id) ); + if ( in_array( $keyword, $yourls_reserved_URL) + or file_exists(dirname(dirname(__FILE__))."/pages/$keyword.php") + or is_dir(dirname(dirname(__FILE__))."$keyword") + ) + return true; + + return false; +} + +// Function: Get IP Address +function yourls_get_IP() { + if(!empty($_SERVER['HTTP_CLIENT_IP'])) { + $ip_address = $_SERVER['HTTP_CLIENT_IP']; + } else if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; + } else if(!empty($_SERVER['REMOTE_ADDR'])) { + $ip_address = $_SERVER['REMOTE_ADDR']; + } else { + $ip_address = ''; + } + if(strpos($ip_address, ',') !== false) { + $ip_address = explode(',', $ip_address); + $ip_address = $ip_address[0]; + } + return $ip_address; +} + +// Add the "Edit" row +function yourls_table_edit_row($id, $db) { + $id = yourls_intval($id); + $table = YOURLS_DB_TABLE_URL; + $url = $db->get_row("SELECT `url` FROM `$table` WHERE `id` = '$id';"); + $safe_url = stripslashes($url->url); + $keyword = yourls_int2string($id); + if($url) { + $return = << + Edit: original URL: + short URL: + +   + +RETURN; + } else { + $return = 'Invalid URL ID'; + } + + return $return; +} + +// Add a link row +function yourls_table_add_row( $id, $keyword, $url, $ip, $clicks, $timestamp ) { + $date = date( 'Y M d H:i', $timestamp+( yourls_HOURS_OFFSET * 3600) ); + $clicks = number_format($clicks); + $www = YOURLS_SITE; + + return << + $keyword + $url + $www/$keyword + $date + $ip + $clicks + +   + + +ROW; +} + +// Get next id a new link will have if no custom keyword provided +function yourls_get_next_decimal($db) { + $table = YOURLS_DB_TABLE_NEXTDEC; + return $db->get_var("SELECT `next_id` FROM `$table`"); +} + +// Update id for next link with no custom keyword +function yourls_update_next_decimal($int = '', $db) { + $int = ( $int == '' ) ? 'next+1' : (int)$int ; + $table = YOURLS_DB_TABLE_NEXTDEC; + return $db->query("UPDATE `$table` set next_id=$int"); +} + +// Delete a link in the DB +function yourls_delete_link_by_id($id, $db) { + $table = YOURLS_DB_TABLE_URL; + $id = yourls_intval($id); + return $db->query("DELETE FROM `$table` WHERE `id` = $id;"); +} + +// SQL query to insert a new link in the DB. Needs sanitized data. Returns boolean for success or failure of the inserting +function yourls_insert_link_in_db($url, $id, $db) { + $table = YOURLS_DB_TABLE_URL; + $timestamp = date('Y-m-d H:i:s'); + $ip = yourls_get_IP(); + return $db->query("INSERT INTO `$table` VALUES($id, '$url', '$timestamp', '$ip', 0);"); +} + +// Add a new link in the DB, either with custom keyword, or find one +function yourls_add_new_link($url, $keyword = '', $db) { + if ( !$url or $url == 'http://' ) { + $return['status'] = 'fail'; + $return['message'] = 'Missing URL input'; + return $return; + } + + $table = YOURLS_DB_TABLE_URL; + $url = mysql_real_escape_string(yourls_sanitize_url($url)); + $strip_url = stripslashes($url); + $url_exists = $db->get_row("SELECT id,url FROM `$table` WHERE `url` = '".$strip_url."';"); + $ip = yourls_get_IP(); + $return = array(); + + // New URL : store it + if( !$url_exists ) { + + // Custom keyword provided + if ($keyword) { + $keyword = yourls_sanitize_string($keyword); + if (!yourls_keyword_is_free($keyword, $db)) { + // This id either reserved or taken already + $return['status'] = 'fail'; + $return['message'] = 'URL id '.$keyword.' already exists in database or is reserved'; + } else { + // all clear, store ! + $id = yourls_string2int($keyword); + yourls_insert_link_in_db($url, $id, $db); + $return['url'] = array('id' => $id, 'keyword' => $keyword, 'url' => $strip_url, 'date' => date('Y-m-d H:i:s'), 'ip' => yourls_get_IP() ); + $return['status'] = 'success'; + $return['message'] = $strip_url.' (ID: '.$keyword.') added to database'; + $return['html'] = yourls_table_add_row( $id, $keyword, $url, yourls_get_IP(), 0, time() ); + $return['shorturl'] = YOURLS_SITE .'/'. $keyword; + } + + // Create random keyword + } else { + $timestamp = date('Y-m-d H:i:s'); + $id = yourls_get_next_decimal($db); + do { + $add_url = yourls_insert_link_in_db($url, $id, $db); + $free = !yourls_is_reserved_id( $id ); + $ok = ($free && $add_url); + if ( $ok === false && $add_url === 1 ) { + // we stored something, but shouldn't have (ie reserved id) + $delete = yourls_delete_link_by_id( $id, $db ); + $return['extra_info'] .= '(deleted '.$id.')'; + } else { + // everything ok, populate needed vars + $keyword = yourls_int2string($id); + $return['url'] = array('id' => $id, 'keyword' => $keyword, 'url' => $strip_url, 'date' => $timestamp, 'ip' => $ip); + $return['status'] = 'success'; + $return['message'] = $strip_url.' (ID: '.$id.') added to database'; + $return['html'] = yourls_table_add_row( $id, $keyword, $url, $ip, 0, time() ); + $return['shorturl'] = YOURLS_SITE .'/'. $keyword; + } + $id++; + } while (!$ok); + yourls_update_next_decimal($id, $db); + } + } else { + // URL was already stored + $return['status'] = 'fail'; + $return['message'] = $strip_url.' already exists in database'; + $return['shorturl'] = YOURLS_SITE .'/'. yourls_int2string( $url_exists->id ); + } + + return $return; +} + + +// Edit a link +function yourls_edit_link($url, $id, $keyword='', $db) { + $table = YOURLS_DB_TABLE_URL; + $url = mysql_real_escape_string(yourls_sanitize_url($url)); + $id = yourls_intval($id); + $strip_url = stripslashes($url); + $old_url = $db->get_var("SELECT `url` FROM `$table` WHERE `id` = '".$id."';"); + + + // Check if new URL is not here already + if ($old_url != $url) { + $url_exists = intval($db->get_var("SELECT id FROM `$table` WHERE `url` = '".$strip_url."';")); + } else { + $url_exists = false; + } + + // Check if the new keyword is not here already + $newid = ( $keyword ? yourls_string2int($keyword) : $id ); + if ($newid != $id) { + $id_exists = intval($db->get_var("SELECT id FROM `$table` WHERE `id` = '".$newid."';")); + $id_free = yourls_keyword_is_free($keyword, $db); + $id_is_ok = ($id_exists == 0) && $id_free; + } else { + $id_is_ok = true; + } + + // All clear, update + if($url_exists == 0 && $id_is_ok ) { + $timestamp4screen = date( 'Y M d H:i', time()+( yourls_HOURS_OFFSET * 3600) ); + $timestamp4db = date('Y-m-d H:i:s', time()+( yourls_HOURS_OFFSET * 3600) ); + $update_url = $db->query("UPDATE `$table` SET `url` = '$url', `timestamp` = '$timestamp4db', `id` = '$newid' WHERE `id` = $id;"); + if($update_url) { + $return['url'] = array('id' => $newid, 'keyword' => $keyword, 'shorturl' => YOURLS_SITE.'/'.$keyword, 'url' => $strip_url, 'date' => $timestamp4screen); + $return['status'] = 'success'; + $return['message'] = 'Link updated in database'; + } else { + $return['status'] = 'fail'; + $return['message'] = 'Error updating '.$strip_url.' (ID: '.$id.') to database'; + } + + // Nope + } else { + $return['status'] = 'fail'; + $return['message'] = 'URL or keyword already exists in database'; + } + + return $return; +} + + +// Check if keyword id is free (ie not already taken, and not reserved) +function yourls_keyword_is_free($str, $db) { + $table = YOURLS_DB_TABLE_URL; + $id = yourls_string2int($str); + if ( yourls_is_reserved_id($id) ) + return false; + + $already_exists = intval($db->get_var("SELECT `id` FROM `$table` WHERE `id` = '".$id."';")); + if ( $already_exists ) + return false; + + return true; +} + + +// Display a page +function yourls_page($page) { + $include = dirname(dirname(__FILE__))."/pages/$page.php"; + if (!file_exists($include)) { + die("Page '$page' not found"); + } + include($include); + die(); +} + +// Connect to DB +function yourls_db_connect() { + if (!defined('YOURLS_DB_USER') + or !defined('YOURLS_DB_PASS') + or !defined('YOURLS_DB_NAME') + or !defined('YOURLS_DB_HOST') + or !class_exists('ezSQL_mysql') + ) die ('DB config/class missing'); + + return new ezSQL_mysql(YOURLS_DB_USER, YOURLS_DB_PASS, YOURLS_DB_NAME, YOURLS_DB_HOST); +} + +// Return JSON output. Compatible with PHP prior to 5.2 +function yourls_json_encode($array) { + if (function_exists('json_encode')) { + return '('.json_encode($array).')'; + } else { + require_once(dirname(__FILE__).'/functions-json.php'); + return '('.yourls_array_to_json($array).')'; + } +} + +// Return XML output. +function yourls_xml_encode($array) { + require_once(dirname(__FILE__).'/functions-xml.php'); + return yourls_array_to_xml($array); +} diff --git a/insert.php b/insert.php new file mode 100644 index 0000000..51c499f --- /dev/null +++ b/insert.php @@ -0,0 +1,265 @@ +=' : '<=' ); + $where = " AND clicks $link_moreless $link_limit"; +} else { + $link_filter = ''; +} +$base_page = 'insert.php'; + +### Searching +if(!empty($search) && !empty($_GET['s_in'])) { + switch($_GET['s_in']) { + case 'id': + $search_in_text = 'ID'; + $search_in_sql = 'id'; + break; + case 'url': + $search_in_text = 'URL'; + $search_in_sql = 'url'; + break; + case 'ip': + $search_in_text = 'IP Address'; + $search_in_sql = 'ip'; + break; + } + $search_text = stripslashes($search); + $search_display = "Searching for $search_text in $search_in_text. "; + $search_url = "&s_search=$search_text &s_in=$search_in_sql"; + $search = str_replace('*', '%', '*'.$search.'*'); + $where .= " AND $search_in_sql LIKE ('$search')"; +} + +### Sorting +if(!empty($_GET['s_by']) || !empty($_GET['s_order'])) { + switch($_GET['s_by']) { + case 'id': + $sort_by_text = 'ID'; + $sort_by_sql = 'id'; + break; + case 'url': + $sort_by_text = 'URL'; + $sort_by_sql = 'url'; + break; + case 'timestamp': + $sort_by_text = 'Date'; + $sort_by_sql = 'timestamp'; + break; + case 'ip': + $sort_by_text = 'IP Address'; + $sort_by_sql = 'ip'; + break; + case 'clicks': + $sort_by_text = 'Clicks'; + $sort_by_sql = 'clicks'; + break; + } + switch($_GET['s_order']) { + case 'asc': + $sort_order_text = 'Ascending Order'; + $sort_order_sql = 'asc'; + break; + case 'desc': + $sort_order_text = 'Descending Order'; + $sort_order_sql = 'desc'; + break; + } +} + +## Get URLs Count for current filter, total links in DB & total clicks +$total_items = $db->get_var("SELECT COUNT(id) FROM url WHERE 1=1 $where"); +$totals = $db->get_row("SELECT COUNT(id) as c, SUM(clicks) as s FROM url WHERE 1=1"); + +### Checking $page, $offset, $perpage +if(empty($page) || $page == 0) { $page = 1; } +if(empty($offset)) { $offset = 0; } +if(empty($perpage) || $perpage == 0) { $perpage = 50; } + +### Determine $offset +$offset = ($page-1) * $perpage; + +### Determine Max Number Of Items To Display On Page +if(($offset + $perpage) > $total_items) { + $max_on_page = $total_items; +} else { + $max_on_page = ($offset + $perpage); +} + +### Determine Number Of Items To Display On Page +if (($offset + 1) > ($total_items)) { + $display_on_page = $total_items; +} else { + $display_on_page = ($offset + 1); +} + +### Determing Total Amount Of Pages +$total_pages = ceil($total_items / $perpage); +?> + + + + Insert URL « YOURLS » Your Own URL Shortener | <?php echo YOURLS_SITE; ?> + + + + + + + + + + + +

YOURLS: Your Own URL Shortener

+

Your are logged in as: . Logout

+

Display to of URLs. + + Overall, tracking c); ?> links, s); ?> clicks, and counting! +

+ +
+
+
+ Enter the URL: + Optional: Custom short URL: + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + get_results("SELECT * FROM url WHERE 1=1 $where ORDER BY $sort_by_sql $sort_order_sql LIMIT $offset, $perpage;"); + if($url_results) { + foreach( $url_results as $url_result ) { + $base36 = yourls_int2string($url_result->id); + $timestamp = strtotime($url_result->timestamp); + $id = ($url_result->id); + $url = stripslashes($url_result->url); + $ip = $url_result->ip; + $clicks = $url_result->clicks; + + echo yourls_table_add_row($id, $base36, $url, $ip, $clicks, $timestamp ); + } + } else { + echo ''; + } + ?> + +
Link ID  Original URLShort URLDateIPClicks  Actions
+
+
+
+ +   + +
+ + Search for  + +  in  + + – Order by  + + + – Show  +  rows
+ + Show links with + + than + clicks + + +
+
+
+ Pages (): + = 4) { + echo '« First ... '; + } + if($page > 1) { + echo ' « '; + } + for($i = $page - 2 ; $i <= $page +2; $i++) { + if ($i >= 1 && $i <= $total_pages) { + if($i == $page) { + echo "[$i] "; + } else { + echo ''.$i.' '; + } + } + } + if($page < $total_pages) { + echo ' » '; + } + if (($page+2) < $total_pages) { + echo ' ... Last »'; + } + ?> +
No URL Found
+ + + + \ No newline at end of file diff --git a/insert_ajax.php b/insert_ajax.php new file mode 100644 index 0000000..53b237e --- /dev/null +++ b/insert_ajax.php @@ -0,0 +1,45 @@ + $row) ); + break; + + case 'edit_save': + $return = yourls_edit_link( $_REQUEST['url'], $_REQUEST['id'], $_REQUEST['newid'], $db ); + echo yourls_json_encode($return); + break; + + case 'delete': + $query = yourls_delete_link_by_id( $_REQUEST['id'], $db ); + echo yourls_json_encode(array('success'=>$query)); + break; + + case 'logout': + // unused for the moment + yourls_logout(); + break; + + default: + die('Not implemented'); + +} +?> \ No newline at end of file diff --git a/js/insert.js b/js/insert.js new file mode 100644 index 0000000..a3d8bb4 --- /dev/null +++ b/js/insert.js @@ -0,0 +1,167 @@ +// Init some stuff +$(document).ready(function(){ + $('#add-url, #add-keyword').keyup(function(e){ if (e.keyCode == 13) {add();} } ); + reset_url(); + $('#new_url_form').attr('action', 'javascript:add();'); + if ($("#tblUrl tr.nourl_found").length != 1) { + $("#tblUrl").tablesorter({ + sortList:[[3,1]], // Sort on column #3 (numbering starts at 0) + headers: { 6: {sorter: false} }, // no sorter on column #6 + widgets: ['zebra'] // prettify + }); + } +}); + +// Create new link and add to table +function add() { + var newurl = $("#add-url").val(); + if ( !newurl || newurl == 'http://' ) { + alert('no URL ?'); + return; + } + var keyword = $("#add-keyword").val(); + add_loading("#add-button"); + $.getJSON( + "insert_ajax.php", + {mode:'add', url: newurl, keyword: keyword}, + function(data){ + if(data.status == 'success') { + $('#tblUrl tbody').prepend( data.html ).trigger("update"); + $('.nourl_found').remove(); + zebra_table(); + reset_url(); + increment(); + } + feedback(data.message, data.status); + end_loading("#add-button"); + end_disable("#add-button"); + } + ); +} + +// Display the edition interface +function edit(id) { + add_loading("#edit-button-" + id); + add_loading("#delete-button-" + id); + $.getJSON( + "insert_ajax.php", + { mode: "edit_display", id: id }, + function(data){ + $("#id-" + id).after( data.html ); + $("#edit-url-"+ id).focus(); + end_loading("#edit-button-" + id); + end_loading("#delete-button-" + id); + } + ); +} + +// Delete a link +function remove(id) { + if (!confirm('Really delete?')) { + return; + } + $.getJSON( + "insert_ajax.php", + { mode: "delete", id: id }, + function(data){ + if (data.success == 1) { + $("#id-" + id).fadeOut(function(){$(this).remove();zebra_table();}); + } else { + alert('something wrong happened while deleting :/'); + } + } + ); +} + +// Cancel edition of a link +function hide_edit(id) { + $("#edit-" + id).fadeOut(200, function(){ + end_disable("#edit-button-" + id); + end_disable("#delete-button-" + id); + }); +} + +// Save edition of a link +function edit_save(id) { + add_loading("#edit-close-" + id); + var newurl = $("#edit-url-" + id).val(); + var newid = $("#edit-id-" + id).val(); + $.getJSON( + "insert_ajax.php", + {mode:'edit_save', url: newurl, id: id, newid: newid }, + function(data){ + if(data.status == 'success') { + $("#url-" + id).html('' + data.url.url + ''); + $("#keyword-" + id).html(data.url.keyword); + $("#shorturl-" + id).html('' + data.url.shorturl + ''); + $("#timestamp-" + id).html(data.url.date); + $("#edit-" + id).fadeOut(200, function(){ + $('#tblUrl tbody').trigger("update"); + }); + } + feedback(data.message, data.status); + end_disable("#edit-close-" + id); + end_loading("#edit-close-" + id); + end_disable("#edit-button-" + id); + end_disable("#delete-button-" + id); + } + ); +} + +// Unused for now since HTTP Auth sucks donkeys. +function logout() { + $.ajax({ + type: "POST", + url: "insert_ajax.php", + data: {mode:'logout'}, + success: function() { + window.parent.location.href = window.parent.location.href; + } + }); +} + +// Begin the spinning animation & disable a button +function add_loading(el) { + $(el).attr("disabled", "disabled").addClass('disabled').addClass('loading'); +} + +// End spinning animation +function end_loading(el) { + $(el).removeClass('loading'); +} + +// Un-disable an element +function end_disable(el) { + $(el).removeAttr("disabled").removeClass('disabled'); +} + +// Prettify table with odd & even rows +function zebra_table() { + $("#tblUrl tbody tr:even").removeClass('odd').addClass('even'); + $("#tblUrl tbody tr:odd").removeClass('even').addClass('odd'); + $('#tblUrl tbody').trigger("update"); +} + +// Update feedback message +function feedback(msg, type) { + var span = (type == 'fail') ? '' : '' ; + var delay = (type == 'fail') ? 2500 : 1000 ; + $('#feedback').html(span + msg + '').fadeIn(200,function(){ + $(this).animate({'opacity':1}, delay, function() { + $(this).fadeOut(800); + }) + }); +} + +// Ready to add another URL +function reset_url() { + $('#add-url').val('http://').focus(); + $('#add-keyword').val(''); +} + +// Increment URL counters +function increment() { + $('.increment').each(function(){ + $(this).html( parseInt($(this).html()) + 1); + }); +} \ No newline at end of file diff --git a/js/jquery-1.3.1.min.js b/js/jquery-1.3.1.min.js new file mode 100644 index 0000000..c327fae --- /dev/null +++ b/js/jquery-1.3.1.min.js @@ -0,0 +1,19 @@ +/* + * jQuery JavaScript Library v1.3.1 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-01-21 20:42:16 -0500 (Wed, 21 Jan 2009) + * Revision: 6158 + */ +(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.makeArray(E))},selector:"",jquery:"1.3.1",size:function(){return this.length},get:function(E){return E===g?o.makeArray(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,find:function(E){if(this.length===1&&!/,/.test(E)){var G=this.pushStack([],"find",E);G.length=0;o.find(E,this[0],G);return G}else{var F=o.map(this,function(H){return o.find(E,H)});return this.pushStack(/[^+>] [^+>]/.test(E)?o.unique(F):F,"find",E)}},clone:function(F){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.cloneNode(true),H=document.createElement("div");H.appendChild(I);return o.clean([H.innerHTML])[0]}else{return this.cloneNode(true)}});var G=E.find("*").andSelf().each(function(){if(this[h]!==g){this[h]=null}});if(F===true){this.find("*").andSelf().each(function(I){if(this.nodeType==3){return}var H=o.data(this,"events");for(var K in H){for(var J in H[K]){o.event.add(G[I],K,H[K][J],H[K][J].data)}}})}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 F=o.expr.match.POS.test(E)?o(E):null;return this.map(function(){var G=this;while(G&&G.ownerDocument){if(F?F.index(G)>-1:o(G).is(E)){return G}G=G.parentNode}})},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=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: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(K,N,M){if(this[0]){var J=(this[0].ownerDocument||this[0]).createDocumentFragment(),G=o.clean(K,(this[0].ownerDocument||this[0]),J),I=J.firstChild,E=this.length>1?J.cloneNode(true):J;if(I){for(var H=0,F=this.length;H0?E.cloneNode(true):J)}}if(G){o.each(G,z)}}return this;function L(O,P){return N&&o.nodeName(O,"table")&&o.nodeName(P,"tr")?(O.getElementsByTagName("tbody")[0]||O.appendChild(O.ownerDocument.createElement("tbody"))):O}}};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-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(G,E,I){if(E=="width"||E=="height"){var K,F={position:"absolute",visibility:"hidden",display:"block"},J=E=="width"?["Left","Right"]:["Top","Bottom"];function H(){K=E=="width"?G.offsetWidth:G.offsetHeight;var M=0,L=0;o.each(J,function(){M+=parseFloat(o.curCSS(G,"padding"+this,true))||0;L+=parseFloat(o.curCSS(G,"border"+this+"Width",true))||0});K-=Math.round(M+L)}if(o(G).is(":visible")){H()}else{o.swap(G,F,H)}return Math.max(0,K)}return o.curCSS(G,E,I)},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,R){if(typeof R==="number"){R+=""}if(!R){return}if(typeof R==="string"){R=R.replace(/(<(\w+)[^>]*?)\/>/g,function(T,U,S){return S.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?T:U+">"});var O=o.trim(R).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
","
"]||[0,"",""];L.innerHTML=Q[1]+R+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var N=!O.indexOf(""&&O.indexOf("=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(R)){L.insertBefore(K.createTextNode(R.match(/^\s*/)[0]),L.firstChild)}R=o.makeArray(L.childNodes)}if(R.nodeType){G.push(R)}else{G=o.merge(G,R)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E*",this).remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var Q=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]+['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,K=0,G=Object.prototype.toString;var F=function(X,T,aa,ab){aa=aa||[];T=T||document;if(T.nodeType!==1&&T.nodeType!==9){return[]}if(!X||typeof X!=="string"){return aa}var Y=[],V,ae,ah,S,ac,U,W=true;Q.lastIndex=0;while((V=Q.exec(X))!==null){Y.push(V[1]);if(V[2]){U=RegExp.rightContext;break}}if(Y.length>1&&L.exec(X)){if(Y.length===2&&H.relative[Y[0]]){ae=I(Y[0]+Y[1],T)}else{ae=H.relative[Y[0]]?[T]:F(Y.shift(),T);while(Y.length){X=Y.shift();if(H.relative[X]){X+=Y.shift()}ae=I(X,ae)}}}else{var ad=ab?{expr:Y.pop(),set:E(ab)}:F.find(Y.pop(),Y.length===1&&T.parentNode?T.parentNode:T,P(T));ae=F.filter(ad.expr,ad.set);if(Y.length>0){ah=E(ae)}else{W=false}while(Y.length){var ag=Y.pop(),af=ag;if(!H.relative[ag]){ag=""}else{af=Y.pop()}if(af==null){af=T}H.relative[ag](ah,af,P(T))}}if(!ah){ah=ae}if(!ah){throw"Syntax error, unrecognized expression: "+(ag||X)}if(G.call(ah)==="[object Array]"){if(!W){aa.push.apply(aa,ah)}else{if(T.nodeType===1){for(var Z=0;ah[Z]!=null;Z++){if(ah[Z]&&(ah[Z]===true||ah[Z].nodeType===1&&J(T,ah[Z]))){aa.push(ae[Z])}}}else{for(var Z=0;ah[Z]!=null;Z++){if(ah[Z]&&ah[Z].nodeType===1){aa.push(ae[Z])}}}}}else{E(ah,aa)}if(U){F(U,T,aa,ab)}return aa};F.matches=function(S,T){return F(S,null,null,T)};F.find=function(Z,S,aa){var Y,W;if(!Z){return[]}for(var V=0,U=H.order.length;V":function(X,T,Y){if(typeof T==="string"&&!/\W/.test(T)){T=Y?T:T.toUpperCase();for(var U=0,S=X.length;U=0){if(!U){S.push(X)}}else{if(U){T[W]=false}}}}return false},ID:function(S){return S[1].replace(/\\/g,"")},TAG:function(T,S){for(var U=0;S[U]===false;U++){}return S[U]&&P(S[U])?T[1]:T[1].toUpperCase()},CHILD:function(S){if(S[1]=="nth"){var T=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(S[2]=="even"&&"2n"||S[2]=="odd"&&"2n+1"||!/\D/.test(S[2])&&"0n+"+S[2]||S[2]);S[2]=(T[1]+(T[2]||1))-0;S[3]=T[3]-0}S[0]="done"+(K++);return S},ATTR:function(T){var S=T[1].replace(/\\/g,"");if(H.attrMap[S]){T[1]=H.attrMap[S]}if(T[2]==="~="){T[4]=" "+T[4]+" "}return T},PSEUDO:function(W,T,U,S,X){if(W[1]==="not"){if(W[3].match(Q).length>1){W[3]=F(W[3],null,null,T)}else{var V=F.filter(W[3],T,U,true^X);if(!U){S.push.apply(S,V)}return false}}else{if(H.match.POS.test(W[0])){return true}}return W},POS:function(S){S.unshift(true);return S}},filters:{enabled:function(S){return S.disabled===false&&S.type!=="hidden"},disabled:function(S){return S.disabled===true},checked:function(S){return S.checked===true},selected:function(S){S.parentNode.selectedIndex;return S.selected===true},parent:function(S){return !!S.firstChild},empty:function(S){return !S.firstChild},has:function(U,T,S){return !!F(S[3],U).length},header:function(S){return/h\d/i.test(S.nodeName)},text:function(S){return"text"===S.type},radio:function(S){return"radio"===S.type},checkbox:function(S){return"checkbox"===S.type},file:function(S){return"file"===S.type},password:function(S){return"password"===S.type},submit:function(S){return"submit"===S.type},image:function(S){return"image"===S.type},reset:function(S){return"reset"===S.type},button:function(S){return"button"===S.type||S.nodeName.toUpperCase()==="BUTTON"},input:function(S){return/input|select|textarea|button/i.test(S.nodeName)}},setFilters:{first:function(T,S){return S===0},last:function(U,T,S,V){return T===V.length-1},even:function(T,S){return S%2===0},odd:function(T,S){return S%2===1},lt:function(U,T,S){return TS[3]-0},nth:function(U,T,S){return S[3]-0==T},eq:function(U,T,S){return S[3]-0==T}},filter:{CHILD:function(S,V){var Y=V[1],Z=S.parentNode;var X=V[0];if(Z&&(!Z[X]||!S.nodeIndex)){var W=1;for(var T=Z.firstChild;T;T=T.nextSibling){if(T.nodeType==1){T.nodeIndex=W++}}Z[X]=W-1}if(Y=="first"){return S.nodeIndex==1}else{if(Y=="last"){return S.nodeIndex==Z[X]}else{if(Y=="only"){return Z[X]==1}else{if(Y=="nth"){var ab=false,U=V[2],aa=V[3];if(U==1&&aa==0){return true}if(U==0){if(S.nodeIndex==aa){ab=true}}else{if((S.nodeIndex-aa)%U==0&&(S.nodeIndex-aa)/U>=0){ab=true}}return ab}}}}},PSEUDO:function(Y,U,V,Z){var T=U[1],W=H.filters[T];if(W){return W(Y,V,U,Z)}else{if(T==="contains"){return(Y.textContent||Y.innerText||"").indexOf(U[3])>=0}else{if(T==="not"){var X=U[3];for(var V=0,S=X.length;V=0:V==="~="?(" "+X+" ").indexOf(T)>=0:!U[4]?S:V==="!="?X!=T:V==="^="?X.indexOf(T)===0:V==="$="?X.substr(X.length-T.length)===T:V==="|="?X===T||X.substr(0,T.length+1)===T+"-":false},POS:function(W,T,U,X){var S=T[2],V=H.setFilters[S];if(V){return V(W,U,T,X)}}}};var L=H.match.POS;for(var N in H.match){H.match[N]=RegExp(H.match[N].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(T,S){T=Array.prototype.slice.call(T);if(S){S.push.apply(S,T);return S}return T};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(M){E=function(W,V){var T=V||[];if(G.call(W)==="[object Array]"){Array.prototype.push.apply(T,W)}else{if(typeof W.length==="number"){for(var U=0,S=W.length;U";var S=document.documentElement;S.insertBefore(T,S.firstChild);if(!!document.getElementById(U)){H.find.ID=function(W,X,Y){if(typeof X.getElementById!=="undefined"&&!Y){var V=X.getElementById(W[1]);return V?V.id===W[1]||typeof V.getAttributeNode!=="undefined"&&V.getAttributeNode("id").nodeValue===W[1]?[V]:g:[]}};H.filter.ID=function(X,V){var W=typeof X.getAttributeNode!=="undefined"&&X.getAttributeNode("id");return X.nodeType===1&&W&&W.nodeValue===V}}S.removeChild(T)})();(function(){var S=document.createElement("div");S.appendChild(document.createComment(""));if(S.getElementsByTagName("*").length>0){H.find.TAG=function(T,X){var W=X.getElementsByTagName(T[1]);if(T[1]==="*"){var V=[];for(var U=0;W[U];U++){if(W[U].nodeType===1){V.push(W[U])}}W=V}return W}}S.innerHTML="";if(S.firstChild&&S.firstChild.getAttribute("href")!=="#"){H.attrHandle.href=function(T){return T.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var S=F,T=document.createElement("div");T.innerHTML="

";if(T.querySelectorAll&&T.querySelectorAll(".TEST").length===0){return}F=function(X,W,U,V){W=W||document;if(!V&&W.nodeType===9&&!P(W)){try{return E(W.querySelectorAll(X),U)}catch(Y){}}return S(X,W,U,V)};F.find=S.find;F.filter=S.filter;F.selectors=S.selectors;F.matches=S.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){H.order.splice(1,0,"CLASS");H.find.CLASS=function(S,T){return T.getElementsByClassName(S[1])}}function O(T,Z,Y,ac,aa,ab){for(var W=0,U=ac.length;W0){W=S;break}}}S=S[T]}ab[V]=W}}}var J=document.compareDocumentPosition?function(T,S){return T.compareDocumentPosition(S)&16}:function(T,S){return T!==S&&(T.contains?T.contains(S):true)};var P=function(S){return S.nodeType===9&&S.documentElement.nodeName!=="HTML"||!!S.ownerDocument&&P(S.ownerDocument)};var I=function(S,Z){var V=[],W="",X,U=Z.nodeType?[Z]:Z;while((X=H.match.PSEUDO.exec(S))){W+=X[0];S=S.replace(H.match.PSEUDO,"")}S=H.relative[S]?S+"*":S;for(var Y=0,T=U.length;Y=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}this[H].style.display=o.data(this[H],"olddisplay",K)}}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)==1){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(H,F){var E=H?"Left":"Top",G=H?"Right":"Bottom";o.fn["inner"+F]=function(){return this[F.toLowerCase()]()+j(this,"padding"+E)+j(this,"padding"+G)};o.fn["outer"+F]=function(J){return this["inner"+F]()+j(this,"border"+E+"Width")+j(this,"border"+G+"Width")+(J?j(this,"margin"+E)+j(this,"margin"+G):0)};var I=F.toLowerCase();o.fn[I]=function(J){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+F]||document.body["client"+F]:this[0]==document?Math.max(document.documentElement["client"+F],document.body["scroll"+F],document.documentElement["scroll"+F],document.body["offset"+F],document.documentElement["offset"+F]):J===g?(this.length?o.css(this[0],I):null):this.css(I,typeof J==="string"?J:J+"px")}})})(); \ No newline at end of file diff --git a/js/jquery.tablesorter.min.js b/js/jquery.tablesorter.min.js new file mode 100644 index 0000000..9014e99 --- /dev/null +++ b/js/jquery.tablesorter.min.js @@ -0,0 +1 @@ +(function($){$.extend({tablesorter:new function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}var rows=table.tBodies[0].rows;if(table.tBodies[0].rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.meta)&&($(cell).data().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;ib)?1:0));};function sortTextDesc(a,b){return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){var $cell=$(this);var i=this.column;this.order=this.count++%2;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i \ No newline at end of file diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..cbadc5d --- /dev/null +++ b/readme.txt @@ -0,0 +1,38 @@ + TODO: Make a better readme :) + +WHAT IS THIS + + explain concept + give examples: lc.sg, ozh.in + + +INSTALL + + blah + + +CONFIGURATION + + explain config.php var + + +REQUIREMENTS + + PHP 4.3 should be enough (untested) + PHP CURL extension + PHP BCCOMP extension for handling large integers (used to convert integers to keywords) http://www.php.net/bccomp + + + +FAQ + + - max length of custom keyword: 12 chars + (makes 'zzzzzzzzzzzz' the longest available) + (That makes 4,738,381,338,321,617,846 available URLs by the way) + + - difference between base 36 and base 62 encoding + + +CREDITS + + blah \ No newline at end of file diff --git a/test-api.php b/test-api.php new file mode 100644 index 0000000..38681c7 --- /dev/null +++ b/test-api.php @@ -0,0 +1,23 @@ + 'http://planetozh.com/', 'keyword'=>'ozh', 'format'=>'json' ); + +// Init the CURL session +$ch = curl_init(); +curl_setopt($ch, CURLOPT_URL, "http://127.0.0.1/ozh.in/api.php"); // URL of the API file +curl_setopt($ch, CURLOPT_HEADER, 0); // No header in the result +curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); // AUTH with any (best) method available +curl_setopt($ch, CURLOPT_USERPWD, 'ozh:richward'); // login/pwd as defined in config.php +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return, do not echo result +curl_setopt($ch, CURLOPT_POST, 1); // This is a POST request +curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // Data to POST + +// Grab URL and return content +$data = curl_exec($ch); +curl_close($ch); + +// Echo result (either a new short URL, or an error message beginning with "Error") +echo htmlentities($data); + +?> \ No newline at end of file diff --git a/test.php b/test.php new file mode 100644 index 0000000..3b88cb9 --- /dev/null +++ b/test.php @@ -0,0 +1,8 @@ + +
+
+

Ozh's PLC - WP - Twitter Bridge

+

This file generates a short link for all your blog posts (from older to latest)

+
    +have_posts()) : $archive_query->the_post(); + delete_post_meta($archive_query->post->ID, 'yourls_shorturl'); // remove any previously stored short url + update_post_meta($archive_query->post->ID, 'yourls_tweeted', 1); // make as if all existing posts had already been tweeted + echo '
  1. '.wp_ozh_yourls_geturl($archive_query->post->ID) .' = ' . $archive_query->post->post_title . "
  2. \n"; +endwhile; +?> +
+ +

Done. You can now delete this file !

\ No newline at end of file diff --git a/wordpress-plugin/ozh-plc-bridge/inc/options.php b/wordpress-plugin/ozh-plc-bridge/inc/options.php new file mode 100644 index 0000000..0d64d87 --- /dev/null +++ b/wordpress-plugin/ozh-plc-bridge/inc/options.php @@ -0,0 +1,63 @@ + +
+

Your Plugin Name

+ +
+ +ozh_yourls_do_posts +ozh_yourls_do_pages +ozh_yourls_twitter_login +ozh_yourls_twitter_password +ozh_yourls_twitter_msg +ozh_yourls_includes + + "; + var_dump($_POST); + echo "
"; + ?> + + + + + + + + + + + + + + + + + + + + + + + + + +
Posts + />
Pages + />
Login
Pwd
+

+ +

+ + +
+ + "; + return ($resultArray['http_code'] == "200"); + +} + +// Debug function +function wp_ozh_yourls_tweet_log($username, $password, $message) { + $f = fopen('/DONNEES/I07143/MES_DOCUMENTS/utils/xampp/xampp/htdocs/wordpress/wp-content/plugins/ozh-plc-bridge/tweet.log', 'a'); + fputs($f, "$username: $message\n"); + fclose($f); +} diff --git a/wordpress-plugin/ozh-plc-bridge/plugin.php b/wordpress-plugin/ozh-plc-bridge/plugin.php new file mode 100644 index 0000000..5fed301 --- /dev/null +++ b/wordpress-plugin/ozh-plc-bridge/plugin.php @@ -0,0 +1,132 @@ +ID; + $post = get_post($post_id); + + if ( ( $post->post_type == 'post' && !WPyourls_DO_POSTS) || ( $post->post_type == 'page' && !WPyourls_DO_PAGES) ) + return; + + $title = get_the_title($post_id); + $url = get_permalink ($post_id); + $short = wp_ozh_yourls_get_new_short_url( $post_id, $url ); + + // Tweet title + short URL (only once, don't tweet on edit) + if ( !post_custom( 'yourls_tweeted' ) ) { + require_once( dirname(__FILE__) . '/inc/twitter.php' ); + $tweet = wp_ozh_yourls_maketweet( $short, $title ); + if ( wp_ozh_yourls_tweet_it(WPyourls_TWITTER_LOGIN, WPyourls_TWITTER_PWD, $tweet) ) { + update_post_meta($post_id, 'yourls_tweeted', 1); + } + } +} + +// Get or create the short URL for a post. Return string(url) +function wp_ozh_yourls_geturl( $id ) { + $short = post_custom( 'yourls_shorturl' ); + if (!$short) { + // short URL never was not created before, let's get it now + $short = wp_ozh_yourls_get_new_short_url( $id ); + } + + return $short; +} + +// Template tag: echo short URL for current post +function wp_ozh_yourls_url() { + global $id; + $short = wp_ozh_yourls_geturl( $id ); + if ($short) + echo "$short"; +} + +// Template tag: echo short URL alternate link in for current post. See http://revcanonical.appspot.com/ && http://shorturl.appjet.net/ +function wp_ozh_yourls_head_linkrel() { + //if ( (is_single() or is_page()) ) + + global $id; + $short = wp_ozh_yourls_geturl( $id ); + if ($short) + echo "\n"; +} + + +// The WP-PLC bridge function: get short URL of a WP post. Returns string(url) +function wp_ozh_yourls_get_new_short_url( $post_id, $url = '' ) { + global $yourls_reserved_URL; + require_once(WPyourls_yourls_INCLUDES_DIR . 'config.php'); + + if (!$url) + $url = get_permalink ($post_id); + + // Get/make new URL + $yourls_db = new wpdb(yourls_DB_USER, yourls_DB_PASS, yourls_DB_NAME, yourls_DB_HOST); + $yourls_result = yourls_add_new_link($url, '', $yourls_db); + // Short URL is: $yourls_result['shorturl'] + + // Store short URL in a custom field + update_post_meta($post_id, 'yourls_shorturl', $yourls_result['shorturl']); + + return $yourls_result['shorturl']; +} + +// Parse the tweet template and make a 140 char string +function wp_ozh_yourls_maketweet( $url, $title ) { + // Replace %U with short url + $tweet = str_replace('%U', $url, WPyourls_TWITTER_MSG); + // Now replace %T with as many chars as possible to keep under 140 + $maxlen = 140 - ( strlen( $tweet ) - 2); // 2 = "%T" + if (strlen($title) > $maxlen) { + $title = substr($title, 0, ($maxlen - 3)) . '...'; + } + + $tweet = str_replace('%T', $title, $tweet); + return $tweet; +} + +// Init plugin options +function wp_ozh_yourls_init(){ + global $wp_ozh_plc; + register_setting( 'wp_ozh_yourls_options', 'ozh_plc', 'wp_ozh_yourls_sanitize' ); + $wp_ozh_plc = get_option('ozh_plc'); +} + + +?> \ No newline at end of file -- 2.45.0