Index: /projects/textcubeapi/trunk/app/webroot/test.php
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/test.php (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/test.php (revision 580)
@@ -0,0 +1,183 @@
+<?php
+/* SVN FILE: $Id: test.php 7296 2008-06-27 09:09:03Z gwoo $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ *  Licensed under The Open Group Test Suite License
+ *  Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
+ * @package			cake
+ * @subpackage		cake.cake.tests.libs
+ * @since			CakePHP(tm) v 1.2.0.4433
+ * @version			$Revision: 7296 $
+ * @modifiedby		$LastChangedBy: gwoo $
+ * @lastmodified	$Date: 2008-06-27 05:09:03 -0400 (Fri, 27 Jun 2008) $
+ * @license			http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
+ */
+error_reporting(E_ALL);
+set_time_limit(0);
+ini_set('memory_limit','128M');
+ini_set('display_errors', 1);
+/**
+ * Use the DS to separate the directories in other defines
+ */
+	if (!defined('DS')) {
+		define('DS', DIRECTORY_SEPARATOR);
+	}
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * When using custom settings be sure to use the DS and do not add a trailing DS.
+ */
+
+/**
+ * The full path to the directory which holds "app", WITHOUT a trailing DS.
+ *
+ */
+	if (!defined('ROOT')) {
+		define('ROOT', dirname(dirname(dirname(__FILE__))));
+	}
+/**
+ * The actual directory name for the "app".
+ *
+ */
+	if (!defined('APP_DIR')) {
+		define('APP_DIR', basename(dirname(dirname(__FILE__))));
+	}
+/**
+ * The absolute path to the "cake" directory, WITHOUT a trailing DS.
+ *
+ */
+	if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+		define('CAKE_CORE_INCLUDE_PATH', ROOT);
+	}
+
+/**
+ * Editing below this line should not be necessary.
+ * Change at your own risk.
+ *
+ */
+if (!defined('WEBROOT_DIR')) {
+	define('WEBROOT_DIR', basename(dirname(__FILE__)));
+}
+if (!defined('WWW_ROOT')) {
+	define('WWW_ROOT', dirname(__FILE__) . DS);
+}
+if (!defined('CORE_PATH')) {
+	if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) {
+		define('APP_PATH', null);
+		define('CORE_PATH', null);
+	} else {
+		define('APP_PATH', ROOT . DS . APP_DIR . DS);
+		define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+	}
+}
+if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
+	trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
+}
+
+$corePath = Configure::corePaths('cake');
+if (isset($corePath[0])) {
+	define('TEST_CAKE_CORE_INCLUDE_PATH', rtrim($corePath[0], DS) . DS);
+} else {
+	define('TEST_CAKE_CORE_INCLUDE_PATH', CAKE_CORE_INCLUDE_PATH);
+}
+
+require_once CAKE_TESTS_LIB . 'test_manager.php';
+
+if (Configure::read('debug') < 1) {
+	die(__('Debug setting does not allow access to this url.', true));
+}
+
+if (!isset($_SERVER['SERVER_NAME'])) {
+	$_SERVER['SERVER_NAME'] = '';
+}
+if (empty( $_GET['output'])) {
+	$_GET['output'] = 'html';
+}
+/**
+ *
+ * Used to determine output to display
+ */
+define('CAKE_TEST_OUTPUT_HTML', 1);
+define('CAKE_TEST_OUTPUT_TEXT', 2);
+
+if (isset($_GET['output']) && $_GET['output'] == 'html') {
+	define('CAKE_TEST_OUTPUT', CAKE_TEST_OUTPUT_HTML);
+} else {
+	Debugger::output('txt');
+	define('CAKE_TEST_OUTPUT', CAKE_TEST_OUTPUT_TEXT);
+}
+
+if (!App::import('Vendor', 'simpletest' . DS . 'reporter')) {
+	CakePHPTestHeader();
+	include CAKE_TESTS_LIB . 'simpletest.php';
+	CakePHPTestSuiteFooter();
+	exit();
+}
+
+$analyzeCodeCoverage = false;
+if (isset($_GET['code_coverage'])) {
+	$analyzeCodeCoverage = true;
+	require_once CAKE_TESTS_LIB . 'code_coverage_manager.php';
+	if (!extension_loaded('xdebug')) {
+		CakePHPTestHeader();
+		include CAKE_TESTS_LIB . 'xdebug.php';
+		CakePHPTestSuiteFooter();
+		exit();
+	}
+}
+
+CakePHPTestHeader();
+CakePHPTestSuiteHeader();
+define('RUN_TEST_LINK', $_SERVER['PHP_SELF']);
+
+if (isset($_GET['group'])) {
+	if ('all' == $_GET['group']) {
+		TestManager::runAllTests(CakeTestsGetReporter());
+	} else {
+		if ($analyzeCodeCoverage) {
+			CodeCoverageManager::start($_GET['group'], CakeTestsGetReporter());
+		}
+		TestManager::runGroupTest(ucfirst($_GET['group']), CakeTestsGetReporter());
+		if ($analyzeCodeCoverage) {
+			CodeCoverageManager::report();
+		}
+	}
+
+	CakePHPTestRunMore();
+	CakePHPTestAnalyzeCodeCoverage();
+} elseif (isset($_GET['case'])) {
+	if ($analyzeCodeCoverage) {
+		CodeCoverageManager::start($_GET['case'], CakeTestsGetReporter());
+	}
+
+	TestManager::runTestCase($_GET['case'], CakeTestsGetReporter());
+
+	if ($analyzeCodeCoverage) {
+		CodeCoverageManager::report();
+	}
+
+	CakePHPTestRunMore();
+	CakePHPTestAnalyzeCodeCoverage();
+} elseif (isset($_GET['show']) && $_GET['show'] == 'cases') {
+	CakePHPTestCaseList();
+} else {
+	CakePHPTestGroupTestList();
+}
+CakePHPTestSuiteFooter();
+$output = ob_get_clean();
+echo $output;
+?>
Index: /projects/textcubeapi/trunk/app/webroot/css/cake.generic.css
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/css/cake.generic.css (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/css/cake.generic.css (revision 580)
@@ -0,0 +1,481 @@
+/* SVN FILE: $Id: cake.generic.css 7690 2008-10-02 04:56:53Z nate $ */
+/**
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.webroot.css
+ * @since			CakePHP(tm)
+ * @version			$Revision: 7690 $
+ * @modifiedby		$LastChangedBy: nate $
+ * @lastmodified	$Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+
+* {
+	margin:0;
+	padding:0;
+}
+
+/* General Style Info */
+body {
+	background: #003d4c;
+	color: #fff;
+	font-family:'lucida grande',verdana,helvetica,arial,sans-serif;
+	font-size:90%;
+	margin: 0;
+}
+a {
+	background:#fff;
+	color: #003d4c;
+	text-decoration: underline;
+	font-weight: bold;
+}
+a:hover {
+	background:#fff;
+	color: #003d4c;
+	text-decoration:none;
+}
+a img {
+	border:none;
+}
+h1, h2, h3, h4 {
+	font-weight: normal;
+}
+h1 {
+	background:#fff;
+	color: #003d4c;
+	font-size: 100%;
+	margin: 0.1em 0;
+}
+h2 {
+	background:#fff;
+	color: #e32;
+	font-family:'Gill Sans','lucida grande',helvetica, arial, sans-serif;
+	font-size: 190%;
+	margin: 0.3em 0;
+	padding-top: 0.8em;
+}
+h3 {
+	color: #993;
+	font-family:'Gill Sans','lucida grande',helvetica, arial, sans-serif;
+	font-size: 165%;
+	padding-top: 1.5em;
+}
+h4 {
+	color: #993;
+	font-weight: normal;
+	padding-top: 0.5em;
+}
+ul, li {
+	margin: 0 12px;
+}
+
+/* Layout */
+#container {
+	text-align: left;
+}
+
+#header{
+	padding: 10px 20px;
+}
+#header h1 {
+	background: #003d4c url('../img/cake.icon.gif') no-repeat left;
+	color: #fff;
+	padding: 0px 30px;
+}
+#header h1 a {
+	color: #fff;
+	background: #003d4c;
+	font-weight: normal;
+	text-decoration: none;
+}
+#header h1 a:hover {
+	color: #fff;
+	background: #003d4c;
+	text-decoration: underline;
+}
+#content{
+	background: #fff;
+	clear: both;
+	color: #333;
+	padding: 10px 20px 40px 20px;
+	overflow: auto;
+}
+#footer {
+	clear: both;
+	padding: 6px 10px;
+	text-align: right;
+}
+
+/* Tables */
+table {
+	background: #fff;
+	border:1px solid #ccc;
+	border-right:0;
+	clear: both;
+	color: #333;
+	margin-bottom: 10px;
+	width: 100%;
+}
+th {
+	background: #f2f2f2;
+	border:1px solid #bbb;
+	border-top: 1px solid #fff;
+	border-left: 1px solid #fff;
+	text-align: center;
+}
+th a {
+	background:#f2f2f2;
+	display: block;
+	padding: 2px 4px;
+	text-decoration: none;
+}
+th a:hover {
+	background: #ccc;
+	color: #333;
+	text-decoration: none;
+}
+table tr td {
+	background: #fff;
+	border-right: 1px solid #ccc;
+	padding: 4px;
+	text-align: center;
+	vertical-align: top;
+}
+table tr.altrow td {
+	background: #f4f4f4;
+}
+td.actions {
+	text-align: center;
+	white-space: nowrap;
+}
+td.actions a {
+	margin: 0px 6px;
+}
+.cake-sql-log table {
+	background: #f4f4f4;
+}
+.cake-sql-log td {
+	padding: 4px 8px;
+	text-align: left;
+}
+
+/* Paging */
+div.paging {
+	background:#fff;
+	color: #ccc;
+	margin-bottom: 2em;
+}
+div.paging div.disabled {
+	color: #ddd;
+	display: inline;
+}
+div.paging span {
+}
+div.paging span.current {
+	color: #000;
+}
+div.paging span a {
+}
+
+/* Scaffold View */
+dl {
+	line-height: 2em;
+	margin: 0em 0em;
+	width: 60%;
+}
+dl.altrow {
+	background: #f4f4f4;
+}
+dt {
+	font-weight: bold;
+	padding-left: 4px;
+	vertical-align: top;
+}
+dd {
+	margin-left: 10em;
+	margin-top: -2em;
+	vertical-align: top;
+}
+
+/* Forms */
+form {
+	clear: both;
+	margin-right: 20px;
+	padding: 0;
+	width: 80%;
+}
+fieldset {
+	border: 1px solid #ccc;
+	margin-top: 30px;
+	padding: 16px 20px;
+}
+fieldset legend {
+	background:#fff;
+	color: #e32;
+	font-size: 160%;
+	font-weight: bold;
+}
+fieldset fieldset {
+	margin-top: 0px;
+	margin-bottom: 20px;
+	padding: 16px 10px;
+}
+fieldset fieldset legend {
+	font-size: 120%;
+	font-weight: normal;
+}
+fieldset fieldset div {
+	clear: left;
+	margin: 0 20px;
+}
+form div {
+	clear: both;
+	margin-bottom: 1em;
+	padding: .5em;
+	vertical-align: text-top;
+}
+form div.input {
+	color: #444;
+}
+form div.required {
+	color: #333;
+	font-weight: bold;
+}
+form div.submit {
+	border: 0;
+	clear: both;
+	margin-top: 10px;
+	margin-left: 140px;
+}
+label {
+	display: block;
+	font-size: 110%;
+	padding-right: 20px;
+}
+input, textarea {
+	clear: both;
+	font-size: 140%;
+	font-family: "frutiger linotype", "lucida grande", "verdana", sans-serif;
+	padding: 2px;
+	width: 100%;
+}
+select {
+	clear: both;
+	font-size: 120%;
+	vertical-align: text-bottom;
+}
+select[multiple=multiple] {
+	width: 100%;
+}
+option {
+	font-size: 120%;
+	padding: 0 3px;
+}
+input[type=checkbox] {
+	clear: left;
+	float: left;
+	margin: 0px 6px 7px 2px;
+	width: auto;
+}
+input[type=radio] {
+	float:left;
+	width:auto;
+	margin: 0 3px 7px 0;
+}
+div.radio label {
+	margin: 0 0 6px 20px;
+}
+input[type=submit] {
+	display: inline;
+	font-size: 110%;
+	padding: 2px 5px;
+	width: auto;
+	vertical-align: bottom;
+}
+
+/* Notices and Errors */
+div.message {
+	clear: both;
+	color: #900;
+	font-size: 140%;
+	font-weight: bold;
+	margin: 1em 0;
+}
+div.error-message {
+	clear: both;
+	color: #900;
+	font-weight: bold;
+}
+p.error {
+	background-color: #e32;
+	color: #fff;
+	font-family: Courier, monospace;
+	font-size: 120%;
+	line-height: 140%;
+	padding: 0.8em;
+	margin: 1em 0;
+}
+p.error em {
+	color: #000;
+	font-weight: normal;
+	line-height: 140%;
+}
+.notice {
+	background: #ffcc00;
+	color: #000;
+	display: block;
+	font-family: Courier, monospace;
+	font-size: 120%;
+	line-height: 140%;
+	padding: 0.8em;
+	margin: 1em 0;
+}
+.success {
+	background: green;
+	color: #fff;
+}
+
+/*  Actions  */
+div.actions ul {
+	margin: 0px 0;
+	padding: 0;
+}
+div.actions li {
+	display: inline;
+	list-style-type: none;
+	line-height: 2em;
+	margin: 0 2em 0 0;
+	white-space: nowrap;
+}
+div.actions ul li a {
+	background:#fff;
+	color: #003d4c;
+	text-decoration: none;
+}
+div.actions ul li a:hover {
+	color: #333;
+	text-decoration: underline;
+}
+
+/* Related */
+div.related {
+	clear: both;
+	display: block;
+}
+
+/* Debugging */
+pre {
+	color: #000;
+	background: #f0f0f0;
+	padding: 1em;
+}
+pre.cake-debug {
+	background: #ffcc00;
+	font-size: 120%;
+	line-height: 140%;
+	margin-top: 1em;
+	overflow: auto;
+	position: relative;
+}
+div.cake-stack-trace {
+	background: #fff;
+	border: 4px dotted #ffcc00;
+	color: #333;
+	margin: 0px;
+	padding: 6px;
+	font-size: 120%;
+	line-height: 140%;
+	overflow: auto;
+	position: relative;
+}
+div.cake-code-dump pre {
+	position: relative;
+	overflow: auto;
+}
+div.cake-stack-trace pre, div.cake-code-dump pre {
+	color: #000;
+	background-color: #F0F0F0;
+	margin: 0px;
+	padding: 1em;
+	overflow: auto;
+}
+div.cake-code-dump pre, div.cake-code-dump pre code {
+	clear: both;
+	font-size: 12px;
+	line-height: 15px;
+	margin: 4px 2px;
+	padding: 4px;
+	overflow: auto;
+}
+div.cake-code-dump span.code-highlight {
+	background-color: #ff0;
+	padding: 4px;
+}
+div.code-coverage-results div.code-line {
+	padding-left:5px;
+	display:block;
+	margin-left:10px;
+}
+div.code-coverage-results div.uncovered span.content {
+	background:#ecc;
+}
+div.code-coverage-results div.covered span.content {
+	background:#cec;
+}
+div.code-coverage-results div.ignored span.content {
+	color:#aaa;
+}
+div.code-coverage-results span.line-num {
+	color:#666;
+	display:block;
+	float:left;
+	width:20px;
+	text-align:right;
+	margin-right:5px;
+}
+div.code-coverage-results span.line-num strong {
+	color:#666;
+}
+div.code-coverage-results div.start {
+	border:1px solid #aaa;
+	border-width:1px 1px 0px 1px;
+	margin-top:30px;
+	padding-top:5px;
+}
+div.code-coverage-results div.end {
+	border:1px solid #aaa;
+	border-width:0px 1px 1px 1px;
+	margin-bottom:30px;
+	padding-bottom:5px;
+}
+div.code-coverage-results div.realstart {
+	margin-top:0px;
+}
+div.code-coverage-results p.note {
+	color:#bbb;
+	padding:5px;
+	margin:5px 0 10px;
+	font-size:10px;
+}
+div.code-coverage-results span.result-bad {
+	color: #a00;
+}
+div.code-coverage-results span.result-ok {
+	color: #fa0;
+}
+div.code-coverage-results span.result-good {
+	color: #0a0;
+}
Index: /projects/textcubeapi/trunk/app/webroot/css/service.css
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/css/service.css (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/css/service.css (revision 580)
@@ -0,0 +1,6 @@
+@charset "utf-8";
+
+body {
+	font-family: "Trebuchet MS", "Verdana", "NanumGothic", "Malgun Gothic", sans-serif;
+	font-size: 0.85em;
+}
Index: /projects/textcubeapi/trunk/app/webroot/.htaccess
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/.htaccess (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/.htaccess (revision 580)
@@ -0,0 +1,6 @@
+<IfModule mod_rewrite.c>
+    RewriteEngine On
+    RewriteCond %{REQUEST_FILENAME} !-d
+    RewriteCond %{REQUEST_FILENAME} !-f
+    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
+</IfModule>
Index: /projects/textcubeapi/trunk/app/webroot/js/latex_renderer/test.js
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/js/latex_renderer/test.js (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/js/latex_renderer/test.js (revision 580)
@@ -0,0 +1,41 @@
+google.load("dojo", "1.1.1");
+google.setOnLoadCallback(function() {
+	dojo.provide('dojo.string');
+	// removed after dojo 0.4.x, so copied from http://trac.dojotoolkit.org/browser/trunk/src/string/extras.js?rev=3266#L88
+	dojo.string.escapeXml = function(str, noSingleQuotes) {
+			str = str.replace(/&/gm, "&amp;").replace(/</gm, "&lt;")
+					.replace(/>/gm, "&gt;").replace(/\"/gm, "&quot;");
+			if(!noSingleQuotes) { str = str.replace(/\'/gm, "&#39;"); }
+			return str;
+	}
+	var f = dojo.byId('testForm');
+	var submitFunc = function(ev) {
+		ev.preventDefault();
+		dojo.byId('msg').innerHTML = 'loading...';
+		dojo.byId('testSubmit').enabled = false;
+		dojo.xhrPost({
+			url: '/latex_renderer/query/',
+			handleAs: 'json',
+			form: 'testForm',
+			load: function(response, args) {
+				if (response.result == 'ok') {
+					var img = dojo.byId('result');
+					// TODO: We need workaround for IE6 and IE7.
+					img.src = 'data:' + response.format + ';base64,' + response.content;
+					img.width = response.sizeX; img.height = response.sizeY;
+					dojo.byId('msg').innerHTML = 'Complete : (' + response.sizeX + 'x' + response.sizeY + ')';
+				} else {
+					dojo.byId('msg').innerHTML = 'Error : &lt;' + response.error_type + '&gt; ' + dojo.string.escapeXml(response.message);
+				}
+				dojo.byId('testSubmit').enabled = true;
+			},
+			error: function(response, args) {
+				alert('AJAX Error : ' + response);
+				dojo.byId('loadingMsg').innerHTML = 'Error during AJAX request.';
+				dojo.byId('testSubmit').enabled = true;
+			}
+		});
+		return false;
+	};
+	dojo.connect(f, 'onsubmit', submitFunc);
+});
Index: /projects/textcubeapi/trunk/app/webroot/js/vendors.php
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/js/vendors.php (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/js/vendors.php (revision 580)
@@ -0,0 +1,44 @@
+<?php
+/* SVN FILE: $Id: vendors.php 7690 2008-10-02 04:56:53Z nate $ */
+/**
+ * Short description for file.
+ *
+ * This file includes js vendor-files from /vendor/ directory if they need to
+ * be accessible to the public.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.webroot.js
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7690 $
+ * @modifiedby		$LastChangedBy: nate $
+ * @lastmodified	$Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Enter description here...
+ */
+if (isset($_GET['file'])) {
+	$file = $_GET['file'];
+	$pos = strpos($file, '..');
+	if ($pos === false) {
+		if (is_file('../../vendors/javascript/'.$file) && (preg_match('/(\/.+)\\.js/', $file))) {
+			readfile('../../vendors/javascript/'.$file);
+			return;
+		}
+	}
+}
+header('HTTP/1.1 404 Not Found');
+?>
Index: /projects/textcubeapi/trunk/app/webroot/index.php
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/index.php (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/index.php (revision 580)
@@ -0,0 +1,95 @@
+<?php
+/* SVN FILE: $Id: index.php 7296 2008-06-27 09:09:03Z gwoo $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.webroot
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7296 $
+ * @modifiedby		$LastChangedBy: gwoo $
+ * @lastmodified	$Date: 2008-06-27 05:09:03 -0400 (Fri, 27 Jun 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Use the DS to separate the directories in other defines
+ */
+	if (!defined('DS')) {
+		define('DS', DIRECTORY_SEPARATOR);
+	}
+/**
+ * These defines should only be edited if you have cake installed in
+ * a directory layout other than the way it is distributed.
+ * When using custom settings be sure to use the DS and do not add a trailing DS.
+ */
+
+/**
+ * The full path to the directory which holds "app", WITHOUT a trailing DS.
+ *
+ */
+	if (!defined('ROOT')) {
+		define('ROOT', dirname(dirname(dirname(__FILE__))));
+	}
+/**
+ * The actual directory name for the "app".
+ *
+ */
+	if (!defined('APP_DIR')) {
+		define('APP_DIR', basename(dirname(dirname(__FILE__))));
+	}
+/**
+ * The absolute path to the "cake" directory, WITHOUT a trailing DS.
+ *
+ */
+	if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+		define('CAKE_CORE_INCLUDE_PATH', ROOT);
+	}
+
+/**
+ * Editing below this line should NOT be necessary.
+ * Change at your own risk.
+ *
+ */
+	if (!defined('WEBROOT_DIR')) {
+		define('WEBROOT_DIR', basename(dirname(__FILE__)));
+	}
+	if (!defined('WWW_ROOT')) {
+		define('WWW_ROOT', dirname(__FILE__) . DS);
+	}
+	if (!defined('CORE_PATH')) {
+		if (function_exists('ini_set') && ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . ROOT . DS . APP_DIR . DS . PATH_SEPARATOR . ini_get('include_path'))) {
+			define('APP_PATH', null);
+			define('CORE_PATH', null);
+		} else {
+			define('APP_PATH', ROOT . DS . APP_DIR . DS);
+			define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
+		}
+	}
+	if (!include(CORE_PATH . 'cake' . DS . 'bootstrap.php')) {
+		trigger_error("CakePHP core could not be found.  Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php.  It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
+	}
+	if (isset($_GET['url']) && $_GET['url'] === 'favicon.ico') {
+		return;
+	} else {
+		$Dispatcher = new Dispatcher();
+		$Dispatcher->dispatch($url);
+	}
+	if (Configure::read() > 0) {
+		echo "<!-- " . round(getMicrotime() - $TIME_START, 4) . "s -->";
+	}
+?>
Index: /projects/textcubeapi/trunk/app/webroot/css.php
===================================================================
--- /projects/textcubeapi/trunk/app/webroot/css.php (revision 580)
+++ /projects/textcubeapi/trunk/app/webroot/css.php (revision 580)
@@ -0,0 +1,104 @@
+<?php
+/* SVN FILE: $Id: css.php 7296 2008-06-27 09:09:03Z gwoo $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.webroot
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7296 $
+ * @modifiedby		$LastChangedBy: gwoo $
+ * @lastmodified	$Date: 2008-06-27 05:09:03 -0400 (Fri, 27 Jun 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+if (!defined('CAKE_CORE_INCLUDE_PATH')) {
+	header('HTTP/1.1 404 Not Found');
+	exit('File Not Found');
+}
+/**
+ * Enter description here...
+ */
+if (!class_exists('File')) {
+	uses('file');
+}
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $path
+ * @param unknown_type $name
+ * @return unknown
+ */
+	function make_clean_css($path, $name) {
+		require(VENDORS . 'csspp' . DS . 'csspp.php');
+		$data = file_get_contents($path);
+		$csspp = new csspp();
+		$output = $csspp->compress($data);
+		$ratio = 100 - (round(strlen($output) / strlen($data), 3) * 100);
+		$output = " /* file: $name, ratio: $ratio% */ " . $output;
+		return $output;
+	}
+/**
+ * Enter description here...
+ *
+ * @param unknown_type $path
+ * @param unknown_type $content
+ * @return unknown
+ */
+	function write_css_cache($path, $content) {
+		if (!is_dir(dirname($path))) {
+			mkdir(dirname($path));
+		}
+		$cache = new File($path);
+		return $cache->write($content);
+	}
+
+	if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
+		die('Wrong file name.');
+	}
+
+	$filename = 'css/' . $regs[1];
+	$filepath = CSS . $regs[1];
+	$cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
+
+	if (!file_exists($filepath)) {
+		die('Wrong file name.');
+	}
+
+	if (file_exists($cachepath)) {
+		$templateModified = filemtime($filepath);
+		$cacheModified = filemtime($cachepath);
+
+		if ($templateModified > $cacheModified) {
+			$output = make_clean_css($filepath, $filename);
+			write_css_cache($cachepath, $output);
+		} else {
+			$output = file_get_contents($cachepath);
+		}
+	} else {
+		$output = make_clean_css($filepath, $filename);
+		write_css_cache($cachepath, $output);
+		$templateModified = time();
+	}
+
+	header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT');
+	header("Content-Type: text/css");
+	header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
+	header("Cache-Control: cache"); // HTTP/1.1
+	header("Pragma: cache");        // HTTP/1.0
+	print $output;
+?>
Index: /projects/textcubeapi/trunk/app/models/latex.php
===================================================================
--- /projects/textcubeapi/trunk/app/models/latex.php (revision 580)
+++ /projects/textcubeapi/trunk/app/models/latex.php (revision 580)
@@ -0,0 +1,5 @@
+<?php
+// No models
+class Latex extends AppModel {
+}
+?>
Index: /projects/textcubeapi/trunk/app/models/user.php
===================================================================
--- /projects/textcubeapi/trunk/app/models/user.php (revision 580)
+++ /projects/textcubeapi/trunk/app/models/user.php (revision 580)
@@ -0,0 +1,10 @@
+<?php
+class User extends AppModel {
+	var $name = 'User';
+	var $validate = array();
+
+	var $hasMany = array('Key' => array('className' => 'Key'));
+
+	// TODO
+}
+?>
Index: /projects/textcubeapi/trunk/app/models/key.php
===================================================================
--- /projects/textcubeapi/trunk/app/models/key.php (revision 580)
+++ /projects/textcubeapi/trunk/app/models/key.php (revision 580)
@@ -0,0 +1,7 @@
+<?php
+class Key extends AppModel {
+	var $name = 'Key';
+	var $belongsTo = array('User' => array('className' => 'User', 'foreignKey' => 'user_id'));
+
+	// TODO
+}
Index: /projects/textcubeapi/trunk/app/config/sql/db_acl.sql
===================================================================
--- /projects/textcubeapi/trunk/app/config/sql/db_acl.sql (revision 580)
+++ /projects/textcubeapi/trunk/app/config/sql/db_acl.sql (revision 580)
@@ -0,0 +1,42 @@
+# $Id: db_acl.sql 7118 2008-06-04 20:49:29Z gwoo $
+#
+# Copyright 2005-2008,	Cake Software Foundation, Inc.
+#								1785 E. Sahara Avenue, Suite 490-204
+#								Las Vegas, Nevada 89104
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+# http://www.opensource.org/licenses/mit-license.php The MIT License
+
+CREATE TABLE acos (
+  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  parent_id INTEGER(10) DEFAULT NULL,
+  model VARCHAR(255) DEFAULT '',
+  foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
+  alias VARCHAR(255) DEFAULT '',
+  lft INTEGER(10) DEFAULT NULL,
+  rght INTEGER(10) DEFAULT NULL,
+  PRIMARY KEY  (id)
+);
+
+CREATE TABLE aros_acos (
+  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  aro_id INTEGER(10) UNSIGNED NOT NULL,
+  aco_id INTEGER(10) UNSIGNED NOT NULL,
+  _create CHAR(2) NOT NULL DEFAULT 0,
+  _read CHAR(2) NOT NULL DEFAULT 0,
+  _update CHAR(2) NOT NULL DEFAULT 0,
+  _delete CHAR(2) NOT NULL DEFAULT 0,
+  PRIMARY KEY(id)
+);
+
+CREATE TABLE aros (
+  id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  parent_id INTEGER(10) DEFAULT NULL,
+  model VARCHAR(255) DEFAULT '',
+  foreign_key INTEGER(10) UNSIGNED DEFAULT NULL,
+  alias VARCHAR(255) DEFAULT '',
+  lft INTEGER(10) DEFAULT NULL,
+  rght INTEGER(10) DEFAULT NULL,
+  PRIMARY KEY  (id)
+);
Index: /projects/textcubeapi/trunk/app/config/sql/sessions.sql
===================================================================
--- /projects/textcubeapi/trunk/app/config/sql/sessions.sql (revision 580)
+++ /projects/textcubeapi/trunk/app/config/sql/sessions.sql (revision 580)
@@ -0,0 +1,16 @@
+# $Id: sessions.sql 7118 2008-06-04 20:49:29Z gwoo $
+#
+# Copyright 2005-2008,	Cake Software Foundation, Inc.
+#								1785 E. Sahara Avenue, Suite 490-204
+#								Las Vegas, Nevada 89104
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+# http://www.opensource.org/licenses/mit-license.php The MIT License
+
+CREATE TABLE cake_sessions (
+  id varchar(255) NOT NULL default '',
+  data text,
+  expires int(11) default NULL,
+  PRIMARY KEY  (id)
+);
Index: /projects/textcubeapi/trunk/app/config/sql/i18n.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/sql/i18n.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/sql/i18n.php (revision 580)
@@ -0,0 +1,58 @@
+<?php
+/* SVN FILE: $Id: i18n.php 7118 2008-06-04 20:49:29Z gwoo $ */
+/*i18n schema generated on: 2007-11-25 07:11:25 : 1196004805*/
+/**
+ * This is i18n Schema file
+ *
+ * Use it to configure database for i18n
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config.sql
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7118 $
+ * @modifiedby		$LastChangedBy: gwoo $
+ * @lastmodified	$Date: 2008-06-04 16:49:29 -0400 (Wed, 04 Jun 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create i18n
+ *
+ */
+class i18nSchema extends CakeSchema {
+
+	var $name = 'i18n';
+
+	function before($event = array()) {
+		return true;
+	}
+
+	function after($event = array()) {
+	}
+
+	var $i18n = array(
+			'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+			'locale' => array('type'=>'string', 'null' => false, 'length' => 6, 'key' => 'index'),
+			'model' => array('type'=>'string', 'null' => false, 'key' => 'index'),
+			'foreign_key' => array('type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
+			'field' => array('type'=>'string', 'null' => false, 'key' => 'index'),
+			'content' => array('type'=>'text', 'null' => true, 'default' => NULL),
+			'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'locale' => array('column' => 'locale', 'unique' => 0), 'model' => array('column' => 'model', 'unique' => 0), 'row_id' => array('column' => 'foreign_key', 'unique' => 0), 'field' => array('column' => 'field', 'unique' => 0))
+		);
+
+}
+?>
Index: /projects/textcubeapi/trunk/app/config/sql/db_acl.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/sql/db_acl.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/sql/db_acl.php (revision 580)
@@ -0,0 +1,81 @@
+<?php
+/* SVN FILE: $Id: db_acl.php 7118 2008-06-04 20:49:29Z gwoo $ */
+/*DbAcl schema generated on: 2007-11-24 15:11:13 : 1195945453*/
+/**
+ * This is Acl Schema file
+ *
+ * Use it to configure database for ACL
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config.sql
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7118 $
+ * @modifiedby		$LastChangedBy: gwoo $
+ * @lastmodified	$Date: 2008-06-04 16:49:29 -0400 (Wed, 04 Jun 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create DbAcl
+ *
+ */
+class DbAclSchema extends CakeSchema {
+
+	var $name = 'DbAcl';
+
+	function before($event = array()) {
+		return true;
+	}
+
+	function after($event = array()) {
+	}
+
+	var $acos = array(
+			'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+			'parent_id' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'model' => array('type'=>'string', 'null' => true),
+			'foreign_key' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'alias' => array('type'=>'string', 'null' => true),
+			'lft' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'rght' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+		);
+
+	var $aros = array(
+			'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+			'parent_id' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'model' => array('type'=>'string', 'null' => true),
+			'foreign_key' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'alias' => array('type'=>'string', 'null' => true),
+			'lft' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'rght' => array('type'=>'integer', 'null' => true, 'default' => NULL, 'length' => 10),
+			'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+		);
+
+	var $aros_acos = array(
+			'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'length' => 10, 'key' => 'primary'),
+			'aro_id' => array('type'=>'integer', 'null' => false, 'length' => 10, 'key' => 'index'),
+			'aco_id' => array('type'=>'integer', 'null' => false, 'length' => 10),
+			'_create' => array('type'=>'string', 'null' => false, 'default' => '0', 'length' => 2),
+			'_read' => array('type'=>'string', 'null' => false, 'default' => '0', 'length' => 2),
+			'_update' => array('type'=>'string', 'null' => false, 'default' => '0', 'length' => 2),
+			'_delete' => array('type'=>'string', 'null' => false, 'default' => '0', 'length' => 2),
+			'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1), 'ARO_ACO_KEY' => array('column' => array('aro_id', 'aco_id'), 'unique' => 1))
+		);
+
+}
+?>
Index: /projects/textcubeapi/trunk/app/config/sql/sessions.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/sql/sessions.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/sql/sessions.php (revision 580)
@@ -0,0 +1,55 @@
+<?php
+/* SVN FILE: $Id: sessions.php 6311 2008-01-02 06:33:52Z phpnut $ */
+/*Sessions schema generated on: 2007-11-25 07:11:54 : 1196004714*/
+/**
+ * This is Sessions Schema file
+ *
+ * Use it to configure database for Sessions
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config.sql
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 6311 $
+ * @modifiedby		$LastChangedBy: phpnut $
+ * @lastmodified	$Date: 2008-01-02 01:33:52 -0500 (Wed, 02 Jan 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/*
+ *
+ * Using the Schema command line utility
+ * cake schema run create Sessions
+ *
+ */
+class SessionsSchema extends CakeSchema {
+
+	var $name = 'Sessions';
+
+	function before($event = array()) {
+		return true;
+	}
+
+	function after($event = array()) {
+	}
+
+	var $cake_sessions = array(
+			'id' => array('type'=>'string', 'null' => false, 'key' => 'primary'),
+			'data' => array('type'=>'text', 'null' => true, 'default' => NULL),
+			'expires' => array('type'=>'integer', 'null' => true, 'default' => NULL),
+			'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
+		);
+
+}
+?>
Index: /projects/textcubeapi/trunk/app/config/sql/i18n.sql
===================================================================
--- /projects/textcubeapi/trunk/app/config/sql/i18n.sql (revision 580)
+++ /projects/textcubeapi/trunk/app/config/sql/i18n.sql (revision 580)
@@ -0,0 +1,28 @@
+# $Id: i18n.sql 7118 2008-06-04 20:49:29Z gwoo $
+#
+# Copyright 2005-2008,	Cake Software Foundation, Inc.
+#								1785 E. Sahara Avenue, Suite 490-204
+#								Las Vegas, Nevada 89104
+#
+# Licensed under The MIT License
+# Redistributions of files must retain the above copyright notice.
+# http://www.opensource.org/licenses/mit-license.php The MIT License
+
+CREATE TABLE i18n (
+	id int(10) NOT NULL auto_increment,
+	locale varchar(6) NOT NULL,
+	model varchar(255) NOT NULL,
+	foreign_key int(10) NOT NULL,
+	field varchar(255) NOT NULL,
+	content mediumtext,
+	PRIMARY KEY	(id),
+#	UNIQUE INDEX I18N_LOCALE_FIELD(locale, model, foreign_key, field),
+#	INDEX I18N_LOCALE_ROW(locale, model, foreign_key),
+#	INDEX I18N_LOCALE_MODEL(locale, model),
+#	INDEX I18N_FIELD(model, foreign_key, field),
+#	INDEX I18N_ROW(model, foreign_key),
+	INDEX locale (locale),
+	INDEX model (model),
+	INDEX row_id (foreign_key),
+	INDEX field (field)
+);
Index: /projects/textcubeapi/trunk/app/config/acl.ini.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/acl.ini.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/acl.ini.php (revision 580)
@@ -0,0 +1,76 @@
+;<?php die() ?>
+; SVN FILE: $Id: acl.ini.php 7690 2008-10-02 04:56:53Z nate $
+;/**
+; * Short description for file.
+; *
+; *
+; * PHP versions 4 and 5
+; *
+; * CakePHP(tm) :  Rapid Development Framework http://www.cakephp.org/
+; * Copyright 2005-2008, Cake Software Foundation, Inc.
+; *							1785 E. Sahara Avenue, Suite 490-204
+; *							Las Vegas, Nevada 89104
+; *
+; *  Licensed under The MIT License
+; *  Redistributions of files must retain the above copyright notice.
+; *
+; * @filesource
+; * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+; * @link			http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+; * @package		cake
+; * @subpackage	cake.app.config
+; * @since			CakePHP(tm) v 0.10.0.1076
+; * @version		$Revision: 7690 $
+; * @modifiedby	$LastChangedBy: nate $
+; * @lastmodified	$Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
+; * @license		http://www.opensource.org/licenses/mit-license.php The MIT License
+; */
+
+; acl.ini.php - Cake ACL Configuration
+; ---------------------------------------------------------------------
+; Use this file to specify user permissions.
+; aco = access control object (something in your application)
+; aro = access request object (something requesting access)
+;
+; User records are added as follows:
+;
+; [uid]
+; groups = group1, group2, group3
+; allow = aco1, aco2, aco3
+; deny = aco4, aco5, aco6
+;
+; Group records are added in a similar manner:
+;
+; [gid]
+; allow = aco1, aco2, aco3
+; deny = aco4, aco5, aco6
+;
+; The allow, deny, and groups sections are all optional.
+; NOTE: groups names *cannot* ever be the same as usernames!
+;
+; ACL permissions are checked in the following order:
+; 1. Check for user denies (and DENY if specified)
+; 2. Check for user allows (and ALLOW if specified)
+; 3. Gather user's groups
+; 4. Check group denies (and DENY if specified)
+; 5. Check group allows (and ALLOW if specified)
+; 6. If no aro, aco, or group information is found, DENY
+;
+; ---------------------------------------------------------------------
+
+;-------------------------------------
+;Users
+;-------------------------------------
+
+[username-goes-here]
+groups = group1, group2
+deny = aco1, aco2
+allow = aco3, aco4
+
+;-------------------------------------
+;Groups
+;-------------------------------------
+
+[groupname-goes-here]
+deny = aco5, aco6
+allow = aco7, aco8
Index: /projects/textcubeapi/trunk/app/config/bootstrap.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/bootstrap.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/bootstrap.php (revision 580)
@@ -0,0 +1,46 @@
+<?php
+/* SVN FILE: $Id: bootstrap.php 6311 2008-01-02 06:33:52Z phpnut $ */
+/**
+ * Short description for file.
+ *
+ * Long description for file
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config
+ * @since			CakePHP(tm) v 0.10.8.2117
+ * @version			$Revision: 6311 $
+ * @modifiedby		$LastChangedBy: phpnut $
+ * @lastmodified	$Date: 2008-01-02 01:33:52 -0500 (Wed, 02 Jan 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ *
+ * This file is loaded automatically by the app/webroot/index.php file after the core bootstrap.php is loaded
+ * This is an application wide file to load any function that is not used within a class define.
+ * You can also use this to include or require any files in your application.
+ *
+ */
+/**
+ * The settings below can be used to set additional paths to models, views and controllers.
+ * This is related to Ticket #470 (https://trac.cakephp.org/ticket/470)
+ *
+ * $modelPaths = array('full path to models', 'second full path to models', 'etc...');
+ * $viewPaths = array('this path to views', 'second full path to views', 'etc...');
+ * $controllerPaths = array('this path to controllers', 'second full path to controllers', 'etc...');
+ *
+ */
+//EOF
+?>
Index: /projects/textcubeapi/trunk/app/config/inflections.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/inflections.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/inflections.php (revision 580)
@@ -0,0 +1,72 @@
+<?php
+/* SVN FILE: $Id: inflections.php 6311 2008-01-02 06:33:52Z phpnut $ */
+/**
+ * Custom Inflected Words.
+ *
+ * This file is used to hold words that are not matched in the normail Inflector::pluralize() and
+ * Inflector::singularize()
+ *
+ * PHP versions 4 and %
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config
+ * @since			CakePHP(tm) v 1.0.0.2312
+ * @version			$Revision: 6311 $
+ * @modifiedby		$LastChangedBy: phpnut $
+ * @lastmodified	$Date: 2008-01-02 01:33:52 -0500 (Wed, 02 Jan 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * This is a key => value array of regex used to match words.
+ * If key matches then the value is returned.
+ *
+ *  $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
+ */
+	$pluralRules = array();
+/**
+ * This is a key only array of plural words that should not be inflected.
+ * Notice the last comma
+ *
+ * $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
+ */
+	$uninflectedPlural = array();
+/**
+ * This is a key => value array of plural irregular words.
+ * If key matches then the value is returned.
+ *
+ *  $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
+ */
+	$irregularPlural = array();
+/**
+ * This is a key => value array of regex used to match words.
+ * If key matches then the value is returned.
+ *
+ *  $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
+ */
+	$singularRules = array();
+/**
+ * This is a key only array of singular words that should not be inflected.
+ * You should not have to change this value below if you do change it use same format
+ * as the $uninflectedPlural above.
+ */
+	$uninflectedSingular = $uninflectedPlural;
+/**
+ * This is a key => value array of singular irregular words.
+ * Most of the time this will be a reverse of the above $irregularPlural array
+ * You should not have to change this value below if you do change it use same format
+ *
+ * $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
+ */
+	$irregularSingular = array_flip($irregularPlural);
+?>
Index: /projects/textcubeapi/trunk/app/config/routes.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/routes.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/routes.php (revision 580)
@@ -0,0 +1,41 @@
+<?php
+/* SVN FILE: $Id: routes.php 7690 2008-10-02 04:56:53Z nate $ */
+/**
+ * Short description for file.
+ *
+ * In this file, you set up routes to your controllers and their actions.
+ * Routes are very important mechanism that allows you to freely connect
+ * different urls to chosen controllers and their actions (functions).
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7690 $
+ * @modifiedby		$LastChangedBy: nate $
+ * @lastmodified	$Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * Here, we are connecting '/' (base path) to controller called 'Pages',
+ * its action called 'display', and we pass a param to select the view file
+ * to use (in this case, /app/views/pages/home.ctp)...
+ */
+	Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
+/**
+ * ...and connect the rest of 'Pages' controller's urls.
+ */
+	Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
+?>
Index: /projects/textcubeapi/trunk/app/config/database.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/database.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/database.php (revision 580)
@@ -0,0 +1,103 @@
+<?php
+/* SVN FILE: $Id: database.php.default 7690 2008-10-02 04:56:53Z nate $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7690 $
+ * @modifiedby		$LastChangedBy: nate $
+ * @lastmodified	$Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * In this file you set up your database connection details.
+ *
+ * @package		cake
+ * @subpackage	cake.config
+ */
+/**
+ * Database configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * driver => The name of a supported driver; valid options are as follows:
+ *		mysql 		- MySQL 4 & 5,
+ *		mysqli 		- MySQL 4 & 5 Improved Interface (PHP5 only),
+ *		sqlite		- SQLite (PHP5 only),
+ *		postgres	- PostgreSQL 7 and higher,
+ *		mssql		- Microsoft SQL Server 2000 and higher,
+ *		db2			- IBM DB2, Cloudscape, and Apache Derby (http://php.net/ibm-db2)
+ *		oracle		- Oracle 8 and higher
+ *		firebird	- Firebird/Interbase
+ *		sybase		- Sybase ASE
+ *		adodb-[drivername]	- ADOdb interface wrapper (see below),
+ *		odbc		- ODBC DBO driver
+ *
+ * You can add custom database drivers (or override existing drivers) by adding the
+ * appropriate file to app/models/datasources/dbo.  Drivers should be named 'dbo_x.php',
+ * where 'x' is the name of the database.
+ *
+ * persistent => true / false
+ * Determines whether or not the database should use a persistent connection
+ *
+ * connect =>
+ * ADOdb set the connect to one of these
+ *	(http://phplens.com/adodb/supported.databases.html) and
+ *	append it '|p' for persistent connection. (mssql|p for example, or just mssql for not persistent)
+ * For all other databases, this setting is deprecated.
+ *
+ * host =>
+ * the host you connect to the database.  To add a socket or port number, use 'port' => #
+ *
+ * prefix =>
+ * Uses the given prefix for all the tables in this database.  This setting can be overridden
+ * on a per-table basis with the Model::$tablePrefix property.
+ *
+ * schema =>
+ * For Postgres and DB2, specifies which schema you would like to use the tables in. Postgres defaults to
+ * 'public', DB2 defaults to empty.
+ *
+ * encoding =>
+ * For MySQL, MySQLi, Postgres and DB2, specifies the character encoding to use when connecting to the
+ * database.  Defaults to 'UTF-8' for DB2.  Uses database default for all others.
+ *
+ */
+class DATABASE_CONFIG {
+
+	var $default = array(
+		'driver' => 'mysql',
+		'persistent' => false,
+		'host' => 'localhost',
+		'login' => 'api',
+		'password' => 'dnflshfdlqslek',
+		'database' => 'api',
+		'prefix' => '',
+	);
+
+	var $test = array(
+		'driver' => 'mysql',
+		'persistent' => false,
+		'host' => 'localhost',
+		'login' => 'user',
+		'password' => 'password',
+		'database' => 'test_database_name',
+		'prefix' => '',
+	);
+}
+?>
Index: /projects/textcubeapi/trunk/app/config/database.php.default
===================================================================
--- /projects/textcubeapi/trunk/app/config/database.php.default (revision 580)
+++ /projects/textcubeapi/trunk/app/config/database.php.default (revision 580)
@@ -0,0 +1,103 @@
+<?php
+/* SVN FILE: $Id: database.php.default 7690 2008-10-02 04:56:53Z nate $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behaviour ofCake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7690 $
+ * @modifiedby		$LastChangedBy: nate $
+ * @lastmodified	$Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * In this file you set up your database connection details.
+ *
+ * @package		cake
+ * @subpackage	cake.config
+ */
+/**
+ * Database configuration class.
+ * You can specify multiple configurations for production, development and testing.
+ *
+ * driver => The name of a supported driver; valid options are as follows:
+ *		mysql 		- MySQL 4 & 5,
+ *		mysqli 		- MySQL 4 & 5 Improved Interface (PHP5 only),
+ *		sqlite		- SQLite (PHP5 only),
+ *		postgres	- PostgreSQL 7 and higher,
+ *		mssql		- Microsoft SQL Server 2000 and higher,
+ *		db2			- IBM DB2, Cloudscape, and Apache Derby (http://php.net/ibm-db2)
+ *		oracle		- Oracle 8 and higher
+ *		firebird	- Firebird/Interbase
+ *		sybase		- Sybase ASE
+ *		adodb-[drivername]	- ADOdb interface wrapper (see below),
+ *		odbc		- ODBC DBO driver
+ *
+ * You can add custom database drivers (or override existing drivers) by adding the
+ * appropriate file to app/models/datasources/dbo.  Drivers should be named 'dbo_x.php',
+ * where 'x' is the name of the database.
+ *
+ * persistent => true / false
+ * Determines whether or not the database should use a persistent connection
+ *
+ * connect =>
+ * ADOdb set the connect to one of these
+ *	(http://phplens.com/adodb/supported.databases.html) and
+ *	append it '|p' for persistent connection. (mssql|p for example, or just mssql for not persistent)
+ * For all other databases, this setting is deprecated.
+ *
+ * host =>
+ * the host you connect to the database.  To add a socket or port number, use 'port' => #
+ *
+ * prefix =>
+ * Uses the given prefix for all the tables in this database.  This setting can be overridden
+ * on a per-table basis with the Model::$tablePrefix property.
+ *
+ * schema =>
+ * For Postgres and DB2, specifies which schema you would like to use the tables in. Postgres defaults to
+ * 'public', DB2 defaults to empty.
+ *
+ * encoding =>
+ * For MySQL, MySQLi, Postgres and DB2, specifies the character encoding to use when connecting to the
+ * database.  Defaults to 'UTF-8' for DB2.  Uses database default for all others.
+ *
+ */
+class DATABASE_CONFIG {
+
+	var $default = array(
+		'driver' => 'mysql',
+		'persistent' => false,
+		'host' => 'localhost',
+		'login' => 'user',
+		'password' => 'password',
+		'database' => 'database_name',
+		'prefix' => '',
+	);
+
+	var $test = array(
+		'driver' => 'mysql',
+		'persistent' => false,
+		'host' => 'localhost',
+		'login' => 'user',
+		'password' => 'password',
+		'database' => 'test_database_name',
+		'prefix' => '',
+	);
+}
+?>
Index: /projects/textcubeapi/trunk/app/config/core.php
===================================================================
--- /projects/textcubeapi/trunk/app/config/core.php (revision 580)
+++ /projects/textcubeapi/trunk/app/config/core.php (revision 580)
@@ -0,0 +1,229 @@
+<?php
+/* SVN FILE: $Id: core.php 7690 2008-10-02 04:56:53Z nate $ */
+/**
+ * This is core configuration file.
+ *
+ * Use it to configure core behavior of Cake.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app.config
+ * @since			CakePHP(tm) v 0.2.9
+ * @version			$Revision: 7690 $
+ * @modifiedby		$LastChangedBy: nate $
+ * @lastmodified	$Date: 2008-10-02 00:56:53 -0400 (Thu, 02 Oct 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+/**
+ * CakePHP Debug Level:
+ *
+ * Production Mode:
+ * 	0: No error messages, errors, or warnings shown. Flash messages redirect.
+ *
+ * Development Mode:
+ * 	1: Errors and warnings shown, model caches refreshed, flash messages halted.
+ * 	2: As in 1, but also with full debug messages and SQL output.
+ * 	3: As in 2, but also with full controller dump.
+ *
+ * In production mode, flash messages redirect after a time interval.
+ * In development mode, you need to click the flash message to continue.
+ */
+	Configure::write('debug', 2);
+/**
+ * Application wide charset encoding
+ */
+	Configure::write('App.encoding', 'UTF-8');
+/**
+ * To configure CakePHP *not* to use mod_rewrite and to
+ * use CakePHP pretty URLs, remove these .htaccess
+ * files:
+ *
+ * /.htaccess
+ * /app/.htaccess
+ * /app/webroot/.htaccess
+ *
+ * And uncomment the App.baseUrl below:
+ */
+	//Configure::write('App.baseUrl', env('SCRIPT_NAME'));
+/**
+ * Uncomment the define below to use CakePHP admin routes.
+ *
+ * The value of the define determines the name of the route
+ * and its associated controller actions:
+ *
+ * 'admin' 		-> admin_index() and /admin/controller/index
+ * 'superuser' -> superuser_index() and /superuser/controller/index
+ */
+	//Configure::write('Routing.admin', 'admin');
+
+/**
+ * Turn off all caching application-wide.
+ *
+ */
+	//Configure::write('Cache.disable', true);
+/**
+ * Enable cache checking.
+ *
+ * If set to true, for view caching you must still use the controller
+ * var $cacheAction inside your controllers to define caching settings.
+ * You can either set it controller-wide by setting var $cacheAction = true,
+ * or in each action using $this->cacheAction = true.
+ *
+ */
+	//Configure::write('Cache.check', true);
+/**
+ * Defines the default error type when using the log() function. Used for
+ * differentiating error logging and debugging. Currently PHP supports LOG_DEBUG.
+ */
+	define('LOG_ERROR', 2);
+/**
+ * The preferred session handling method. Valid values:
+ *
+ * 'php'	 		Uses settings defined in your php.ini.
+ * 'cake'		Saves session files in CakePHP's /tmp directory.
+ * 'database'	Uses CakePHP's database sessions.
+ *
+ * To define a custom session handler, save it at /app/config/<name>.php.
+ * Set the value of 'Session.save' to <name> to utilize it in CakePHP.
+ *
+ * To use database sessions, execute the SQL file found at /app/config/sql/sessions.sql.
+ *
+ */
+	Configure::write('Session.save', 'php');
+/**
+ * The name of the table used to store CakePHP database sessions.
+ *
+ * 'Session.save' must be set to 'database' in order to utilize this constant.
+ *
+ * The table name set here should *not* include any table prefix defined elsewhere.
+ */
+	//Configure::write('Session.table', 'cake_sessions');
+/**
+ * The DATABASE_CONFIG::$var to use for database session handling.
+ *
+ * 'Session.save' must be set to 'database' in order to utilize this constant.
+ */
+	//Configure::write('Session.database', 'default');
+/**
+ * The name of CakePHP's session cookie.
+ */
+	Configure::write('Session.cookie', 'CAKEPHP');
+/**
+ * Session time out time (in seconds).
+ * Actual value depends on 'Security.level' setting.
+ */
+	Configure::write('Session.timeout', '120');
+/**
+ * If set to false, sessions are not automatically started.
+ */
+	Configure::write('Session.start', true);
+/**
+ * When set to false, HTTP_USER_AGENT will not be checked
+ * in the session
+ */
+	Configure::write('Session.checkAgent', true);
+/**
+ * The level of CakePHP security. The session timeout time defined
+ * in 'Session.timeout' is multiplied according to the settings here.
+ * Valid values:
+ *
+ * 'high'	Session timeout in 'Session.timeout' x 10
+ * 'medium'	Session timeout in 'Session.timeout' x 100
+ * 'low'		Session timeout in 'Session.timeout' x 300
+ *
+ * CakePHP session IDs are also regenerated between requests if
+ * 'Security.level' is set to 'high'.
+ */
+	Configure::write('Security.level', 'high');
+/**
+ * A random string used in security hashing methods.
+ */
+	Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUgjg23ubWwvniR2G0FgaC9mi');
+/**
+ * Compress CSS output by removing comments, whitespace, repeating tags, etc.
+ * This requires a/var/cache directory to be writable by the web server for caching.
+ * and /vendors/csspp/csspp.php
+ *
+ * To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use HtmlHelper::css().
+ */
+	//Configure::write('Asset.filter.css', 'css.php');
+/**
+ * Plug in your own custom JavaScript compressor by dropping a script in your webroot to handle the
+ * output, and setting the config below to the name of the script.
+ *
+ * To use, prefix your JavaScript link URLs with '/cjs/' instead of '/js/' or use JavaScriptHelper::link().
+ */
+	//Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');
+/**
+ * The classname and database used in CakePHP's
+ * access control lists.
+ */
+	Configure::write('Acl.classname', 'DbAcl');
+	Configure::write('Acl.database', 'default');
+/**
+ *
+ * Cache Engine Configuration
+ * Default settings provided below
+ *
+ * File storage engine.
+ *
+ * 	 Cache::config('default', array(
+ *		'engine' => 'File', //[required]
+ *		'duration'=> 3600, //[optional]
+ *		'probability'=> 100, //[optional]
+ * 		'path' => CACHE, //[optional] use system tmp directory - remember to use absolute path
+ * 		'prefix' => 'cake_', //[optional]  prefix every cache file with this string
+ * 		'lock' => false, //[optional]  use file locking
+ * 		'serialize' => true, [optional]
+ *	));
+ *
+ *
+ * APC (http://pecl.php.net/package/APC)
+ *
+ * 	 Cache::config('default', array(
+ *		'engine' => 'Apc', //[required]
+ *		'duration'=> 3600, //[optional]
+ *		'probability'=> 100, //[optional]
+ * 		'prefix' => Inflector::slug(APP_DIR) . '_', //[optional]  prefix every cache file with this string
+ *	));
+ *
+ * Xcache (http://xcache.lighttpd.net/)
+ *
+ * 	 Cache::config('default', array(
+ *		'engine' => 'Xcache', //[required]
+ *		'duration'=> 3600, //[optional]
+ *		'probability'=> 100, //[optional]
+ * 		'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
+ *		'user' => 'user', //user from xcache.admin.user settings
+ *      'password' => 'password', //plaintext password (xcache.admin.pass)
+ *	));
+ *
+ *
+ * Memcache (http://www.danga.com/memcached/)
+ *
+ * 	 Cache::config('default', array(
+ *		'engine' => 'Memcache', //[required]
+ *		'duration'=> 3600, //[optional]
+ *		'probability'=> 100, //[optional]
+ * 		'prefix' => Inflector::slug(APP_DIR) . '_', //[optional]  prefix every cache file with this string
+ * 		'servers' => array(
+ * 			'127.0.0.1:11211' // localhost, default port 11211
+ * 		), //[optional]
+ * 		'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
+ *	));
+ *
+ */
+	Cache::config('default', array('engine' => 'File'));
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/api.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/api.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/api.php (revision 580)
@@ -0,0 +1,61 @@
+<?php
+require_once 'class.exceptions.php';
+require_once 'class.latexrender.php';
+require_once 'lib.utils.php';
+
+// Configuration
+header("Content-Type: text/json-comment-filtered");
+$latexrender_path = '/data/www/api.textcube.org/root/latex_renderer';
+$latexrender_path_http = '/latex_renderer';
+
+// Processing the request
+try {
+	// TODO: API Key validation
+	$api_key = $_POST['key'];
+
+	// Retrieving the form data
+	$mode = $_POST['mode']; // validated at setMode()
+	$format = $_POST['format']; // validated at setFormat()
+	$packages = explode(',', $_POST['packages']); // validated at addPackage()
+	$transparent = isset($_POST['transparent']) ? true : false;
+	$size = $_POST['size']; // validated at setSize()
+	$formula = trim($_POST['formula']);
+
+	// Render it
+	$latex = new LatexRender($latexrender_path."/pictures", $latexrender_path_http."/pictures", $latexrender_path."/tmp");
+	$latex->setFormat($format);
+	foreach ($packages as $p)
+		if (!empty($p))
+			$latex->addPackage($p);
+	$latex->setMode($mode);
+	$latex->setSize($size);
+	$latex->setTransparent($transparent);
+	if (empty($formula))
+		throw new InvalidParametersError("Empty formula");
+	$result = $latex->render($formula);
+} catch (Exception $e) {
+	$json_error = array(
+		'result'=>'error',
+		'error_type'=>get_class($e),
+		'message'=>$e->getMessage()
+	);
+	echo json_encode($json_error);
+	exit;
+}
+
+// Pack the image into a JSON response and send it.
+$path = $latex->getPicturePath() . '/' . $result['filename'];
+$json_result = array(
+	'result'=>'ok',
+	'format'=>'image/'.$format,
+	'sizeX'=>$result['size_x'],
+	'sizeY'=>$result['size_y'],
+	'content'=>base64_encode(file_get_contents($path, FILE_BINARY))
+);
+$output = json_encode($json_result);
+
+header("Content-Length: ".count($output));
+echo $output;
+
+unlink($path);
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/tmp/.log
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/tmp/.log (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/tmp/.log (revision 580)
@@ -0,0 +1,22 @@
+This is TeX, Version 3.14159 (Web2C 7.4.5) (format=latex 2007.11.9)  21 SEP 2008 13:42
+**.tex
+(/usr/share/texmf/tex/latex/tools/.tex
+LaTeX2e <2001/06/01>
+Babel <v3.7h> and hyphenation patterns for american, french, german, ngerman, n
+ohyphenation, loaded.
+File ignored)
+! Emergency stop.
+<*> .tex
+        
+*** (job aborted, no legal \end found)
+
+ 
+Here is how much of TeX's memory you used:
+ 4 strings out of 95847
+ 111 string characters out of 1194789
+ 44507 words of memory out of 1000001
+ 3034 multiletter control sequences out of 10000+50000
+ 3640 words of font info for 14 fonts, out of 500000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 5i,0n,1p,84b,7s stack positions out of 1500i,500n,5000p,200000b,5000s
+No pages of output.
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/example.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/example.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/example.php (revision 580)
@@ -0,0 +1,68 @@
+<?php
+/**
+ * LaTeX Rendering Class - Simple Usage Example
+ * Copyright (C) 2003  Benjamin Zeiss <zeiss@math.uni-goettingen.de>
+ *
+ * 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
+ * --------------------------------------------------------------------
+ * @author Benjamin Zeiss <zeiss@math.uni-goettingen.de>
+ * @version v0.8
+ * @package latexrender
+ *
+ */
+	// the final image is shown on the page using
+	// echo latex_content($text);
+
+    // this is just an example page
+    echo "<html><title>LatexRender Demo</title>
+    <head><script language=\"JavaScript\" type=\"text/javascript\">
+	function addtags() {
+		if (document.selection.createRange().text!='') {
+	  		document.selection.createRange().text = '[tex]'+document.selection.createRange().text+'[/tex]';
+	  	}
+	}//--></script>
+	<style type=\"text/css\">
+	img { vertical-align:middle; }
+	</style>
+	</head>";
+    echo "<body bgcolor='lightgrey'><center><h3>LatexRender Demo</h3>";
+    echo "<font size=-1><i>Add tags around text you want to convert to an image<br>
+    or press the button to add them around highlighted text</i></font>";
+
+    echo "<form method='post'>";
+    echo "<input onclick=\"addtags()\" type=\"button\" value=\"Add TeX tags\" name=\"btnCopy\"><br><br>";
+	echo "<textarea name='latex_formula' rows=8 cols=50>";
+
+    if (isset($_POST['latex_formula'])) {
+        echo htmlentities($_POST['latex_formula']);
+    } else {
+        echo "Example Text:\nThis is just text but [tex]$\\sqrt{2}$[/tex] should be shown as an image and so should [tex]$\\frac{\\pi}{2}$[/tex].
+			\nAnother formula is [tex]\\begin{displaymath}\\sum_{a=1}^{n}\\left(\\frac{\\color{blue}a^2 + b^2 - c^2}{\\log 2}\\right) \\sqrt{\\color{red}\\alpha\\pi}\\end{displaymath}[/tex]";
+    }
+
+    echo "</textarea>";
+    echo "<br><br><input type='submit' value='Render'>";
+    echo "</form>";
+
+    if (isset($_POST['latex_formula'])) {
+		$text=$_POST['latex_formula'];
+        echo "<u>Result</u><br><br>";
+        // now convert and show the image
+		include_once("latex.php");
+     	echo nl2br(latex_content($text));
+    }
+
+    echo "</center></body></html>";
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/RPM-GPG-KEY.art.txt
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/RPM-GPG-KEY.art.txt (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/RPM-GPG-KEY.art.txt (revision 580)
@@ -0,0 +1,24 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.1 (GNU/Linux)
+
+mQGiBEGP+skRBACyZz7muj2OgWc9FxK+Hj7tWPnrfxEN+0PE+n8MtqH+dxwQpMTd
+gDpOXxJa45GM5pEwB6CFSFK7Fb/faniF9fDbm1Ga7MpBupIBYLactkoOTZMuTlGB
+T0O5ha4h26YLqFfQOtlEi7d0+BDDdfHRQw3o67ycgRnLgYSA79DISc3MywCgk2TR
+yd5sRfZAG23b4EDl+D0+oaMEAK73J7zuxf6F6V5EaxLd/w4JVB2xW0Glcn0fACOe
+8FV9lzcZuo2xPpdGuyj02f/xlqvEav3XqTfFU2no61mA2pamaRNhlo+CEfGc7qde
+/1twfSgOYqzeCx7+aybyPo8Th41b80FT19mfkjBf6+5NbUHffRabFFh1FmcPVNBn
+F3FoA/95nRIzqDMItdTRitaZn02dIGNjdwllBD75bSVEvaR9O5hjBo0VMc25DB7f
+DM2qEO52wCQbAKw9zFC284ekZVDaK4aHYt7iobHaqJEpKHgsDut5WWuMiSLR+SsF
+aBHIZ9HvrKWLSUQKHU6A1Hva0P0r3GnoCMc/VCVfrLl721SjPbQzQXRvbWljIFJv
+Y2tldCBUdXJ0bGUgPGFkbWluQGF0b21pY3JvY2tldHR1cnRsZS5jb20+iFkEExEC
+ABkFAkGP+skECwcDAgMVAgMDFgIBAh4BAheAAAoJEDKpURRevSdEzcQAn1hSHqTO
+jwv/z/picpOnR+mgycwHAKCBex2ciyXo5xeaQ9w7OMf7Jsmon7kBDQRBj/rMEAQA
+6JvRndqE4koK0e49fUkICm1X0ZEzsVg9VmUW+Zft5guCRxmGlYTmtlC7oJCToRP/
+m/xH5uIevGiJycRKB0Ix+Csl6f9QuTkQ7tSTHcaIKbI3tL1x6CCBoWeTGYaOJlvk
+ubrmajiMFaBfopLH2firoSToDGoUvv4e7bImIHEgNr8AAwUEAND0YR9DOEZvc+Lq
+Ta/PQyxkdZ75o+Ty/O64E3OmO1Tuw2ciSQXCcwrbrMSE6EHHetxtGCnOdkjjjtmH
+AnxsxdONv/EJuQmLcoNcsigZZ4tfRdmtXgcbnOmXBgmy1ea1KvWcsmecNSAMJHwR
+7vDDKzbj4mSmudzjapHeeOewFF10iEYEGBECAAYFAkGP+swACgkQMqlRFF69J0Sq
+nQCfa/q9Y/oY4dOTGj6MsdmRIQkKZhYAoIscjinFwTru4FVi2MIEzUUMToDK
+=NOIx
+-----END PGP PUBLIC KEY BLOCK-----
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/latex.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/latex.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/latex.php (revision 580)
@@ -0,0 +1,80 @@
+<?php
+/**
+ * LaTeX Rendering Class - Calling function
+ * Copyright (C) 2003  Benjamin Zeiss <zeiss@math.uni-goettingen.de>
+ *
+ * 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
+ * --------------------------------------------------------------------
+ * @author Benjamin Zeiss <zeiss@math.uni-goettingen.de>
+ * @version v0.8
+ * @package latexrender
+ * Revised by Steve Mayer
+ * This file can be included in many PHP programs by using something like (see example.php to see how it can be used)
+ * 		include_once('/full_path_here_to/latexrender/latex.php');
+ * 		$text_to_be_converted=latex_content($text_to_be_converted);
+ * $text_to_be_converted will then contain the link to the appropriate image
+ * or an error code as follows (the 500 values can be altered in class.latexrender.php):
+ * 	0 OK
+ * 	1 Formula longer than 500 characters
+ * 	2 Includes a blacklisted tag
+ * 	3 (Not used) Latex rendering failed
+ * 	4 Cannot create DVI file
+ * 	5 Picture larger than 500 x 500 followed by x x y dimensions
+ * 	6 Cannot copy image to pictures directory
+ */
+
+ function latex_content($text) {
+    // --------------------------------------------------------------------------------------------------
+    // adjust this to match your system configuration
+    $latexrender_path = "/data/www/api.textcube.org/root/latex_renderer";
+    $latexrender_path_http = "/latex_renderer";
+
+    // --------------------------------------------------------------------------------------------------
+
+    include_once($latexrender_path."/class.latexrender.php");
+
+    preg_match_all("#\[tex\](.*?)\[/tex\]#si",$text,$tex_matches);
+
+    $latex = new LatexRender($latexrender_path."/pictures",$latexrender_path_http."/pictures",$latexrender_path."/tmp");
+
+    for ($i=0; $i < count($tex_matches[0]); $i++) {
+        $pos = strpos($text, $tex_matches[0][$i]);
+        $latex_formula = $tex_matches[1][$i];
+		
+	// if you use htmlArea to input the text then uncomment the next 6 lines
+	//	$latex_formula = str_replace("&amp;","&",$latex_formula);
+	//	$latex_formula = str_replace("&#38;","&",$latex_formula);
+	//	$latex_formula = str_replace("&nbsp;"," ",$latex_formula);
+	//	$latex_formula = str_replace("<BR>","",$latex_formula);
+	//	$latex_formula = str_replace("<P>","",$latex_formula);
+	//	$latex_formula = str_replace("</P>","",$latex_formula);
+
+        $url = $latex->getFormulaURL($latex_formula);
+
+		$alt_latex_formula = htmlentities($latex_formula, ENT_QUOTES);
+		$alt_latex_formula = str_replace("\r","&#13;",$alt_latex_formula);
+		$alt_latex_formula = str_replace("\n","&#10;",$alt_latex_formula);
+
+        if ($url != false) {
+            $text = substr_replace($text, "<img src='".$url."' title='".$alt_latex_formula."' alt='".$alt_latex_formula."' align=absmiddle>",$pos,strlen($tex_matches[0][$i]));
+        } else {
+            $text = substr_replace($text, "[Unparseable or potentially dangerous latex formula. Error $latex->_errorcode $latex->_errorextra]",$pos,strlen($tex_matches[0][$i]));
+        }
+
+    }
+    return $text;
+}
+
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/test.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/test.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/test.php (revision 580)
@@ -0,0 +1,11 @@
+<?php
+$X['a'] = 1;
+try {
+	if ($X['b'] == 'a')
+		echo 'ok';
+	else
+		echo 'not ok';
+} catch (Exception $e) {
+	echo $e->getMessage();
+}
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/class.latexrender.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/class.latexrender.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/class.latexrender.php (revision 580)
@@ -0,0 +1,399 @@
+<?php
+/**
+ * LaTeX Rendering Class
+ * Copyright (C) 2003  Benjamin Zeiss <zeiss@math.uni-goettingen.de>
+ *
+ * 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
+ * --------------------------------------------------------------------
+ * @author Benjamin Zeiss <zeiss@math.uni-goettingen.de>
+ * @version v0.8
+ * @package latexrender
+ *
+ */
+require_once 'class.exceptions.php';
+require_once 'lib.utils.php';
+
+class LatexRender {
+
+	// ====================================================================================
+	// Variable Definitions
+	// ====================================================================================
+	private $_picture_path = "./pictures";
+	private $_picture_path_httpd = "http://api.textcube.org/latex_renderer/pictures";
+	private $_tmp_dir = "./tmp";
+	// i was too lazy to write mutator functions for every single program used
+	// just access it outside the class or change it here if nescessary
+	private $_latex_path = "/usr/bin/latex";
+	private $_dvips_path = "/usr/bin/dvips";
+	private $_convert_path = "/usr/bin/convert";
+	private $_gs_path = "/usr/bin/gs";
+	private $_identify_path="/usr/bin/identify";
+	private $_formula_density = 120;
+	private $_xsize_limit = 1000;
+	private $_ysize_limit = 1000;
+	private $_string_length_limit = 1024;
+	private $_font_size = 10;
+	private $_latexclass = "article"; //install extarticle class if you wish to have smaller font sizes
+	private $_tmp_filename;
+	private $_image_format = "png"; //change to png if you prefer
+	// this most certainly needs to be extended. in the long term it is planned to use
+	// a positive list for more security. this is hopefully enough for now. i'd be glad
+	// to receive more bad tags !
+	private $_latex_tags_blacklist = array(
+		"include","def","command","loop","repeat","open","toks","output","input","\\end{displaymath}",
+		"catcode","name","^^",
+		"\\every","\\errhelp","\\errorstopmode","\\scrollmode","\\nonstopmode","\\batchmode",
+		"\\read","\\write","csname","\\newhelp","\\uppercase", "\\lowercase","\\relax","\\aftergroup",
+		"\\afterassignment","\\expandafter","\\noexpand","\\special"
+		);
+	private $_supported_packages = array(
+		'amsmath','amssymb','amsfonts','color', // default installed & included packages
+		);
+
+	private $_errorcode = 0;
+	private $_errorextra = "";
+	private $_mode = '$';
+	private $_transparent = false;
+	private $_size = 'normal';
+	private $_extra_packages = array();
+
+
+	// ====================================================================================
+	// constructor
+	// ====================================================================================
+
+	/**
+	 * Initializes the class
+	 *
+	 * @param string path where the rendered pictures should be stored
+	 * @param string same path, but from the httpd chroot
+	 */
+	function __construct($picture_path, $picture_path_httpd, $tmp_dir) {
+		$this->_picture_path = $picture_path;
+		$this->_picture_path_httpd = $picture_path_httpd;
+		$this->_tmp_dir = $tmp_dir;
+		$this->_tmp_filename = md5(mt_rand() + time());
+	}
+
+	// ====================================================================================
+	// public functions
+	// ====================================================================================
+
+	public function addPackage($name) {
+		if (array_search($name, $this->_supported_packages) === FALSE)
+			throw new UnsupportedPackageError("Unsupported package: $name");
+		if (array_search($name, $this->_extra_packages) === FALSE)
+			array_push($this->_extra_packages, $name);
+	}
+
+	public function setMode($mode) {
+		switch ($mode) {
+		case 'displaymath':
+		case 'eqnarray':
+		case '$':
+			$this->_mode = $mode;
+			break;
+		default:
+			throw new InvalidParametersError("Unsupported mode: $mode");
+		}
+	}
+
+	public function setSize($size) {
+		if (!in($size, array('scriptsize', 'footnotesize', 'small', 'normalsize', 'large', 'Large', 'huge', 'Huge')))
+			throw new InvalidParametersError("Unsupported size: $size");
+		$this->_size = $size;
+	}
+
+	public function setTransparent($flag) {
+		if (!is_bool($flag))
+			throw new InvalidParametersError("Invalid type: ".gettype($flag)." for transparency option");
+		$this->_transparent = $flag;
+	}
+
+	public function setFormat($format) {
+		$f = strtolower($format);
+		switch ($f) {
+		case 'png':
+		case 'gif':
+			$this->_image_format = $f;
+			break;
+		default:
+			throw new UnsupportedFormatError("Unsupported format: $format");
+		}
+	}
+
+	/**
+	 * Picture path Mutator function
+	 *
+	 * @param string sets the current picture path to a new location
+	 */
+	public function setPicturePath($name) {
+		$this->_picture_path = $name;
+	}
+
+	/**
+	 * Picture path Mutator function
+	 *
+	 * @returns the current picture path
+	 */
+	public function getPicturePath() {
+		return $this->_picture_path;
+	}
+
+	/**
+	 * Picture path HTTPD Mutator function
+	 *
+	 * @param string sets the current httpd picture path to a new location
+	 */
+	public function setPicturePathHTTPD($name) {
+		$this->_picture_path_httpd = $name;
+	}
+
+	/**
+	 * Picture path HTTPD Mutator function
+	 *
+	 * @returns the current picture path
+	 */
+	public function getPicturePathHTTPD() {
+		return $this->_picture_path_httpd;
+	}
+
+	/**
+	 * Tries to match the LaTeX Formula given as argument against the
+	 * formula cache. If the picture has not been rendered before, it'll
+	 * try to render the formula and drop it in the picture cache directory.
+	 *
+	 * @param string formula in LaTeX format
+	 * @returns the webserver based URL to a picture which contains the
+	 * requested LaTeX formula. If anything fails, the resultvalue is false.
+	 *
+	 * DEPRECATED: Because cache is done locally, all image files are removed
+	 *             immediately after sending them to clients.
+	 */
+	public function getFormulaURL($latex_formula) {
+		// circumvent certain security functions of web-software which
+		// is pretty pointless right here
+		$latex_formula = preg_replace("/&gt;/i", ">", $latex_formula);
+		$latex_formula = preg_replace("/&lt;/i", "<", $latex_formula);
+
+		$formula_hash = md5($latex_formula);
+
+		$filename = $formula_hash.".".$this->_image_format;
+		$full_path_filename = $this->getPicturePath()."/".$filename;
+
+		// security checks assume correct formula, let's render it
+		if ($this->render($latex_formula)) {
+			return $this->getPicturePathHTTPD()."/".$filename;
+		} else {
+			// uncomment if required
+			$this->_errorcode = 3;
+			return false;
+		}
+	}
+
+	// ====================================================================================
+	// private functions
+	// ====================================================================================
+
+	/**
+	 * wraps a minimalistic LaTeX document around the formula and returns a string
+	 * containing the whole document as string. Customize if you want other fonts for
+	 * example.
+	 *
+	 * @param string formula in LaTeX format
+	 * @returns minimalistic LaTeX document containing the given formula
+	 */
+	private function wrap_formula($latex_formula) {
+		$string  = "\\documentclass[{$this->_font_size}pt]{".$this->_latexclass."}\n";
+		$string .= "\\usepackage[latin1]{inputenc}\n";
+		$string .= "\\usepackage{newcent}\n";
+		//$string .= "\\usepackage{dhucs}\n";
+		$string .= "\\usepackage{amsmath}\n";
+		$string .= "\\usepackage{amsfonts}\n";
+		$string .= "\\usepackage{amssymb}\n";
+		$string .= "\\usepackage{color}\n";
+		foreach ($this->_extra_packages as $package) {
+			$string .= "\\usepackage{".$package."}\n";
+		}
+		$string .= "\\begin{document}\n";
+		$string .= "\\pagestyle{empty}\n";
+		switch ($this->_mode) {
+		case '$':
+			if (isset($this->_size))
+				$string .= "\\".$this->_size;
+			$string .= '$'.$latex_formula."$\n";
+			break;
+		case 'eqnarray':
+			$latex_formula = preg_replace("/\\\\\\\\/", " \\\\nonumber \\\\\\\\ ", $latex_formula) . " \\nonumber";
+			$string .= "\\{$this->_size}\\begin{eqnarray}".$latex_formula."\\end{eqnarray}\n";
+			break;
+		case 'displaymath':
+			$string .= "\\{$this->_size}\\begin{displaymath}".$latex_formula."\\end{displaymath}\n";
+			break;
+		}
+		$string .= "\\end{document}\n";
+		//echo nl2br(htmlentities($string));
+
+		return $string;
+	}
+
+	/**
+	 * returns the dimensions of a picture file using 'identify' of the
+	 * imagemagick tools. The resulting array can be adressed with either
+	 * $dim[0] / $dim[1] or $dim["x"] / $dim["y"]
+	 *
+	 * @param string path to a picture
+	 * @returns array containing the picture dimensions
+	 */
+	private function getDimensions($filename) {
+		$output=exec($this->_identify_path." ".$filename);
+		$result=explode(' ',$output);
+		if ($result[1] == 'GIF') {
+			// GIF images have animation sequences, so the actual whole size is stored in frame information.
+			// Normal size field containes only trimmed frame size.
+			$dim_part = explode('+',$result[3]);
+			$dim = explode('x', $dim_part[0]);
+		} else
+			$dim = explode('x',$result[2]);
+		$dim['x'] = intval($dim[0]);
+		$dim['y'] = intval($dim[1]);
+
+		return $dim;
+	}
+
+	/**
+	 * Renders a LaTeX formula by the using the following method:
+	 *	- write the formula into a wrapped tex-file in a temporary directory
+	 *	  and change to it
+	 *	- Create a DVI file using latex (tetex)
+	 *	- Convert DVI file to Postscript (PS) using dvips (tetex)
+	 *	- convert, trim and add transparancy by using 'convert' from the
+	 *	  imagemagick package.
+	 *	- Save the resulting image to the picture cache directory using an
+	 *	  md5 hash as filename. Already rendered formulas can be found directly
+	 *	  this way.
+	 *
+	 * @param string LaTeX formula
+	 * @returns the result filename if the picture has been successfully saved to the picture
+	 *			cache directory
+	 */
+	public function render($latex_formula) {
+
+		// security filter: reject too long formulas
+		if (strlen($latex_formula) > $this->_string_length_limit) {
+			throw new TooLongExpressionError(strlen($latex_formula)."/{$this->_string_length_limit}");
+		}
+
+		// security filter: try to match against LaTeX-Tags Blacklist
+		for ($i=0;$i<sizeof($this->_latex_tags_blacklist);$i++) {
+			if (stristr($latex_formula,$this->_latex_tags_blacklist[$i]))
+				throw new InvalidTeXCommandError();
+		}
+
+		$latex_document = $this->wrap_formula($latex_formula);
+
+		$current_dir = getcwd();
+		chdir($this->_tmp_dir);
+
+		// create temporary latex file
+		$fp = fopen("{$this->_tmp_dir}/{$this->_tmp_filename}.tex", "w");
+		fputs($fp,$latex_document);
+		fclose($fp);
+
+		// create temporary dvi file
+		$command = "{$this->_latex_path} --interaction=nonstopmode {$this->_tmp_filename}.tex";
+		$status_code = exec($command);
+
+		if (!$status_code) { $this->cleanTemporaryDirectory(); chdir($current_dir); $this->_errorcode = 4; return false; }
+
+		// convert dvi file to postscript using dvips
+		$command = "{$this->_dvips_path} -E {$this->_tmp_filename}.dvi -o {$this->_tmp_filename}.ps";
+		$status_code = exec($command);
+
+		// imagemagick convert ps to image and trim picture
+		switch ($this->_image_format) {
+		case 'gif':
+		default:
+			// Cut out the white background, but semi-transparent pixels will remain gray-scale opaque.
+			$command = "{$this->_convert_path} -density {$this->_formula_density} -trim ";
+			if ($this->_transparent)
+				$command .= "-transparent \"#FFFFFF\" ";
+			$command .= "{$this->_tmp_filename}.ps {$this->_tmp_filename}.{$this->_image_format}";
+			break;
+		case 'png':
+			// Uses alpha-channel to preserve semi-transparent pixels
+			if ($this->_transparent)
+				$command = "{$this->_gs_path} -dNOPAUSE -dBATCH -sDEVICE=pngalpha -r{$this->_formula_density} -dEPSCrop -sOutputFile={$this->_tmp_filename}.{$this->_image_format} {$this->_tmp_filename}.ps";
+			else
+				$command = "{$this->_convert_path} -density {$this->_formula_density} -trim {$this->_tmp_filename}.ps {$this->_tmp_filename}.{$this->_image_format}";
+			break;
+		}
+
+		$status_code = exec($command);
+
+		// test picture for correct dimensions
+		$dim = $this->getDimensions("{$this->_tmp_filename}.{$this->_image_format}");
+
+		if ( ($dim["x"] > $this->_xsize_limit) or ($dim["y"] > $this->_ysize_limit)) {
+			$this->cleanTemporaryDirectory();
+			chdir($current_dir);
+			throw new SizeLimitExceededError("{$dim['x']}x{$dim['y']} / {$this->_xsize_limit}x{$this->_ysize_limit}");
+		}
+
+		// copy temporary formula file to cahed formula directory
+		$log = file_get_contents("{$this->_tmp_filename}.log");
+		$latex_hash = md5($latex_formula);
+		$filename = $this->getPicturePath()."/{$latex_hash}.{$this->_image_format}";
+
+		$status_code = copy("{$this->_tmp_filename}.{$this->_image_format}", $filename);
+
+		$this->cleanTemporaryDirectory();
+
+		if (!$status_code) {
+			chdir($current_dir);
+			$matches = array();
+			preg_match("/(LaTeX Error: .*?)\\n/i", $log, $matches);
+			throw new GeneralLaTeXError("Image was not generated. ({$matches[1]})");
+		}
+		chdir($current_dir);
+
+		return array(
+			'filename'=>"{$latex_hash}.{$this->_image_format}",
+			'size_x'=>$dim['x'],
+			'size_y'=>$dim['y']
+		);
+	}
+
+	/**
+	 * Cleans the temporary directory
+	 */
+	private function cleanTemporaryDirectory() {
+		$current_dir = getcwd();
+		chdir($this->_tmp_dir);
+
+		@unlink($this->_tmp_dir."/".$this->_tmp_filename.".tex");
+		@unlink($this->_tmp_dir."/".$this->_tmp_filename.".aux");
+		@unlink($this->_tmp_dir."/".$this->_tmp_filename.".log");
+		@unlink($this->_tmp_dir."/".$this->_tmp_filename.".dvi");
+		@unlink($this->_tmp_dir."/".$this->_tmp_filename.".ps");
+		@unlink($this->_tmp_dir."/".$this->_tmp_filename.".".$this->_image_format);
+
+		chdir($current_dir);
+	}
+
+}
+
+/* vim: set noet ts=4 sts=4 sw=4: */
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/class.exceptions.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/class.exceptions.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/class.exceptions.php (revision 580)
@@ -0,0 +1,11 @@
+<?php
+class InvalidParametersError extends Exception {};
+class RequestLimitExceededError extends Exception {};
+class APIKeyError extends Exception {};
+class SizeLimitExceededError extends Exception {};
+class UnsupportedPackageError extends Exception {};
+class UnsupportedFormatError extends Exception {};
+class TooLongExpressionError extends Exception {};
+class InvliadTeXCommandError extends Exception {};
+class GeneralLaTeXError extends Exception {};
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/lib.utils.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/lib.utils.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/lib.utils.php (revision 580)
@@ -0,0 +1,14 @@
+<?php
+// Helper Functions
+
+function array_get($array, $key, $default = null) {
+	if (empty($array[$key]))
+		return $default;
+	return $array[$key];
+}
+
+function in($value, $array) {
+	return array_search($value, $array) !== FALSE;
+}
+
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/api-test.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/api-test.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/api-test.php (revision 580)
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+	<title>API Interface Test</title>
+	<script type="text/javascript" src="http://www.google.com/jsapi"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+google.load("dojo", "1.1.1");
+google.setOnLoadCallback(function() {
+	dojo.provide('dojo.string');
+	// removed after dojo 0.4.x, so copied from http://trac.dojotoolkit.org/browser/trunk/src/string/extras.js?rev=3266#L88
+	dojo.string.escapeXml = function(str, noSingleQuotes) {
+			str = str.replace(/&/gm, "&amp;").replace(/</gm, "&lt;")
+					.replace(/>/gm, "&gt;").replace(/\"/gm, "&quot;");
+			if(!noSingleQuotes) { str = str.replace(/\'/gm, "&#39;"); }
+			return str;
+	}
+	var f = dojo.byId('testForm');
+	var submitFunc = function(ev) {
+		ev.preventDefault();
+		dojo.byId('msg').innerHTML = 'loading...';
+		dojo.byId('testSubmit').enabled = false;
+		dojo.xhrPost({
+			url: 'api.php',
+			handleAs: 'json',
+			form: 'testForm',
+			load: function(response, args) {
+				if (response.result == 'ok') {
+					var img = dojo.byId('result');
+					// TODO: We need workaround for IE6 and IE7.
+					img.src = 'data:' + response.format + ';base64,' + response.content;
+					img.width = response.sizeX; img.height = response.sizeY;
+					dojo.byId('msg').innerHTML = 'Complete : (' + response.sizeX + 'x' + response.sizeY + ')';
+				} else {
+					dojo.byId('msg').innerHTML = 'Error : &lt;' + response.error_type + '&gt; ' + dojo.string.escapeXml(response.message);
+				}
+				dojo.byId('testSubmit').enabled = true;
+			},
+			error: function(response, args) {
+				alert('AJAX Error : ' + response);
+				dojo.byId('loadingMsg').innerHTML = 'Error during AJAX request.';
+				dojo.byId('testSubmit').enabled = true;
+			}
+		});
+		return false;
+	};
+	dojo.connect(f, 'onsubmit', submitFunc);
+});
+	//]]>
+	</script>
+	<style type="text/css">
+body { font-family: Trebuchet MS, Verdana, sans-serif; font-size: 0.85em; }
+label { font-weight: bold; }
+.desc { font-size: 0.9em; color:gray; }
+#msg { color: #736998; }
+#result-container { background: #f2f2f2 url(slash01_10x10.png) repeat; width: 800px; height: 500px; padding: 0;}
+	</style>
+</head>
+<body>
+<form id="testForm" method="post" action="api.php">
+<p><label>API Key : <input type="text" name="key" value="TESTING" /></label></p>
+<p>
+	<label>Extra packages : <input type="text" name="packages" value="" /></label>
+	<br/><span class="desc">Separate multiple packages with comma. Default packages are amsmath, amsfonts, amssymb, color.</span>
+</p>
+<p>
+	<label>Mode : 
+	<select name="mode">
+		<option value="$">Inline math</option>
+		<option value="displaymath" selected="selected">Display math</option>
+		<option value="eqnarray">Eqn. Array</option>
+	</select>
+	</label>
+</p>
+<p>
+	<label>Transparent Background : <input type="checkbox" name="transparent" value="true" checked="checked" /></label>
+	<br/><span class="desc">If you use PNG format, this will generate 32bit ARGB PNG to preserve semi-transparent pixels correctly.</span>
+</p>
+<p><label>Size :
+	<select name="size">
+		<option value="scriptsize">Very small</option>
+		<option value="footnotesize">Smaller</option>
+		<option value="small">Small</option>
+		<option value="normalsize" selected="selected">Normal</option>
+		<option value="large">Large</option>
+		<option value="Large">Larger</option>
+		<option value="huge">Very large</option>
+		<option value="Huge">Largest</option>
+	</select>
+</label></p>
+<p><label>Format : 
+	<select name="format">
+		<option value="gif">GIF</option>
+		<option value="png" selected="selected">PNG</option>
+	</select>
+</label></p>
+<p><label>Formula : <textarea name="formula" rows="5" cols="40"><?php echo htmlentities(''); ?></textarea></label></p>
+<p><input type="submit" id="testSubmit" value="Submit" /></p>
+</form>
+<p id="msg">Test your formula.</p>
+<div id="result-container">
+	<img id="result" src="" />
+</div>
+</body>
+</html>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer/index.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer/index.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer/index.php (revision 580)
@@ -0,0 +1,7 @@
+<html>
+<body>
+	<center>
+		You are not supposed to access this directory
+	</center>
+</body>
+</html>
Index: /projects/textcubeapi/trunk/app/controllers/keys_controller.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/keys_controller.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/keys_controller.php (revision 580)
@@ -0,0 +1,5 @@
+<?php
+class KeysController extends AppController {
+	var $uses = array('User', 'Key');
+	//var $scaffold;
+}
Index: /projects/textcubeapi/trunk/app/controllers/service_controller.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/service_controller.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/service_controller.php (revision 580)
@@ -0,0 +1,9 @@
+<?php
+class ServiceController extends AppController {
+	var $uses = array();
+
+	function index() {
+		$this->pageTitle = 'Textcube API Service';
+	}
+}
+?>
Index: /projects/textcubeapi/trunk/app/controllers/users_controller.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/users_controller.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/users_controller.php (revision 580)
@@ -0,0 +1,6 @@
+<?php
+class UsersController extends AppController {
+	var $uses = array('User', 'Key');
+	//var $scaffold;
+}
+?>
Index: /projects/textcubeapi/trunk/app/controllers/latex_renderer_controller.php
===================================================================
--- /projects/textcubeapi/trunk/app/controllers/latex_renderer_controller.php (revision 580)
+++ /projects/textcubeapi/trunk/app/controllers/latex_renderer_controller.php (revision 580)
@@ -0,0 +1,93 @@
+<?php
+class LatexRendererController extends AppController {
+	var $uses = array('Key');
+	var $components = array('RequestHandler');
+	var $helpers = array('Html', 'Javascript');
+	//var $scaffold;
+	
+	public function index() {
+		$this->pageTitle = 'LaTeX Render API: Index';
+	}
+
+	public function test() {
+		$this->pageTitle = 'LaTeX Render API: Test';
+	}
+
+	public function query($protocol = 'json') {
+		require_once 'latex_renderer/class.latexrender.php';
+		App::import('Vendor', 'commonDatetime', array('file' => 'common.datetime.php'));
+
+		try {
+			// Validate key
+			// TODO: 이것을 따로 모듈화하여 다른 서비스에서도 중복 작성하지 않고 불러다 쓸 수 있도록 한다.
+			$api_key = $this->params['form']['key'];
+			$this->log("API Query for LaTeX Renderer with key=$api_key from {$_SERVER['HTTP_REFERER']}", LOG_DEBUG);
+			$qresult = $this->Key->findByKeyAndService($api_key, 'latex_renderer');
+			if (empty($qresult))
+				throw new Exception("No such key.");
+			// TODECIDE: Do more strict domain validation? (including reverse-resolving from IP)
+			if (preg_match("@^(?:http|https)://{$qresult['Key']['domain']}@i", $_SERVER['HTTP_REFERER']) != 1)
+				throw new Exception("Invalid domain.");
+			if ($qresult['Key']['query_count'] >= $qresult['Key']['max_query_per_day'])
+				throw new Exception("Query limit exceeded ({$qresult['Key']['max_query_per_day']}).");
+
+			// Increment query count and update last query time
+			$this->Key->id = $qresult['Key']['id'];
+			$last_query = mysqltime2timestamp($qresult['Key']['last_query']);
+			if ($last_query != 0 && isYesterday($last_query))
+				$this->Key->saveField('query_count', 0);
+			else
+				$this->Key->saveField('query_count', $qresult['Key']['query_count'] + 1);
+			$this->Key->saveField('last_query', date('Y-m-d H:i:s', time()));
+			
+			// Read parameters
+			$mode = $this->params['form']['mode']; // validated at setMode()
+			$format = $this->params['form']['format']; // validated at setFormat()
+			$packages = explode(',', $this->params['form']['packages']); // validated at addPackage()
+			$transparent = isset($this->params['form']['transparent']) ? true : false;
+			$size = $this->params['form']['size']; // validated at setSize()
+			$formula = trim($this->params['form']['formula']);
+
+			$path_temp = APP.'tmp/latex_renderer/intermediate';
+			$path_picture = APP.'tmp/latex_renderer/result';
+			
+			// Do rendering
+			$latex = new LatexRender($path_picture, null, $path_temp);
+			$latex->setFormat($format);
+			foreach ($packages as $p)
+				if (!empty($p))
+					$latex->addPackage($p);
+			$latex->setMode($mode);
+			$latex->setSize($size);
+			$latex->setTransparent($transparent);
+			if (empty($formula))
+				throw new Exception("Empty formula");
+			$result = $latex->render($formula);
+
+			$path_result = $path_picture.DS.$result['filename'];
+			$result = array(
+				'result'=>'ok',
+				'format'=>'image/'.$format,
+				'sizeX'=>$result['size_x'],
+				'sizeY'=>$result['size_y'],
+				'content'=>base64_encode(file_get_contents($path_result))
+			);
+
+			unlink($path_result);
+
+		} catch (Exception $e) {
+			$result = array(
+				'result'=>'error',
+				'error_type'=>get_class($e),
+				'message'=>$e->getMessage()
+			);
+		}
+
+		// View will perform the works needed for each protocol.
+		$this->set('protocol', $protocol);
+		$this->set('result', $result);
+		Configure::write('debug', 0); // 실행 시간 표시해주는 html comment 제거
+	}
+
+}
+?>
Index: /projects/textcubeapi/trunk/app/.htaccess
===================================================================
--- /projects/textcubeapi/trunk/app/.htaccess (revision 580)
+++ /projects/textcubeapi/trunk/app/.htaccess (revision 580)
@@ -0,0 +1,5 @@
+<IfModule mod_rewrite.c>
+    RewriteEngine on
+    RewriteRule    ^$    webroot/    [L]
+    RewriteRule    (.*) webroot/$1    [L]
+ </IfModule>
Index: /projects/textcubeapi/trunk/app/index.php
===================================================================
--- /projects/textcubeapi/trunk/app/index.php (revision 580)
+++ /projects/textcubeapi/trunk/app/index.php (revision 580)
@@ -0,0 +1,26 @@
+<?php
+/* SVN FILE: $Id: index.php 6311 2008-01-02 06:33:52Z phpnut $ */
+/**
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) :  Rapid Development Framework <http://www.cakephp.org/>
+ * Copyright 2005-2008, Cake Software Foundation, Inc.
+ *								1785 E. Sahara Avenue, Suite 490-204
+ *								Las Vegas, Nevada 89104
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @filesource
+ * @copyright		Copyright 2005-2008, Cake Software Foundation, Inc.
+ * @link				http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
+ * @package			cake
+ * @subpackage		cake.app
+ * @since			CakePHP(tm) v 0.10.0.1076
+ * @version			$Revision: 6311 $
+ * @modifiedby		$LastChangedBy: phpnut $
+ * @lastmodified	$Date: 2008-01-02 01:33:52 -0500 (Wed, 02 Jan 2008) $
+ * @license			http://www.opensource.org/licenses/mit-license.php The MIT License
+ */
+require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
+?>
Index: /projects/textcubeapi/trunk/app/views/pages/_home.ctp
===================================================================
--- /projects/textcubeapi/trunk/app/views/pages/_home.ctp (revision 580)
+++ /projects/textcubeapi/trunk/app/views/pages/_home.ctp (revision 580)
@@ -0,0 +1,1 @@
+TEST
Index: /projects/textcubeapi/trunk/app/views/pages/home.ctp
===================================================================
--- /projects/textcubeapi/trunk/app/views/pages/home.ctp (revision 580)
+++ /projects/textcubeapi/trunk/app/views/pages/home.ctp (revision 580)
@@ -0,0 +1,6 @@
+<p>Temporary portal of <a href="/service/">Textcube API Service.</a></p>
+<h2>List of APIs</h2>
+<ul>
+	<li>Nemo Nemo : 실종 어린이 찾기</li>
+	<li>LaTeX Renderer : 고품질 LaTeX 수식 렌더링 서비스</li>
+</ul>
Index: /projects/textcubeapi/trunk/app/views/layouts/default.ctp
===================================================================
--- /projects/textcubeapi/trunk/app/views/layouts/default.ctp (revision 580)
+++ /projects/textcubeapi/trunk/app/views/layouts/default.ctp (revision 580)
@@ -0,0 +1,22 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title><?echo $title_for_layout; ?></title>
+	<link rel="stylesheet" type="text/css" href="/css/service.css" />
+	<script type="text/javascript" src="http://www.google.com/jsapi"></script>
+<?php echo $scripts_for_layout; ?>
+</head>
+<body>
+<div id="wrap">
+	<div id="header">
+		<h1><?echo $title_for_layout; ?></h1>
+	</div>
+	<div id="content">
+<?php echo $content_for_layout; ?>
+	</div>
+	<div id="footer">
+		<p>Textcube API Service, Copyright&copy; 2008, Needlworks Team.</p>
+	</div>
+</div>
+</body>
+</html>
Index: /projects/textcubeapi/trunk/app/views/service/index.ctp
===================================================================
--- /projects/textcubeapi/trunk/app/views/service/index.ctp (revision 580)
+++ /projects/textcubeapi/trunk/app/views/service/index.ctp (revision 580)
@@ -0,0 +1,6 @@
+<p>API Service Page</p>
+<ul>
+	<li>Sign In</li>
+	<li>View Keys and Statistics</li>
+	<li>Register New Key</li>
+</ul>
Index: /projects/textcubeapi/trunk/app/views/latex_renderer/test.ctp
===================================================================
--- /projects/textcubeapi/trunk/app/views/latex_renderer/test.ctp (revision 580)
+++ /projects/textcubeapi/trunk/app/views/latex_renderer/test.ctp (revision 580)
@@ -0,0 +1,46 @@
+<?php $javascript->link('latex_renderer/test.js', false); ?>
+<form id="testForm" method="post" action="/latex_renderer/query">
+<p><label>API Key : <input type="text" name="key" value="TESTING" /></label></p>
+<p>
+	<label>Extra packages : <input type="text" name="packages" value="" /></label>
+	<br/><span class="desc">Separate multiple packages with comma. Default packages are amsmath, amsfonts, amssymb, color.</span>
+</p>
+<p>
+	<label>Mode : 
+	<select name="mode">
+		<option value="$">Inline math</option>
+		<option value="displaymath" selected="selected">Display math</option>
+		<option value="eqnarray">Eqn. Array</option>
+	</select>
+	</label>
+</p>
+<p>
+	<label>Transparent Background : <input type="checkbox" name="transparent" value="true" checked="checked" /></label>
+	<br/><span class="desc">If you use PNG format, this will generate 32bit ARGB PNG to preserve semi-transparent pixels correctly.</span>
+</p>
+<p><label>Size :
+	<select name="size">
+		<option value="scriptsize">Very small</option>
+		<option value="footnotesize">Smaller</option>
+		<option value="small">Small</option>
+		<option value="normalsize" selected="selected">Normal</option>
+		<option value="large">Large</option>
+		<option value="Large">Larger</option>
+		<option value="huge">Very large</option>
+		<option value="Huge">Largest</option>
+	</select>
+</label></p>
+<p><label>Format : 
+	<select name="format">
+		<option value="gif">GIF</option>
+		<option value="png" selected="selected">PNG</option>
+	</select>
+</label></p>
+<p><label>Formula : <textarea name="formula" rows="5" cols="40"><?php echo htmlentities(''); ?></textarea></label></p>
+<p><input type="submit" id="testSubmit" value="Submit" /></p>
+</form>
+<p id="msg">Test your formula.</p>
+<div id="result-container">
+	<img id="result" src="" />
+</div>
+
Index: /projects/textcubeapi/trunk/app/views/latex_renderer/query.ctp
===================================================================
--- /projects/textcubeapi/trunk/app/views/latex_renderer/query.ctp (revision 580)
+++ /projects/textcubeapi/trunk/app/views/latex_renderer/query.ctp (revision 580)
@@ -0,0 +1,14 @@
+<?php
+switch ($protocol) {
+case 'xml':
+	header('Content-Type: text/xml; charset=utf-8');
+	break;
+case 'json':
+	header('Content-Type: text/json-comment-filtered; charset=utf-8');
+	echo $javascript->object($result);
+	break;
+default:
+	header('Content-Type: text/plain; charset=utf-8');
+	echo 'Protocol was not specified.';
+}
+?>
Index: /projects/textcubeapi/trunk/app/views/latex_renderer/index.ctp
===================================================================
--- /projects/textcubeapi/trunk/app/views/latex_renderer/index.ctp (revision 580)
+++ /projects/textcubeapi/trunk/app/views/latex_renderer/index.ctp (revision 580)
@@ -0,0 +1,5 @@
+<p>LaTeX Renderer API 서비스는 웹호스팅 환경에서 이용하기 어려운 고품질 수식 렌더링을 제공합니다.
+텍스트큐브 2.0부터 포함되는 수식 플러그인을 이용하면 보다 편리하게 아름다운 수식을 블로그에 삽입할 수 있습니다.</p>
+<ul>
+	<li><a href="/latex_renderer/test/">API 테스트해보기</a></li>
+</ul>
