summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel <darthdaniel85@gmail.com>2013-11-17 10:17:44 -0800
committerDaniel <darthdaniel85@gmail.com>2013-11-17 10:17:44 -0800
commitb0c2fecd42bd8b95f2535a525b035f27aebde287 (patch)
tree9a709073895f4f52713ed0e83241278c4f6f6e57
parent4cdac46fcc8411607352defeb962602f93a5b26b (diff)
WSAT, similar to Microsoft - Web Site Administration Tool and Yii's Gii, will allow as to generate a lot code such as AR classes with the proper relationships... scaffolding... as well as to admin the app configuration and pages configurations in a GUI fashion.
-rw-r--r--.gitignore73
-rw-r--r--framework/Wsat/TWsatARGenerator.php136
-rw-r--r--framework/Wsat/TWsatService.php42
-rw-r--r--framework/Wsat/TWsatUserManager.php18
-rw-r--r--framework/Wsat/pages/TWsatGenerateAR.page23
-rw-r--r--framework/Wsat/pages/TWsatGenerateAR.php33
-rw-r--r--framework/Wsat/pages/TWsatHome.page5
-rw-r--r--framework/Wsat/pages/TWsatHome.php15
-rw-r--r--framework/Wsat/pages/TWsatLogin.page9
-rw-r--r--framework/Wsat/pages/TWsatLogin.php30
-rw-r--r--framework/Wsat/pages/TWsatScaffolding.page3
-rw-r--r--framework/Wsat/pages/TWsatScaffolding.php15
-rw-r--r--framework/Wsat/pages/config.xml9
-rw-r--r--framework/Wsat/pages/layout/TWsatLayout.php32
-rw-r--r--framework/Wsat/pages/layout/TWsatLayout.tpl53
-rw-r--r--framework/Wsat/themes/.htaccess1
-rw-r--r--framework/Wsat/themes/PradoSoft/imgs/arrowdown.gifbin0 -> 836 bytes
-rw-r--r--framework/Wsat/themes/PradoSoft/imgs/mantisbg.jpgbin0 -> 4043 bytes
-rw-r--r--framework/Wsat/themes/PradoSoft/imgs/pradologo.gifbin0 -> 3039 bytes
-rw-r--r--framework/Wsat/themes/PradoSoft/style.css123
20 files changed, 584 insertions, 36 deletions
diff --git a/.gitignore b/.gitignore
index 93cbf3f5..f779bdd3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,36 +1,37 @@
-/.idea
-atlassian-ide-plugin.xml
-/.project
-/assets
-/.settings
-/.cache
-/build
-/vendor
-/composer.lock
-/.cache
-buildscripts/chmbuilder/classes/Data/classes.data
-buildscripts/classtree/Configuration
-buildscripts/classtree/PRADO.mxi
-buildscripts/texbuilder/quickstart/*.aux
-buildscripts/texbuilder/quickstart/*.png
-buildscripts/texbuilder/quickstart/*.tex
-buildscripts/texbuilder/quickstart/quickstart.log
-buildscripts/texbuilder/quickstart/quickstart.out
-buildscripts/texbuilder/quickstart/quickstart.toc
-demos/quickstart/.cache
-demos/quickstart/.project
-demos/quickstart/.settings
-demos/quickstart/index_pl.php
-tests/FunctionalTests/results.dat
-tests/unit/Data/db/test.db
-
-# Composer stuff
-vendor/*
-bin/phpunit
-bin/phing
-bin/apigen.php
-bin/coveralls
-bin/dbunit.php
-
-#OSX
-.DS_Store \ No newline at end of file
+/.idea
+atlassian-ide-plugin.xml
+/.project
+/assets
+/.settings
+/.cache
+/build
+/vendor
+/composer.lock
+/.cache
+buildscripts/chmbuilder/classes/Data/classes.data
+buildscripts/classtree/Configuration
+buildscripts/classtree/PRADO.mxi
+buildscripts/texbuilder/quickstart/*.aux
+buildscripts/texbuilder/quickstart/*.png
+buildscripts/texbuilder/quickstart/*.tex
+buildscripts/texbuilder/quickstart/quickstart.log
+buildscripts/texbuilder/quickstart/quickstart.out
+buildscripts/texbuilder/quickstart/quickstart.toc
+demos/quickstart/.cache
+demos/quickstart/.project
+demos/quickstart/.settings
+demos/quickstart/index_pl.php
+tests/FunctionalTests/results.dat
+tests/unit/Data/db/test.db
+
+# Composer stuff
+vendor/*
+bin/phpunit
+bin/phing
+bin/apigen.php
+bin/coveralls
+bin/dbunit.php
+
+#OSX
+.DS_Store
+/nbproject/private/ \ No newline at end of file
diff --git a/framework/Wsat/TWsatARGenerator.php b/framework/Wsat/TWsatARGenerator.php
new file mode 100644
index 00000000..7b39fce1
--- /dev/null
+++ b/framework/Wsat/TWsatARGenerator.php
@@ -0,0 +1,136 @@
+<?php
+
+/**
+ * Description of TWsatARGenerator
+ *
+ * @author Daniel
+ */
+class TWsatARGenerator {
+
+ /**
+ * @return TActiveRecordManager static instance of record manager.
+ */
+ private $_ar_manager;
+
+ /**
+ * Output folder (by namespace) where AR classes will be generated.
+ */
+ private $_opnamespace;
+
+ function __construct($_opnamespace = "Application.App_Data.AR_Classes") {
+ $this->_ar_manager = TActiveRecordManager::getInstance();
+ $this->_opnamespace = $_opnamespace;
+ }
+
+ // <editor-fold defaultstate="collapsed" desc="Main APIs">
+ public function generate($tableName, $clasName = '') {
+ $conn = $this->_ar_manager->getDbConnection();
+ $gateway = $this->_ar_manager->getRecordGateway();
+ $tableInfo = $gateway->getTableInfo($conn, $tableName);
+
+ if (count($tableInfo->getColumns()) === 0) {
+ throw new TIOException("Unable to find table or view $tableName in " . $conn->getConnectionString() . ".");
+ } else {
+ $properties = array();
+ foreach ($tableInfo->getColumns() as $field => $column)
+ $properties[] = $this->generateProperty($field, $column);
+ }
+
+ $clasName = empty($clasName) ? $this->_getClassName($tableName) : $clasName;
+ $class = $this->generateClass($properties, $tableName, $clasName);
+ $op_file = Prado::getPathOfNamespace($this->_opnamespace);
+ if (!is_dir($op_file)) {
+ mkdir($op_file, 0777, true);
+ }
+
+ $output = $op_file . DIRECTORY_SEPARATOR . $clasName . ".php";
+ file_put_contents($output, $class);
+ }
+
+ public function generateAll() {
+ foreach ($this->_getAllTableNames() as $tableName) {
+ $this->generate($tableName);
+ }
+ }
+
+// </editor-fold>
+//-----------------------------------------------------------------------------
+ // <editor-fold defaultstate="collapsed" desc="Common Methods">
+ private function getDbConnection() {
+ $con = $this->_ar_manager->getDbConnection();
+ $con->Active = true;
+ return $con;
+ }
+
+ private function _getAllTableNames() {
+ $con = $this->getDbConnection();
+ $command = $con->createCommand("Show Tables");
+ $dataReader = $command->query();
+ $dataReader->bindColumn(1, $table);
+ $tables = array();
+ while ($dataReader->read()) {
+ $tables[] = $table;
+ }
+ $con->setActive(false);
+ return $tables;
+ }
+
+ private function _getClassName($tableName) {
+ return ucfirst($tableName);
+ }
+
+ public function renderAllTablesInformation() {
+ $conn = $this->_ar_manager->getDbConnection();
+ $gateway = $this->_ar_manager->getRecordGateway();
+
+ foreach ($this->_getAllTableNames() as $table_name) {
+ echo $table_name . "<br>";
+
+ $tableInfo = $gateway->getTableInfo($conn, $table_name);
+ echo "Table info:" . "<br>";
+ echo "<pre>";
+ var_dump($tableInfo);
+ echo "</pre>";
+ }
+ }
+
+//-----------------------------------------------------------------------------
+
+ protected function generateProperty($field, $column) {
+ $prop = '';
+ $name = '$' . $field;
+
+ /* TODO use in version 2.0 */
+ // $type = $column->getPHPType();
+
+ $prop .= "\tpublic $name;";
+ return $prop;
+ }
+
+ protected function generateClass($properties, $tablename, $class) {
+ $props = implode("\n", $properties);
+ $date = date('Y-m-d h:i:s');
+ return <<<EOD
+<?php
+/**
+ * Auto generated by prado-cli.php on $date.
+ */
+class $class extends TActiveRecord
+{
+ const TABLE='$tablename';
+
+$props
+
+ public static function finder(\$className=__CLASS__)
+ {
+ return parent::finder(\$className);
+ }
+}
+?>
+EOD;
+ }
+
+// </editor-fold>
+}
+
+?>
diff --git a/framework/Wsat/TWsatService.php b/framework/Wsat/TWsatService.php
new file mode 100644
index 00000000..009ad302
--- /dev/null
+++ b/framework/Wsat/TWsatService.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * Description of TWsat
+ * Inspired in both Microsoft Web Site Administration Tool(WSAT) and Yii's Gii.
+ * @version 1.0
+ * @author Daniel Sampedro darthdaniel85@gmail.com
+ * @since Prado 3.3
+ */
+class TWsatService extends TPageService {
+
+ private $_pass = '';
+
+//-----------------------------------------------------------------------------
+ public function init($config) {
+ if ($this->getApplication()->getMode() === TApplicationMode::Performance
+ || $this->getApplication()->getMode() === TApplicationMode::Normal) {
+ throw new TInvalidOperationException("You should not use Prado WSAT in any of the production modes.");
+ }
+ if (empty($this->_pass)) {
+ throw new TConfigurationException("You need to specify the Password attribute.");
+ }
+ $this->setDefaultPage("TWsatHome");
+ parent::init($config);
+ }
+
+ public function getBasePath() {
+ $basePath = Prado::getPathOfNamespace("System.Wsat.pages");
+ return realpath($basePath);
+ }
+
+ public function getPassword() {
+ return $this->_pass;
+ }
+
+ public function setPassword($_pass) {
+ $this->_pass = $_pass;
+ }
+
+}
+
+?>
diff --git a/framework/Wsat/TWsatUserManager.php b/framework/Wsat/TWsatUserManager.php
new file mode 100644
index 00000000..b9a9eb8b
--- /dev/null
+++ b/framework/Wsat/TWsatUserManager.php
@@ -0,0 +1,18 @@
+<?php
+
+Prado::using('System.Security.TUserManager');
+
+/**
+ * Description of TWsatUserManager
+ *
+ * @author Daniel
+ */
+class TWsatUserManager extends TUserManager {
+
+ public function init($config) {
+ parent::init($config);
+ }
+
+}
+
+?>
diff --git a/framework/Wsat/pages/TWsatGenerateAR.page b/framework/Wsat/pages/TWsatGenerateAR.page
new file mode 100644
index 00000000..3905d023
--- /dev/null
+++ b/framework/Wsat/pages/TWsatGenerateAR.page
@@ -0,0 +1,23 @@
+<com:TContent ID="Content">
+ <div style="margin-left: 220px">
+ <div class="form_row">
+ <com:TLabel Text="Table Name:" ForControl="table_name" style="margin-right: 14px" />
+ <com:TTextBox ID="table_name" Text="*" CssClass="in_text" />
+ </div>
+ <div class="form_row">
+ <com:TLabel Text="Class Prefix:" ForControl="class_prefix" style="margin-right: 16px"/>
+ <com:TTextBox ID="class_prefix" Text="AR_" CssClass="in_text" />
+ </div>
+ <div class="form_row">
+ <com:TLabel Text="Output Folder:" ForControl="output_folder"/>
+ <com:TTextBox ID="output_folder" Text="Application.App_Data.AR_Classes" CssClass="in_text" />
+ </div>
+
+ <br/>
+ <div style="text-align: center">
+ <com:TButton Text="Preview" OnClick="preview" />
+ <com:TButton Text="Generate" OnClick="generate" />
+ </div>
+ </div>
+
+</com:TContent>
diff --git a/framework/Wsat/pages/TWsatGenerateAR.php b/framework/Wsat/pages/TWsatGenerateAR.php
new file mode 100644
index 00000000..754cac5c
--- /dev/null
+++ b/framework/Wsat/pages/TWsatGenerateAR.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Description of Inicio
+ *
+ * @author daniels
+ */
+Prado::using("System.Wsat.TWsatARGenerator");
+
+class TWsatGenerateAR extends TPage {
+
+ public function onInit($param) {
+ parent::onInit($param);
+ }
+
+ public function generate($sender) {
+ $table_name = $this->table_name->Text;
+
+ $ar_generator = new TWsatARGenerator();
+ if ($table_name != "*") {
+ $ar_generator->generate($table_name);
+ } else {
+ $ar_generator->generateAll();
+ }
+ }
+
+ public function preview($sender) {
+
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatHome.page b/framework/Wsat/pages/TWsatHome.page
new file mode 100644
index 00000000..16aa3669
--- /dev/null
+++ b/framework/Wsat/pages/TWsatHome.page
@@ -0,0 +1,5 @@
+<com:TContent ID="Content">
+ <label style="font-size: 18px; font-weight: bold">Welcome to Web Site Administration Tool</label>
+
+ <div style="margin-top: 25px"><b>Application Dir:</b> <%= Prado::getPathOfNamespace('Application') %></div>
+</com:TContent>
diff --git a/framework/Wsat/pages/TWsatHome.php b/framework/Wsat/pages/TWsatHome.php
new file mode 100644
index 00000000..3c1358e1
--- /dev/null
+++ b/framework/Wsat/pages/TWsatHome.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * Description of Inicio
+ *
+ * @author daniels
+ */
+Prado::using("System.Wsat.TWsatARGenerator");
+
+class TWsatHome extends TPage {
+
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatLogin.page b/framework/Wsat/pages/TWsatLogin.page
new file mode 100644
index 00000000..dada4248
--- /dev/null
+++ b/framework/Wsat/pages/TWsatLogin.page
@@ -0,0 +1,9 @@
+<com:TContent ID="Content">
+ <div>
+ <com:TLabel Text="Password:" ForControl="password"/>
+ <com:TTextBox ID="password" />
+ </div>
+
+ <br/>
+ <com:TButton Text="Login" OnClick="login" />
+</com:TContent>
diff --git a/framework/Wsat/pages/TWsatLogin.php b/framework/Wsat/pages/TWsatLogin.php
new file mode 100644
index 00000000..7435d75d
--- /dev/null
+++ b/framework/Wsat/pages/TWsatLogin.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * Description of Inicio
+ *
+ * @author daniels
+ */
+class TWsatLogin extends TPage {
+
+ public function login() {
+ $config_pass = $this->getService()->getPassword();
+ $user_pass = $this->password->Text;
+
+ if ($user_pass === $config_pass) {
+ $this->Session["wsat_password"] = $config_pass;
+
+ $authManager = $this->Application->getModule('auth');
+ $url = $authManager->ReturnUrl;
+ if (empty($url)) {
+ $url = $this->Service->constructUrl('TWsatHome');
+ }
+ $this->Response->redirect($url);
+ } else {
+ echo "user or pass wrong";
+ }
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Wsat/pages/TWsatScaffolding.page b/framework/Wsat/pages/TWsatScaffolding.page
new file mode 100644
index 00000000..42f78d09
--- /dev/null
+++ b/framework/Wsat/pages/TWsatScaffolding.page
@@ -0,0 +1,3 @@
+<com:TContent ID="Content">
+ Scaffolding will be avaliable in Prado 3.4
+</com:TContent>
diff --git a/framework/Wsat/pages/TWsatScaffolding.php b/framework/Wsat/pages/TWsatScaffolding.php
new file mode 100644
index 00000000..afa00273
--- /dev/null
+++ b/framework/Wsat/pages/TWsatScaffolding.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * Description of Inicio
+ *
+ * @author daniels
+ */
+Prado::using("System.Wsat.TWsatARGenerator");
+
+class TWsatScaffolding extends TPage {
+
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Wsat/pages/config.xml b/framework/Wsat/pages/config.xml
new file mode 100644
index 00000000..832b6cc3
--- /dev/null
+++ b/framework/Wsat/pages/config.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+ <modules>
+ <module id="wsat_theme" class="System.Web.UI.TThemeManager" BasePath="System.Wsat.themes" />
+ </modules>
+
+ <pages Theme="PradoSoft" MasterClass="System.Wsat.pages.layout.TWsatLayout" />
+</configuration> \ No newline at end of file
diff --git a/framework/Wsat/pages/layout/TWsatLayout.php b/framework/Wsat/pages/layout/TWsatLayout.php
new file mode 100644
index 00000000..30e52f44
--- /dev/null
+++ b/framework/Wsat/pages/layout/TWsatLayout.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * Description of MainLayout
+ *
+ * @author daniels
+ */
+class TWsatLayout extends TTemplateControl {
+
+ public function onLoad($param) {
+ parent::onLoad($param);
+ $this->validateSecurity();
+ }
+
+ private function validateSecurity() {
+ if ($this->Session["wsat_password"] !== $this->getService()->getPassword()) {
+ if (!$this->getPage() instanceof TWsatLogin) {
+ $url = $this->Service->constructUrl('TWsatLogin');
+ $this->Response->redirect($url);
+ }
+ }
+ }
+
+ public function logout() {
+ $this->Session["wsat_password"] = "";
+ $url = $this->Service->constructUrl('TWsatLogin');
+ $this->Response->redirect($url);
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/framework/Wsat/pages/layout/TWsatLayout.tpl b/framework/Wsat/pages/layout/TWsatLayout.tpl
new file mode 100644
index 00000000..47068a3f
--- /dev/null
+++ b/framework/Wsat/pages/layout/TWsatLayout.tpl
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <com:THead Title="PRADO - WSAT">
+ <com:TMetaTag HttpEquiv="Content-Type" Content="text/html; charset=utf-8" />
+ <com:TMetaTag HttpEquiv="Content-Language" Content="en" />
+ </com:THead>
+
+ <body>
+ <com:TForm>
+
+ <div id="header">
+ <a href="<%= $this->Service->DefaultPageUrl %>">
+ <div class="logo"></div>
+ <div style="float: left; margin-top: 17px">PRADO <br /> Web Site Administration Tool</div>
+ </a>
+ <div class="mantisbg"></div>
+ <div style="clear: both"></div>
+ </div>
+
+ <div class="mainmenu">
+ <div style="float: right"><com:TLinkButton Text="Logout" OnClick="logout" /></div>
+ <div style="float: right"><com:THyperLink NavigateUrl="http://www.pradosoft.com/" Text="PradoSoft.com" Target="_blank" />&nbsp;|&nbsp;</div>
+ <div style="float: right"><com:THyperLink NavigateUrl="<%= $this->Service->DefaultPageUrl %>" Text="Web App" Target="_blank" />&nbsp;|&nbsp;</div>
+ <div style="float: right"><com:THyperLink NavigateUrl="http://www.pradosoft.com/forum/" Text="Help" Target="_blank" />&nbsp;|&nbsp;</div>
+ <div style="clear: both"></div>
+ </div>
+
+ <div id="central_div">
+ <div id="toc">
+ <div class="topic">
+ <div>Code Generation</div>
+ <ul>
+ <li><com:THyperLink NavigateUrl="<%= $this->Service->constructUrl('TWsatGenerateAR') %>" Text="AR Classes" /></li>
+ <li><com:THyperLink NavigateUrl="<%= $this->Service->constructUrl('TWsatScaffolding') %>" Text="Scaffolding" /></li>
+ </ul>
+ </div>
+ </div>
+
+ <div id="content">
+ <com:TContentPlaceHolder ID="Content" />
+ </div>
+
+ <div style="clear: both"></div>
+ </div>
+
+ <div id="footer">
+ Copyright &copy; 2005-<%= date('Y') %> <a href="http://www.pradosoft.com">PradoSoft</a>.
+ <br/><br/>
+ <%= Prado::poweredByPrado() %>
+ </div>
+ </com:TForm>
+ </body>
+</html> \ No newline at end of file
diff --git a/framework/Wsat/themes/.htaccess b/framework/Wsat/themes/.htaccess
new file mode 100644
index 00000000..1caf5e97
--- /dev/null
+++ b/framework/Wsat/themes/.htaccess
@@ -0,0 +1 @@
+allow from all
diff --git a/framework/Wsat/themes/PradoSoft/imgs/arrowdown.gif b/framework/Wsat/themes/PradoSoft/imgs/arrowdown.gif
new file mode 100644
index 00000000..1b508cd6
--- /dev/null
+++ b/framework/Wsat/themes/PradoSoft/imgs/arrowdown.gif
Binary files differ
diff --git a/framework/Wsat/themes/PradoSoft/imgs/mantisbg.jpg b/framework/Wsat/themes/PradoSoft/imgs/mantisbg.jpg
new file mode 100644
index 00000000..ee06998d
--- /dev/null
+++ b/framework/Wsat/themes/PradoSoft/imgs/mantisbg.jpg
Binary files differ
diff --git a/framework/Wsat/themes/PradoSoft/imgs/pradologo.gif b/framework/Wsat/themes/PradoSoft/imgs/pradologo.gif
new file mode 100644
index 00000000..3b073b80
--- /dev/null
+++ b/framework/Wsat/themes/PradoSoft/imgs/pradologo.gif
Binary files differ
diff --git a/framework/Wsat/themes/PradoSoft/style.css b/framework/Wsat/themes/PradoSoft/style.css
new file mode 100644
index 00000000..5424388b
--- /dev/null
+++ b/framework/Wsat/themes/PradoSoft/style.css
@@ -0,0 +1,123 @@
+html, body{
+ margin: 0px;
+ padding: 0px;
+ font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Helvetica, Arial, sans-serif;
+ font-weight: normal;
+}
+
+#header {
+ font-size:25px;
+ font-weight:bold;
+ color: #666;
+}
+
+.logo{
+ width: 204px;
+ height:100px;
+ background-image: url('imgs/pradologo.gif');
+ background-repeat: no-repeat;
+ float: left;
+}
+
+.mantisbg{
+ width: 221px;
+ height: 100px;
+ background-image: url('imgs/mantisbg.jpg');
+ background-repeat: no-repeat;
+ float: right;
+}
+
+.mainmenu {
+ padding:10px;
+ padding-right:10px;
+ background:#EDEDED;
+ border-bottom: 1px solid #A6A6A6;
+ border-top: 1px solid #DCDCDC;
+ color:white;
+ text-align:right;
+ font-size: 10pt;
+}
+
+.mainmenu a {
+ color:#737373;
+ text-decoration:none;
+}
+
+.mainmenu a:hover {
+ color: #FF0000;
+}
+
+#toc {
+ background-color: #F3F3F3;
+ width:220px;
+ padding:0px 10px 0px 10px;
+ float: left;
+}
+
+#content {
+ padding: 1em 1em 1em 1em;
+ line-height: 135%;
+ float: left;
+}
+
+.topic {
+ font-size: 9pt;
+ padding: 0px 0px 0px 0px;
+}
+
+.topic div {
+ background-image: url('imgs/arrowdown.gif');
+ background-repeat: no-repeat;
+ background-position: left center;
+ margin: 0px;
+ font-size: 8pt;
+ font-weight:bold;
+ color:#2A480A;
+ padding: 5px;
+ padding-left: 15px;
+ border-top: 1px solid #fff;
+ border-bottom: 1px solid #E2E2E2;
+}
+
+.topic ul
+{
+ margin: 0px;
+ padding: 0px;
+}
+
+.topic ul li
+{
+ list-style: none;
+ margin: 0px;
+ padding: 5px;
+ padding-left: 15px;
+ border-bottom: 1px dotted #D8D8D8;
+}
+
+.topic a {
+ color:#4F811A;
+ font-size: 8pt;
+ text-decoration: none;
+}
+
+.topic a:hover {
+ color:#2A480A;
+}
+
+/* form styles */
+.form_row{
+ margin: 10px;
+}
+
+.in_text{
+ width: 250px;
+}
+
+#footer {
+ clear:both;
+ color: gray;
+ font-size:8pt;
+ text-align:center;
+ margin-top:25px;
+ padding:10px;
+} \ No newline at end of file