瀏覽代碼

new structure

Oscar Leiva 5 年之前
父節點
當前提交
eab25e7ab2
共有 100 個文件被更改,包括 11890 次插入0 次删除
  1. 2 0
      Dockerfile
  2. 7 0
      README.md
  3. 43 0
      docker-compose.yml
  4. 134 0
      dump/db.sql
  5. 6 0
      www/application/.htaccess
  6. 11 0
      www/application/cache/index.html
  7. 135 0
      www/application/config/autoload.php
  8. 523 0
      www/application/config/config.php
  9. 85 0
      www/application/config/constants.php
  10. 96 0
      www/application/config/database.php
  11. 24 0
      www/application/config/doctypes.php
  12. 103 0
      www/application/config/foreign_chars.php
  13. 39 0
      www/application/config/grocery_crud.php
  14. 13 0
      www/application/config/hooks.php
  15. 11 0
      www/application/config/index.html
  16. 19 0
      www/application/config/memcached.php
  17. 84 0
      www/application/config/migration.php
  18. 183 0
      www/application/config/mimes.php
  19. 14 0
      www/application/config/profiler.php
  20. 54 0
      www/application/config/routes.php
  21. 64 0
      www/application/config/smileys.php
  22. 214 0
      www/application/config/user_agents.php
  23. 74 0
      www/application/controllers/Admin.php
  24. 76 0
      www/application/controllers/Publico.php
  25. 11 0
      www/application/controllers/index.html
  26. 11 0
      www/application/core/index.html
  27. 11 0
      www/application/helpers/index.html
  28. 11 0
      www/application/hooks/index.html
  29. 11 0
      www/application/index.html
  30. 11 0
      www/application/language/english/index.html
  31. 11 0
      www/application/language/index.html
  32. 5628 0
      www/application/libraries/Grocery_CRUD.php
  33. 1153 0
      www/application/libraries/image_moo.php
  34. 11 0
      www/application/libraries/index.html
  35. 11 0
      www/application/logs/index.html
  36. 72 0
      www/application/models/Calculadora_model.php
  37. 587 0
      www/application/models/Grocery_crud_model.php
  38. 11 0
      www/application/models/index.html
  39. 11 0
      www/application/third_party/index.html
  40. 63 0
      www/application/views/calculadora.php
  41. 8 0
      www/application/views/errors/cli/error_404.php
  42. 8 0
      www/application/views/errors/cli/error_db.php
  43. 21 0
      www/application/views/errors/cli/error_exception.php
  44. 8 0
      www/application/views/errors/cli/error_general.php
  45. 21 0
      www/application/views/errors/cli/error_php.php
  46. 11 0
      www/application/views/errors/cli/index.html
  47. 64 0
      www/application/views/errors/html/error_404.php
  48. 64 0
      www/application/views/errors/html/error_db.php
  49. 32 0
      www/application/views/errors/html/error_exception.php
  50. 64 0
      www/application/views/errors/html/error_general.php
  51. 33 0
      www/application/views/errors/html/error_php.php
  52. 11 0
      www/application/views/errors/html/index.html
  53. 11 0
      www/application/views/errors/index.html
  54. 25 0
      www/application/views/example.php
  55. 11 0
      www/application/views/index.html
  56. 34 0
      www/application/views/resultado.php
  57. 89 0
      www/application/views/welcome_message.php
  58. 10 0
      www/assets/grocery_crud/config/index.html
  59. 33 0
      www/assets/grocery_crud/config/language_alias.php
  60. 169 0
      www/assets/grocery_crud/config/translit_chars.php
  61. 10 0
      www/assets/grocery_crud/css/index.html
  62. 二進制
      www/assets/grocery_crud/css/jquery_plugins/chosen/chosen-sprite.png
  63. 二進制
      www/assets/grocery_crud/css/jquery_plugins/chosen/chosen-sprite@2x.png
  64. 450 0
      www/assets/grocery_crud/css/jquery_plugins/chosen/chosen.css
  65. 2 0
      www/assets/grocery_crud/css/jquery_plugins/chosen/chosen.min.css
  66. 10 0
      www/assets/grocery_crud/css/jquery_plugins/chosen/index.html
  67. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/blank.gif
  68. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_close.png
  69. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_loading.png
  70. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_nav_left.png
  71. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_nav_right.png
  72. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_e.png
  73. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_n.png
  74. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_ne.png
  75. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_nw.png
  76. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_s.png
  77. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_se.png
  78. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_sw.png
  79. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_w.png
  80. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_left.png
  81. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_main.png
  82. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_over.png
  83. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_right.png
  84. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancybox-x.png
  85. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancybox-y.png
  86. 二進制
      www/assets/grocery_crud/css/jquery_plugins/fancybox/fancybox.png
  87. 359 0
      www/assets/grocery_crud/css/jquery_plugins/fancybox/jquery.fancybox.css
  88. 360 0
      www/assets/grocery_crud/css/jquery_plugins/file_upload/bootstrap.min.css
  89. 29 0
      www/assets/grocery_crud/css/jquery_plugins/file_upload/file-uploader.css
  90. 71 0
      www/assets/grocery_crud/css/jquery_plugins/file_upload/fileuploader.css
  91. 56 0
      www/assets/grocery_crud/css/jquery_plugins/file_upload/jquery.fileupload-ui.css
  92. 二進制
      www/assets/grocery_crud/css/jquery_plugins/file_upload/loading.gif
  93. 二進制
      www/assets/grocery_crud/css/jquery_plugins/file_upload/progressbar.gif
  94. 10 0
      www/assets/grocery_crud/css/jquery_plugins/index.html
  95. 10 0
      www/assets/grocery_crud/css/jquery_plugins/jquery-ui-timepicker-addon.css
  96. 116 0
      www/assets/grocery_crud/css/jquery_plugins/jquery.ui.datetime.css
  97. 32 0
      www/assets/grocery_crud/css/jquery_plugins/ui.multiselect.css
  98. 10 0
      www/assets/grocery_crud/css/ui/index.html
  99. 二進制
      www/assets/grocery_crud/css/ui/simple/images/animated-overlay.gif
  100. 二進制
      www/assets/grocery_crud/css/ui/simple/images/ui-bg_flat_0_aaaaaa_40x100.png

+ 2 - 0
Dockerfile

@@ -0,0 +1,2 @@
+FROM php:7.3-apache 
+RUN docker-php-ext-install mysqli

+ 7 - 0
README.md

@@ -0,0 +1,7 @@
+# Aplicación Calculadora Solar
+## Inverlec Solar
+
+Desarrollada por: Fernando Carranza
+Para: Inverlec Solar
+
+http://calculadora.inverlec.solar

+ 43 - 0
docker-compose.yml

@@ -0,0 +1,43 @@
+version: "3.1"
+services:
+    www:
+        build: .
+        ports: 
+            - "8090:80"
+        volumes:
+            - ./www:/var/www/html/
+        environment:
+            CI_ENV: production
+        links:
+            - db
+        networks:
+            - default
+    db:
+        image: mysql:8.0
+        ports: 
+            - "3306:3306"
+        command: --default-authentication-plugin=mysql_native_password
+        environment:
+            MYSQL_DATABASE: calculadora
+            MYSQL_USER: admin
+            MYSQL_PASSWORD: Mercados2020
+            MYSQL_ROOT_PASSWORD: Mercados2020
+        volumes:
+            - ./dump:/docker-entrypoint-initdb.d
+            - ./conf:/etc/mysql/conf.d
+            - persistent:/var/lib/mysql
+        networks:
+            - default
+    phpmyadmin:
+        image: phpmyadmin/phpmyadmin
+        links: 
+            - db:db
+        ports:
+            - 8000:80
+        environment:
+            MYSQL_USER: user
+            MYSQL_PASSWORD: test
+            MYSQL_ROOT_PASSWORD: test
+
+volumes:
+    persistent:

+ 134 - 0
dump/db.sql

@@ -0,0 +1,134 @@
+-- phpMyAdmin SQL Dump
+-- version 4.7.5
+-- https://www.phpmyadmin.net/
+--
+-- Host: localhost
+-- Generation Time: Oct 26, 2017 at 05:52 AM
+-- Server version: 5.7.20-0ubuntu0.16.04.1
+-- PHP Version: 7.0.22-0ubuntu0.16.04.1
+
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET AUTOCOMMIT = 0;
+START TRANSACTION;
+SET time_zone = "+00:00";
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8mb4 */;
+
+--
+-- Database: `website`
+--
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `datosPanel`
+--
+
+CREATE TABLE `datosPanel` (
+  `parametro` varchar(255) NOT NULL,
+  `valor` varchar(255) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Dumping data for table `datosPanel`
+--
+
+INSERT INTO `datosPanel` (`parametro`, `valor`) VALUES
+('coeficiente Isc', '0.0053'),
+('Coeficiente Pmax', '-0.41'),
+('coeficiente Voc', '-0.31'),
+('espectrum AM', '1.5'),
+('Imp', '8.78'),
+('irradiancia', '800'),
+('Isc', '9.34'),
+('noct', '45'),
+('Pmax', '325'),
+('Temperatura Ambiente', '20'),
+('Vmp', '37'),
+('Voc', '45.5');
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `datos_x_depto`
+--
+
+CREATE TABLE `datos_x_depto` (
+  `departamento` varchar(255) NOT NULL,
+  `irradiancia` decimal(18,2) NOT NULL,
+  `temperatura_ambiente_promedio` decimal(18,2) NOT NULL,
+  `temperatura_ambiente` decimal(18,2) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Dumping data for table `datos_x_depto`
+--
+
+INSERT INTO `datos_x_depto` (`departamento`, `irradiancia`, `temperatura_ambiente_promedio`, `temperatura_ambiente`) VALUES
+('Ahuachapan ', '5.41', '24.80', '31.00'),
+('Cabañas', '5.39', '24.80', '31.00'),
+('Chalatenango ', '5.26', '25.20', '32.00'),
+('Cuscatlan ', '5.51', '23.50', '31.00'),
+('La  Union ', '5.62', '29.70', '36.00'),
+('La Libertad ', '5.35', '23.10', '34.00'),
+('La Paz', '5.56', '27.30', '32.00'),
+('Morazan ', '5.33', '29.10', '30.00'),
+('San Miguel ', '5.47', '29.10', '35.00'),
+('San Salvador', '5.35', '24.90', '31.00'),
+('San Vicente ', '5.57', '26.00', '34.00'),
+('SANTA ANA', '5.43', '25.10', '31.00'),
+('Sonsonate', '5.10', '26.90', '31.00'),
+('Usulutan ', '5.27', '28.40', '34.00');
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `distribuidoras`
+--
+
+CREATE TABLE `distribuidoras` (
+  `distribuidora` varchar(255) NOT NULL,
+  `tarifapromedio` decimal(18,8) NOT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+
+--
+-- Dumping data for table `distribuidoras`
+--
+
+INSERT INTO `distribuidoras` (`distribuidora`, `tarifapromedio`) VALUES
+('CAESS', '0.13704300'),
+('CLESA', '0.14027500'),
+('DELSUR', '0.13772600'),
+('DEUSEM', '0.13783700'),
+('EEO', '0.13933000');
+
+--
+-- Indexes for dumped tables
+--
+
+--
+-- Indexes for table `datosPanel`
+--
+ALTER TABLE `datosPanel`
+  ADD PRIMARY KEY (`parametro`);
+
+--
+-- Indexes for table `datos_x_depto`
+--
+ALTER TABLE `datos_x_depto`
+  ADD PRIMARY KEY (`departamento`);
+
+--
+-- Indexes for table `distribuidoras`
+--
+ALTER TABLE `distribuidoras`
+  ADD PRIMARY KEY (`distribuidora`);
+COMMIT;
+
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

+ 6 - 0
www/application/.htaccess

@@ -0,0 +1,6 @@
+<IfModule authz_core_module>
+    Require all denied
+</IfModule>
+<IfModule !authz_core_module>
+    Deny from all
+</IfModule>

+ 11 - 0
www/application/cache/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 135 - 0
www/application/config/autoload.php

@@ -0,0 +1,135 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| AUTO-LOADER
+| -------------------------------------------------------------------
+| This file specifies which systems should be loaded by default.
+|
+| In order to keep the framework as light-weight as possible only the
+| absolute minimal resources are loaded by default. For example,
+| the database is not connected to automatically since no assumption
+| is made regarding whether you intend to use it.  This file lets
+| you globally define which systems you would like loaded with every
+| request.
+|
+| -------------------------------------------------------------------
+| Instructions
+| -------------------------------------------------------------------
+|
+| These are the things you can load automatically:
+|
+| 1. Packages
+| 2. Libraries
+| 3. Drivers
+| 4. Helper files
+| 5. Custom config files
+| 6. Language files
+| 7. Models
+|
+*/
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Packages
+| -------------------------------------------------------------------
+| Prototype:
+|
+|  $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
+|
+*/
+$autoload['packages'] = array();
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Libraries
+| -------------------------------------------------------------------
+| These are the classes located in system/libraries/ or your
+| application/libraries/ directory, with the addition of the
+| 'database' library, which is somewhat of a special case.
+|
+| Prototype:
+|
+|	$autoload['libraries'] = array('database', 'email', 'session');
+|
+| You can also supply an alternative library name to be assigned
+| in the controller:
+|
+|	$autoload['libraries'] = array('user_agent' => 'ua');
+*/
+$autoload['libraries'] = array('database', 'email', 'session');
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Drivers
+| -------------------------------------------------------------------
+| These classes are located in system/libraries/ or in your
+| application/libraries/ directory, but are also placed inside their
+| own subdirectory and they extend the CI_Driver_Library class. They
+| offer multiple interchangeable driver options.
+|
+| Prototype:
+|
+|	$autoload['drivers'] = array('cache');
+|
+| You can also supply an alternative property name to be assigned in
+| the controller:
+|
+|	$autoload['drivers'] = array('cache' => 'cch');
+|
+*/
+$autoload['drivers'] = array();
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Helper Files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['helper'] = array('url', 'file');
+*/
+$autoload['helper'] = array('url');
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Config files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['config'] = array('config1', 'config2');
+|
+| NOTE: This item is intended for use ONLY if you have created custom
+| config files.  Otherwise, leave it blank.
+|
+*/
+$autoload['config'] = array();
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Language files
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['language'] = array('lang1', 'lang2');
+|
+| NOTE: Do not include the "_lang" part of your file.  For example
+| "codeigniter_lang.php" would be referenced as array('codeigniter');
+|
+*/
+$autoload['language'] = array();
+
+/*
+| -------------------------------------------------------------------
+|  Auto-load Models
+| -------------------------------------------------------------------
+| Prototype:
+|
+|	$autoload['model'] = array('first_model', 'second_model');
+|
+| You can also supply an alternative model name to be assigned
+| in the controller:
+|
+|	$autoload['model'] = array('first_model' => 'first');
+*/
+$autoload['model'] = array();

+ 523 - 0
www/application/config/config.php

@@ -0,0 +1,523 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| Base Site URL
+|--------------------------------------------------------------------------
+|
+| URL to your CodeIgniter root. Typically this will be your base URL,
+| WITH a trailing slash:
+|
+|	http://example.com/
+|
+| WARNING: You MUST set this value!
+|
+| If it is not set, then CodeIgniter will try guess the protocol and path
+| your installation, but due to security concerns the hostname will be set
+| to $_SERVER['SERVER_ADDR'] if available, or localhost otherwise.
+| The auto-detection mechanism exists only for convenience during
+| development and MUST NOT be used in production!
+|
+| If you need to allow multiple domains, remember that this file is still
+| a PHP script and you can easily do that on your own.
+|
+*/
+$config['base_url'] = 'http://calculadora.inverlec.solar';
+
+/*
+|--------------------------------------------------------------------------
+| Index File
+|--------------------------------------------------------------------------
+|
+| Typically this will be your index.php file, unless you've renamed it to
+| something else. If you are using mod_rewrite to remove the page set this
+| variable so that it is blank.
+|
+*/
+$config['index_page'] = 'index.php';
+
+/*
+|--------------------------------------------------------------------------
+| URI PROTOCOL
+|--------------------------------------------------------------------------
+|
+| This item determines which server global should be used to retrieve the
+| URI string.  The default setting of 'REQUEST_URI' works for most servers.
+| If your links do not seem to work, try one of the other delicious flavors:
+|
+| 'REQUEST_URI'    Uses $_SERVER['REQUEST_URI']
+| 'QUERY_STRING'   Uses $_SERVER['QUERY_STRING']
+| 'PATH_INFO'      Uses $_SERVER['PATH_INFO']
+|
+| WARNING: If you set this to 'PATH_INFO', URIs will always be URL-decoded!
+*/
+$config['uri_protocol']	= 'REQUEST_URI';
+
+/*
+|--------------------------------------------------------------------------
+| URL suffix
+|--------------------------------------------------------------------------
+|
+| This option allows you to add a suffix to all URLs generated by CodeIgniter.
+| For more information please see the user guide:
+|
+| https://codeigniter.com/user_guide/general/urls.html
+*/
+$config['url_suffix'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Default Language
+|--------------------------------------------------------------------------
+|
+| This determines which set of language files should be used. Make sure
+| there is an available translation if you intend to use something other
+| than english.
+|
+*/
+$config['language']	= '';
+
+/*
+|--------------------------------------------------------------------------
+| Default Character Set
+|--------------------------------------------------------------------------
+|
+| This determines which character set is used by default in various methods
+| that require a character set to be provided.
+|
+| See http://php.net/htmlspecialchars for a list of supported charsets.
+|
+*/
+$config['charset'] = 'UTF-8';
+
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable System Hooks
+|--------------------------------------------------------------------------
+|
+| If you would like to use the 'hooks' feature you must enable it by
+| setting this variable to TRUE (boolean).  See the user guide for details.
+|
+*/
+$config['enable_hooks'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Class Extension Prefix
+|--------------------------------------------------------------------------
+|
+| This item allows you to set the filename/classname prefix when extending
+| native libraries.  For more information please see the user guide:
+|
+| https://codeigniter.com/user_guide/general/core_classes.html
+| https://codeigniter.com/user_guide/general/creating_libraries.html
+|
+*/
+$config['subclass_prefix'] = 'MY_';
+
+/*
+|--------------------------------------------------------------------------
+| Composer auto-loading
+|--------------------------------------------------------------------------
+|
+| Enabling this setting will tell CodeIgniter to look for a Composer
+| package auto-loader script in application/vendor/autoload.php.
+|
+|	$config['composer_autoload'] = TRUE;
+|
+| Or if you have your vendor/ directory located somewhere else, you
+| can opt to set a specific path as well:
+|
+|	$config['composer_autoload'] = '/path/to/vendor/autoload.php';
+|
+| For more information about Composer, please visit http://getcomposer.org/
+|
+| Note: This will NOT disable or override the CodeIgniter-specific
+|	autoloading (application/config/autoload.php)
+*/
+$config['composer_autoload'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Allowed URL Characters
+|--------------------------------------------------------------------------
+|
+| This lets you specify which characters are permitted within your URLs.
+| When someone tries to submit a URL with disallowed characters they will
+| get a warning message.
+|
+| As a security measure you are STRONGLY encouraged to restrict URLs to
+| as few characters as possible.  By default only these are allowed: a-z 0-9~%.:_-
+|
+| Leave blank to allow all characters -- but only if you are insane.
+|
+| The configured value is actually a regular expression character group
+| and it will be executed as: ! preg_match('/^[<permitted_uri_chars>]+$/i
+|
+| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
+|
+*/
+$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
+
+/*
+|--------------------------------------------------------------------------
+| Enable Query Strings
+|--------------------------------------------------------------------------
+|
+| By default CodeIgniter uses search-engine friendly segment based URLs:
+| example.com/who/what/where/
+|
+| You can optionally enable standard query string based URLs:
+| example.com?who=me&what=something&where=here
+|
+| Options are: TRUE or FALSE (boolean)
+|
+| The other items let you set the query string 'words' that will
+| invoke your controllers and its functions:
+| example.com/index.php?c=controller&m=function
+|
+| Please note that some of the helpers won't work as expected when
+| this feature is enabled, since CodeIgniter is designed primarily to
+| use segment based URLs.
+|
+*/
+$config['enable_query_strings'] = FALSE;
+$config['controller_trigger'] = 'c';
+$config['function_trigger'] = 'm';
+$config['directory_trigger'] = 'd';
+
+/*
+|--------------------------------------------------------------------------
+| Allow $_GET array
+|--------------------------------------------------------------------------
+|
+| By default CodeIgniter enables access to the $_GET array.  If for some
+| reason you would like to disable it, set 'allow_get_array' to FALSE.
+|
+| WARNING: This feature is DEPRECATED and currently available only
+|          for backwards compatibility purposes!
+|
+*/
+$config['allow_get_array'] = TRUE;
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Threshold
+|--------------------------------------------------------------------------
+|
+| You can enable error logging by setting a threshold over zero. The
+| threshold determines what gets logged. Threshold options are:
+|
+|	0 = Disables logging, Error logging TURNED OFF
+|	1 = Error Messages (including PHP errors)
+|	2 = Debug Messages
+|	3 = Informational Messages
+|	4 = All Messages
+|
+| You can also pass an array with threshold levels to show individual error types
+|
+| 	array(2) = Debug Messages, without Error Messages
+|
+| For a live site you'll usually only enable Errors (1) to be logged otherwise
+| your log files will fill up very fast.
+|
+*/
+$config['log_threshold'] = 0;
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/logs/ directory. Use a full server path with trailing slash.
+|
+*/
+$config['log_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Log File Extension
+|--------------------------------------------------------------------------
+|
+| The default filename extension for log files. The default 'php' allows for
+| protecting the log files via basic scripting, when they are to be stored
+| under a publicly accessible directory.
+|
+| Note: Leaving it blank will default to 'php'.
+|
+*/
+$config['log_file_extension'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Log File Permissions
+|--------------------------------------------------------------------------
+|
+| The file system permissions to be applied on newly created log files.
+|
+| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal
+|            integer notation (i.e. 0700, 0644, etc.)
+*/
+$config['log_file_permissions'] = 0644;
+
+/*
+|--------------------------------------------------------------------------
+| Date Format for Logs
+|--------------------------------------------------------------------------
+|
+| Each item that is logged has an associated date. You can use PHP date
+| codes to set your own date formatting
+|
+*/
+$config['log_date_format'] = 'Y-m-d H:i:s';
+
+/*
+|--------------------------------------------------------------------------
+| Error Views Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/views/errors/ directory.  Use a full server path with trailing slash.
+|
+*/
+$config['error_views_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Cache Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/cache/ directory.  Use a full server path with trailing slash.
+|
+*/
+$config['cache_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Cache Include Query String
+|--------------------------------------------------------------------------
+|
+| Whether to take the URL query string into consideration when generating
+| output cache files. Valid options are:
+|
+|	FALSE      = Disabled
+|	TRUE       = Enabled, take all query parameters into account.
+|	             Please be aware that this may result in numerous cache
+|	             files generated for the same page over and over again.
+|	array('q') = Enabled, but only take into account the specified list
+|	             of query parameters.
+|
+*/
+$config['cache_query_string'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Encryption Key
+|--------------------------------------------------------------------------
+|
+| If you use the Encryption class, you must set an encryption key.
+| See the user guide for more info.
+|
+| https://codeigniter.com/user_guide/libraries/encryption.html
+|
+*/
+$config['encryption_key'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Session Variables
+|--------------------------------------------------------------------------
+|
+| 'sess_driver'
+|
+|	The storage driver to use: files, database, redis, memcached
+|
+| 'sess_cookie_name'
+|
+|	The session cookie name, must contain only [0-9a-z_-] characters
+|
+| 'sess_expiration'
+|
+|	The number of SECONDS you want the session to last.
+|	Setting to 0 (zero) means expire when the browser is closed.
+|
+| 'sess_save_path'
+|
+|	The location to save sessions to, driver dependent.
+|
+|	For the 'files' driver, it's a path to a writable directory.
+|	WARNING: Only absolute paths are supported!
+|
+|	For the 'database' driver, it's a table name.
+|	Please read up the manual for the format with other session drivers.
+|
+|	IMPORTANT: You are REQUIRED to set a valid save path!
+|
+| 'sess_match_ip'
+|
+|	Whether to match the user's IP address when reading the session data.
+|
+|	WARNING: If you're using the database driver, don't forget to update
+|	         your session table's PRIMARY KEY when changing this setting.
+|
+| 'sess_time_to_update'
+|
+|	How many seconds between CI regenerating the session ID.
+|
+| 'sess_regenerate_destroy'
+|
+|	Whether to destroy session data associated with the old session ID
+|	when auto-regenerating the session ID. When set to FALSE, the data
+|	will be later deleted by the garbage collector.
+|
+| Other session cookie settings are shared with the rest of the application,
+| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here.
+|
+*/
+$config['sess_driver'] = 'files';
+$config['sess_cookie_name'] = 'ci_session';
+$config['sess_expiration'] = 7200;
+$config['sess_save_path'] = '/tmp';
+$config['sess_match_ip'] = FALSE;
+$config['sess_time_to_update'] = 300;
+$config['sess_regenerate_destroy'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Cookie Related Variables
+|--------------------------------------------------------------------------
+|
+| 'cookie_prefix'   = Set a cookie name prefix if you need to avoid collisions
+| 'cookie_domain'   = Set to .your-domain.com for site-wide cookies
+| 'cookie_path'     = Typically will be a forward slash
+| 'cookie_secure'   = Cookie will only be set if a secure HTTPS connection exists.
+| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript)
+|
+| Note: These settings (with the exception of 'cookie_prefix' and
+|       'cookie_httponly') will also affect sessions.
+|
+*/
+$config['cookie_prefix']	= '';
+$config['cookie_domain']	= '';
+$config['cookie_path']		= '/';
+$config['cookie_secure']	= FALSE;
+$config['cookie_httponly'] 	= FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Standardize newlines
+|--------------------------------------------------------------------------
+|
+| Determines whether to standardize newline characters in input data,
+| meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value.
+|
+| WARNING: This feature is DEPRECATED and currently available only
+|          for backwards compatibility purposes!
+|
+*/
+$config['standardize_newlines'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Global XSS Filtering
+|--------------------------------------------------------------------------
+|
+| Determines whether the XSS filter is always active when GET, POST or
+| COOKIE data is encountered
+|
+| WARNING: This feature is DEPRECATED and currently available only
+|          for backwards compatibility purposes!
+|
+*/
+$config['global_xss_filtering'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Cross Site Request Forgery
+|--------------------------------------------------------------------------
+| Enables a CSRF cookie token to be set. When set to TRUE, token will be
+| checked on a submitted form. If you are accepting user data, it is strongly
+| recommended CSRF protection be enabled.
+|
+| 'csrf_token_name' = The token name
+| 'csrf_cookie_name' = The cookie name
+| 'csrf_expire' = The number in seconds the token should expire.
+| 'csrf_regenerate' = Regenerate token on every submission
+| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
+*/
+$config['csrf_protection'] = FALSE;
+$config['csrf_token_name'] = 'csrf_test_name';
+$config['csrf_cookie_name'] = 'csrf_cookie_name';
+$config['csrf_expire'] = 7200;
+$config['csrf_regenerate'] = TRUE;
+$config['csrf_exclude_uris'] = array();
+
+/*
+|--------------------------------------------------------------------------
+| Output Compression
+|--------------------------------------------------------------------------
+|
+| Enables Gzip output compression for faster page loads.  When enabled,
+| the output class will test whether your server supports Gzip.
+| Even if it does, however, not all browsers support compression
+| so enable only if you are reasonably sure your visitors can handle it.
+|
+| Only used if zlib.output_compression is turned off in your php.ini.
+| Please do not use it together with httpd-level output compression.
+|
+| VERY IMPORTANT:  If you are getting a blank page when compression is enabled it
+| means you are prematurely outputting something to your browser. It could
+| even be a line of whitespace at the end of one of your scripts.  For
+| compression to work, nothing can be sent before the output buffer is called
+| by the output class.  Do not 'echo' any values with compression enabled.
+|
+*/
+$config['compress_output'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Master Time Reference
+|--------------------------------------------------------------------------
+|
+| Options are 'local' or any PHP supported timezone. This preference tells
+| the system whether to use your server's local time as the master 'now'
+| reference, or convert it to the configured one timezone. See the 'date
+| helper' page of the user guide for information regarding date handling.
+|
+*/
+$config['time_reference'] = 'local';
+
+/*
+|--------------------------------------------------------------------------
+| Rewrite PHP Short Tags
+|--------------------------------------------------------------------------
+|
+| If your PHP installation does not have short tag support enabled CI
+| can rewrite the tags on-the-fly, enabling you to utilize that syntax
+| in your view files.  Options are TRUE or FALSE (boolean)
+|
+| Note: You need to have eval() enabled for this to work.
+|
+*/
+$config['rewrite_short_tags'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Reverse Proxy IPs
+|--------------------------------------------------------------------------
+|
+| If your server is behind a reverse proxy, you must whitelist the proxy
+| IP addresses from which CodeIgniter should trust headers such as
+| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
+| the visitor's IP address.
+|
+| You can use both an array or a comma-separated list of proxy addresses,
+| as well as specifying whole subnets. Here are a few examples:
+|
+| Comma-separated:	'10.0.1.200,192.168.5.0/24'
+| Array:		array('10.0.1.200', '192.168.5.0/24')
+*/
+$config['proxy_ips'] = '';

+ 85 - 0
www/application/config/constants.php

@@ -0,0 +1,85 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| Display Debug backtrace
+|--------------------------------------------------------------------------
+|
+| If set to TRUE, a backtrace will be displayed along with php errors. If
+| error_reporting is disabled, the backtrace will not display, regardless
+| of this setting
+|
+*/
+defined('SHOW_DEBUG_BACKTRACE') OR define('SHOW_DEBUG_BACKTRACE', TRUE);
+
+/*
+|--------------------------------------------------------------------------
+| File and Directory Modes
+|--------------------------------------------------------------------------
+|
+| These prefs are used when checking and setting modes when working
+| with the file system.  The defaults are fine on servers with proper
+| security, but you may wish (or even need) to change the values in
+| certain environments (Apache running a separate process for each
+| user, PHP under CGI with Apache suEXEC, etc.).  Octal values should
+| always be used to set the mode correctly.
+|
+*/
+defined('FILE_READ_MODE')  OR define('FILE_READ_MODE', 0644);
+defined('FILE_WRITE_MODE') OR define('FILE_WRITE_MODE', 0666);
+defined('DIR_READ_MODE')   OR define('DIR_READ_MODE', 0755);
+defined('DIR_WRITE_MODE')  OR define('DIR_WRITE_MODE', 0755);
+
+/*
+|--------------------------------------------------------------------------
+| File Stream Modes
+|--------------------------------------------------------------------------
+|
+| These modes are used when working with fopen()/popen()
+|
+*/
+defined('FOPEN_READ')                           OR define('FOPEN_READ', 'rb');
+defined('FOPEN_READ_WRITE')                     OR define('FOPEN_READ_WRITE', 'r+b');
+defined('FOPEN_WRITE_CREATE_DESTRUCTIVE')       OR define('FOPEN_WRITE_CREATE_DESTRUCTIVE', 'wb'); // truncates existing file data, use with care
+defined('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE')  OR define('FOPEN_READ_WRITE_CREATE_DESTRUCTIVE', 'w+b'); // truncates existing file data, use with care
+defined('FOPEN_WRITE_CREATE')                   OR define('FOPEN_WRITE_CREATE', 'ab');
+defined('FOPEN_READ_WRITE_CREATE')              OR define('FOPEN_READ_WRITE_CREATE', 'a+b');
+defined('FOPEN_WRITE_CREATE_STRICT')            OR define('FOPEN_WRITE_CREATE_STRICT', 'xb');
+defined('FOPEN_READ_WRITE_CREATE_STRICT')       OR define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b');
+
+/*
+|--------------------------------------------------------------------------
+| Exit Status Codes
+|--------------------------------------------------------------------------
+|
+| Used to indicate the conditions under which the script is exit()ing.
+| While there is no universal standard for error codes, there are some
+| broad conventions.  Three such conventions are mentioned below, for
+| those who wish to make use of them.  The CodeIgniter defaults were
+| chosen for the least overlap with these conventions, while still
+| leaving room for others to be defined in future versions and user
+| applications.
+|
+| The three main conventions used for determining exit status codes
+| are as follows:
+|
+|    Standard C/C++ Library (stdlibc):
+|       http://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
+|       (This link also contains other GNU-specific conventions)
+|    BSD sysexits.h:
+|       http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits
+|    Bash scripting:
+|       http://tldp.org/LDP/abs/html/exitcodes.html
+|
+*/
+defined('EXIT_SUCCESS')        OR define('EXIT_SUCCESS', 0); // no errors
+defined('EXIT_ERROR')          OR define('EXIT_ERROR', 1); // generic error
+defined('EXIT_CONFIG')         OR define('EXIT_CONFIG', 3); // configuration error
+defined('EXIT_UNKNOWN_FILE')   OR define('EXIT_UNKNOWN_FILE', 4); // file not found
+defined('EXIT_UNKNOWN_CLASS')  OR define('EXIT_UNKNOWN_CLASS', 5); // unknown class
+defined('EXIT_UNKNOWN_METHOD') OR define('EXIT_UNKNOWN_METHOD', 6); // unknown class member
+defined('EXIT_USER_INPUT')     OR define('EXIT_USER_INPUT', 7); // invalid user input
+defined('EXIT_DATABASE')       OR define('EXIT_DATABASE', 8); // database error
+defined('EXIT__AUTO_MIN')      OR define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code
+defined('EXIT__AUTO_MAX')      OR define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code

+ 96 - 0
www/application/config/database.php

@@ -0,0 +1,96 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| DATABASE CONNECTIVITY SETTINGS
+| -------------------------------------------------------------------
+| This file will contain the settings needed to access your database.
+|
+| For complete instructions please consult the 'Database Connection'
+| page of the User Guide.
+|
+| -------------------------------------------------------------------
+| EXPLANATION OF VARIABLES
+| -------------------------------------------------------------------
+|
+|	['dsn']      The full DSN string describe a connection to the database.
+|	['hostname'] The hostname of your database server.
+|	['username'] The username used to connect to the database
+|	['password'] The password used to connect to the database
+|	['database'] The name of the database you want to connect to
+|	['dbdriver'] The database driver. e.g.: mysqli.
+|			Currently supported:
+|				 cubrid, ibase, mssql, mysql, mysqli, oci8,
+|				 odbc, pdo, postgre, sqlite, sqlite3, sqlsrv
+|	['dbprefix'] You can add an optional prefix, which will be added
+|				 to the table name when using the  Query Builder class
+|	['pconnect'] TRUE/FALSE - Whether to use a persistent connection
+|	['db_debug'] TRUE/FALSE - Whether database errors should be displayed.
+|	['cache_on'] TRUE/FALSE - Enables/disables query caching
+|	['cachedir'] The path to the folder where cache files should be stored
+|	['char_set'] The character set used in communicating with the database
+|	['dbcollat'] The character collation used in communicating with the database
+|				 NOTE: For MySQL and MySQLi databases, this setting is only used
+| 				 as a backup if your server is running PHP < 5.2.3 or MySQL < 5.0.7
+|				 (and in table creation queries made with DB Forge).
+| 				 There is an incompatibility in PHP with mysql_real_escape_string() which
+| 				 can make your site vulnerable to SQL injection if you are using a
+| 				 multi-byte character set and are running versions lower than these.
+| 				 Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
+|	['swap_pre'] A default table prefix that should be swapped with the dbprefix
+|	['encrypt']  Whether or not to use an encrypted connection.
+|
+|			'mysql' (deprecated), 'sqlsrv' and 'pdo/sqlsrv' drivers accept TRUE/FALSE
+|			'mysqli' and 'pdo/mysql' drivers accept an array with the following options:
+|
+|				'ssl_key'    - Path to the private key file
+|				'ssl_cert'   - Path to the public key certificate file
+|				'ssl_ca'     - Path to the certificate authority file
+|				'ssl_capath' - Path to a directory containing trusted CA certificats in PEM format
+|				'ssl_cipher' - List of *allowed* ciphers to be used for the encryption, separated by colons (':')
+|				'ssl_verify' - TRUE/FALSE; Whether verify the server certificate or not ('mysqli' only)
+|
+|	['compress'] Whether or not to use client compression (MySQL only)
+|	['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
+|							- good for ensuring strict SQL while developing
+|	['ssl_options']	Used to set various SSL options that can be used when making SSL connections.
+|	['failover'] array - A array with 0 or more data for connections if the main should fail.
+|	['save_queries'] TRUE/FALSE - Whether to "save" all executed queries.
+| 				NOTE: Disabling this will also effectively disable both
+| 				$this->db->last_query() and profiling of DB queries.
+| 				When you run a query, with this setting set to TRUE (default),
+| 				CodeIgniter will store the SQL statement for debugging purposes.
+| 				However, this may cause high memory usage, especially if you run
+| 				a lot of SQL queries ... disable this to avoid that problem.
+|
+| The $active_group variable lets you choose which connection group to
+| make active.  By default there is only one group (the 'default' group).
+|
+| The $query_builder variables lets you determine whether or not to load
+| the query builder class.
+*/
+$active_group = 'default';
+$query_builder = TRUE;
+
+$db['default'] = array(
+	'dsn'	=> '',
+	'hostname' => 'db',
+	'username' => 'root',
+	'password' => 'Mercados2020',
+	'database' => 'calculadora',
+	'dbdriver' => 'mysqli',
+	'dbprefix' => '',
+	'pconnect' => FALSE,
+	'db_debug' => (ENVIRONMENT !== 'production'),
+	'cache_on' => FALSE,
+	'cachedir' => '',
+	'char_set' => 'utf8',
+	'dbcollat' => 'utf8_general_ci',
+	'swap_pre' => '',
+	'encrypt' => FALSE,
+	'compress' => FALSE,
+	'stricton' => FALSE,
+	'failover' => array(),
+	'save_queries' => TRUE
+);

+ 24 - 0
www/application/config/doctypes.php

@@ -0,0 +1,24 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+$_doctypes = array(
+	'xhtml11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
+	'xhtml1-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+	'xhtml1-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+	'xhtml1-frame' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+	'xhtml-basic11' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
+	'html5' => '<!DOCTYPE html>',
+	'html4-strict' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+	'html4-trans' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+	'html4-frame' => '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
+	'mathml1' => '<!DOCTYPE math SYSTEM "http://www.w3.org/Math/DTD/mathml1/mathml.dtd">',
+	'mathml2' => '<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/mathml2.dtd">',
+	'svg10' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">',
+	'svg11' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">',
+	'svg11-basic' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
+	'svg11-tiny' => '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
+	'xhtml-math-svg-xh' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
+	'xhtml-math-svg-sh' => '<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">',
+	'xhtml-rdfa-1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
+	'xhtml-rdfa-2' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.1//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-2.dtd">'
+);

+ 103 - 0
www/application/config/foreign_chars.php

@@ -0,0 +1,103 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| Foreign Characters
+| -------------------------------------------------------------------
+| This file contains an array of foreign characters for transliteration
+| conversion used by the Text helper
+|
+*/
+$foreign_characters = array(
+	'/ä|æ|ǽ/' => 'ae',
+	'/ö|œ/' => 'oe',
+	'/ü/' => 'ue',
+	'/Ä/' => 'Ae',
+	'/Ü/' => 'Ue',
+	'/Ö/' => 'Oe',
+	'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A',
+	'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a',
+	'/Б/' => 'B',
+	'/б/' => 'b',
+	'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
+	'/ç|ć|ĉ|ċ|č/' => 'c',
+	'/Д/' => 'D',
+	'/д/' => 'd',
+	'/Ð|Ď|Đ|Δ/' => 'Dj',
+	'/ð|ď|đ|δ/' => 'dj',
+	'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E',
+	'/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e',
+	'/Ф/' => 'F',
+	'/ф/' => 'f',
+	'/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G',
+	'/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g',
+	'/Ĥ|Ħ/' => 'H',
+	'/ĥ|ħ/' => 'h',
+	'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I',
+	'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i',
+	'/Ĵ/' => 'J',
+	'/ĵ/' => 'j',
+	'/Ķ|Κ|К/' => 'K',
+	'/ķ|κ|к/' => 'k',
+	'/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L',
+	'/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l',
+	'/М/' => 'M',
+	'/м/' => 'm',
+	'/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N',
+	'/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n',
+	'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O',
+	'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o',
+	'/П/' => 'P',
+	'/п/' => 'p',
+	'/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R',
+	'/ŕ|ŗ|ř|ρ|р/' => 'r',
+	'/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S',
+	'/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's',
+	'/Ț|Ţ|Ť|Ŧ|τ|Т/' => 'T',
+	'/ț|ţ|ť|ŧ|т/' => 't',
+	'/Þ|þ/' => 'th',
+	'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U',
+	'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u',
+	'/Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y',
+	'/ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y',
+	'/В/' => 'V',
+	'/в/' => 'v',
+	'/Ŵ/' => 'W',
+	'/ŵ/' => 'w',
+	'/Ź|Ż|Ž|Ζ|З/' => 'Z',
+	'/ź|ż|ž|ζ|з/' => 'z',
+	'/Æ|Ǽ/' => 'AE',
+	'/ß/' => 'ss',
+	'/IJ/' => 'IJ',
+	'/ij/' => 'ij',
+	'/Œ/' => 'OE',
+	'/ƒ/' => 'f',
+	'/ξ/' => 'ks',
+	'/π/' => 'p',
+	'/β/' => 'v',
+	'/μ/' => 'm',
+	'/ψ/' => 'ps',
+	'/Ё/' => 'Yo',
+	'/ё/' => 'yo',
+	'/Є/' => 'Ye',
+	'/є/' => 'ye',
+	'/Ї/' => 'Yi',
+	'/Ж/' => 'Zh',
+	'/ж/' => 'zh',
+	'/Х/' => 'Kh',
+	'/х/' => 'kh',
+	'/Ц/' => 'Ts',
+	'/ц/' => 'ts',
+	'/Ч/' => 'Ch',
+	'/ч/' => 'ch',
+	'/Ш/' => 'Sh',
+	'/ш/' => 'sh',
+	'/Щ/' => 'Shch',
+	'/щ/' => 'shch',
+	'/Ъ|ъ|Ь|ь/' => '',
+	'/Ю/' => 'Yu',
+	'/ю/' => 'yu',
+	'/Я/' => 'Ya',
+	'/я/' => 'ya'
+);

+ 39 - 0
www/application/config/grocery_crud.php

@@ -0,0 +1,39 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+    // For view all the languages go to the folder assets/grocery_crud/languages/
+    $config['grocery_crud_default_language'] = 'english';
+
+    // There are only three choices: "uk-date" (dd/mm/yyyy), "us-date" (mm/dd/yyyy) or "sql-date" (yyyy-mm-dd)
+    $config['grocery_crud_date_format'] = 'uk-date';
+
+    // The default per page when a user firstly see a list page
+    $config['grocery_crud_default_per_page'] = 10;
+
+    $config['grocery_crud_file_upload_allow_file_types'] = 'gif|jpeg|jpg|png|tiff|doc|docx|txt|odt|xls|xlsx|pdf|ppt|pptx|pps|ppsx|mp3|m4a|ogg|wav|mp4|m4v|mov|wmv|flv|avi|mpg|ogv|3gp|3g2';
+    $config['grocery_crud_file_upload_max_file_size'] = '20MB'; //ex. '10MB' (Mega Bytes), '1067KB' (Kilo Bytes), '5000B' (Bytes)
+
+    // You can choose 'ckeditor','tinymce' or 'markitup'
+    $config['grocery_crud_default_text_editor'] = 'ckeditor';
+    // You can choose 'minimal' or 'full'
+    $config['grocery_crud_text_editor_type'] = 'full';
+
+    // The character limiter at the list page, zero(0) value if you don't want character limiter at your list page
+    $config['grocery_crud_character_limiter'] = 30;
+
+    // All the forms are opening with dialog forms without refreshing the page once again.
+    // IMPORTANT: PLease be aware that this functionality is still in BETA phase and it is
+    // not suggested to use this in production mode
+    $config['grocery_crud_dialog_forms'] = false;
+
+    // Having some options at the list paging. This is the default one that all the websites are using.
+    // Make sure that the number of grocery_crud_default_per_page variable is included to this array.
+    $config['grocery_crud_paging_options'] = array('10','25','50','100');
+
+    // Default theme for grocery CRUD
+    $config['grocery_crud_default_theme'] = 'flexigrid';
+
+    // The environment is important so we can have specific configurations for specific environments
+    $config['grocery_crud_environment'] = 'production';
+
+    // Turn XSS clean into true in case you are exposing your CRUD into public. Please be aware that this is
+    // stripping all the HTML and do not just trim the extra javascript
+    $config['grocery_crud_xss_clean'] = false;

+ 13 - 0
www/application/config/hooks.php

@@ -0,0 +1,13 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| Hooks
+| -------------------------------------------------------------------------
+| This file lets you define "hooks" to extend CI without hacking the core
+| files.  Please see the user guide for info:
+|
+|	https://codeigniter.com/user_guide/general/hooks.html
+|
+*/

+ 11 - 0
www/application/config/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 19 - 0
www/application/config/memcached.php

@@ -0,0 +1,19 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| Memcached settings
+| -------------------------------------------------------------------------
+| Your Memcached servers can be specified below.
+|
+|	See: https://codeigniter.com/user_guide/libraries/caching.html#memcached
+|
+*/
+$config = array(
+	'default' => array(
+		'hostname' => '127.0.0.1',
+		'port'     => '11211',
+		'weight'   => '1',
+	),
+);

+ 84 - 0
www/application/config/migration.php

@@ -0,0 +1,84 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+|--------------------------------------------------------------------------
+| Enable/Disable Migrations
+|--------------------------------------------------------------------------
+|
+| Migrations are disabled by default for security reasons.
+| You should enable migrations whenever you intend to do a schema migration
+| and disable it back when you're done.
+|
+*/
+$config['migration_enabled'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Migration Type
+|--------------------------------------------------------------------------
+|
+| Migration file names may be based on a sequential identifier or on
+| a timestamp. Options are:
+|
+|   'sequential' = Sequential migration naming (001_add_blog.php)
+|   'timestamp'  = Timestamp migration naming (20121031104401_add_blog.php)
+|                  Use timestamp format YYYYMMDDHHIISS.
+|
+| Note: If this configuration value is missing the Migration library
+|       defaults to 'sequential' for backward compatibility with CI2.
+|
+*/
+$config['migration_type'] = 'timestamp';
+
+/*
+|--------------------------------------------------------------------------
+| Migrations table
+|--------------------------------------------------------------------------
+|
+| This is the name of the table that will store the current migrations state.
+| When migrations runs it will store in a database table which migration
+| level the system is at. It then compares the migration level in this
+| table to the $config['migration_version'] if they are not the same it
+| will migrate up. This must be set.
+|
+*/
+$config['migration_table'] = 'migrations';
+
+/*
+|--------------------------------------------------------------------------
+| Auto Migrate To Latest
+|--------------------------------------------------------------------------
+|
+| If this is set to TRUE when you load the migrations class and have
+| $config['migration_enabled'] set to TRUE the system will auto migrate
+| to your latest migration (whatever $config['migration_version'] is
+| set to). This way you do not have to call migrations anywhere else
+| in your code to have the latest migration.
+|
+*/
+$config['migration_auto_latest'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Migrations version
+|--------------------------------------------------------------------------
+|
+| This is used to set migration version that the file system should be on.
+| If you run $this->migration->current() this is the version that schema will
+| be upgraded / downgraded to.
+|
+*/
+$config['migration_version'] = 0;
+
+/*
+|--------------------------------------------------------------------------
+| Migrations Path
+|--------------------------------------------------------------------------
+|
+| Path to your migrations folder.
+| Typically, it will be within your application path.
+| Also, writing permission is required within the migrations path.
+|
+*/
+$config['migration_path'] = APPPATH.'migrations/';

+ 183 - 0
www/application/config/mimes.php

@@ -0,0 +1,183 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| MIME TYPES
+| -------------------------------------------------------------------
+| This file contains an array of mime types.  It is used by the
+| Upload class to help identify allowed file types.
+|
+*/
+return array(
+	'hqx'	=>	array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
+	'cpt'	=>	'application/mac-compactpro',
+	'csv'	=>	array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'),
+	'bin'	=>	array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'),
+	'dms'	=>	'application/octet-stream',
+	'lha'	=>	'application/octet-stream',
+	'lzh'	=>	'application/octet-stream',
+	'exe'	=>	array('application/octet-stream', 'application/x-msdownload'),
+	'class'	=>	'application/octet-stream',
+	'psd'	=>	array('application/x-photoshop', 'image/vnd.adobe.photoshop'),
+	'so'	=>	'application/octet-stream',
+	'sea'	=>	'application/octet-stream',
+	'dll'	=>	'application/octet-stream',
+	'oda'	=>	'application/oda',
+	'pdf'	=>	array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'),
+	'ai'	=>	array('application/pdf', 'application/postscript'),
+	'eps'	=>	'application/postscript',
+	'ps'	=>	'application/postscript',
+	'smi'	=>	'application/smil',
+	'smil'	=>	'application/smil',
+	'mif'	=>	'application/vnd.mif',
+	'xls'	=>	array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'),
+	'ppt'	=>	array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'),
+	'pptx'	=> 	array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'),
+	'wbxml'	=>	'application/wbxml',
+	'wmlc'	=>	'application/wmlc',
+	'dcr'	=>	'application/x-director',
+	'dir'	=>	'application/x-director',
+	'dxr'	=>	'application/x-director',
+	'dvi'	=>	'application/x-dvi',
+	'gtar'	=>	'application/x-gtar',
+	'gz'	=>	'application/x-gzip',
+	'gzip'  =>	'application/x-gzip',
+	'php'	=>	array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'),
+	'php4'	=>	'application/x-httpd-php',
+	'php3'	=>	'application/x-httpd-php',
+	'phtml'	=>	'application/x-httpd-php',
+	'phps'	=>	'application/x-httpd-php-source',
+	'js'	=>	array('application/x-javascript', 'text/plain'),
+	'swf'	=>	'application/x-shockwave-flash',
+	'sit'	=>	'application/x-stuffit',
+	'tar'	=>	'application/x-tar',
+	'tgz'	=>	array('application/x-tar', 'application/x-gzip-compressed'),
+	'z'	=>	'application/x-compress',
+	'xhtml'	=>	'application/xhtml+xml',
+	'xht'	=>	'application/xhtml+xml',
+	'zip'	=>	array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'),
+	'rar'	=>	array('application/x-rar', 'application/rar', 'application/x-rar-compressed'),
+	'mid'	=>	'audio/midi',
+	'midi'	=>	'audio/midi',
+	'mpga'	=>	'audio/mpeg',
+	'mp2'	=>	'audio/mpeg',
+	'mp3'	=>	array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
+	'aif'	=>	array('audio/x-aiff', 'audio/aiff'),
+	'aiff'	=>	array('audio/x-aiff', 'audio/aiff'),
+	'aifc'	=>	'audio/x-aiff',
+	'ram'	=>	'audio/x-pn-realaudio',
+	'rm'	=>	'audio/x-pn-realaudio',
+	'rpm'	=>	'audio/x-pn-realaudio-plugin',
+	'ra'	=>	'audio/x-realaudio',
+	'rv'	=>	'video/vnd.rn-realvideo',
+	'wav'	=>	array('audio/x-wav', 'audio/wave', 'audio/wav'),
+	'bmp'	=>	array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'),
+	'gif'	=>	'image/gif',
+	'jpeg'	=>	array('image/jpeg', 'image/pjpeg'),
+	'jpg'	=>	array('image/jpeg', 'image/pjpeg'),
+	'jpe'	=>	array('image/jpeg', 'image/pjpeg'),
+	'jp2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'j2k'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpf'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpg2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpx'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'jpm'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'mj2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'mjp2'	=>	array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+	'png'	=>	array('image/png',  'image/x-png'),
+	'tiff'	=>	'image/tiff',
+	'tif'	=>	'image/tiff',
+	'css'	=>	array('text/css', 'text/plain'),
+	'html'	=>	array('text/html', 'text/plain'),
+	'htm'	=>	array('text/html', 'text/plain'),
+	'shtml'	=>	array('text/html', 'text/plain'),
+	'txt'	=>	'text/plain',
+	'text'	=>	'text/plain',
+	'log'	=>	array('text/plain', 'text/x-log'),
+	'rtx'	=>	'text/richtext',
+	'rtf'	=>	'text/rtf',
+	'xml'	=>	array('application/xml', 'text/xml', 'text/plain'),
+	'xsl'	=>	array('application/xml', 'text/xsl', 'text/xml'),
+	'mpeg'	=>	'video/mpeg',
+	'mpg'	=>	'video/mpeg',
+	'mpe'	=>	'video/mpeg',
+	'qt'	=>	'video/quicktime',
+	'mov'	=>	'video/quicktime',
+	'avi'	=>	array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'),
+	'movie'	=>	'video/x-sgi-movie',
+	'doc'	=>	array('application/msword', 'application/vnd.ms-office'),
+	'docx'	=>	array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'),
+	'dot'	=>	array('application/msword', 'application/vnd.ms-office'),
+	'dotx'	=>	array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'),
+	'xlsx'	=>	array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'),
+	'word'	=>	array('application/msword', 'application/octet-stream'),
+	'xl'	=>	'application/excel',
+	'eml'	=>	'message/rfc822',
+	'json'  =>	array('application/json', 'text/json'),
+	'pem'   =>	array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'),
+	'p10'   =>	array('application/x-pkcs10', 'application/pkcs10'),
+	'p12'   =>	'application/x-pkcs12',
+	'p7a'   =>	'application/x-pkcs7-signature',
+	'p7c'   =>	array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
+	'p7m'   =>	array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
+	'p7r'   =>	'application/x-pkcs7-certreqresp',
+	'p7s'   =>	'application/pkcs7-signature',
+	'crt'   =>	array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'),
+	'crl'   =>	array('application/pkix-crl', 'application/pkcs-crl'),
+	'der'   =>	'application/x-x509-ca-cert',
+	'kdb'   =>	'application/octet-stream',
+	'pgp'   =>	'application/pgp',
+	'gpg'   =>	'application/gpg-keys',
+	'sst'   =>	'application/octet-stream',
+	'csr'   =>	'application/octet-stream',
+	'rsa'   =>	'application/x-pkcs7',
+	'cer'   =>	array('application/pkix-cert', 'application/x-x509-ca-cert'),
+	'3g2'   =>	'video/3gpp2',
+	'3gp'   =>	array('video/3gp', 'video/3gpp'),
+	'mp4'   =>	'video/mp4',
+	'm4a'   =>	'audio/x-m4a',
+	'f4v'   =>	array('video/mp4', 'video/x-f4v'),
+	'flv'	=>	'video/x-flv',
+	'webm'	=>	'video/webm',
+	'aac'   =>	'audio/x-acc',
+	'm4u'   =>	'application/vnd.mpegurl',
+	'm3u'   =>	'text/plain',
+	'xspf'  =>	'application/xspf+xml',
+	'vlc'   =>	'application/videolan',
+	'wmv'   =>	array('video/x-ms-wmv', 'video/x-ms-asf'),
+	'au'    =>	'audio/x-au',
+	'ac3'   =>	'audio/ac3',
+	'flac'  =>	'audio/x-flac',
+	'ogg'   =>	array('audio/ogg', 'video/ogg', 'application/ogg'),
+	'kmz'	=>	array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'),
+	'kml'	=>	array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'),
+	'ics'	=>	'text/calendar',
+	'ical'	=>	'text/calendar',
+	'zsh'	=>	'text/x-scriptzsh',
+	'7zip'	=>	array('application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'),
+	'cdr'	=>	array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'),
+	'wma'	=>	array('audio/x-ms-wma', 'video/x-ms-asf'),
+	'jar'	=>	array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'),
+	'svg'	=>	array('image/svg+xml', 'application/xml', 'text/xml'),
+	'vcf'	=>	'text/x-vcard',
+	'srt'	=>	array('text/srt', 'text/plain'),
+	'vtt'	=>	array('text/vtt', 'text/plain'),
+	'ico'	=>	array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'),
+	'odc'	=>	'application/vnd.oasis.opendocument.chart',
+	'otc'	=>	'application/vnd.oasis.opendocument.chart-template',
+	'odf'	=>	'application/vnd.oasis.opendocument.formula',
+	'otf'	=>	'application/vnd.oasis.opendocument.formula-template',
+	'odg'	=>	'application/vnd.oasis.opendocument.graphics',
+	'otg'	=>	'application/vnd.oasis.opendocument.graphics-template',
+	'odi'	=>	'application/vnd.oasis.opendocument.image',
+	'oti'	=>	'application/vnd.oasis.opendocument.image-template',
+	'odp'	=>	'application/vnd.oasis.opendocument.presentation',
+	'otp'	=>	'application/vnd.oasis.opendocument.presentation-template',
+	'ods'	=>	'application/vnd.oasis.opendocument.spreadsheet',
+	'ots'	=>	'application/vnd.oasis.opendocument.spreadsheet-template',
+	'odt'	=>	'application/vnd.oasis.opendocument.text',
+	'odm'	=>	'application/vnd.oasis.opendocument.text-master',
+	'ott'	=>	'application/vnd.oasis.opendocument.text-template',
+	'oth'	=>	'application/vnd.oasis.opendocument.text-web'
+);

+ 14 - 0
www/application/config/profiler.php

@@ -0,0 +1,14 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| Profiler Sections
+| -------------------------------------------------------------------------
+| This file lets you determine whether or not various sections of Profiler
+| data are displayed when the Profiler is enabled.
+| Please see the user guide for info:
+|
+|	https://codeigniter.com/user_guide/general/profiling.html
+|
+*/

+ 54 - 0
www/application/config/routes.php

@@ -0,0 +1,54 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------------
+| URI ROUTING
+| -------------------------------------------------------------------------
+| This file lets you re-map URI requests to specific controller functions.
+|
+| Typically there is a one-to-one relationship between a URL string
+| and its corresponding controller class/method. The segments in a
+| URL normally follow this pattern:
+|
+|	example.com/class/method/id/
+|
+| In some instances, however, you may want to remap this relationship
+| so that a different class/function is called than the one
+| corresponding to the URL.
+|
+| Please see the user guide for complete details:
+|
+|	https://codeigniter.com/user_guide/general/routing.html
+|
+| -------------------------------------------------------------------------
+| RESERVED ROUTES
+| -------------------------------------------------------------------------
+|
+| There are three reserved routes:
+|
+|	$route['default_controller'] = 'welcome';
+|
+| This route indicates which controller class should be loaded if the
+| URI contains no data. In the above example, the "welcome" class
+| would be loaded.
+|
+|	$route['404_override'] = 'errors/page_missing';
+|
+| This route will tell the Router which controller/method to use if those
+| provided in the URL cannot be matched to a valid route.
+|
+|	$route['translate_uri_dashes'] = FALSE;
+|
+| This is not exactly a route, but allows you to automatically route
+| controller and method names that contain dashes. '-' isn't a valid
+| class or method name character, so it requires translation.
+| When you set this option to TRUE, it will replace ALL dashes in the
+| controller and method URI segments.
+|
+| Examples:	my-controller/index	-> my_controller/index
+|		my-controller/my-method	-> my_controller/my_method
+*/
+$route['default_controller'] = 'Publico';
+$route['404_override'] = '';
+$route['translate_uri_dashes'] = FALSE;

+ 64 - 0
www/application/config/smileys.php

@@ -0,0 +1,64 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| SMILEYS
+| -------------------------------------------------------------------
+| This file contains an array of smileys for use with the emoticon helper.
+| Individual images can be used to replace multiple smileys.  For example:
+| :-) and :) use the same image replacement.
+|
+| Please see user guide for more info:
+| https://codeigniter.com/user_guide/helpers/smiley_helper.html
+|
+*/
+$smileys = array(
+
+//	smiley			image name						width	height	alt
+
+	':-)'			=>	array('grin.gif',			'19',	'19',	'grin'),
+	':lol:'			=>	array('lol.gif',			'19',	'19',	'LOL'),
+	':cheese:'		=>	array('cheese.gif',			'19',	'19',	'cheese'),
+	':)'			=>	array('smile.gif',			'19',	'19',	'smile'),
+	';-)'			=>	array('wink.gif',			'19',	'19',	'wink'),
+	';)'			=>	array('wink.gif',			'19',	'19',	'wink'),
+	':smirk:'		=>	array('smirk.gif',			'19',	'19',	'smirk'),
+	':roll:'		=>	array('rolleyes.gif',		'19',	'19',	'rolleyes'),
+	':-S'			=>	array('confused.gif',		'19',	'19',	'confused'),
+	':wow:'			=>	array('surprise.gif',		'19',	'19',	'surprised'),
+	':bug:'			=>	array('bigsurprise.gif',	'19',	'19',	'big surprise'),
+	':-P'			=>	array('tongue_laugh.gif',	'19',	'19',	'tongue laugh'),
+	'%-P'			=>	array('tongue_rolleye.gif',	'19',	'19',	'tongue rolleye'),
+	';-P'			=>	array('tongue_wink.gif',	'19',	'19',	'tongue wink'),
+	':P'			=>	array('raspberry.gif',		'19',	'19',	'raspberry'),
+	':blank:'		=>	array('blank.gif',			'19',	'19',	'blank stare'),
+	':long:'		=>	array('longface.gif',		'19',	'19',	'long face'),
+	':ohh:'			=>	array('ohh.gif',			'19',	'19',	'ohh'),
+	':grrr:'		=>	array('grrr.gif',			'19',	'19',	'grrr'),
+	':gulp:'		=>	array('gulp.gif',			'19',	'19',	'gulp'),
+	'8-/'			=>	array('ohoh.gif',			'19',	'19',	'oh oh'),
+	':down:'		=>	array('downer.gif',			'19',	'19',	'downer'),
+	':red:'			=>	array('embarrassed.gif',	'19',	'19',	'red face'),
+	':sick:'		=>	array('sick.gif',			'19',	'19',	'sick'),
+	':shut:'		=>	array('shuteye.gif',		'19',	'19',	'shut eye'),
+	':-/'			=>	array('hmm.gif',			'19',	'19',	'hmmm'),
+	'>:('			=>	array('mad.gif',			'19',	'19',	'mad'),
+	':mad:'			=>	array('mad.gif',			'19',	'19',	'mad'),
+	'>:-('			=>	array('angry.gif',			'19',	'19',	'angry'),
+	':angry:'		=>	array('angry.gif',			'19',	'19',	'angry'),
+	':zip:'			=>	array('zip.gif',			'19',	'19',	'zipper'),
+	':kiss:'		=>	array('kiss.gif',			'19',	'19',	'kiss'),
+	':ahhh:'		=>	array('shock.gif',			'19',	'19',	'shock'),
+	':coolsmile:'	=>	array('shade_smile.gif',	'19',	'19',	'cool smile'),
+	':coolsmirk:'	=>	array('shade_smirk.gif',	'19',	'19',	'cool smirk'),
+	':coolgrin:'	=>	array('shade_grin.gif',		'19',	'19',	'cool grin'),
+	':coolhmm:'		=>	array('shade_hmm.gif',		'19',	'19',	'cool hmm'),
+	':coolmad:'		=>	array('shade_mad.gif',		'19',	'19',	'cool mad'),
+	':coolcheese:'	=>	array('shade_cheese.gif',	'19',	'19',	'cool cheese'),
+	':vampire:'		=>	array('vampire.gif',		'19',	'19',	'vampire'),
+	':snake:'		=>	array('snake.gif',			'19',	'19',	'snake'),
+	':exclaim:'		=>	array('exclaim.gif',		'19',	'19',	'exclaim'),
+	':question:'	=>	array('question.gif',		'19',	'19',	'question')
+
+);

+ 214 - 0
www/application/config/user_agents.php

@@ -0,0 +1,214 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+/*
+| -------------------------------------------------------------------
+| USER AGENT TYPES
+| -------------------------------------------------------------------
+| This file contains four arrays of user agent data. It is used by the
+| User Agent Class to help identify browser, platform, robot, and
+| mobile device data. The array keys are used to identify the device
+| and the array values are used to set the actual name of the item.
+*/
+$platforms = array(
+	'windows nt 10.0'	=> 'Windows 10',
+	'windows nt 6.3'	=> 'Windows 8.1',
+	'windows nt 6.2'	=> 'Windows 8',
+	'windows nt 6.1'	=> 'Windows 7',
+	'windows nt 6.0'	=> 'Windows Vista',
+	'windows nt 5.2'	=> 'Windows 2003',
+	'windows nt 5.1'	=> 'Windows XP',
+	'windows nt 5.0'	=> 'Windows 2000',
+	'windows nt 4.0'	=> 'Windows NT 4.0',
+	'winnt4.0'			=> 'Windows NT 4.0',
+	'winnt 4.0'			=> 'Windows NT',
+	'winnt'				=> 'Windows NT',
+	'windows 98'		=> 'Windows 98',
+	'win98'				=> 'Windows 98',
+	'windows 95'		=> 'Windows 95',
+	'win95'				=> 'Windows 95',
+	'windows phone'			=> 'Windows Phone',
+	'windows'			=> 'Unknown Windows OS',
+	'android'			=> 'Android',
+	'blackberry'		=> 'BlackBerry',
+	'iphone'			=> 'iOS',
+	'ipad'				=> 'iOS',
+	'ipod'				=> 'iOS',
+	'os x'				=> 'Mac OS X',
+	'ppc mac'			=> 'Power PC Mac',
+	'freebsd'			=> 'FreeBSD',
+	'ppc'				=> 'Macintosh',
+	'linux'				=> 'Linux',
+	'debian'			=> 'Debian',
+	'sunos'				=> 'Sun Solaris',
+	'beos'				=> 'BeOS',
+	'apachebench'		=> 'ApacheBench',
+	'aix'				=> 'AIX',
+	'irix'				=> 'Irix',
+	'osf'				=> 'DEC OSF',
+	'hp-ux'				=> 'HP-UX',
+	'netbsd'			=> 'NetBSD',
+	'bsdi'				=> 'BSDi',
+	'openbsd'			=> 'OpenBSD',
+	'gnu'				=> 'GNU/Linux',
+	'unix'				=> 'Unknown Unix OS',
+	'symbian' 			=> 'Symbian OS'
+);
+
+
+// The order of this array should NOT be changed. Many browsers return
+// multiple browser types so we want to identify the sub-type first.
+$browsers = array(
+	'OPR'			=> 'Opera',
+	'Flock'			=> 'Flock',
+	'Edge'			=> 'Spartan',
+	'Chrome'		=> 'Chrome',
+	// Opera 10+ always reports Opera/9.80 and appends Version/<real version> to the user agent string
+	'Opera.*?Version'	=> 'Opera',
+	'Opera'			=> 'Opera',
+	'MSIE'			=> 'Internet Explorer',
+	'Internet Explorer'	=> 'Internet Explorer',
+	'Trident.* rv'	=> 'Internet Explorer',
+	'Shiira'		=> 'Shiira',
+	'Firefox'		=> 'Firefox',
+	'Chimera'		=> 'Chimera',
+	'Phoenix'		=> 'Phoenix',
+	'Firebird'		=> 'Firebird',
+	'Camino'		=> 'Camino',
+	'Netscape'		=> 'Netscape',
+	'OmniWeb'		=> 'OmniWeb',
+	'Safari'		=> 'Safari',
+	'Mozilla'		=> 'Mozilla',
+	'Konqueror'		=> 'Konqueror',
+	'icab'			=> 'iCab',
+	'Lynx'			=> 'Lynx',
+	'Links'			=> 'Links',
+	'hotjava'		=> 'HotJava',
+	'amaya'			=> 'Amaya',
+	'IBrowse'		=> 'IBrowse',
+	'Maxthon'		=> 'Maxthon',
+	'Ubuntu'		=> 'Ubuntu Web Browser'
+);
+
+$mobiles = array(
+	// legacy array, old values commented out
+	'mobileexplorer'	=> 'Mobile Explorer',
+//  'openwave'			=> 'Open Wave',
+//	'opera mini'		=> 'Opera Mini',
+//	'operamini'			=> 'Opera Mini',
+//	'elaine'			=> 'Palm',
+	'palmsource'		=> 'Palm',
+//	'digital paths'		=> 'Palm',
+//	'avantgo'			=> 'Avantgo',
+//	'xiino'				=> 'Xiino',
+	'palmscape'			=> 'Palmscape',
+//	'nokia'				=> 'Nokia',
+//	'ericsson'			=> 'Ericsson',
+//	'blackberry'		=> 'BlackBerry',
+//	'motorola'			=> 'Motorola'
+
+	// Phones and Manufacturers
+	'motorola'		=> 'Motorola',
+	'nokia'			=> 'Nokia',
+	'palm'			=> 'Palm',
+	'iphone'		=> 'Apple iPhone',
+	'ipad'			=> 'iPad',
+	'ipod'			=> 'Apple iPod Touch',
+	'sony'			=> 'Sony Ericsson',
+	'ericsson'		=> 'Sony Ericsson',
+	'blackberry'	=> 'BlackBerry',
+	'cocoon'		=> 'O2 Cocoon',
+	'blazer'		=> 'Treo',
+	'lg'			=> 'LG',
+	'amoi'			=> 'Amoi',
+	'xda'			=> 'XDA',
+	'mda'			=> 'MDA',
+	'vario'			=> 'Vario',
+	'htc'			=> 'HTC',
+	'samsung'		=> 'Samsung',
+	'sharp'			=> 'Sharp',
+	'sie-'			=> 'Siemens',
+	'alcatel'		=> 'Alcatel',
+	'benq'			=> 'BenQ',
+	'ipaq'			=> 'HP iPaq',
+	'mot-'			=> 'Motorola',
+	'playstation portable'	=> 'PlayStation Portable',
+	'playstation 3'		=> 'PlayStation 3',
+	'playstation vita'  	=> 'PlayStation Vita',
+	'hiptop'		=> 'Danger Hiptop',
+	'nec-'			=> 'NEC',
+	'panasonic'		=> 'Panasonic',
+	'philips'		=> 'Philips',
+	'sagem'			=> 'Sagem',
+	'sanyo'			=> 'Sanyo',
+	'spv'			=> 'SPV',
+	'zte'			=> 'ZTE',
+	'sendo'			=> 'Sendo',
+	'nintendo dsi'	=> 'Nintendo DSi',
+	'nintendo ds'	=> 'Nintendo DS',
+	'nintendo 3ds'	=> 'Nintendo 3DS',
+	'wii'			=> 'Nintendo Wii',
+	'open web'		=> 'Open Web',
+	'openweb'		=> 'OpenWeb',
+
+	// Operating Systems
+	'android'		=> 'Android',
+	'symbian'		=> 'Symbian',
+	'SymbianOS'		=> 'SymbianOS',
+	'elaine'		=> 'Palm',
+	'series60'		=> 'Symbian S60',
+	'windows ce'	=> 'Windows CE',
+
+	// Browsers
+	'obigo'			=> 'Obigo',
+	'netfront'		=> 'Netfront Browser',
+	'openwave'		=> 'Openwave Browser',
+	'mobilexplorer'	=> 'Mobile Explorer',
+	'operamini'		=> 'Opera Mini',
+	'opera mini'	=> 'Opera Mini',
+	'opera mobi'	=> 'Opera Mobile',
+	'fennec'		=> 'Firefox Mobile',
+
+	// Other
+	'digital paths'	=> 'Digital Paths',
+	'avantgo'		=> 'AvantGo',
+	'xiino'			=> 'Xiino',
+	'novarra'		=> 'Novarra Transcoder',
+	'vodafone'		=> 'Vodafone',
+	'docomo'		=> 'NTT DoCoMo',
+	'o2'			=> 'O2',
+
+	// Fallback
+	'mobile'		=> 'Generic Mobile',
+	'wireless'		=> 'Generic Mobile',
+	'j2me'			=> 'Generic Mobile',
+	'midp'			=> 'Generic Mobile',
+	'cldc'			=> 'Generic Mobile',
+	'up.link'		=> 'Generic Mobile',
+	'up.browser'	=> 'Generic Mobile',
+	'smartphone'	=> 'Generic Mobile',
+	'cellphone'		=> 'Generic Mobile'
+);
+
+// There are hundreds of bots but these are the most common.
+$robots = array(
+	'googlebot'		=> 'Googlebot',
+	'msnbot'		=> 'MSNBot',
+	'baiduspider'		=> 'Baiduspider',
+	'bingbot'		=> 'Bing',
+	'slurp'			=> 'Inktomi Slurp',
+	'yahoo'			=> 'Yahoo',
+	'ask jeeves'		=> 'Ask Jeeves',
+	'fastcrawler'		=> 'FastCrawler',
+	'infoseek'		=> 'InfoSeek Robot 1.0',
+	'lycos'			=> 'Lycos',
+	'yandex'		=> 'YandexBot',
+	'mediapartners-google'	=> 'MediaPartners Google',
+	'CRAZYWEBCRAWLER'	=> 'Crazy Webcrawler',
+	'adsbot-google'		=> 'AdsBot Google',
+	'feedfetcher-google'	=> 'Feedfetcher Google',
+	'curious george'	=> 'Curious George',
+	'ia_archiver'		=> 'Alexa Crawler',
+	'MJ12bot'		=> 'Majestic-12',
+	'Uptimebot'		=> 'Uptimebot'
+);

+ 74 - 0
www/application/controllers/Admin.php

@@ -0,0 +1,74 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+
+class Admin extends CI_Controller {
+
+	public function __construct()
+	{
+		parent::__construct();
+
+		if (!isset($_SERVER['PHP_AUTH_USER']) || $_SERVER['PHP_AUTH_USER'] != 'admin' || $_SERVER['PHP_AUTH_PW'] != 'Fernando1') {
+		 header('WWW-Authenticate: Basic realm="Acceso a Administrador"');
+		 header('HTTP/1.0 401 Unauthorized');
+		 die('Access Denied');
+	 }
+
+		$this->load->database();
+		$this->load->helper('url');
+
+		$this->load->library('grocery_CRUD');
+	}
+
+	public function _example_output($output = null)
+	{
+		$this->load->view('example.php',(array)$output);
+	}
+
+	public function offices()
+	{
+		$output = $this->grocery_crud->render();
+
+		$this->_example_output($output);
+	}
+
+	public function index()
+	{
+		$this->_example_output((object)array('output' => '' , 'js_files' => array() , 'css_files' => array()));
+	}
+
+
+	public function deptos()
+	{
+			$crud = new grocery_CRUD();
+
+			$crud->set_table('datos_x_depto');
+
+			$output = $crud->render();
+
+			$this->_example_output($output);
+	}
+
+	public function distribuidoras()
+	{
+			$crud = new grocery_CRUD();
+
+			$crud->set_table('distribuidoras');
+
+			$output = $crud->render();
+
+			$this->_example_output($output);
+	}
+
+	public function datospanel()
+	{
+			$crud = new grocery_CRUD();
+
+			$crud->set_table('datosPanel');
+
+			$output = $crud->render();
+
+			$this->_example_output($output);
+	}
+
+
+
+}

+ 76 - 0
www/application/controllers/Publico.php

@@ -0,0 +1,76 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class Publico extends CI_Controller {
+
+	/**
+	 * Index Page for this controller.
+	 *
+	 * Maps to the following URL
+	 * 		http://example.com/index.php/welcome
+	 *	- or -
+	 * 		http://example.com/index.php/welcome/index
+	 *	- or -
+	 * Since this controller is set as the default controller in
+	 * config/routes.php, it's displayed at http://example.com/
+	 *
+	 * So any other public methods not prefixed with an underscore will
+	 * map to /index.php/welcome/<method_name>
+	 * @see https://codeigniter.com/user_guide/general/urls.html
+	 */
+	public function index()
+	{
+			 $this->load->model('calculadora_model');
+			 $data['distribuidoras'] = $this->calculadora_model->getDistribuidoras();
+			 $data['departamentos'] = $this->calculadora_model->getDepartamentos();
+			 $this->load->view('calculadora', $data);
+
+	}
+
+	public function calculo(){
+		$this->load->model('calculadora_model');
+		$consumo = $this->input->post("consumo");
+		$departamento = $this->input->post("departamento");
+		$Distribuidora = $this->input->post("Distribuidora");
+		//echo "Depto: " . $Distribuidora;
+		$consumoDiario = $consumo / 30;
+		$datosDepartamentoSeleccionado = $this->calculadora_model->getDepartamento($departamento);
+		echo ($datosDepartamentoSeleccionado[0]["irradiancia"]);
+		$potenciaEfectiva = $consumoDiario / $datosDepartamentoSeleccionado[0]["irradiancia"]*1000;
+		$potenciaEfectivaPico = $potenciaEfectiva / 0.8;
+		$noct = $this->calculadora_model->getDatoPanel("noct");
+		$irradianciaPanel = $this->calculadora_model->getDatoPanel("irradiancia");
+		//print_r($datosDepartamentoSeleccionado);
+		$temperatura_ambiente_promedio = $datosDepartamentoSeleccionado[0]["temperatura_ambiente_promedio"];
+		$temperatura_ambiente = $datosDepartamentoSeleccionado[0]["temperatura_ambiente"];
+		$noctVal = $noct[0]["valor"];
+		$irraPanel = $irradianciaPanel[0]["valor"];
+		//echo "T" . $temperatura_ambiente_promedio . "irradianciaPanel" . $irraPanel . "noctVal" . $noctVal;
+		$coeficienteTemperatura = ($noctVal - $temperatura_ambiente_promedio) /$irraPanel;
+		$calculoIntermedio = $coeficienteTemperatura *1000;
+		$tc =  $temperatura_ambiente + $calculoIntermedio;
+		$diferenciaTemperatura = $tc - $temperatura_ambiente_promedio;
+		$pmax = $this->calculadora_model->getDatoPanel("Coeficiente Pmax");
+		$declinacion_x_temp = $pmax[0]["valor"] * $diferenciaTemperatura;
+		$declinacion_x_temp100 = $declinacion_x_temp /100;
+
+		$Pmax = $this->calculadora_model->getDatoPanel("Pmax");
+		$porcentaje_reduccion = $declinacion_x_temp100 * $Pmax[0]["valor"];
+		$potenciaReal = $Pmax[0]["valor"] + $porcentaje_reduccion;
+		$numeroPaneles = $potenciaEfectivaPico / $potenciaReal;
+		$produccionMensual = $potenciaEfectiva *30;
+
+		$datosDistribuidora = $this->calculadora_model->getDistribuidora($Distribuidora);
+	//	echo ($Distribuidora);
+		$ahorroMensual = ($produccionMensual /100) * $datosDistribuidora[0]["tarifapromedio"];
+
+		$kwpRequeridos = $numeroPaneles *0.325;
+
+			 $data['ahorroMensual'] = $ahorroMensual;
+			 $data['kwpRequeridos'] = $kwpRequeridos;
+
+			 $this->load->view('resultado', $data);
+
+
+	}
+}

+ 11 - 0
www/application/controllers/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/core/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/helpers/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/hooks/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/language/english/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/language/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 5628 - 0
www/application/libraries/Grocery_CRUD.php

@@ -0,0 +1,5628 @@
+<?php
+/**
+ * PHP grocery CRUD
+ *
+ * A Codeigniter library that creates a CRUD automatically with just few lines of code.
+ *
+ * Copyright (C) 2010 - 2014  John Skoumbourdis.
+ *
+ * LICENSE
+ *
+ * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
+ * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
+ * Please see the corresponding license file for details of these licenses.
+ * You are free to use, modify and distribute this software, but all copyright information must remain.
+ *
+ * @package    	grocery CRUD
+ * @copyright  	Copyright (c) 2010 through 2014, John Skoumbourdis
+ * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @version    	1.5.8
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * grocery Field Types
+ *
+ * The types of the fields and the default reactions
+ *
+ * @package    	grocery CRUD
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ * @license     https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @link		http://www.grocerycrud.com/documentation
+ */
+class grocery_CRUD_Field_Types
+{
+	/**
+	 * Gets the field types of the main table.
+	 * @return array
+	 */
+	public function get_field_types()
+	{
+		if ($this->field_types !== null) {
+			return $this->field_types;
+		}
+
+		$types	= array();
+		foreach($this->basic_model->get_field_types_basic_table() as $field_info)
+		{
+			$field_info->required = !empty($this->required_fields) && in_array($field_info->name,$this->required_fields) ? true : false;
+
+			$field_info->display_as =
+				isset($this->display_as[$field_info->name]) ?
+					$this->display_as[$field_info->name] :
+					ucfirst(str_replace("_"," ",$field_info->name));
+
+			if($this->change_field_type !== null && isset($this->change_field_type[$field_info->name]))
+			{
+				$field_type 			= $this->change_field_type[$field_info->name];
+
+				if (isset($this->relation[$field_info->name])) {
+					$field_info->crud_type = "relation_".$field_type->type;
+				}
+				elseif (isset($this->upload_fields[$field_info->name])) {
+					$field_info->crud_type = "upload_file_".$field_type->type;
+				} else {
+					$field_info->crud_type 	= $field_type->type;
+					$field_info->extras 	=  $field_type->extras;
+				}
+
+				$real_type				= $field_info->crud_type;
+			}
+			elseif(isset($this->relation[$field_info->name]))
+			{
+				$real_type				= 'relation';
+				$field_info->crud_type 	= 'relation';
+			}
+			elseif(isset($this->upload_fields[$field_info->name]))
+			{
+				$real_type				= 'upload_file';
+				$field_info->crud_type 	= 'upload_file';
+			}
+			else
+			{
+				$real_type = $this->get_type($field_info);
+				$field_info->crud_type = $real_type;
+			}
+
+			switch ($real_type) {
+				case 'text':
+					if(!empty($this->unset_texteditor) && in_array($field_info->name,$this->unset_texteditor))
+						$field_info->extras = false;
+					else
+						$field_info->extras = 'text_editor';
+				break;
+
+				case 'relation':
+				case 'relation_readonly':
+					$field_info->extras 	= $this->relation[$field_info->name];
+				break;
+
+				case 'upload_file':
+				case 'upload_file_readonly':
+					$field_info->extras 	= $this->upload_fields[$field_info->name];
+				break;
+
+				default:
+					if(empty($field_info->extras))
+						$field_info->extras = false;
+				break;
+			}
+
+			$types[$field_info->name] = $field_info;
+		}
+
+		if(!empty($this->relation_n_n))
+		{
+			foreach($this->relation_n_n as $field_name => $field_extras)
+			{
+				$is_read_only = $this->change_field_type !== null
+								&& isset($this->change_field_type[$field_name])
+								&& $this->change_field_type[$field_name]->type == 'readonly'
+									? true : false;
+				$field_info = (object)array();
+				$field_info->name		= $field_name;
+				$field_info->crud_type 	= $is_read_only ? 'readonly' : 'relation_n_n';
+				$field_info->extras 	= $field_extras;
+				$field_info->required	= !empty($this->required_fields) && in_array($field_name,$this->required_fields) ? true : false;;
+				$field_info->display_as =
+					isset($this->display_as[$field_name]) ?
+						$this->display_as[$field_name] :
+						ucfirst(str_replace("_"," ",$field_name));
+
+				$types[$field_name] = $field_info;
+			}
+		}
+
+		if(!empty($this->add_fields))
+			foreach($this->add_fields as $field_object)
+			{
+				$field_name = isset($field_object->field_name) ? $field_object->field_name : $field_object;
+
+				if(!isset($types[$field_name]))//Doesn't exist in the database? Create it for the CRUD
+				{
+					$extras = false;
+					if($this->change_field_type !== null && isset($this->change_field_type[$field_name]))
+					{
+						$field_type = $this->change_field_type[$field_name];
+						$extras 	=  $field_type->extras;
+					}
+
+					$field_info = (object)array(
+						'name' => $field_name,
+						'crud_type' => $this->change_field_type !== null && isset($this->change_field_type[$field_name]) ?
+											$this->change_field_type[$field_name]->type :
+											'string',
+						'display_as' => isset($this->display_as[$field_name]) ?
+												$this->display_as[$field_name] :
+												ucfirst(str_replace("_"," ",$field_name)),
+						'required'	=> !empty($this->required_fields) && in_array($field_name,$this->required_fields) ? true : false,
+						'extras'	=> $extras
+					);
+
+					$types[$field_name] = $field_info;
+				}
+			}
+
+		if(!empty($this->edit_fields))
+			foreach($this->edit_fields as $field_object)
+			{
+				$field_name = isset($field_object->field_name) ? $field_object->field_name : $field_object;
+
+				if(!isset($types[$field_name]))//Doesn't exist in the database? Create it for the CRUD
+				{
+					$extras = false;
+					if($this->change_field_type !== null && isset($this->change_field_type[$field_name]))
+					{
+						$field_type = $this->change_field_type[$field_name];
+						$extras 	=  $field_type->extras;
+					}
+
+					$field_info = (object)array(
+						'name' => $field_name,
+						'crud_type' => $this->change_field_type !== null && isset($this->change_field_type[$field_name]) ?
+											$this->change_field_type[$field_name]->type :
+											'string',
+						'display_as' => isset($this->display_as[$field_name]) ?
+												$this->display_as[$field_name] :
+												ucfirst(str_replace("_"," ",$field_name)),
+						'required'	=> in_array($field_name,$this->required_fields) ? true : false,
+						'extras'	=> $extras
+					);
+
+					$types[$field_name] = $field_info;
+				}
+			}
+
+		$this->field_types = $types;
+
+		return $this->field_types;
+	}
+
+	public function get_primary_key()
+	{
+		return $this->basic_model->get_primary_key();
+	}
+
+	/**
+	 * Get the html input for the specific field with the
+	 * current value
+	 *
+	 * @param object $field_info
+	 * @param string $value
+	 * @return object
+	 */
+	protected function get_field_input($field_info, $value = null)
+	{
+			$real_type = $field_info->crud_type;
+
+			$types_array = array(
+					'integer',
+					'text',
+					'true_false',
+					'string',
+					'date',
+					'datetime',
+					'enum',
+					'set',
+					'relation',
+					'relation_readonly',
+					'relation_n_n',
+					'upload_file',
+					'upload_file_readonly',
+					'hidden',
+					'password',
+					'readonly',
+					'dropdown',
+					'multiselect'
+			);
+
+			if (in_array($real_type,$types_array)) {
+				/* A quick way to go to an internal method of type $this->get_{type}_input .
+				 * For example if the real type is integer then we will use the method
+				 * $this->get_integer_input
+				 *  */
+				$field_info->input = $this->{"get_".$real_type."_input"}($field_info,$value);
+			}
+			else
+			{
+				$field_info->input = $this->get_string_input($field_info,$value);
+			}
+
+		return $field_info;
+	}
+
+	protected function change_list_value($field_info, $value = null)
+	{
+		$real_type = $field_info->crud_type;
+
+		switch ($real_type) {
+			case 'hidden':
+			case 'invisible':
+			case 'integer':
+
+			break;
+			case 'true_false':
+				if(is_array($field_info->extras) && array_key_exists($value,$field_info->extras)) {
+					$value = $field_info->extras[$value];
+				} else if(isset($this->default_true_false_text[$value])) {
+					$value = $this->default_true_false_text[$value];
+				}
+			break;
+			case 'string':
+				$value = $this->character_limiter($value,$this->character_limiter,"...");
+			break;
+			case 'text':
+				$value = $this->character_limiter(strip_tags($value),$this->character_limiter,"...");
+			break;
+			case 'date':
+				if(!empty($value) && $value != '0000-00-00' && $value != '1970-01-01')
+				{
+					list($year,$month,$day) = explode("-",$value);
+
+					$value = date($this->php_date_format, mktime (0, 0, 0, (int)$month , (int)$day , (int)$year));
+				}
+				else
+				{
+					$value = '';
+				}
+			break;
+			case 'datetime':
+				if(!empty($value) && $value != '0000-00-00 00:00:00' && $value != '1970-01-01 00:00:00')
+				{
+					list($year,$month,$day) = explode("-",$value);
+					list($hours,$minutes) = explode(":",substr($value,11));
+
+					$value = date($this->php_date_format." - H:i", mktime ((int)$hours , (int)$minutes , 0, (int)$month , (int)$day ,(int)$year));
+				}
+				else
+				{
+					$value = '';
+				}
+			break;
+			case 'enum':
+				$value = $this->character_limiter($value,$this->character_limiter,"...");
+			break;
+
+			case 'multiselect':
+				$value_as_array = array();
+				foreach(explode(",",$value) as $row_value)
+				{
+					$value_as_array[] = array_key_exists($row_value,$field_info->extras) ? $field_info->extras[$row_value] : $row_value;
+				}
+				$value = implode(",",$value_as_array);
+			break;
+
+			case 'relation_n_n':
+				$value = $this->character_limiter(str_replace(',',', ',$value),$this->character_limiter,"...");
+			break;
+
+			case 'password':
+				$value = '******';
+			break;
+
+			case 'dropdown':
+				$value = array_key_exists($value,$field_info->extras) ? $field_info->extras[$value] : $value;
+			break;
+
+			case 'upload_file':
+				if(empty($value))
+				{
+					$value = "";
+				}
+				else
+				{
+					$is_image = !empty($value) &&
+					( substr($value,-4) == '.jpg'
+							|| substr($value,-4) == '.png'
+							|| substr($value,-5) == '.jpeg'
+							|| substr($value,-4) == '.gif'
+							|| substr($value,-5) == '.tiff')
+							? true : false;
+
+					$file_url = base_url().$field_info->extras->upload_path."/$value";
+
+					$file_url_anchor = '<a href="'.$file_url.'"';
+					if($is_image)
+					{
+						$file_url_anchor .= ' class="image-thumbnail"><img src="'.$file_url.'" height="50px">';
+					}
+					else
+					{
+						$file_url_anchor .= ' target="_blank">'.$this->character_limiter($value,$this->character_limiter,'...',true);
+					}
+					$file_url_anchor .= '</a>';
+
+					$value = $file_url_anchor;
+				}
+			break;
+
+			default:
+				$value = $this->character_limiter($value,$this->character_limiter,"...");
+			break;
+		}
+
+		return $value;
+	}
+
+	/**
+	 * Character Limiter of codeigniter (I just don't want to load the helper )
+	 *
+	 * Limits the string based on the character count.  Preserves complete words
+	 * so the character count may not be exactly as specified.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	integer
+	 * @param	string	the end character. Usually an ellipsis
+	 * @return	string
+	 */
+	function character_limiter($str, $n = 500, $end_char = '&#8230;')
+	{
+		if (strlen($str) < $n)
+		{
+			return $str;
+		}
+
+		// a bit complicated, but faster than preg_replace with \s+
+		$str = preg_replace('/ {2,}/', ' ', str_replace(array("\r", "\n", "\t", "\x0B", "\x0C"), ' ', $str));
+
+		if (strlen($str) <= $n)
+		{
+			return $str;
+		}
+
+		$out = '';
+		foreach (explode(' ', trim($str)) as $val)
+		{
+			$out .= $val.' ';
+
+			if (strlen($out) >= $n)
+			{
+				$out = trim($out);
+				return (strlen($out) === strlen($str)) ? $out : $out.$end_char;
+			}
+		}
+	}
+
+	protected function get_type($db_type)
+	{
+		$type = false;
+		if(!empty($db_type->type))
+		{
+			switch ($db_type->type) {
+				case '1':
+				case '3':
+				case 'int':
+				case 'tinyint':
+				case 'mediumint':
+				case 'longint':
+					if( $db_type->db_type == 'tinyint' && $db_type->db_max_length ==  1)
+						$type = 'true_false';
+					else
+						$type = 'integer';
+				break;
+				case '254':
+				case 'string':
+				case 'enum':
+					if($db_type->db_type != 'enum')
+						$type = 'string';
+					else
+						$type = 'enum';
+				break;
+				case 'set':
+					if($db_type->db_type != 'set')
+						$type = 'string';
+					else
+						$type = 'set';
+				break;
+				case '252':
+				case 'blob':
+				case 'text':
+				case 'mediumtext':
+				case 'longtext':
+					$type = 'text';
+				break;
+				case '10':
+				case 'date':
+					$type = 'date';
+				break;
+				case '12':
+				case 'datetime':
+				case 'timestamp':
+					$type = 'datetime';
+				break;
+			}
+		}
+		return $type;
+	}
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Grocery Model Driver
+ *
+ * Drives the model - I'ts so easy like you drive a bicycle :-)
+ *
+ * @package    	grocery CRUD
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ * @version    	1.5.8
+ * @link		http://www.grocerycrud.com/documentation
+ */
+class grocery_CRUD_Model_Driver extends grocery_CRUD_Field_Types
+{
+	/**
+	 * @var Grocery_crud_model
+	 */
+	public $basic_model = null;
+
+	protected function set_default_Model()
+	{
+		$ci = &get_instance();
+		$ci->load->model('Grocery_crud_model');
+
+		$this->basic_model = new Grocery_crud_model();
+	}
+
+	protected function get_total_results()
+	{
+		if(!empty($this->where))
+			foreach($this->where as $where)
+				$this->basic_model->where($where[0],$where[1],$where[2]);
+
+		if(!empty($this->or_where))
+			foreach($this->or_where as $or_where)
+				$this->basic_model->or_where($or_where[0],$or_where[1],$or_where[2]);
+
+		if(!empty($this->like))
+			foreach($this->like as $like)
+				$this->basic_model->like($like[0],$like[1],$like[2]);
+
+		if(!empty($this->or_like))
+			foreach($this->or_like as $or_like)
+				$this->basic_model->or_like($or_like[0],$or_like[1],$or_like[2]);
+
+		if(!empty($this->having))
+			foreach($this->having as $having)
+				$this->basic_model->having($having[0],$having[1],$having[2]);
+
+		if(!empty($this->or_having))
+			foreach($this->or_having as $or_having)
+				$this->basic_model->or_having($or_having[0],$or_having[1],$or_having[2]);
+
+		if(!empty($this->relation))
+			foreach($this->relation as $relation)
+				$this->basic_model->join_relation($relation[0],$relation[1],$relation[2]);
+
+		if(!empty($this->relation_n_n))
+		{
+			$columns = $this->get_columns();
+			foreach($columns as $column)
+			{
+				//Use the relation_n_n ONLY if the column is called . The set_relation_n_n are slow and it will make the table slower without any reason as we don't need those queries.
+				if(isset($this->relation_n_n[$column->field_name]))
+				{
+					$this->basic_model->set_relation_n_n_field($this->relation_n_n[$column->field_name]);
+				}
+			}
+
+		}
+
+		return $this->basic_model->get_total_results();
+	}
+
+    protected function filter_data_from_xss($post_data) {
+        foreach ($post_data as $field_name => $rawData) {
+            if (!is_array($rawData)) {
+                $post_data[$field_name] = filter_var(strip_tags($rawData));
+            }
+        }
+        return $post_data;
+    }
+
+	public function set_model($model_name)
+	{
+		$ci = &get_instance();
+		$ci->load->model('Grocery_crud_model');
+
+		$ci->load->model($model_name);
+
+		$temp = explode('/',$model_name);
+		krsort($temp);
+		foreach($temp as $t)
+		{
+			$real_model_name = $t;
+			break;
+		}
+
+		$this->basic_model = $ci->$real_model_name;
+	}
+
+	protected function set_ajax_list_queries($state_info = null)
+	{
+        $field_types = $this->get_field_types();
+
+		if(!empty($state_info->per_page))
+		{
+			if(empty($state_info->page) || !is_numeric($state_info->page) )
+				$this->limit($state_info->per_page);
+			else
+			{
+				$limit_page = ( ($state_info->page-1) * $state_info->per_page );
+				$this->limit($state_info->per_page, $limit_page);
+			}
+		}
+
+		if(!empty($state_info->order_by))
+		{
+			$this->order_by($state_info->order_by[0],$state_info->order_by[1]);
+		}
+
+		if(!empty($state_info->search))
+		{
+			if (!empty($this->relation)) {
+				foreach ($this->relation as $relation_name => $relation_values) {
+					$temp_relation[$this->_unique_field_name($relation_name)] = $this->_get_field_names_to_search($relation_values);
+                }
+            }
+
+            if (is_array($state_info->search)) {
+                foreach ($state_info->search as $search_field => $search_text) {
+
+
+                    if (isset($temp_relation[$search_field])) {
+                        if (is_array($temp_relation[$search_field])) {
+                            foreach ($temp_relation[$search_field] as $relation_field) {
+                                $this->or_like($relation_field , $search_text);
+                            }
+                        } else {
+                            $this->like($temp_relation[$search_field] , $search_text);
+                        }
+                    } elseif(isset($this->relation_n_n[$search_field])) {
+                        $escaped_text = $this->basic_model->escape_str($search_text);
+                        $this->having($search_field." LIKE '%".$escaped_text."%'");
+                    } else {
+                        $this->like($search_field, $search_text);
+                    }
+
+
+
+                }
+            } elseif ($state_info->search->field !== null) {
+				if (isset($temp_relation[$state_info->search->field])) {
+					if (is_array($temp_relation[$state_info->search->field])) {
+						foreach ($temp_relation[$state_info->search->field] as $search_field) {
+							$this->or_like($search_field , $state_info->search->text);
+                        }
+                    } else {
+						$this->like($temp_relation[$state_info->search->field] , $state_info->search->text);
+                    }
+				} elseif(isset($this->relation_n_n[$state_info->search->field])) {
+					$escaped_text = $this->basic_model->escape_str($state_info->search->text);
+					$this->having($state_info->search->field." LIKE '%".$escaped_text."%'");
+				} else {
+					$this->like($state_info->search->field , $state_info->search->text);
+				}
+			}
+			else
+			{
+				$columns = $this->get_columns();
+
+				$search_text = $state_info->search->text;
+
+				if(!empty($this->where))
+					foreach($this->where as $where)
+						$this->basic_model->having($where[0],$where[1],$where[2]);
+
+				foreach($columns as $column)
+				{
+					if(isset($temp_relation[$column->field_name]))
+					{
+						if(is_array($temp_relation[$column->field_name]))
+						{
+							foreach($temp_relation[$column->field_name] as $search_field)
+							{
+								$this->or_like($search_field, $search_text);
+							}
+						}
+						else
+						{
+							$this->or_like($temp_relation[$column->field_name], $search_text);
+						}
+					}
+					elseif(isset($this->relation_n_n[$column->field_name]))
+					{
+						//@todo have a where for the relation_n_n statement
+					}
+					elseif (isset($field_types[$column->field_name])
+                        && !in_array($field_types[$column->field_name]->type, array('date', 'datetime', 'timestamp')))
+					{
+						$this->or_like($column->field_name, $search_text);
+					}
+				}
+			}
+		}
+	}
+
+	protected function table_exists($table_name = null)
+	{
+		if($this->basic_model->db_table_exists($table_name))
+			return true;
+		return false;
+	}
+
+	protected function get_relation_array($relation_info, $primary_key_value = null, $limit = null)
+	{
+		list($field_name , $related_table , $related_field_title, $where_clause, $order_by)  = $relation_info;
+
+		if($primary_key_value !== null)
+		{
+			$primary_key = $this->basic_model->get_primary_key($related_table);
+
+			//A where clause with the primary key is enough to take the selected key row
+			$where_clause = array($primary_key => $primary_key_value);
+		}
+
+		$relation_array = $this->basic_model->get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, $limit);
+
+		return $relation_array;
+	}
+
+	protected function get_relation_total_rows($relation_info)
+	{
+		list($field_name , $related_table , $related_field_title, $where_clause)  = $relation_info;
+
+		$relation_array = $this->basic_model->get_relation_total_rows($field_name , $related_table , $related_field_title, $where_clause);
+
+		return $relation_array;
+	}
+
+	protected function db_insert_validation()
+	{
+		$validation_result = (object)array('success'=>false);
+
+		$field_types = $this->get_field_types();
+		$required_fields = $this->required_fields;
+		$unique_fields = $this->_unique_fields;
+		$add_fields = $this->get_add_fields();
+
+		if(!empty($required_fields))
+		{
+			foreach($add_fields as $add_field)
+			{
+				$field_name = $add_field->field_name;
+				if(!isset($this->validation_rules[$field_name]) && in_array( $field_name, $required_fields) )
+				{
+					$this->set_rules( $field_name, $field_types[$field_name]->display_as, 'required');
+				}
+			}
+		}
+
+		/** Checking for unique fields. If the field value is not unique then
+		 * return a validation error straight away, if not continue... */
+		if(!empty($unique_fields))
+		{
+			$form_validation = $this->form_validation();
+
+			foreach($add_fields as $add_field)
+			{
+				$field_name = $add_field->field_name;
+				if(in_array( $field_name, $unique_fields) )
+				{
+					$form_validation->set_rules( $field_name,
+							$field_types[$field_name]->display_as,
+							'is_unique['.$this->basic_db_table.'.'.$field_name.']');
+				}
+			}
+
+			if(!$form_validation->run())
+			{
+				$validation_result->error_message = $form_validation->error_string();
+				$validation_result->error_fields = $form_validation->_error_array;
+
+				return $validation_result;
+			}
+		}
+
+		if(!empty($this->validation_rules))
+		{
+			$form_validation = $this->form_validation();
+
+			$add_fields = $this->get_add_fields();
+
+			foreach($add_fields as $add_field)
+			{
+				$field_name = $add_field->field_name;
+				if(isset($this->validation_rules[$field_name]))
+				{
+					$rule = $this->validation_rules[$field_name];
+					$form_validation->set_rules($rule['field'],$rule['label'],$rule['rules'],$rule['errors']);
+				}
+			}
+
+			if($form_validation->run())
+			{
+				$validation_result->success = true;
+			}
+			else
+			{
+				$validation_result->error_message = $form_validation->error_string();
+				$validation_result->error_fields = $form_validation->_error_array;
+			}
+		}
+		else
+		{
+			$validation_result->success = true;
+		}
+
+		return $validation_result;
+	}
+
+	protected function form_validation()
+	{
+		if($this->form_validation === null)
+		{
+			$this->form_validation = new grocery_CRUD_Form_validation();
+			$ci = &get_instance();
+			$ci->load->library('form_validation');
+			$ci->form_validation = $this->form_validation;
+		}
+		return $this->form_validation;
+	}
+
+	protected function db_update_validation()
+	{
+		$validation_result = (object)array('success'=>false);
+
+		$field_types = $this->get_field_types();
+		$required_fields = $this->required_fields;
+		$unique_fields = $this->_unique_fields;
+		$edit_fields = $this->get_edit_fields();
+
+		if(!empty($required_fields))
+		{
+			foreach($edit_fields as $edit_field)
+			{
+				$field_name = $edit_field->field_name;
+				if(!isset($this->validation_rules[$field_name]) && in_array( $field_name, $required_fields) )
+				{
+					$this->set_rules( $field_name, $field_types[$field_name]->display_as, 'required');
+				}
+			}
+		}
+
+
+		/** Checking for unique fields. If the field value is not unique then
+		 * return a validation error straight away, if not continue... */
+		if(!empty($unique_fields))
+		{
+			$form_validation = $this->form_validation();
+
+			$form_validation_check = false;
+
+			foreach($edit_fields as $edit_field)
+			{
+				$field_name = $edit_field->field_name;
+				if(in_array( $field_name, $unique_fields) )
+				{
+					$state_info = $this->getStateInfo();
+					$primary_key = $this->get_primary_key();
+					$field_name_value = $_POST[$field_name];
+
+					$this->basic_model->where($primary_key,$state_info->primary_key);
+					$row = $this->basic_model->get_row();
+
+					if(!isset($row->$field_name)) {
+						throw new Exception("The field name doesn't exist in the database. ".
+								 			"Please use the unique fields only for fields ".
+											"that exist in the database");
+					}
+
+					$previous_field_name_value = $row->$field_name;
+
+					if(!empty($previous_field_name_value) && $previous_field_name_value != $field_name_value) {
+						$form_validation->set_rules( $field_name,
+								$field_types[$field_name]->display_as,
+								'is_unique['.$this->basic_db_table.'.'.$field_name.']');
+
+						$form_validation_check = true;
+					}
+				}
+			}
+
+			if($form_validation_check && !$form_validation->run())
+			{
+				$validation_result->error_message = $form_validation->error_string();
+				$validation_result->error_fields = $form_validation->_error_array;
+
+				return $validation_result;
+			}
+		}
+
+		if(!empty($this->validation_rules))
+		{
+			$form_validation = $this->form_validation();
+
+			$edit_fields = $this->get_edit_fields();
+
+			foreach($edit_fields as $edit_field)
+			{
+				$field_name = $edit_field->field_name;
+				if(isset($this->validation_rules[$field_name]))
+				{
+					$rule = $this->validation_rules[$field_name];
+					$form_validation->set_rules($rule['field'],$rule['label'],$rule['rules'],$rule['errors']);
+				}
+			}
+
+			if($form_validation->run())
+			{
+				$validation_result->success = true;
+			}
+			else
+			{
+				$validation_result->error_message = $form_validation->error_string();
+				$validation_result->error_fields = $form_validation->_error_array;
+			}
+		}
+		else
+		{
+			$validation_result->success = true;
+		}
+
+		return $validation_result;
+	}
+
+	protected function db_insert($state_info)
+	{
+		$validation_result = $this->db_insert_validation();
+
+		if($validation_result->success)
+		{
+			$post_data = $state_info->unwrapped_data;
+
+            if ($this->config->xss_clean) {
+                $post_data = $this->filter_data_from_xss($post_data);
+            }
+
+			$add_fields = $this->get_add_fields();
+
+			if($this->callback_insert === null)
+			{
+				if($this->callback_before_insert !== null)
+				{
+					$callback_return = call_user_func($this->callback_before_insert, $post_data);
+
+					if(!empty($callback_return) && is_array($callback_return))
+						$post_data = $callback_return;
+					elseif($callback_return === false)
+						return false;
+				}
+
+				$insert_data = array();
+				$types = $this->get_field_types();
+				foreach($add_fields as $num_row => $field)
+				{
+					/* If the multiselect or the set is empty then the browser doesn't send an empty array. Instead it sends nothing */
+					if(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect') && !isset($post_data[$field->field_name]))
+					{
+						$post_data[$field->field_name] = array();
+					}
+
+					if(isset($post_data[$field->field_name]) && !isset($this->relation_n_n[$field->field_name]))
+					{
+						if(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && is_array($post_data[$field->field_name]) && empty($post_data[$field->field_name]))
+						{
+							$insert_data[$field->field_name] = null;
+						}
+						elseif(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && $post_data[$field->field_name] === '')
+						{
+							$insert_data[$field->field_name] = null;
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'date')
+						{
+							$insert_data[$field->field_name] = $this->_convert_date_to_sql_date($post_data[$field->field_name]);
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'readonly')
+						{
+							//This empty if statement is to make sure that a readonly field will never inserted/updated
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect'))
+						{
+							$insert_data[$field->field_name] = !empty($post_data[$field->field_name]) ? implode(',',$post_data[$field->field_name]) : '';
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'datetime'){
+							$insert_data[$field->field_name] = $this->_convert_date_to_sql_date(substr($post_data[$field->field_name],0,10)).
+																		substr($post_data[$field->field_name],10);
+						}
+						else
+						{
+							$insert_data[$field->field_name] = $post_data[$field->field_name];
+						}
+					}
+				}
+
+				$insert_result =  $this->basic_model->db_insert($insert_data);
+
+				if($insert_result !== false)
+				{
+					$insert_primary_key = $insert_result;
+				}
+				else
+				{
+					return false;
+				}
+
+				if(!empty($this->relation_n_n))
+				{
+					foreach($this->relation_n_n as $field_name => $field_info)
+					{
+						$relation_data = isset( $post_data[$field_name] ) ? $post_data[$field_name] : array() ;
+						$this->db_relation_n_n_update($field_info, $relation_data  ,$insert_primary_key);
+					}
+				}
+
+				if($this->callback_after_insert !== null)
+				{
+					$callback_return = call_user_func($this->callback_after_insert, $post_data, $insert_primary_key);
+
+					if($callback_return === false)
+					{
+						return false;
+					}
+
+				}
+			}else
+			{
+					$callback_return = call_user_func($this->callback_insert, $post_data);
+
+					if($callback_return === false)
+					{
+						return false;
+					}
+			}
+
+			if(isset($insert_primary_key))
+				return $insert_primary_key;
+			else
+				return true;
+		}
+
+		return false;
+
+	}
+
+	protected function db_update($state_info)
+	{
+		$validation_result = $this->db_update_validation();
+
+		$edit_fields = $this->get_edit_fields();
+
+		if($validation_result->success)
+		{
+			$post_data 		= $state_info->unwrapped_data;
+			$primary_key 	= $state_info->primary_key;
+
+            if ($this->config->xss_clean) {
+                $post_data = $this->filter_data_from_xss($post_data);
+            }
+
+			if($this->callback_update === null)
+			{
+				if($this->callback_before_update !== null)
+				{
+					$callback_return = call_user_func($this->callback_before_update, $post_data, $primary_key);
+
+					if(!empty($callback_return) && is_array($callback_return))
+					{
+						$post_data = $callback_return;
+					}
+					elseif($callback_return === false)
+					{
+						return false;
+					}
+
+				}
+
+				$update_data = array();
+				$types = $this->get_field_types();
+				foreach($edit_fields as $num_row => $field)
+				{
+					/* If the multiselect or the set is empty then the browser doesn't send an empty array. Instead it sends nothing */
+					if(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect') && !isset($post_data[$field->field_name]))
+					{
+						$post_data[$field->field_name] = array();
+					}
+
+					if(isset($post_data[$field->field_name]) && !isset($this->relation_n_n[$field->field_name]))
+					{
+						if(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && is_array($post_data[$field->field_name]) && empty($post_data[$field->field_name]))
+						{
+							$update_data[$field->field_name] = null;
+						}
+						elseif(isset($types[$field->field_name]->db_null) && $types[$field->field_name]->db_null && $post_data[$field->field_name] === '')
+						{
+							$update_data[$field->field_name] = null;
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'date')
+						{
+							$update_data[$field->field_name] = $this->_convert_date_to_sql_date($post_data[$field->field_name]);
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'readonly')
+						{
+							//This empty if statement is to make sure that a readonly field will never inserted/updated
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && ($types[$field->field_name]->crud_type == 'set' || $types[$field->field_name]->crud_type == 'multiselect'))
+						{
+							$update_data[$field->field_name] = !empty($post_data[$field->field_name]) ? implode(',',$post_data[$field->field_name]) : '';
+						}
+						elseif(isset($types[$field->field_name]->crud_type) && $types[$field->field_name]->crud_type == 'datetime'){
+							$update_data[$field->field_name] = $this->_convert_date_to_sql_date(substr($post_data[$field->field_name],0,10)).
+																		substr($post_data[$field->field_name],10);
+						}
+						else
+						{
+							$update_data[$field->field_name] = $post_data[$field->field_name];
+						}
+					}
+				}
+
+				if($this->basic_model->db_update($update_data, $primary_key) === false)
+				{
+					return false;
+				}
+
+				if(!empty($this->relation_n_n))
+				{
+					foreach($this->relation_n_n as $field_name => $field_info)
+					{
+						if (   $this->unset_edit_fields !== null
+							&& is_array($this->unset_edit_fields)
+							&& in_array($field_name,$this->unset_edit_fields)
+						) {
+								continue;
+						}
+
+						$relation_data = isset( $post_data[$field_name] ) ? $post_data[$field_name] : array() ;
+						$this->db_relation_n_n_update($field_info, $relation_data ,$primary_key);
+					}
+				}
+
+				if($this->callback_after_update !== null)
+				{
+					$callback_return = call_user_func($this->callback_after_update, $post_data, $primary_key);
+
+					if($callback_return === false)
+					{
+						return false;
+					}
+
+				}
+			}
+			else
+			{
+				$callback_return = call_user_func($this->callback_update, $post_data, $primary_key);
+
+				if($callback_return === false)
+				{
+					return false;
+				}
+			}
+
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	protected function _convert_date_to_sql_date($date)
+	{
+		$date = substr($date,0,10);
+		if(preg_match('/\d{4}-\d{2}-\d{2}/',$date))
+		{
+			//If it's already a sql-date don't convert it!
+			return $date;
+		}elseif(empty($date))
+		{
+			return '';
+		}
+
+		$date_array = preg_split( '/[-\.\/ ]/', $date);
+		if($this->php_date_format == 'd/m/Y')
+		{
+			$sql_date = date('Y-m-d',mktime(0,0,0,$date_array[1],$date_array[0],$date_array[2]));
+		}
+		elseif($this->php_date_format == 'm/d/Y')
+		{
+			$sql_date = date('Y-m-d',mktime(0,0,0,$date_array[0],$date_array[1],$date_array[2]));
+		}
+		else
+		{
+			$sql_date = $date;
+		}
+
+		return $sql_date;
+	}
+
+	protected function _get_field_names_to_search(array $relation_values)
+	{
+		if(!strstr($relation_values[2],'{')) {
+			return $this->_unique_join_name($relation_values[0]).'.'.$relation_values[2];
+		} else {
+			$relation_values[2] = ' '.$relation_values[2].' ';
+			$temp1 = explode('{',$relation_values[2]);
+			unset($temp1[0]);
+
+			$field_names_array = array();
+			foreach($temp1 as $field) {
+				list($field_name) = explode('}',$field);
+				$field_name = $this->_unique_join_name($relation_values[0]).'.'. $field_name;
+				$field_names_array[] = $field_name;
+			}
+
+			return $field_names_array;
+		}
+	}
+
+    protected function _unique_join_name($field_name)
+    {
+    	return 'j'.substr(md5($field_name),0,8); //This j is because is better for a string to begin with a letter and not a number
+    }
+
+    protected function _unique_field_name($field_name)
+    {
+    	return 's'.substr(md5($field_name),0,8); //This s is because is better for a string to begin with a letter and not a number
+    }
+
+    protected function db_multiple_delete($state_info)
+    {
+        foreach ($state_info->ids as $delete_id) {
+            $result = $this->db_delete((object)array('primary_key' => $delete_id));
+            if (!$result) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+	protected function db_delete($state_info)
+	{
+		$primary_key_value 	= $state_info->primary_key;
+
+		if($this->callback_delete === null)
+		{
+			if($this->callback_before_delete !== null)
+			{
+				$callback_return = call_user_func($this->callback_before_delete, $primary_key_value);
+
+				if($callback_return === false)
+				{
+					return false;
+				}
+
+			}
+
+			if(!empty($this->relation_n_n))
+			{
+				foreach($this->relation_n_n as $field_name => $field_info)
+				{
+					$this->db_relation_n_n_delete( $field_info, $primary_key_value );
+				}
+			}
+
+			$delete_result = $this->basic_model->db_delete($primary_key_value);
+
+			if($delete_result === false)
+			{
+				return false;
+			}
+
+			if($this->callback_after_delete !== null)
+			{
+				$callback_return = call_user_func($this->callback_after_delete, $primary_key_value);
+
+				if($callback_return === false)
+				{
+					return false;
+				}
+
+			}
+		}
+		else
+		{
+			$callback_return = call_user_func($this->callback_delete, $primary_key_value);
+
+			if($callback_return === false)
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	protected function db_relation_n_n_update($field_info, $post_data , $primary_key_value)
+	{
+		$this->basic_model->db_relation_n_n_update($field_info, $post_data , $primary_key_value);
+	}
+
+	protected function db_relation_n_n_delete($field_info, $primary_key_value)
+	{
+		$this->basic_model->db_relation_n_n_delete($field_info, $primary_key_value);
+	}
+
+	protected function get_list()
+	{
+		if(!empty($this->order_by))
+			$this->basic_model->order_by($this->order_by[0],$this->order_by[1]);
+
+		if(!empty($this->where))
+			foreach($this->where as $where)
+				$this->basic_model->where($where[0],$where[1],$where[2]);
+
+		if(!empty($this->or_where))
+			foreach($this->or_where as $or_where)
+				$this->basic_model->or_where($or_where[0],$or_where[1],$or_where[2]);
+
+		if(!empty($this->like))
+			foreach($this->like as $like)
+				$this->basic_model->like($like[0],$like[1],$like[2]);
+
+		if(!empty($this->or_like))
+			foreach($this->or_like as $or_like)
+				$this->basic_model->or_like($or_like[0],$or_like[1],$or_like[2]);
+
+		if(!empty($this->having))
+			foreach($this->having as $having)
+				$this->basic_model->having($having[0],$having[1],$having[2]);
+
+		if(!empty($this->or_having))
+			foreach($this->or_having as $or_having)
+				$this->basic_model->or_having($or_having[0],$or_having[1],$or_having[2]);
+
+		if(!empty($this->relation))
+			foreach($this->relation as $relation)
+				$this->basic_model->join_relation($relation[0],$relation[1],$relation[2]);
+
+		if(!empty($this->relation_n_n))
+		{
+			$columns = $this->get_columns();
+			foreach($columns as $column)
+			{
+				//Use the relation_n_n ONLY if the column is called . The set_relation_n_n are slow and it will make the table slower without any reason as we don't need those queries.
+				if(isset($this->relation_n_n[$column->field_name]))
+				{
+					$this->basic_model->set_relation_n_n_field($this->relation_n_n[$column->field_name]);
+				}
+			}
+
+		}
+
+		if($this->theme_config['crud_paging'] === true)
+		{
+			if($this->limit === null)
+			{
+				$default_per_page = $this->config->default_per_page;
+				if(is_numeric($default_per_page) && $default_per_page >1)
+				{
+					$this->basic_model->limit($default_per_page);
+				}
+				else
+				{
+					$this->basic_model->limit(10);
+				}
+			}
+			else
+			{
+				$this->basic_model->limit($this->limit[0],$this->limit[1]);
+			}
+		}
+
+		$results = $this->basic_model->get_list();
+
+		return $results;
+	}
+
+	protected function get_edit_values($primary_key_value)
+	{
+		$values = $this->basic_model->get_edit_values($primary_key_value);
+
+		if(!empty($this->relation_n_n))
+		{
+			foreach($this->relation_n_n as $field_name => $field_info)
+			{
+				$values->$field_name = $this->get_relation_n_n_selection_array($primary_key_value, $field_info);
+			}
+		}
+
+		return $values;
+	}
+
+	protected function get_relation_n_n_selection_array($primary_key_value, $field_info)
+	{
+		return $this->basic_model->get_relation_n_n_selection_array($primary_key_value, $field_info);
+	}
+
+	protected function get_relation_n_n_unselected_array($field_info, $selected_values)
+	{
+		return $this->basic_model->get_relation_n_n_unselected_array($field_info, $selected_values);
+	}
+
+	protected function set_basic_db_table($table_name = null)
+	{
+		$this->basic_model->set_basic_table($table_name);
+	}
+
+	protected function upload_file($state_info)
+	{
+		if(isset($this->upload_fields[$state_info->field_name]) )
+		{
+			if($this->callback_upload === null)
+			{
+				if($this->callback_before_upload !== null)
+				{
+					$callback_before_upload_response = call_user_func($this->callback_before_upload, $_FILES,  $this->upload_fields[$state_info->field_name]);
+
+					if($callback_before_upload_response === false)
+						return false;
+					elseif(is_string($callback_before_upload_response))
+						return $callback_before_upload_response;
+				}
+
+				$upload_info = $this->upload_fields[$state_info->field_name];
+
+				header('Pragma: no-cache');
+				header('Cache-Control: private, no-cache');
+				header('Content-Disposition: inline; filename="files.json"');
+				header('X-Content-Type-Options: nosniff');
+				header('Access-Control-Allow-Origin: *');
+				header('Access-Control-Allow-Methods: OPTIONS, HEAD, GET, POST, PUT, DELETE');
+				header('Access-Control-Allow-Headers: X-File-Name, X-File-Type, X-File-Size');
+
+				$allowed_files = $this->config->file_upload_allow_file_types;
+
+		                $reg_exp = '';
+		                if(!empty($upload_info->allowed_file_types)){
+		                    $reg_exp = '/(\\.|\\/)('.$upload_info->allowed_file_types.')$/i';
+		                }else{
+		                    $reg_exp = '/(\\.|\\/)('.$allowed_files.')$/i';
+		                }
+
+				$max_file_size_ui = $this->config->file_upload_max_file_size;
+				$max_file_size_bytes = $this->_convert_bytes_ui_to_bytes($max_file_size_ui);
+
+				$options = array(
+					'upload_dir' 		=> $upload_info->upload_path.'/',
+					'param_name'		=> $this->_unique_field_name($state_info->field_name),
+					'upload_url'		=> base_url().$upload_info->upload_path.'/',
+					'accept_file_types' => $reg_exp,
+					'max_file_size'		=> $max_file_size_bytes
+				);
+				$upload_handler = new UploadHandler($options);
+				$upload_handler->default_config_path = $this->default_config_path;
+				$uploader_response = $upload_handler->post();
+
+				if(is_array($uploader_response))
+				{
+					foreach($uploader_response as &$response)
+					{
+						unset($response->delete_url);
+						unset($response->delete_type);
+					}
+				}
+
+				if($this->callback_after_upload !== null)
+				{
+					$callback_after_upload_response = call_user_func($this->callback_after_upload, $uploader_response ,  $this->upload_fields[$state_info->field_name] , $_FILES );
+
+					if($callback_after_upload_response === false)
+						return false;
+					elseif(is_string($callback_after_upload_response))
+						return $callback_after_upload_response;
+					elseif(is_array($callback_after_upload_response))
+						$uploader_response = $callback_after_upload_response;
+				}
+
+				return $uploader_response;
+			}
+			else
+			{
+				$upload_response = call_user_func($this->callback_upload, $_FILES, $this->upload_fields[$state_info->field_name] );
+
+				if($upload_response === false)
+				{
+					return false;
+				}
+				else
+				{
+					return $upload_response;
+				}
+			}
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	protected function delete_file($state_info)
+	{
+
+		if(isset($state_info->field_name) && isset($this->upload_fields[$state_info->field_name]))
+		{
+			$upload_info = $this->upload_fields[$state_info->field_name];
+
+			if(file_exists("{$upload_info->upload_path}/{$state_info->file_name}"))
+			{
+				if( unlink("{$upload_info->upload_path}/{$state_info->file_name}") )
+				{
+					$this->basic_model->db_file_delete($state_info->field_name, $state_info->file_name);
+
+					return true;
+				}
+				else
+				{
+					return false;
+				}
+			}
+			else
+			{
+				$this->basic_model->db_file_delete($state_info->field_name, $state_info->file_name);
+				return true;
+			}
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	protected function ajax_relation($state_info)
+	{
+		if(!isset($this->relation[$state_info->field_name]))
+			return false;
+
+		list($field_name, $related_table, $related_field_title, $where_clause, $order_by)  = $this->relation[$state_info->field_name];
+
+		return $this->basic_model->get_ajax_relation_array($state_info->search, $field_name, $related_table, $related_field_title, $where_clause, $order_by);
+	}
+}
+
+
+/**
+ * PHP grocery CRUD
+ *
+ * LICENSE
+ *
+ * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
+ * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
+ * Please see the corresponding license file for details of these licenses.
+ * You are free to use, modify and distribute this software, but all copyright information must remain.
+ *
+ * @package    	grocery CRUD
+ * @copyright  	Copyright (c) 2010 through 2014, John Skoumbourdis
+ * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * PHP grocery Layout
+ *
+ * Here you manage all the HTML Layout
+ *
+ * @package    	grocery CRUD
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ * @version    	1.5.8
+ */
+class grocery_CRUD_Layout extends grocery_CRUD_Model_Driver
+{
+	private $theme_path 				= null;
+	private $views_as_string			= '';
+	private $echo_and_die				= false;
+	protected $theme 					= null;
+	protected $default_true_false_text 	= array('inactive' , 'active');
+
+	protected $css_files				= array();
+	protected $js_files					= array();
+	protected $js_lib_files				= array();
+	protected $js_config_files			= array();
+
+	protected function set_basic_Layout()
+	{
+		if(!file_exists($this->theme_path.$this->theme.'/views/list_template.php'))
+		{
+			throw new Exception('The template does not exist. Please check your files and try again.', 12);
+			die();
+		}
+	}
+
+	protected function showList($ajax = false, $state_info = null)
+	{
+		$data = $this->get_common_data();
+
+		$data->order_by 	= $this->order_by;
+
+		$data->types 		= $this->get_field_types();
+
+		$data->list = $this->get_list();
+		$data->list = $this->change_list($data->list , $data->types);
+		$data->list = $this->change_list_add_actions($data->list);
+
+		$data->total_results = $this->get_total_results();
+
+        $data->dialog_forms = $this->config->dialog_forms;
+		$data->columns 				= $this->get_columns();
+
+		$data->success_message		= $this->get_success_message_at_list($state_info);
+
+		$data->primary_key 			= $this->get_primary_key();
+		$data->add_url				= $this->getAddUrl();
+		$data->edit_url				= $this->getEditUrl();
+		$data->delete_url			= $this->getDeleteUrl();
+        $data->delete_multiple_url	= $this->getDeleteMultipleUrl();
+		$data->read_url				= $this->getReadUrl();
+		$data->ajax_list_url		= $this->getAjaxListUrl();
+		$data->ajax_list_info_url	= $this->getAjaxListInfoUrl();
+		$data->export_url			= $this->getExportToExcelUrl();
+		$data->print_url			= $this->getPrintUrl();
+		$data->actions				= $this->actions;
+		$data->unique_hash			= $this->get_method_hash();
+		$data->order_by				= $this->order_by;
+
+		$data->unset_add			= $this->unset_add;
+		$data->unset_edit			= $this->unset_edit;
+		$data->unset_read			= $this->unset_read;
+		$data->unset_delete			= $this->unset_delete;
+		$data->unset_export			= $this->unset_export;
+		$data->unset_print			= $this->unset_print;
+
+		$default_per_page = $this->config->default_per_page;
+		$data->paging_options = $this->config->paging_options;
+		$data->default_per_page		= is_numeric($default_per_page) && $default_per_page >1 && in_array($default_per_page,$data->paging_options)? $default_per_page : 25;
+
+		if($data->list === false)
+		{
+			throw new Exception('It is impossible to get data. Please check your model and try again.', 13);
+			$data->list = array();
+		}
+
+		foreach($data->list as $num_row => $row)
+		{
+            $data->list[$num_row]->primary_key_value = $row->{$data->primary_key};
+			$data->list[$num_row]->edit_url = $data->edit_url.'/'.$row->{$data->primary_key};
+			$data->list[$num_row]->delete_url = $data->delete_url.'/'.$row->{$data->primary_key};
+			$data->list[$num_row]->read_url = $data->read_url.'/'.$row->{$data->primary_key};
+		}
+
+		if(!$ajax)
+		{
+			$this->_add_js_vars(array('dialog_forms' => $this->config->dialog_forms));
+
+			$data->list_view = $this->_theme_view('list.php',$data,true);
+			$this->_theme_view('list_template.php',$data);
+		}
+		else
+		{
+			$this->set_echo_and_die();
+			$this->_theme_view('list.php',$data);
+		}
+	}
+
+	protected function exportToExcel($state_info = null)
+	{
+		$data = $this->get_common_data();
+
+		$data->order_by 	= $this->order_by;
+		$data->types 		= $this->get_field_types();
+
+		$data->list = $this->get_list();
+		$data->list = $this->change_list($data->list , $data->types);
+		$data->list = $this->change_list_add_actions($data->list);
+
+		$data->total_results = $this->get_total_results();
+
+		$data->columns 				= $this->get_columns();
+		$data->primary_key 			= $this->get_primary_key();
+
+		@ob_end_clean();
+		$this->_export_to_excel($data);
+	}
+
+	protected function _export_to_excel($data)
+	{
+		/**
+		 * No need to use an external library here. The only bad thing without using external library is that Microsoft Excel is complaining
+		 * that the file is in a different format than specified by the file extension. If you press "Yes" everything will be just fine.
+		 * */
+
+		$string_to_export = "";
+		foreach($data->columns as $column){
+			$string_to_export .= $column->display_as."\t";
+		}
+		$string_to_export .= "\n";
+
+		foreach($data->list as $num_row => $row){
+			foreach($data->columns as $column){
+				$string_to_export .= $this->_trim_export_string($row->{$column->field_name})."\t";
+			}
+			$string_to_export .= "\n";
+		}
+
+		// Convert to UTF-16LE and Prepend BOM
+		$string_to_export = "\xFF\xFE" .mb_convert_encoding($string_to_export, 'UTF-16LE', 'UTF-8');
+
+		$filename = "export-".date("Y-m-d_H:i:s").".xls";
+
+		header('Content-type: application/vnd.ms-excel;charset=UTF-16LE');
+		header('Content-Disposition: attachment; filename='.$filename);
+		header("Cache-Control: no-cache");
+		echo $string_to_export;
+		die();
+	}
+
+	protected function print_webpage($state_info = null)
+	{
+		$data = $this->get_common_data();
+
+		$data->order_by 	= $this->order_by;
+		$data->types 		= $this->get_field_types();
+
+		$data->list = $this->get_list();
+		$data->list = $this->change_list($data->list , $data->types);
+		$data->list = $this->change_list_add_actions($data->list);
+
+		$data->total_results = $this->get_total_results();
+
+		$data->columns 				= $this->get_columns();
+		$data->primary_key 			= $this->get_primary_key();
+
+		@ob_end_clean();
+		$this->_print_webpage($data);
+	}
+
+	protected function _print_webpage($data)
+	{
+		$string_to_print = "<meta charset=\"utf-8\" /><style type=\"text/css\" >
+		#print-table{ color: #000; background: #fff; font-family: Verdana,Tahoma,Helvetica,sans-serif; font-size: 13px;}
+		#print-table table tr td, #print-table table tr th{ border: 1px solid black; border-bottom: none; border-right: none; padding: 4px 8px 4px 4px}
+		#print-table table{ border-bottom: 1px solid black; border-right: 1px solid black}
+		#print-table table tr th{text-align: left;background: #ddd}
+		#print-table table tr:nth-child(odd){background: #eee}
+		</style>";
+		$string_to_print .= "<div id='print-table'>";
+
+		$string_to_print .= '<table width="100%" cellpadding="0" cellspacing="0" ><tr>';
+		foreach($data->columns as $column){
+			$string_to_print .= "<th>".$column->display_as."</th>";
+		}
+		$string_to_print .= "</tr>";
+
+		foreach($data->list as $num_row => $row){
+			$string_to_print .= "<tr>";
+			foreach($data->columns as $column){
+				$string_to_print .= "<td>".$this->_trim_print_string($row->{$column->field_name})."</td>";
+			}
+			$string_to_print .= "</tr>";
+		}
+
+		$string_to_print .= "</table></div>";
+
+		echo $string_to_print;
+		die();
+	}
+
+	protected function _trim_export_string($value)
+	{
+		$value = str_replace(array("&nbsp;","&amp;","&gt;","&lt;"),array(" ","&",">","<"),$value);
+		return  strip_tags(str_replace(array("\t","\n","\r"),"",$value));
+	}
+
+	protected function _trim_print_string($value)
+	{
+		$value = str_replace(array("&nbsp;","&amp;","&gt;","&lt;"),array(" ","&",">","<"),$value);
+
+		//If the value has only spaces and nothing more then add the whitespace html character
+		if(str_replace(" ","",$value) == "")
+			$value = "&nbsp;";
+
+		return strip_tags($value);
+	}
+
+	protected function set_echo_and_die()
+	{
+		$this->echo_and_die = true;
+	}
+
+	protected function unset_echo_and_die()
+	{
+		$this->echo_and_die = false;
+	}
+
+	protected function showListInfo()
+	{
+		$this->set_echo_and_die();
+
+		$total_results = (int)$this->get_total_results();
+		@ob_end_clean();
+		echo json_encode(array('total_results' => $total_results));
+		die();
+	}
+
+	protected function change_list_add_actions($list)
+	{
+		if(empty($this->actions))
+			return $list;
+
+		$primary_key = $this->get_primary_key();
+
+		foreach($list as $num_row => $row)
+		{
+			$actions_urls = array();
+			foreach($this->actions as $unique_id => $action)
+			{
+				if(!empty($action->url_callback))
+				{
+					$actions_urls[$unique_id] = call_user_func($action->url_callback, $row->$primary_key, $row);
+				}
+				else
+				{
+					$actions_urls[$unique_id] =
+						$action->url_has_http ?
+							$action->link_url.$row->$primary_key :
+							site_url($action->link_url.'/'.$row->$primary_key);
+				}
+			}
+			$row->action_urls = $actions_urls;
+		}
+
+		return $list;
+	}
+
+	protected function change_list($list,$types)
+	{
+		$primary_key = $this->get_primary_key();
+		$has_callbacks = !empty($this->callback_column) ? true : false;
+		$output_columns = $this->get_columns();
+		foreach($list as $num_row => $row)
+		{
+			foreach($output_columns as $column)
+			{
+				$field_name 	= $column->field_name;
+				$field_value 	= isset( $row->{$column->field_name} ) ? $row->{$column->field_name} : null;
+				if( $has_callbacks && isset($this->callback_column[$field_name]) )
+					$list[$num_row]->$field_name = call_user_func($this->callback_column[$field_name], $field_value, $row);
+				elseif(isset($types[$field_name]))
+					$list[$num_row]->$field_name = $this->change_list_value($types[$field_name] , $field_value);
+				else
+					$list[$num_row]->$field_name = $field_value;
+			}
+		}
+
+		return $list;
+	}
+
+	protected function showAddForm()
+	{
+		$this->set_js_lib($this->default_javascript_path.'/'.grocery_CRUD::JQUERY);
+
+		$data 				= $this->get_common_data();
+		$data->types 		= $this->get_field_types();
+
+		$data->list_url 		= $this->getListUrl();
+		$data->insert_url		= $this->getInsertUrl();
+		$data->validation_url	= $this->getValidationInsertUrl();
+		$data->input_fields 	= $this->get_add_input_fields();
+
+		$data->fields 			= $this->get_add_fields();
+		$data->hidden_fields	= $this->get_add_hidden_fields();
+		$data->unset_back_to_list	= $this->unset_back_to_list;
+		$data->unique_hash			= $this->get_method_hash();
+		$data->is_ajax 			= $this->_is_ajax();
+
+		$this->_theme_view('add.php',$data);
+		$this->_inline_js("var js_date_format = '".$this->js_date_format."';");
+
+		$this->_get_ajax_results();
+	}
+
+	protected function showEditForm($state_info)
+	{
+		$this->set_js_lib($this->default_javascript_path.'/'.grocery_CRUD::JQUERY);
+
+		$data 				= $this->get_common_data();
+		$data->types 		= $this->get_field_types();
+
+		$data->field_values = $this->get_edit_values($state_info->primary_key);
+
+		$data->add_url		= $this->getAddUrl();
+
+		$data->list_url 	= $this->getListUrl();
+		$data->update_url	= $this->getUpdateUrl($state_info);
+		$data->delete_url	= $this->getDeleteUrl($state_info);
+		$data->read_url		= $this->getReadUrl($state_info->primary_key);
+		$data->input_fields = $this->get_edit_input_fields($data->field_values);
+		$data->unique_hash			= $this->get_method_hash();
+
+		$data->fields 		= $this->get_edit_fields();
+		$data->hidden_fields	= $this->get_edit_hidden_fields();
+		$data->unset_back_to_list	= $this->unset_back_to_list;
+
+		$data->validation_url	= $this->getValidationUpdateUrl($state_info->primary_key);
+		$data->is_ajax 			= $this->_is_ajax();
+
+		$this->_theme_view('edit.php',$data);
+		$this->_inline_js("var js_date_format = '".$this->js_date_format."';");
+
+		$this->_get_ajax_results();
+	}
+
+	protected function showReadForm($state_info)
+	{
+		$this->set_js_lib($this->default_javascript_path.'/'.grocery_CRUD::JQUERY);
+
+		$data 				= $this->get_common_data();
+		$data->types 		= $this->get_field_types();
+
+		$data->field_values = $this->get_edit_values($state_info->primary_key);
+
+		$data->add_url		= $this->getAddUrl();
+
+		$data->list_url 	= $this->getListUrl();
+		$data->update_url	= $this->getUpdateUrl($state_info);
+		$data->delete_url	= $this->getDeleteUrl($state_info);
+		$data->read_url		= $this->getReadUrl($state_info->primary_key);
+		$data->input_fields = $this->get_read_input_fields($data->field_values);
+		$data->unique_hash			= $this->get_method_hash();
+
+		$data->fields 		= $this->get_read_fields();
+		$data->hidden_fields	= $this->get_edit_hidden_fields();
+		$data->unset_back_to_list	= $this->unset_back_to_list;
+
+		$data->validation_url	= $this->getValidationUpdateUrl($state_info->primary_key);
+		$data->is_ajax 			= $this->_is_ajax();
+
+		$this->_theme_view('read.php',$data);
+		$this->_inline_js("var js_date_format = '".$this->js_date_format."';");
+
+		$this->_get_ajax_results();
+	}
+
+	protected function delete_layout($delete_result = true)
+	{
+		@ob_end_clean();
+		if($delete_result === false)
+		{
+			$error_message = '<p>'.$this->l('delete_error_message').'</p>';
+
+			echo json_encode(array('success' => $delete_result ,'error_message' => $error_message));
+		}
+		else
+		{
+			$success_message = '<p>'.$this->l('delete_success_message').'</p>';
+
+			echo json_encode(array('success' => true , 'success_message' => $success_message));
+		}
+		$this->set_echo_and_die();
+	}
+
+	protected function get_success_message_at_list($field_info = null)
+	{
+		if($field_info !== null && isset($field_info->success_message) && $field_info->success_message)
+		{
+			if(!empty($field_info->primary_key) && !$this->unset_edit)
+			{
+				return $this->l('insert_success_message')." <a class='go-to-edit-form' href='".$this->getEditUrl($field_info->primary_key)."'>".$this->l('form_edit')." {$this->subject}</a> ";
+			}
+			else
+			{
+				return $this->l('insert_success_message');
+			}
+		}
+		else
+		{
+			return null;
+		}
+	}
+
+	protected function insert_layout($insert_result = false)
+	{
+		@ob_end_clean();
+		if($insert_result === false)
+		{
+			echo json_encode(array('success' => false));
+		}
+		else
+		{
+			$success_message = '<p>'.$this->l('insert_success_message');
+
+			if(!$this->unset_back_to_list && !empty($insert_result) && !$this->unset_edit)
+			{
+				$success_message .= " <a class='go-to-edit-form' href='".$this->getEditUrl($insert_result)."'>".$this->l('form_edit')." {$this->subject}</a> ";
+
+				if (!$this->_is_ajax()) {
+					$success_message .= $this->l('form_or');
+				}
+			}
+
+			if(!$this->unset_back_to_list && !$this->_is_ajax())
+			{
+				$success_message .= " <a href='".$this->getListUrl()."'>".$this->l('form_go_back_to_list')."</a>";
+			}
+
+			$success_message .= '</p>';
+
+			echo json_encode(array(
+					'success' => true ,
+					'insert_primary_key' => $insert_result,
+					'success_message' => $success_message,
+					'success_list_url'	=> $this->getListSuccessUrl($insert_result)
+			));
+		}
+		$this->set_echo_and_die();
+	}
+
+	protected function validation_layout($validation_result)
+	{
+		@ob_end_clean();
+		echo json_encode($validation_result);
+		$this->set_echo_and_die();
+	}
+
+	protected function upload_layout($upload_result, $field_name)
+	{
+		@ob_end_clean();
+		if($upload_result !== false && !is_string($upload_result) && empty($upload_result[0]->error))
+		{
+			echo json_encode(
+					(object)array(
+							'success' => true,
+							'files'	=> $upload_result
+					));
+		}
+		else
+		{
+			$result = (object)array('success' => false);
+			if(is_string($upload_result))
+				$result->message = $upload_result;
+			if(!empty($upload_result[0]->error))
+				$result->message = $upload_result[0]->error;
+
+			echo json_encode($result);
+		}
+
+		$this->set_echo_and_die();
+	}
+
+	protected function delete_file_layout($upload_result)
+	{
+		@ob_end_clean();
+		if($upload_result !== false)
+		{
+			echo json_encode( (object)array( 'success' => true ) );
+		}
+		else
+		{
+			echo json_encode((object)array('success' => false));
+		}
+
+		$this->set_echo_and_die();
+	}
+
+	public function set_css($css_file)
+	{
+		$this->css_files[sha1($css_file)] = base_url().$css_file;
+	}
+
+	public function set_js($js_file)
+	{
+		$this->js_files[sha1($js_file)] = base_url().$js_file;
+	}
+
+	public function set_js_lib($js_file)
+	{
+		$this->js_lib_files[sha1($js_file)] = base_url().$js_file;
+		$this->js_files[sha1($js_file)] = base_url().$js_file;
+	}
+
+	public function set_js_config($js_file)
+	{
+		$this->js_config_files[sha1($js_file)] = base_url().$js_file;
+		$this->js_files[sha1($js_file)] = base_url().$js_file;
+	}
+
+	public function is_IE7()
+	{
+		return isset($_SERVER['HTTP_USER_AGENT'])
+					&& (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7') !== false)
+					? true : false;
+	}
+
+	public function get_css_files()
+	{
+		return $this->css_files;
+	}
+
+	public function get_js_files()
+	{
+		return $this->js_files;
+	}
+
+	public function get_js_lib_files()
+	{
+		return $this->js_lib_files;
+	}
+
+	public function get_js_config_files()
+	{
+		return $this->js_config_files;
+	}
+
+	/**
+	 * Load Javascripts
+	 **/
+	protected function load_js_fancybox()
+	{
+		$this->set_css($this->default_css_path.'/jquery_plugins/fancybox/jquery.fancybox.css');
+
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.fancybox-1.3.4.js');
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.easing-1.3.pack.js');
+	}
+
+	protected function load_js_chosen()
+	{
+		$this->set_css($this->default_css_path.'/jquery_plugins/chosen/chosen.css');
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.chosen.min.js');
+	}
+
+	protected function load_js_jqueryui()
+	{
+		$this->set_css($this->default_css_path.'/ui/simple/'.grocery_CRUD::JQUERY_UI_CSS);
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/ui/'.grocery_CRUD::JQUERY_UI_JS);
+	}
+
+	protected function load_js_uploader()
+	{
+		$this->set_css($this->default_css_path.'/ui/simple/'.grocery_CRUD::JQUERY_UI_CSS);
+		$this->set_css($this->default_css_path.'/jquery_plugins/file_upload/file-uploader.css');
+		$this->set_css($this->default_css_path.'/jquery_plugins/file_upload/jquery.fileupload-ui.css');
+
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/ui/'.grocery_CRUD::JQUERY_UI_JS);
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/tmpl.min.js');
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/load-image.min.js');
+
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.iframe-transport.js');
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.fileupload.js');
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.fileupload.config.js');
+	}
+
+	protected function get_layout()
+	{
+		$js_files = $this->get_js_files();
+		$css_files =  $this->get_css_files();
+
+		$js_lib_files = $this->get_js_lib_files();
+		$js_config_files = $this->get_js_config_files();
+
+		if ($this->unset_jquery) {
+			unset($js_files[sha1($this->default_javascript_path.'/'.grocery_CRUD::JQUERY)]);
+		}
+
+		if ($this->unset_jquery_ui) {
+			unset($css_files[sha1($this->default_css_path.'/ui/simple/'.grocery_CRUD::JQUERY_UI_CSS)]);
+			unset($js_files[sha1($this->default_javascript_path.'/jquery_plugins/ui/'.grocery_CRUD::JQUERY_UI_JS)]);
+		}
+
+		if ($this->unset_bootstrap) {
+			unset($js_files[sha1($this->default_theme_path.'/bootstrap/js/bootstrap/dropdown.js')]);
+			unset($js_files[sha1($this->default_theme_path.'/bootstrap/js/bootstrap/modal.js')]);
+			unset($js_files[sha1($this->default_theme_path.'/bootstrap/js/bootstrap/dropdown.min.js')]);
+			unset($js_files[sha1($this->default_theme_path.'/bootstrap/js/bootstrap/modal.min.js')]);
+			unset($css_files[sha1($this->default_theme_path.'/bootstrap/css/bootstrap/bootstrap.css')]);
+			unset($css_files[sha1($this->default_theme_path.'/bootstrap/css/bootstrap/bootstrap.min.css')]);
+            unset($css_files[sha1($this->default_theme_path.'/bootstrap-v4/css/bootstrap/bootstrap.css')]);
+            unset($css_files[sha1($this->default_theme_path.'/bootstrap-v4/css/bootstrap/bootstrap.min.css')]);
+		}
+
+		if($this->echo_and_die === false)
+		{
+			/** Initialize JavaScript variables */
+			$js_vars =  array(
+					'default_javascript_path'	=> base_url().$this->default_javascript_path,
+					'default_css_path'			=> base_url().$this->default_css_path,
+					'default_texteditor_path'	=> base_url().$this->default_texteditor_path,
+					'default_theme_path'		=> base_url().$this->default_theme_path,
+					'base_url'				 	=> base_url()
+			);
+			$this->_add_js_vars($js_vars);
+
+			return (object)array(
+					'js_files' => $js_files,
+					'js_lib_files' => $js_lib_files,
+					'js_config_files' => $js_config_files,
+					'css_files' => $css_files,
+					'output' => $this->views_as_string,
+			);
+		}
+		elseif($this->echo_and_die === true)
+		{
+			echo $this->views_as_string;
+			die();
+		}
+	}
+
+	protected function update_layout($update_result = false, $state_info = null)
+	{
+		@ob_end_clean();
+		if($update_result === false)
+		{
+			echo json_encode(array('success' => $update_result));
+		}
+		else
+		{
+			$success_message = '<p>'.$this->l('update_success_message');
+			if(!$this->unset_back_to_list && !$this->_is_ajax())
+			{
+				$success_message .= " <a href='".$this->getListUrl()."'>".$this->l('form_go_back_to_list')."</a>";
+			}
+			$success_message .= '</p>';
+
+			echo json_encode(array(
+					'success' => true ,
+					'insert_primary_key' => $update_result,
+					'success_message' => $success_message,
+					'success_list_url'	=> $this->getListSuccessUrl($state_info->primary_key)
+			));
+		}
+		$this->set_echo_and_die();
+	}
+
+	protected function get_integer_input($field_info,$value)
+	{
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.numeric.min.js');
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.numeric.config.js');
+		$extra_attributes = '';
+		if(!empty($field_info->db_max_length))
+			$extra_attributes .= "maxlength='{$field_info->db_max_length}'";
+		$input = "<input id='field-{$field_info->name}' name='{$field_info->name}' type='text' value='$value' class='numeric form-control' $extra_attributes />";
+		return $input;
+	}
+
+	protected function get_true_false_input($field_info,$value)
+	{
+		$value_is_null = empty($value) && $value !== '0' && $value !== 0 ? true : false;
+
+		$input = "<div class='pretty-radio-buttons'>";
+
+		$true_string = is_array($field_info->extras) && array_key_exists(1,$field_info->extras) ? $field_info->extras[1] : $this->default_true_false_text[1];
+		$checked = $value === '1' || ($value_is_null && $field_info->default === '1') ? "checked = 'checked'" : "";
+		$input .=
+			"<div class=\"radio\"><label>
+				<input id='field-{$field_info->name}-true' type=\"radio\" name=\"{$field_info->name}\" value=\"1\" $checked />
+				$true_string
+			 </label> </div>";
+
+		$false_string =  is_array($field_info->extras) && array_key_exists(0,$field_info->extras) ? $field_info->extras[0] : $this->default_true_false_text[0];
+		$checked = $value === '0' || ($value_is_null && $field_info->default === '0') ? "checked = 'checked'" : "";
+		$input .=
+			"<div class=\"radio\"><label>
+				<input id='field-{$field_info->name}-false' type=\"radio\" name=\"{$field_info->name}\" value=\"0\" $checked />
+				$false_string
+			 </label> </div>";
+
+		$input .= "</div>";
+
+		return $input;
+	}
+
+	protected function get_string_input($field_info,$value)
+	{
+		$value = !is_string($value) ? '' : str_replace('"',"&quot;",$value);
+
+		$extra_attributes = '';
+		if (!empty($field_info->db_max_length)) {
+
+            if (in_array($field_info->type, array("decimal", "float"))) {
+                $decimal_lentgh = explode(",", $field_info->db_max_length);
+                $decimal_lentgh = ((int)$decimal_lentgh[0]) + 1;
+
+                $extra_attributes .= "maxlength='" . $decimal_lentgh . "'";
+            } else {
+                $extra_attributes .= "maxlength='{$field_info->db_max_length}'";
+            }
+
+        }
+		$input = "<input id='field-{$field_info->name}' class='form-control' name='{$field_info->name}' type='text' value=\"$value\" $extra_attributes />";
+		return $input;
+	}
+
+	protected function get_text_input($field_info,$value)
+	{
+		if($field_info->extras == 'text_editor')
+		{
+			$editor = $this->config->default_text_editor;
+			switch ($editor) {
+				case 'ckeditor':
+					$this->set_js_lib($this->default_texteditor_path.'/ckeditor/ckeditor.js');
+					$this->set_js_lib($this->default_texteditor_path.'/ckeditor/adapters/jquery.js');
+					$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.ckeditor.config.js');
+				break;
+
+				case 'tinymce':
+					$this->set_js_lib($this->default_texteditor_path.'/tiny_mce/jquery.tinymce.js');
+					$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.tine_mce.config.js');
+				break;
+
+				case 'markitup':
+					$this->set_css($this->default_texteditor_path.'/markitup/skins/markitup/style.css');
+					$this->set_css($this->default_texteditor_path.'/markitup/sets/default/style.css');
+
+					$this->set_js_lib($this->default_texteditor_path.'/markitup/jquery.markitup.js');
+					$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.markitup.config.js');
+				break;
+			}
+
+			$class_name = $this->config->text_editor_type == 'minimal' ? 'mini-texteditor' : 'texteditor';
+
+			$input = "<textarea id='field-{$field_info->name}' name='{$field_info->name}' class='$class_name' >$value</textarea>";
+		}
+		else
+		{
+			$input = "<textarea id='field-{$field_info->name}' name='{$field_info->name}' class='form-control'>$value</textarea>";
+		}
+		return $input;
+	}
+
+	protected function get_datetime_input($field_info,$value)
+	{
+		$this->set_css($this->default_css_path.'/ui/simple/'.grocery_CRUD::JQUERY_UI_CSS);
+		$this->set_css($this->default_css_path.'/jquery_plugins/jquery.ui.datetime.css');
+		$this->set_css($this->default_css_path.'/jquery_plugins/jquery-ui-timepicker-addon.css');
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/ui/'.grocery_CRUD::JQUERY_UI_JS);
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery-ui-timepicker-addon.js');
+
+		if($this->language !== 'english')
+		{
+			include($this->default_config_path.'/language_alias.php');
+			if(array_key_exists($this->language, $language_alias))
+			{
+				$i18n_date_js_file = $this->default_javascript_path.'/jquery_plugins/ui/i18n/datepicker/jquery.ui.datepicker-'.$language_alias[$this->language].'.js';
+				if(file_exists($i18n_date_js_file))
+				{
+					$this->set_js_lib($i18n_date_js_file);
+				}
+
+				$i18n_datetime_js_file = $this->default_javascript_path.'/jquery_plugins/ui/i18n/timepicker/jquery-ui-timepicker-'.$language_alias[$this->language].'.js';
+				if(file_exists($i18n_datetime_js_file))
+				{
+					$this->set_js_lib($i18n_datetime_js_file);
+				}
+			}
+		}
+
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery-ui-timepicker-addon.config.js');
+
+		if(!empty($value) && $value != '0000-00-00 00:00:00' && $value != '1970-01-01 00:00:00'){
+			list($year,$month,$day) = explode('-',substr($value,0,10));
+			$date = date($this->php_date_format, mktime(0,0,0,$month,$day,$year));
+			$datetime = $date.substr($value,10);
+		}
+		else
+		{
+			$datetime = '';
+		}
+		$input = "<input id='field-{$field_info->name}' name='{$field_info->name}' type='text' value='$datetime' maxlength='19' class='datetime-input form-control' />
+		<a class='datetime-input-clear' tabindex='-1'>".$this->l('form_button_clear')."</a>
+		({$this->ui_date_format}) hh:mm:ss";
+		return $input;
+	}
+
+	protected function get_hidden_input($field_info,$value)
+	{
+		if($field_info->extras !== null && $field_info->extras != false)
+			$value = $field_info->extras;
+		$input = "<input id='field-{$field_info->name}' type='hidden' name='{$field_info->name}' value='$value' />";
+		return $input;
+	}
+
+	protected function get_password_input($field_info,$value)
+	{
+		$value = !is_string($value) ? '' : $value;
+
+		$extra_attributes = '';
+		if(!empty($field_info->db_max_length))
+			$extra_attributes .= "maxlength='{$field_info->db_max_length}'";
+		$input = "<input id='field-{$field_info->name}' class='form-control' name='{$field_info->name}' type='password' value='$value' $extra_attributes />";
+		return $input;
+	}
+
+	protected function get_date_input($field_info,$value)
+	{
+		$this->set_css($this->default_css_path.'/ui/simple/'.grocery_CRUD::JQUERY_UI_CSS);
+		$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/ui/'.grocery_CRUD::JQUERY_UI_JS);
+
+		if($this->language !== 'english')
+		{
+			include($this->default_config_path.'/language_alias.php');
+			if(array_key_exists($this->language, $language_alias))
+			{
+				$i18n_date_js_file = $this->default_javascript_path.'/jquery_plugins/ui/i18n/datepicker/jquery.ui.datepicker-'.$language_alias[$this->language].'.js';
+				if(file_exists($i18n_date_js_file))
+				{
+					$this->set_js_lib($i18n_date_js_file);
+				}
+			}
+		}
+
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.datepicker.config.js');
+
+		if(!empty($value) && $value != '0000-00-00' && $value != '1970-01-01')
+		{
+			list($year,$month,$day) = explode('-',substr($value,0,10));
+			$date = date($this->php_date_format, mktime(0,0,0,$month,$day,$year));
+		}
+		else
+		{
+			$date = '';
+		}
+
+		$input = "<input id='field-{$field_info->name}' name='{$field_info->name}' type='text' value='$date' maxlength='10' class='datepicker-input form-control' />
+		<a class='datepicker-input-clear' tabindex='-1'>".$this->l('form_button_clear')."</a> (".$this->ui_date_format.")";
+		return $input;
+	}
+
+	protected function get_dropdown_input($field_info,$value)
+	{
+		$this->load_js_chosen();
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.chosen.config.js');
+
+		$select_title = str_replace('{field_display_as}',$field_info->display_as,$this->l('set_relation_title'));
+
+		$input = "<select id='field-{$field_info->name}' name='{$field_info->name}' class='chosen-select' data-placeholder='".$select_title."'>";
+		$options = array('' => '') + $field_info->extras;
+		foreach($options as $option_value => $option_label)
+		{
+			$selected = !empty($value) && $value == $option_value ? "selected='selected'" : '';
+			$input .= "<option value='$option_value' $selected >$option_label</option>";
+		}
+
+		$input .= "</select>";
+		return $input;
+	}
+
+	protected function get_enum_input($field_info,$value)
+	{
+		$this->load_js_chosen();
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.chosen.config.js');
+
+		$select_title = str_replace('{field_display_as}',$field_info->display_as,$this->l('set_relation_title'));
+
+		$input = "<select id='field-{$field_info->name}' name='{$field_info->name}' class='chosen-select' data-placeholder='".$select_title."'>";
+		$options_array = $field_info->extras !== false && is_array($field_info->extras)? $field_info->extras : explode("','",substr($field_info->db_max_length,1,-1));
+		$options_array = array('' => '') + $options_array;
+
+		foreach($options_array as $option)
+		{
+			$selected = !empty($value) && $value == $option ? "selected='selected'" : '';
+			$input .= "<option value='$option' $selected >$option</option>";
+		}
+
+		$input .= "</select>";
+		return $input;
+	}
+
+	protected function get_readonly_input($field_info, $value)
+	{
+		$read_only_value = "&nbsp;";
+
+	    if (!empty($value) && !is_array($value)) {
+	    	$read_only_value = $value;
+    	} elseif (is_array($value)) {
+    		$all_values = array_values($value);
+    		$read_only_value = implode(", ",$all_values);
+    	}
+
+        return '<div id="field-'.$field_info->name.'" class="readonly_label">'.$read_only_value.'</div>';
+	}
+
+	protected function get_set_input($field_info,$value)
+	{
+		$this->load_js_chosen();
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.chosen.config.js');
+
+		$options_array = $field_info->extras !== false && is_array($field_info->extras)? $field_info->extras : explode("','",substr($field_info->db_max_length,1,-1));
+		$selected_values 	= !empty($value) ? explode(",",$value) : array();
+
+		$select_title = str_replace('{field_display_as}',$field_info->display_as,$this->l('set_relation_title'));
+		$input = "<select id='field-{$field_info->name}' name='{$field_info->name}[]' multiple='multiple' size='8' class='chosen-multiple-select' data-placeholder='$select_title' style='width:510px;' >";
+
+		foreach($options_array as $option)
+		{
+			$selected = !empty($value) && in_array($option,$selected_values) ? "selected='selected'" : '';
+			$input .= "<option value='$option' $selected >$option</option>";
+		}
+
+		$input .= "</select>";
+
+		return $input;
+	}
+
+	protected function get_multiselect_input($field_info,$value)
+	{
+		$this->load_js_chosen();
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.chosen.config.js');
+
+		$options_array = $field_info->extras;
+		$selected_values 	= !empty($value) ? explode(",",$value) : array();
+
+		$select_title = str_replace('{field_display_as}',$field_info->display_as,$this->l('set_relation_title'));
+		$input = "<select id='field-{$field_info->name}' name='{$field_info->name}[]' multiple='multiple' size='8' class='chosen-multiple-select' data-placeholder='$select_title' style='width:510px;' >";
+
+		foreach($options_array as $option_value => $option_label)
+		{
+			$selected = !empty($value) && in_array($option_value,$selected_values) ? "selected='selected'" : '';
+			$input .= "<option value='$option_value' $selected >$option_label</option>";
+		}
+
+		$input .= "</select>";
+
+		return $input;
+	}
+
+	protected function get_relation_input($field_info,$value)
+	{
+		$this->load_js_chosen();
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.chosen.config.js');
+
+		$ajax_limitation = 10000;
+		$total_rows = $this->get_relation_total_rows($field_info->extras);
+
+
+		//Check if we will use ajax for our queries or just clien-side javascript
+		$using_ajax = $total_rows > $ajax_limitation ? true : false;
+
+		//We will not use it for now. It is not ready yet. Probably we will have this functionality at version 1.4
+		$using_ajax = false;
+
+		//If total rows are more than the limitation, use the ajax plugin
+		$ajax_or_not_class = $using_ajax ? 'chosen-select' : 'chosen-select';
+
+		$this->_inline_js("var ajax_relation_url = '".$this->getAjaxRelationUrl()."';\n");
+
+		$select_title = str_replace('{field_display_as}',$field_info->display_as,$this->l('set_relation_title'));
+		$input = "<select id='field-{$field_info->name}'  name='{$field_info->name}' class='$ajax_or_not_class' data-placeholder='$select_title' style='width:300px'>";
+		$input .= "<option value=''></option>";
+
+		if(!$using_ajax)
+		{
+			$options_array = $this->get_relation_array($field_info->extras);
+			foreach($options_array as $option_value => $option)
+			{
+				$selected = !empty($value) && $value == $option_value ? "selected='selected'" : '';
+				$input .= "<option value='$option_value' $selected >$option</option>";
+			}
+		}
+		elseif(!empty($value) || (is_numeric($value) && $value == '0') ) //If it's ajax then we only need the selected items and not all the items
+		{
+			$selected_options_array = $this->get_relation_array($field_info->extras, $value);
+			foreach($selected_options_array as $option_value => $option)
+			{
+				$input .= "<option value='$option_value'selected='selected' >$option</option>";
+			}
+		}
+
+		$input .= "</select>";
+		return $input;
+	}
+
+	protected function get_relation_readonly_input($field_info,$value)
+	{
+		$options_array = $this->get_relation_array($field_info->extras);
+
+		$value = isset($options_array[$value]) ? $options_array[$value] : '';
+
+		return $this->get_readonly_input($field_info, $value);
+	}
+
+	protected function get_upload_file_readonly_input($field_info,$value)
+	{
+		$file = $file_url = base_url().$field_info->extras->upload_path.'/'.$value;
+
+		$value = !empty($value) ? '<a href="'.$file.'" target="_blank">'.$value.'</a>' : '';
+
+		return $this->get_readonly_input($field_info, $value);
+	}
+
+	protected function get_relation_n_n_input($field_info_type, $selected_values)
+	{
+		$has_priority_field = !empty($field_info_type->extras->priority_field_relation_table) ? true : false;
+		$is_ie_7 = isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 7') !== false) ? true : false;
+
+		if($has_priority_field || $is_ie_7)
+		{
+			$this->set_css($this->default_css_path.'/ui/simple/'.grocery_CRUD::JQUERY_UI_CSS);
+			$this->set_css($this->default_css_path.'/jquery_plugins/ui.multiselect.css');
+			$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/ui/'.grocery_CRUD::JQUERY_UI_JS);
+			$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/ui.multiselect.min.js');
+			$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.multiselect.js');
+
+			if($this->language !== 'english')
+			{
+				include($this->default_config_path.'/language_alias.php');
+				if(array_key_exists($this->language, $language_alias))
+				{
+					$i18n_date_js_file = $this->default_javascript_path.'/jquery_plugins/ui/i18n/multiselect/ui-multiselect-'.$language_alias[$this->language].'.js';
+					if(file_exists($i18n_date_js_file))
+					{
+						$this->set_js_lib($i18n_date_js_file);
+					}
+				}
+			}
+		}
+		else
+		{
+			$this->set_css($this->default_css_path.'/jquery_plugins/chosen/chosen.css');
+			$this->set_js_lib($this->default_javascript_path.'/jquery_plugins/jquery.chosen.min.js');
+			$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.chosen.config.js');
+		}
+
+		$this->_inline_js("var ajax_relation_url = '".$this->getAjaxRelationUrl()."';\n");
+
+		$field_info 		= $this->relation_n_n[$field_info_type->name]; //As we use this function the relation_n_n exists, so don't need to check
+		$unselected_values 	= $this->get_relation_n_n_unselected_array($field_info, $selected_values);
+
+		if(empty($unselected_values) && empty($selected_values))
+		{
+			$input = "Please add {$field_info_type->display_as} first";
+		}
+		else
+		{
+			$css_class = $has_priority_field || $is_ie_7 ? 'multiselect': 'chosen-multiple-select';
+			$width_style = $has_priority_field || $is_ie_7 ? '' : 'width:510px;';
+
+			$select_title = str_replace('{field_display_as}',$field_info_type->display_as,$this->l('set_relation_title'));
+			$input = "<select id='field-{$field_info_type->name}' name='{$field_info_type->name}[]' multiple='multiple' size='8' class='$css_class' data-placeholder='$select_title' style='$width_style' >";
+
+			if(!empty($unselected_values))
+				foreach($unselected_values as $id => $name)
+				{
+					$input .= "<option value='$id'>$name</option>";
+				}
+
+			if(!empty($selected_values))
+				foreach($selected_values as $id => $name)
+				{
+					$input .= "<option value='$id' selected='selected'>$name</option>";
+				}
+
+			$input .= "</select>";
+		}
+
+		return $input;
+	}
+
+	protected function _convert_bytes_ui_to_bytes($bytes_ui)
+	{
+		$bytes_ui = str_replace(' ','',$bytes_ui);
+		if(strstr($bytes_ui,'MB'))
+			$bytes = (int)(str_replace('MB','',$bytes_ui))*1024*1024;
+		elseif(strstr($bytes_ui,'KB'))
+			$bytes = (int)(str_replace('KB','',$bytes_ui))*1024;
+		elseif(strstr($bytes_ui,'B'))
+			$bytes = (int)(str_replace('B','',$bytes_ui));
+		else
+			$bytes = (int)($bytes_ui);
+
+		return $bytes;
+	}
+
+	protected function get_upload_file_input($field_info, $value)
+	{
+		$this->load_js_uploader();
+
+		//Fancybox
+		$this->load_js_fancybox();
+
+		$this->set_js_config($this->default_javascript_path.'/jquery_plugins/config/jquery.fancybox.config.js');
+
+		$unique = mt_rand();
+
+		$allowed_files = $this->config->file_upload_allow_file_types;
+		$allowed_files_ui = '.'.str_replace('|',',.',$allowed_files);
+		$max_file_size_ui = $this->config->file_upload_max_file_size;
+		$max_file_size_bytes = $this->_convert_bytes_ui_to_bytes($max_file_size_ui);
+
+		$this->_inline_js('
+			var upload_info_'.$unique.' = {
+				accepted_file_types: /(\\.|\\/)('.$allowed_files.')$/i,
+				accepted_file_types_ui : "'.$allowed_files_ui.'",
+				max_file_size: '.$max_file_size_bytes.',
+				max_file_size_ui: "'.$max_file_size_ui.'"
+			};
+
+			var string_upload_file 	= "'.$this->l('form_upload_a_file').'";
+			var string_delete_file 	= "'.$this->l('string_delete_file').'";
+			var string_progress 			= "'.$this->l('string_progress').'";
+			var error_on_uploading 			= "'.$this->l('error_on_uploading').'";
+			var message_prompt_delete_file 	= "'.$this->l('message_prompt_delete_file').'";
+
+			var error_max_number_of_files 	= "'.$this->l('error_max_number_of_files').'";
+			var error_accept_file_types 	= "'.$this->l('error_accept_file_types').'";
+			var error_max_file_size 		= "'.str_replace("{max_file_size}",$max_file_size_ui,$this->l('error_max_file_size')).'";
+			var error_min_file_size 		= "'.$this->l('error_min_file_size').'";
+
+			var base_url = "'.base_url().'";
+			var upload_a_file_string = "'.$this->l('form_upload_a_file').'";
+		');
+
+		$uploader_display_none 	= empty($value) ? "" : "display:none;";
+		$file_display_none  	= empty($value) ?  "display:none;" : "";
+
+		$is_image = !empty($value) &&
+						( substr($value,-4) == '.jpg'
+								|| substr($value,-4) == '.png'
+								|| substr($value,-5) == '.jpeg'
+								|| substr($value,-4) == '.gif'
+								|| substr($value,-5) == '.tiff')
+					? true : false;
+
+		$image_class = $is_image ? 'image-thumbnail' : '';
+
+		$input = '<span class="fileinput-button qq-upload-button" id="upload-button-'.$unique.'" style="'.$uploader_display_none.'">
+			<span>'.$this->l('form_upload_a_file').'</span>
+			<input type="file" name="'.$this->_unique_field_name($field_info->name).'" class="gc-file-upload" rel="'.$this->getUploadUrl($field_info->name).'" id="'.$unique.'">
+			<input class="hidden-upload-input" type="hidden" name="'.$field_info->name.'" value="'.$value.'" rel="'.$this->_unique_field_name($field_info->name).'" />
+		</span>';
+
+		$this->set_css($this->default_css_path.'/jquery_plugins/file_upload/fileuploader.css');
+
+		$file_url = base_url().$field_info->extras->upload_path.'/'.$value;
+
+		$input .= "<div id='uploader_$unique' rel='$unique' class='grocery-crud-uploader' style='$uploader_display_none'></div>";
+		$input .= "<div id='success_$unique' class='upload-success-url' style='$file_display_none padding-top:7px;'>";
+		$input .= "<a href='".$file_url."' id='file_$unique' class='open-file";
+		$input .= $is_image ? " $image_class'><img src='".$file_url."' height='50px'>" : "' target='_blank'>$value";
+		$input .= "</a> ";
+		$input .= "<a href='javascript:void(0)' id='delete_$unique' class='delete-anchor'>".$this->l('form_upload_delete')."</a> ";
+		$input .= "</div><div style='clear:both'></div>";
+		$input .= "<div id='loading-$unique' style='display:none'><span id='upload-state-message-$unique'></span> <span class='qq-upload-spinner'></span> <span id='progress-$unique'></span></div>";
+		$input .= "<div style='display:none'><a href='".$this->getUploadUrl($field_info->name)."' id='url_$unique'></a></div>";
+		$input .= "<div style='display:none'><a href='".$this->getFileDeleteUrl($field_info->name)."' id='delete_url_$unique' rel='$value' ></a></div>";
+
+		return $input;
+	}
+
+	protected function get_add_hidden_fields()
+	{
+		return $this->add_hidden_fields;
+	}
+
+	protected function get_edit_hidden_fields()
+	{
+		return $this->edit_hidden_fields;
+	}
+
+	protected function get_add_input_fields($field_values = null)
+	{
+		$fields = $this->get_add_fields();
+		$types 	= $this->get_field_types();
+
+		$input_fields = array();
+
+		foreach($fields as $field_num => $field)
+		{
+			$field_info = $types[$field->field_name];
+
+			$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
+
+			if(!isset($this->callback_add_field[$field->field_name]))
+			{
+				$field_input = $this->get_field_input($field_info, $field_value);
+			}
+			else
+			{
+				$field_input = $field_info;
+				$field_input->input = call_user_func($this->callback_add_field[$field->field_name], $field_value, null, $field_info);
+			}
+
+			switch ($field_info->crud_type) {
+				case 'invisible':
+					unset($this->add_fields[$field_num]);
+					unset($fields[$field_num]);
+					continue;
+				break;
+				case 'hidden':
+					$this->add_hidden_fields[] = $field_input;
+					unset($this->add_fields[$field_num]);
+					unset($fields[$field_num]);
+					continue;
+				break;
+			}
+
+			$input_fields[$field->field_name] = $field_input;
+		}
+
+		return $input_fields;
+	}
+
+	protected function get_edit_input_fields($field_values = null)
+	{
+		$fields = $this->get_edit_fields();
+		$types 	= $this->get_field_types();
+
+		$input_fields = array();
+
+		foreach($fields as $field_num => $field)
+		{
+			$field_info = $types[$field->field_name];
+
+			$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
+			if(!isset($this->callback_edit_field[$field->field_name]))
+			{
+				$field_input = $this->get_field_input($field_info, $field_value);
+			}
+			else
+			{
+				$primary_key = $this->getStateInfo()->primary_key;
+				$field_input = $field_info;
+				$field_input->input = call_user_func($this->callback_edit_field[$field->field_name], $field_value, $primary_key, $field_info, $field_values);
+			}
+
+			switch ($field_info->crud_type) {
+				case 'invisible':
+					unset($this->edit_fields[$field_num]);
+					unset($fields[$field_num]);
+					continue;
+				break;
+				case 'hidden':
+					$this->edit_hidden_fields[] = $field_input;
+					unset($this->edit_fields[$field_num]);
+					unset($fields[$field_num]);
+					continue;
+				break;
+			}
+
+			$input_fields[$field->field_name] = $field_input;
+		}
+
+		return $input_fields;
+	}
+
+	protected function get_read_input_fields($field_values = null)
+	{
+		$read_fields = $this->get_read_fields();
+
+		$this->field_types = null;
+		$this->required_fields = null;
+
+		$read_inputs = array();
+		foreach ($read_fields as $field) {
+			if (!empty($this->change_field_type)
+					&& isset($this->change_field_type[$field->field_name])
+					&& $this->change_field_type[$field->field_name]->type == 'hidden') {
+				continue;
+			}
+			$this->field_type($field->field_name, 'readonly');
+		}
+
+		$fields = $this->get_read_fields();
+		$types 	= $this->get_field_types();
+
+		$input_fields = array();
+
+		foreach($fields as $field_num => $field)
+		{
+			$field_info = $types[$field->field_name];
+
+			$field_value = !empty($field_values) && isset($field_values->{$field->field_name}) ? $field_values->{$field->field_name} : null;
+			if(!isset($this->callback_read_field[$field->field_name]))
+			{
+				$field_input = $this->get_field_input($field_info, $field_value);
+			}
+			else
+			{
+				$primary_key = $this->getStateInfo()->primary_key;
+				$field_input = $field_info;
+				$field_input->input = call_user_func($this->callback_read_field[$field->field_name], $field_value, $primary_key, $field_info, $field_values);
+			}
+
+			switch ($field_info->crud_type) {
+			    case 'invisible':
+			    	unset($this->read_fields[$field_num]);
+			    	unset($fields[$field_num]);
+			    	continue;
+			    	break;
+			    case 'hidden':
+			    	$this->read_hidden_fields[] = $field_input;
+			    	unset($this->read_fields[$field_num]);
+			    	unset($fields[$field_num]);
+			    	continue;
+			    	break;
+			}
+
+			$input_fields[$field->field_name] = $field_input;
+		}
+
+		return $input_fields;
+	}
+
+	protected function setThemeBasics()
+	{
+		$this->theme_path = $this->default_theme_path;
+		if(substr($this->theme_path,-1) != '/')
+			$this->theme_path = $this->theme_path.'/';
+
+		include($this->theme_path.$this->theme.'/config.php');
+
+		$this->theme_config = $config;
+	}
+
+	public function set_theme($theme = null)
+	{
+		$this->theme = $theme;
+
+		return $this;
+	}
+
+	protected function _get_ajax_results()
+	{
+		//This is a $_POST request rather that $_GET request , because
+		//Codeigniter doesn't like the $_GET requests so much!
+		if ($this->_is_ajax()) {
+			@ob_end_clean();
+			$results= (object)array(
+					'output' => $this->views_as_string,
+					'js_files' => array_values($this->get_js_files()),
+					'js_lib_files' => array_values($this->get_js_lib_files()),
+					'js_config_files' => array_values($this->get_js_config_files()),
+					'css_files' => array_values($this->get_css_files())
+			);
+
+			echo json_encode($results);
+			die;
+		}
+		//else just continue
+	}
+
+	protected function _is_ajax()
+	{
+		return array_key_exists('is_ajax', $_POST) && $_POST['is_ajax'] == 'true' ? true: false;
+	}
+
+	protected function _theme_view($view, $vars = array(), $return = FALSE)
+	{
+		$vars = (is_object($vars)) ? get_object_vars($vars) : $vars;
+
+		$file_exists = FALSE;
+
+		$ext = pathinfo($view, PATHINFO_EXTENSION);
+		$file = ($ext == '') ? $view.'.php' : $view;
+
+		$view_file = $this->theme_path.$this->theme.'/views/';
+
+		if (file_exists($view_file.$file))
+		{
+			$path = $view_file.$file;
+			$file_exists = TRUE;
+		}
+
+		if ( ! $file_exists)
+		{
+			throw new Exception('Unable to load the requested file: '.$file, 16);
+		}
+
+		extract($vars);
+
+		#region buffering...
+		ob_start();
+
+		include($path);
+
+		$buffer = ob_get_contents();
+		@ob_end_clean();
+		#endregion
+
+		if ($return === TRUE)
+		{
+			return $buffer;
+		}
+
+		$this->views_as_string .= $buffer;
+	}
+
+	protected function _inline_js($inline_js = '')
+	{
+		$this->views_as_string .= "<script type=\"text/javascript\">\n{$inline_js}\n</script>\n";
+	}
+
+	protected function _add_js_vars($js_vars = array())
+	{
+		$javascript_as_string = "<script type=\"text/javascript\">\n";
+		foreach ($js_vars as $js_var => $js_value) {
+			$javascript_as_string .= "\tvar $js_var = '$js_value';\n";
+		}
+		$javascript_as_string .= "\n</script>\n";
+		$this->views_as_string .= $javascript_as_string;
+	}
+
+	protected function get_views_as_string()
+	{
+		if(!empty($this->views_as_string))
+			return $this->views_as_string;
+		else
+			return null;
+	}
+}
+
+
+/**
+ * PHP grocery CRUD
+ *
+ * LICENSE
+ *
+ * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
+ * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
+ * Please see the corresponding license file for details of these licenses.
+ * You are free to use, modify and distribute this software, but all copyright information must remain.
+ *
+ * @package    	grocery CRUD
+ * @copyright  	Copyright (c) 2010 through 2014, John Skoumbourdis
+ * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * PHP grocery States
+ *
+ * States of grocery CRUD
+ *
+ * @package    	grocery CRUD
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ * @version    	1.5.8
+ */
+class grocery_CRUD_States extends grocery_CRUD_Layout
+{
+    const STATE_UNKNOWN = 0;
+    const STATE_LIST = 1;
+    const STATE_ADD = 2;
+    const STATE_EDIT = 3;
+    const STATE_DELETE = 4;
+    const STATE_INSERT = 5;
+
+    const STATE_READ = 18;
+    const STATE_DELETE_MULTIPLE = '19';
+
+	protected $states = array(
+		0	=> 'unknown',
+		1	=> 'list',
+		2	=> 'add',
+		3	=> 'edit',
+		4	=> 'delete',
+		5	=> 'insert',
+		6	=> 'update',
+		7	=> 'ajax_list',
+		8   => 'ajax_list_info',
+		9	=> 'insert_validation',
+		10	=> 'update_validation',
+		11	=> 'upload_file',
+		12	=> 'delete_file',
+		13	=> 'ajax_relation',
+		14	=> 'ajax_relation_n_n',
+		15	=> 'success',
+		16  => 'export',
+		17  => 'print',
+		18  => 'read',
+        19  => 'delete_multiple'
+	);
+
+    public function getStateInfo()
+    {
+        $state_code = $this->getStateCode();
+        $segment_object = $this->get_state_info_from_url();
+
+        $first_parameter = $segment_object->first_parameter;
+        $second_parameter = $segment_object->second_parameter;
+
+        $state_info = (object)array();
+
+        switch ($state_code) {
+            case self::STATE_LIST:
+            case self::STATE_ADD:
+                //for now... do nothing! Keeping this switch here in case we need any information at the future.
+                break;
+
+            case self::STATE_EDIT:
+            case self::STATE_READ:
+                if ($first_parameter !== null) {
+                    $state_info = (object) array('primary_key' => $first_parameter);
+                } else {
+                    throw new Exception('On the state "edit" the Primary key cannot be null', 6);
+                    die();
+                }
+                break;
+
+            case self::STATE_DELETE:
+                if ($first_parameter !== null) {
+                    $state_info = (object) array('primary_key' => $first_parameter);
+                } else {
+                    throw new Exception('On the state "delete" the Primary key cannot be null',7);
+                    die();
+                }
+                break;
+
+            case self::STATE_DELETE_MULTIPLE:
+                if (!empty($_POST) && !empty($_POST['ids']) && is_array($_POST['ids'])) {
+                    $state_info = (object) array('ids' => $_POST['ids']);
+                } else {
+                    throw new Exception('On the state "Delete Multiple" you need send the ids as a post array.');
+                    die();
+                }
+                break;
+
+            case self::STATE_INSERT:
+                if(!empty($_POST))
+                {
+                    $state_info = (object)array('unwrapped_data' => $_POST);
+                }
+                else
+                {
+                    throw new Exception('On the state "insert" you must have post data',8);
+                    die();
+                }
+                break;
+
+            case 6:
+                if(!empty($_POST) && $first_parameter !== null)
+                {
+                    $state_info = (object)array('primary_key' => $first_parameter,'unwrapped_data' => $_POST);
+                }
+                elseif(empty($_POST))
+                {
+                    throw new Exception('On the state "update" you must have post data',9);
+                    die();
+                }
+                else
+                {
+                    throw new Exception('On the state "update" the Primary key cannot be null',10);
+                    die();
+                }
+                break;
+
+            case 7:
+            case 8:
+            case 16: //export to excel
+            case 17: //print
+                $state_info = (object)array();
+                $data = !empty($_POST) ? $_POST : $_GET;
+
+                if(!empty($data['per_page']))
+                {
+                    $state_info->per_page = is_numeric($data['per_page']) ? $data['per_page'] : null;
+                }
+                if(!empty($data['page']))
+                {
+                    $state_info->page = is_numeric($data['page']) ? $data['page'] : null;
+                }
+                //If we request an export or a print we don't care about what page we are
+                if($state_code === 16 || $state_code === 17)
+                {
+                    $state_info->page = 1;
+                    $state_info->per_page = 1000000; //a very big number!
+                }
+                if(!empty($data['order_by'][0]))
+                {
+                    $state_info->order_by = $data['order_by'];
+                }
+                if(!empty($data['search_text']))
+                {
+                    if(empty($data['search_field']))
+                    {
+                        $search_text = strip_tags($data['search_field']);
+                        $state_info->search = (object)array('field' => null , 'text' => $data['search_text']);
+                    }
+                    else
+                    {
+                        if (is_array($data['search_field'])) {
+                            $search_array = array();
+                            foreach ($data['search_field'] as $search_key => $search_field_name) {
+                                $search_array[$search_field_name] = !empty($data['search_text'][$search_key]) ? $data['search_text'][$search_key] : '';
+                            }
+                            $state_info->search	= $search_array;
+                        } else {
+                            $state_info->search	= (object)array(
+                                'field' => strip_tags($data['search_field']) ,
+                                'text' => $data['search_text'] );
+                        }
+                    }
+                }
+                break;
+
+            case 9:
+
+                break;
+
+            case 10:
+                if($first_parameter !== null)
+                {
+                    $state_info = (object)array('primary_key' => $first_parameter);
+                }
+                break;
+
+            case 11:
+                $state_info->field_name = $first_parameter;
+                break;
+
+            case 12:
+                $state_info->field_name = $first_parameter;
+                $state_info->file_name = $second_parameter;
+                break;
+
+            case 13:
+                $state_info->field_name = $_POST['field_name'];
+                $state_info->search 	= $_POST['term'];
+                break;
+
+            case 14:
+                $state_info->field_name = $_POST['field_name'];
+                $state_info->search 	= $_POST['term'];
+                break;
+
+            case 15:
+                $state_info = (object)array(
+                    'primary_key' 		=> $first_parameter,
+                    'success_message'	=> true
+                );
+                break;
+        }
+
+        return $state_info;
+    }
+
+	protected function getStateCode()
+	{
+		$state_string = $this->get_state_info_from_url()->operation;
+
+		if( $state_string != 'unknown' && in_array( $state_string, $this->states ) )
+			$state_code =  array_search($state_string, $this->states);
+		else
+			$state_code = 0;
+
+		return $state_code;
+	}
+
+	protected function state_url($url = '', $is_list_page = false)
+	{
+		//Easy scenario, we had set the crud_url_path
+		if (!empty($this->crud_url_path)) {
+			$state_url = !empty($this->list_url_path) && $is_list_page?
+							$this->list_url_path :
+							$this->crud_url_path.'/'.$url ;
+		} else {
+			//Complicated scenario. The crud_url_path is not specified so we are
+			//trying to understand what is going on from the URL.
+			$ci = &get_instance();
+
+			$segment_object = $this->get_state_info_from_url();
+			$method_name = $this->get_method_name();
+			$segment_position = $segment_object->segment_position;
+
+			$state_url_array = array();
+
+		    if( sizeof($ci->uri->segments) > 0 ) {
+		      foreach($ci->uri->segments as $num => $value)
+		      {
+		        $state_url_array[$num] = $value;
+		        if($num == ($segment_position - 1))
+		          break;
+		      }
+
+		      if( $method_name == 'index' && !in_array( 'index', $state_url_array ) ) //there is a scenario that you don't have the index to your url
+		        $state_url_array[$num+1] = 'index';
+		    }
+
+			$state_url =  site_url(implode('/',$state_url_array).'/'.$url);
+		}
+
+		return $state_url;
+	}
+
+	protected function get_state_info_from_url()
+	{
+		$ci = &get_instance();
+
+		$segment_position = count($ci->uri->segments) + 1;
+		$operation = 'list';
+
+		$segements = $ci->uri->segments;
+		foreach($segements as $num => $value)
+		{
+			if($value != 'unknown' && in_array($value, $this->states))
+			{
+				$segment_position = (int)$num;
+				$operation = $value; //I don't have a "break" here because I want to ensure that is the LAST segment with name that is in the array.
+			}
+		}
+
+		$function_name = $this->get_method_name();
+
+		if($function_name == 'index' && !in_array('index',$ci->uri->segments))
+			$segment_position++;
+
+		$first_parameter = isset($segements[$segment_position+1]) ? $segements[$segment_position+1] : null;
+		$second_parameter = isset($segements[$segment_position+2]) ? $segements[$segment_position+2] : null;
+
+		return (object)array('segment_position' => $segment_position, 'operation' => $operation, 'first_parameter' => $first_parameter, 'second_parameter' => $second_parameter);
+	}
+
+	protected function get_method_hash()
+	{
+		$ci = &get_instance();
+
+		$state_info = $this->get_state_info_from_url();
+		$extra_values = $ci->uri->segment($state_info->segment_position - 1) != $this->get_method_name() ? $ci->uri->segment($state_info->segment_position - 1) : '';
+
+		return $this->crud_url_path !== null
+					? md5($this->crud_url_path)
+					: md5($this->get_controller_name().$this->get_method_name().$extra_values);
+	}
+
+	protected function get_method_name()
+	{
+		$ci = &get_instance();
+		return $ci->router->method;
+	}
+
+	protected function get_controller_name()
+	{
+		$ci = &get_instance();
+		return $ci->router->class;
+	}
+
+	public function getState()
+	{
+		return $this->states[$this->getStateCode()];
+	}
+
+	protected function getListUrl()
+	{
+		return $this->state_url('',true);
+	}
+
+	protected function getAjaxListUrl()
+	{
+		return $this->state_url('ajax_list');
+	}
+
+	protected function getExportToExcelUrl()
+	{
+		return $this->state_url('export');
+	}
+
+	protected function getPrintUrl()
+	{
+		return $this->state_url('print');
+	}
+
+	protected function getAjaxListInfoUrl()
+	{
+		return $this->state_url('ajax_list_info');
+	}
+
+	protected function getAddUrl()
+	{
+		return $this->state_url('add');
+	}
+
+	protected function getInsertUrl()
+	{
+		return $this->state_url('insert');
+	}
+
+	protected function getValidationInsertUrl()
+	{
+		return $this->state_url('insert_validation');
+	}
+
+	protected function getValidationUpdateUrl($primary_key = null)
+	{
+		if($primary_key === null)
+			return $this->state_url('update_validation');
+		else
+			return $this->state_url('update_validation/'.$primary_key);
+	}
+
+	protected function getEditUrl($primary_key = null)
+	{
+		if($primary_key === null)
+			return $this->state_url('edit');
+		else
+			return $this->state_url('edit/'.$primary_key);
+	}
+
+	protected function getReadUrl($primary_key = null)
+	{
+		if($primary_key === null)
+			return $this->state_url('read');
+		else
+			return $this->state_url('read/'.$primary_key);
+	}
+
+	protected function getUpdateUrl($state_info)
+	{
+		return $this->state_url('update/'.$state_info->primary_key);
+	}
+
+	protected function getDeleteUrl($state_info = null)
+	{
+		if (empty($state_info)) {
+            return $this->state_url('delete');
+        } else {
+			return $this->state_url('delete/'.$state_info->primary_key);
+        }
+	}
+
+    protected function getDeleteMultipleUrl()
+    {
+        return $this->state_url('delete_multiple');
+    }
+
+	protected function getListSuccessUrl($primary_key = null)
+	{
+		if(empty($primary_key))
+			return $this->state_url('success',true);
+		else
+			return $this->state_url('success/'.$primary_key,true);
+	}
+
+	protected function getUploadUrl($field_name)
+	{
+		return $this->state_url('upload_file/'.$field_name);
+	}
+
+	protected function getFileDeleteUrl($field_name)
+	{
+		return $this->state_url('delete_file/'.$field_name);
+	}
+
+	protected function getAjaxRelationUrl()
+	{
+		return $this->state_url('ajax_relation');
+	}
+
+	protected function getAjaxRelationManytoManyUrl()
+	{
+		return $this->state_url('ajax_relation_n_n');
+	}
+}
+
+
+/**
+ * PHP grocery CRUD
+ *
+ * LICENSE
+ *
+ * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
+ * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
+ * Please see the corresponding license file for details of these licenses.
+ * You are free to use, modify and distribute this software, but all copyright information must remain.
+ *
+ * @package    	grocery CRUD
+ * @copyright  	Copyright (c) 2010 through 2014, John Skoumbourdis
+ * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @version    	1.5.8
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * PHP grocery CRUD
+ *
+ * Creates a full functional CRUD with few lines of code.
+ *
+ * @package    	grocery CRUD
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ * @license     https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @link		http://www.grocerycrud.com/documentation
+ */
+class Grocery_CRUD extends grocery_CRUD_States
+{
+	/**
+	 * Grocery CRUD version
+	 *
+	 * @var	string
+	 */
+	const	VERSION = "1.5.8";
+
+	const	JQUERY 			= "jquery-1.11.1.min.js";
+	const	JQUERY_UI_JS 	= "jquery-ui-1.10.3.custom.min.js";
+	const	JQUERY_UI_CSS 	= "jquery-ui-1.10.1.custom.min.css";
+
+	protected $state_code 			= null;
+	protected $state_info 			= null;
+	protected $columns				= null;
+
+	private $basic_db_table_checked = false;
+	private $columns_checked		= false;
+	private $add_fields_checked		= false;
+	private $edit_fields_checked	= false;
+	private $read_fields_checked	= false;
+
+	protected $default_theme		= 'flexigrid';
+	protected $language				= null;
+	protected $lang_strings			= array();
+	protected $php_date_format		= null;
+	protected $js_date_format		= null;
+	protected $ui_date_format		= null;
+	protected $character_limiter    = null;
+	protected $config    			= null;
+
+	protected $add_fields			= null;
+	protected $edit_fields			= null;
+	protected $read_fields			= null;
+	protected $add_hidden_fields 	= array();
+	protected $edit_hidden_fields 	= array();
+	protected $field_types 			= null;
+	protected $basic_db_table 		= null;
+	protected $theme_config 		= array();
+	protected $subject 				= null;
+	protected $subject_plural 		= null;
+	protected $display_as 			= array();
+	protected $order_by 			= null;
+	protected $where 				= array();
+	protected $like 				= array();
+	protected $having 				= array();
+	protected $or_having 			= array();
+	protected $limit 				= null;
+	protected $required_fields		= array();
+	protected $_unique_fields 			= array();
+	protected $validation_rules		= array();
+	protected $relation				= array();
+	protected $relation_n_n			= array();
+	protected $upload_fields		= array();
+	protected $actions				= array();
+
+	protected $form_validation		= null;
+	protected $change_field_type	= null;
+	protected $primary_keys			= array();
+	protected $crud_url_path		= null;
+	protected $list_url_path		= null;
+
+	/* The unsetters */
+	protected $unset_texteditor		= array();
+	protected $unset_add			= false;
+	protected $unset_edit			= false;
+	protected $unset_delete			= false;
+	protected $unset_read			= false;
+	protected $unset_jquery			= false;
+	protected $unset_jquery_ui		= false;
+	protected $unset_bootstrap 		= false;
+	protected $unset_list			= false;
+	protected $unset_export			= false;
+	protected $unset_print			= false;
+	protected $unset_back_to_list	= false;
+	protected $unset_columns		= null;
+	protected $unset_add_fields 	= null;
+	protected $unset_edit_fields	= null;
+	protected $unset_read_fields	= null;
+
+	/* Callbacks */
+	protected $callback_before_insert 	= null;
+	protected $callback_after_insert 	= null;
+	protected $callback_insert 			= null;
+	protected $callback_before_update 	= null;
+	protected $callback_after_update 	= null;
+	protected $callback_update 			= null;
+	protected $callback_before_delete 	= null;
+	protected $callback_after_delete 	= null;
+	protected $callback_delete 			= null;
+	protected $callback_column			= array();
+	protected $callback_add_field		= array();
+	protected $callback_edit_field		= array();
+	protected $callback_upload			= null;
+	protected $callback_before_upload	= null;
+	protected $callback_after_upload	= null;
+
+	protected $default_javascript_path	= null; //autogenerate, please do not modify
+	protected $default_css_path			= null; //autogenerate, please do not modify
+	protected $default_texteditor_path 	= null; //autogenerate, please do not modify
+	protected $default_theme_path		= null; //autogenerate, please do not modify
+	protected $default_language_path	= 'assets/grocery_crud/languages';
+	protected $default_config_path		= 'assets/grocery_crud/config';
+	protected $default_assets_path		= 'assets/grocery_crud';
+
+	/**
+	 *
+	 * Constructor
+	 *
+	 * @access	public
+	 */
+	public function __construct()
+	{
+
+	}
+
+	/**
+	 * The displayed columns that user see
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	array
+	 * @return	void
+	 */
+	public function columns()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->columns = $args;
+
+		return $this;
+	}
+
+
+	/**
+	 * Set Validation Rules
+	 *
+	 * Important note: If the $field is an array then no automated crud fields will take apart
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @param	string
+      * @oaram array
+	 * @return	void
+	 */
+	function set_rules($field, $label = '', $rules = '', $errors = array())
+	{
+		if(is_string($field))
+		{
+			$this->validation_rules[$field] = array('field' => $field, 'label' => $label, 'rules' => $rules, 'errors' => $errors);
+		}elseif(is_array($field))
+		{
+			foreach($field as $num_field => $field_array)
+			{
+				$this->validation_rules[$field_array['field']] = $field_array;
+			}
+		}
+		return $this;
+	}
+
+	/**
+	 *
+	 * Changes the default field type
+	 * @param string $field
+	 * @param string $type
+	 * @param array|string $extras
+	 */
+	public function change_field_type($field , $type, $extras = null)
+	{
+		$field_type = (object)array('type' => $type);
+
+		$field_type->extras = $extras;
+
+		$this->change_field_type[$field] = $field_type;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Just an alias to the change_field_type method
+	 * @param string $field
+	 * @param string $type
+	 * @param array|string $extras
+	 */
+	public function field_type($field , $type, $extras = null)
+	{
+		return $this->change_field_type($field , $type, $extras);
+	}
+
+	/**
+	 * Change the default primary key for a specific table.
+	 * If the $table_name is NULL then the primary key is for the default table name that we added at the set_table method
+	 *
+	 * @param string $primary_key_field
+	 * @param string $table_name
+	 */
+	public function set_primary_key($primary_key_field, $table_name = null)
+	{
+		$this->primary_keys[] = array('field_name' => $primary_key_field, 'table_name' => $table_name);
+
+		return $this;
+	}
+
+	/**
+	 * Unsets the texteditor of the selected fields
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	array
+	 * @return	void
+	 */
+	public function unset_texteditor()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+		foreach($args as $arg)
+		{
+			$this->unset_texteditor[] = $arg;
+		}
+
+		return $this;
+	}
+
+	/**
+	 * Unsets just the jquery library from the js. This function can be used if there is already a jquery included
+	 * in the main template. This will avoid all jquery conflicts.
+	 *
+	 * @return	void
+	 */
+	public function unset_jquery()
+	{
+		$this->unset_jquery = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets the jquery UI Javascript and CSS. This function is really useful
+	 * when the jquery UI JavaScript and CSS are already included in the main template.
+	 * This will avoid all jquery UI conflicts.
+	 *
+	 * @return	void
+	 */
+	public function unset_jquery_ui()
+	{
+		$this->unset_jquery_ui = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets just the twitter bootstrap libraries from the js and css. This function can be used if there is already twitter bootstrap files included
+	 * in the main template. If you are already using a bootstrap template then it's not necessary to load the files again.
+	 *
+	 * @return	void
+	 */
+	public function unset_bootstrap()
+	{
+		$this->unset_bootstrap = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets the add operation from the list
+	 *
+	 * @return	void
+	 */
+	public function unset_add()
+	{
+		$this->unset_add = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets the edit operation from the list
+	 *
+	 * @return	void
+	 */
+	public function unset_edit()
+	{
+		$this->unset_edit = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets the delete operation from the list
+	 *
+	 * @return	void
+	 */
+	public function unset_delete()
+	{
+		$this->unset_delete = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets the read operation from the list
+	 *
+	 * @return	void
+	 */
+	public function unset_read()
+	{
+		$this->unset_read = true;
+
+		return $this;
+	}
+
+	/**
+	 * Just an alias to unset_read
+	 *
+	 * @return	void
+	 * */
+	public function unset_view()
+	{
+		return unset_read();
+	}
+
+	/**
+	 * Unsets the export button and functionality from the list
+	 *
+	 * @return	void
+	 */
+	public function unset_export()
+	{
+		$this->unset_export = true;
+
+		return $this;
+	}
+
+
+	/**
+	 * Unsets the print button and functionality from the list
+	 *
+	 * @return	void
+	 */
+	public function unset_print()
+	{
+		$this->unset_print = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets all the operations from the list
+	 *
+	 * @return	void
+	 */
+	public function unset_operations()
+	{
+		$this->unset_add 	= true;
+		$this->unset_edit 	= true;
+		$this->unset_delete = true;
+		$this->unset_read	= true;
+		$this->unset_export = true;
+		$this->unset_print  = true;
+
+		return $this;
+	}
+
+	/**
+	 * Unsets a column from the list
+	 *
+	 * @return	void.
+	 */
+	public function unset_columns()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->unset_columns = $args;
+
+		return $this;
+	}
+
+	public function unset_list()
+	{
+		$this->unset_list = true;
+
+		return $this;
+	}
+
+	public function unset_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->unset_add_fields = $args;
+		$this->unset_edit_fields = $args;
+		$this->unset_read_fields = $args;
+
+		return $this;
+	}
+
+	public function unset_add_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->unset_add_fields = $args;
+
+		return $this;
+	}
+
+	public function unset_edit_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->unset_edit_fields = $args;
+
+		return $this;
+	}
+
+	public function unset_read_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->unset_read_fields = $args;
+
+		return $this;
+	}
+
+
+	/**
+	 * Unsets everything that has to do with buttons or links with go back to list message
+	 * @access	public
+	 * @return	void
+	 */
+	public function unset_back_to_list()
+	{
+		$this->unset_back_to_list = true;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * The fields that user will see on add/edit
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	array
+	 * @return	void
+	 */
+	public function fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->add_fields = $args;
+		$this->edit_fields = $args;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * The fields that user can see . It is only for the add form
+	 */
+	public function add_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->add_fields = $args;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 *  The fields that user can see . It is only for the edit form
+	 */
+	public function edit_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->edit_fields = $args;
+
+		return $this;
+	}
+
+	public function set_read_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0])) {
+			$args = $args[0];
+		}
+
+		$this->read_fields = $args;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Changes the displaying label of the field
+	 * @param $field_name
+	 * @param $display_as
+	 * @return void
+	 */
+	public function display_as($field_name, $display_as = null)
+	{
+		if(is_array($field_name))
+		{
+			foreach($field_name as $field => $display_as)
+			{
+				$this->display_as[$field] = $display_as;
+			}
+		}
+		elseif($display_as !== null)
+		{
+			$this->display_as[$field_name] = $display_as;
+		}
+		return $this;
+	}
+
+	/**
+	 *
+	 * Load the language strings array from the language file
+	 */
+	protected function _load_language()
+	{
+		if($this->language === null)
+		{
+			$this->language = strtolower($this->config->default_language);
+		}
+		include($this->default_language_path.'/'.$this->language.'.php');
+
+		foreach($lang as $handle => $lang_string)
+			if(!isset($this->lang_strings[$handle]))
+				$this->lang_strings[$handle] = $lang_string;
+
+		$this->default_true_false_text = array( $this->l('form_inactive') , $this->l('form_active'));
+		$this->subject = $this->subject === null ? $this->l('list_record') : $this->subject;
+
+	}
+
+	protected function _load_date_format()
+	{
+		list($php_day, $php_month, $php_year) = array('d','m','Y');
+		list($js_day, $js_month, $js_year) = array('dd','mm','yy');
+		list($ui_day, $ui_month, $ui_year) = array($this->l('ui_day'), $this->l('ui_month'), $this->l('ui_year'));
+
+		$date_format = $this->config->date_format;
+		switch ($date_format) {
+			case 'uk-date':
+				$this->php_date_format 		= "$php_day/$php_month/$php_year";
+				$this->js_date_format		= "$js_day/$js_month/$js_year";
+				$this->ui_date_format		= "$ui_day/$ui_month/$ui_year";
+			break;
+
+			case 'us-date':
+				$this->php_date_format 		= "$php_month/$php_day/$php_year";
+				$this->js_date_format		= "$js_month/$js_day/$js_year";
+				$this->ui_date_format		= "$ui_month/$ui_day/$ui_year";
+			break;
+
+			case 'sql-date':
+			default:
+				$this->php_date_format 		= "$php_year-$php_month-$php_day";
+				$this->js_date_format		= "$js_year-$js_month-$js_day";
+				$this->ui_date_format		= "$ui_year-$ui_month-$ui_day";
+			break;
+		}
+	}
+
+	/**
+	 *
+	 * Set a language string directly
+	 * @param string $handle
+	 * @param string $string
+	 */
+	public function set_lang_string($handle, $lang_string){
+		$this->lang_strings[$handle] = $lang_string;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Just an alias to get_lang_string method
+	 * @param string $handle
+	 */
+	public function l($handle)
+	{
+		return $this->get_lang_string($handle);
+	}
+
+	/**
+	 *
+	 * Get the language string of the inserted string handle
+	 * @param string $handle
+	 */
+	public function get_lang_string($handle)
+	{
+		return $this->lang_strings[$handle];
+	}
+
+	/**
+	 *
+	 * Simply set the language
+	 * @example english
+	 * @param string $language
+	 */
+	public function set_language($language)
+	{
+		$this->language = $language;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	protected function get_columns()
+	{
+		if($this->columns_checked === false)
+		{
+			$field_types = $this->get_field_types();
+			if(empty($this->columns))
+			{
+				$this->columns = array();
+				foreach($field_types as $field)
+				{
+					if( !isset($field->db_extra) || $field->db_extra != 'auto_increment' )
+						$this->columns[] = $field->name;
+				}
+			}
+
+			foreach($this->columns as $col_num => $column)
+			{
+
+				if(isset($this->relation[$column]))
+				{
+
+					$new_column = $this->_unique_field_name($this->relation[$column][0]);
+					$this->columns[$col_num] = $new_column;
+
+					if(isset($this->display_as[$column]))
+					{
+						$display_as = $this->display_as[$column];
+						unset($this->display_as[$column]);
+						$this->display_as[$new_column] = $display_as;
+					}
+					else
+					{
+						$this->display_as[$new_column] = ucfirst(str_replace('_',' ',$column));
+					}
+
+					$column = $new_column;
+					$this->columns[$col_num] = $new_column;
+				}
+				else
+				{
+					if(!empty($this->relation))
+					{
+						$table_name  = $this->get_table();
+						foreach($this->relation as $relation)
+						{
+							if( $relation[2] == $column )
+							{
+								$new_column = $table_name.'.'.$column;
+								if(isset($this->display_as[$column]))
+								{
+									$display_as = $this->display_as[$column];
+									unset($this->display_as[$column]);
+									$this->display_as[$new_column] = $display_as;
+								}
+								else
+								{
+									$this->display_as[$new_column] = ucfirst(str_replace('_',' ',$column));
+								}
+
+								$column = $new_column;
+								$this->columns[$col_num] = $new_column;
+							}
+						}
+					}
+
+				}
+
+				if(isset($this->display_as[$column]))
+					$this->columns[$col_num] = (object)array('field_name' => $column, 'display_as' => $this->display_as[$column]);
+				elseif(isset($field_types[$column]))
+					$this->columns[$col_num] = (object)array('field_name' => $column, 'display_as' => $field_types[$column]->display_as);
+				else
+					$this->columns[$col_num] = (object)array('field_name' => $column, 'display_as' =>
+						ucfirst(str_replace('_',' ',$column)));
+
+				if(!empty($this->unset_columns) && in_array($column,$this->unset_columns))
+				{
+					unset($this->columns[$col_num]);
+				}
+			}
+
+			$this->columns_checked = true;
+
+		}
+
+		return $this->columns;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	protected function get_add_fields()
+	{
+		if($this->add_fields_checked === false)
+		{
+			$field_types = $this->get_field_types();
+			if(!empty($this->add_fields))
+			{
+				foreach($this->add_fields as $field_num => $field)
+				{
+					if(isset($this->display_as[$field]))
+						$this->add_fields[$field_num] = (object)array('field_name' => $field, 'display_as' => $this->display_as[$field]);
+					elseif(isset($field_types[$field]->display_as))
+						$this->add_fields[$field_num] = (object)array('field_name' => $field, 'display_as' => $field_types[$field]->display_as);
+					else
+						$this->add_fields[$field_num] = (object)array('field_name' => $field, 'display_as' => ucfirst(str_replace('_',' ',$field)));
+				}
+			}
+			else
+			{
+				$this->add_fields = array();
+				foreach($field_types as $field)
+				{
+					//Check if an unset_add_field is initialize for this field name
+					if($this->unset_add_fields !== null && is_array($this->unset_add_fields) && in_array($field->name,$this->unset_add_fields))
+						continue;
+
+					if( (!isset($field->db_extra) || $field->db_extra != 'auto_increment') )
+					{
+						if(isset($this->display_as[$field->name]))
+							$this->add_fields[] = (object)array('field_name' => $field->name, 'display_as' => $this->display_as[$field->name]);
+						else
+							$this->add_fields[] = (object)array('field_name' => $field->name, 'display_as' => $field->display_as);
+					}
+				}
+			}
+
+			$this->add_fields_checked = true;
+		}
+		return $this->add_fields;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	protected function get_edit_fields()
+	{
+		if($this->edit_fields_checked === false)
+		{
+			$field_types = $this->get_field_types();
+			if(!empty($this->edit_fields))
+			{
+				foreach($this->edit_fields as $field_num => $field)
+				{
+					if(isset($this->display_as[$field]))
+						$this->edit_fields[$field_num] = (object)array('field_name' => $field, 'display_as' => $this->display_as[$field]);
+					else
+						$this->edit_fields[$field_num] = (object)array('field_name' => $field, 'display_as' => $field_types[$field]->display_as);
+				}
+			}
+			else
+			{
+				$this->edit_fields = array();
+				foreach($field_types as $field)
+				{
+					//Check if an unset_edit_field is initialize for this field name
+					if($this->unset_edit_fields !== null && is_array($this->unset_edit_fields) && in_array($field->name,$this->unset_edit_fields))
+						continue;
+
+					if(!isset($field->db_extra) || $field->db_extra != 'auto_increment')
+					{
+						if(isset($this->display_as[$field->name]))
+							$this->edit_fields[] = (object)array('field_name' => $field->name, 'display_as' => $this->display_as[$field->name]);
+						else
+							$this->edit_fields[] = (object)array('field_name' => $field->name, 'display_as' => $field->display_as);
+					}
+				}
+			}
+
+			$this->edit_fields_checked = true;
+		}
+		return $this->edit_fields;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	protected function get_read_fields()
+	{
+		if($this->read_fields_checked === false)
+		{
+			$field_types = $this->get_field_types();
+			if(!empty($this->read_fields))
+			{
+				foreach($this->read_fields as $field_num => $field)
+				{
+					if(isset($this->display_as[$field]))
+						$this->read_fields[$field_num] = (object)array('field_name' => $field, 'display_as' => $this->display_as[$field]);
+					else
+						$this->read_fields[$field_num] = (object)array('field_name' => $field, 'display_as' => $field_types[$field]->display_as);
+				}
+			}
+			else
+			{
+				$this->read_fields = array();
+				foreach($field_types as $field)
+				{
+					//Check if an unset_read_field is initialize for this field name
+					if($this->unset_read_fields !== null && is_array($this->unset_read_fields) && in_array($field->name,$this->unset_read_fields))
+						continue;
+
+					if(!isset($field->db_extra) || $field->db_extra != 'auto_increment')
+					{
+						if(isset($this->display_as[$field->name]))
+							$this->read_fields[] = (object)array('field_name' => $field->name, 'display_as' => $this->display_as[$field->name]);
+						else
+							$this->read_fields[] = (object)array('field_name' => $field->name, 'display_as' => $field->display_as);
+					}
+				}
+			}
+
+			$this->read_fields_checked = true;
+		}
+		return $this->read_fields;
+	}
+
+	public function order_by($order_by, $direction = 'asc')
+	{
+		$this->order_by = array($order_by,$direction);
+
+		return $this;
+	}
+
+	public function where($key, $value = NULL, $escape = TRUE)
+	{
+		$this->where[] = array($key,$value,$escape);
+
+		return $this;
+	}
+
+	public function or_where($key, $value = NULL, $escape = TRUE)
+	{
+		$this->or_where[] = array($key,$value,$escape);
+
+		return $this;
+	}
+
+	public function like($field, $match = '', $side = 'both')
+	{
+		$this->like[] = array($field, $match, $side);
+
+		return $this;
+	}
+
+	protected function having($key, $value = '', $escape = TRUE)
+	{
+		$this->having[] = array($key, $value, $escape);
+
+		return $this;
+	}
+
+	protected function or_having($key, $value = '', $escape = TRUE)
+	{
+		$this->or_having[] = array($key, $value, $escape);
+
+		return $this;
+	}
+
+	public function or_like($field, $match = '', $side = 'both')
+	{
+		$this->or_like[] = array($field, $match, $side);
+
+		return $this;
+	}
+
+	public function limit($limit, $offset = '')
+	{
+		$this->limit = array($limit,$offset);
+
+		return $this;
+	}
+
+	protected function _initialize_helpers()
+	{
+		$ci = &get_instance();
+
+		$ci->load->helper('url');
+		$ci->load->helper('form');
+	}
+
+	protected function _initialize_variables()
+	{
+		$ci = &get_instance();
+		$ci->load->config('grocery_crud');
+
+		$this->config = (object)array();
+
+		/** Initialize all the config variables into this object */
+		$this->config->default_language 	= $ci->config->item('grocery_crud_default_language');
+		$this->config->date_format 			= $ci->config->item('grocery_crud_date_format');
+		$this->config->default_per_page		= $ci->config->item('grocery_crud_default_per_page');
+		$this->config->file_upload_allow_file_types	= $ci->config->item('grocery_crud_file_upload_allow_file_types');
+		$this->config->file_upload_max_file_size	= $ci->config->item('grocery_crud_file_upload_max_file_size');
+		$this->config->default_text_editor	= $ci->config->item('grocery_crud_default_text_editor');
+		$this->config->text_editor_type		= $ci->config->item('grocery_crud_text_editor_type');
+		$this->config->character_limiter	= $ci->config->item('grocery_crud_character_limiter');
+		$this->config->dialog_forms			= $ci->config->item('grocery_crud_dialog_forms');
+		$this->config->paging_options		= $ci->config->item('grocery_crud_paging_options');
+        $this->config->default_theme        = $ci->config->item('grocery_crud_default_theme');
+        $this->config->environment          = $ci->config->item('grocery_crud_environment');
+        $this->config->xss_clean            = $ci->config->item('grocery_crud_xss_clean');
+
+		/** Initialize default paths */
+		$this->default_javascript_path				= $this->default_assets_path.'/js';
+		$this->default_css_path						= $this->default_assets_path.'/css';
+		$this->default_texteditor_path 				= $this->default_assets_path.'/texteditor';
+		$this->default_theme_path					= $this->default_assets_path.'/themes';
+
+		$this->character_limiter = $this->config->character_limiter;
+
+		if ($this->character_limiter === 0 || $this->character_limiter === '0') {
+			$this->character_limiter = 1000000; //a very big number
+		} elseif($this->character_limiter === null || $this->character_limiter === false) {
+			$this->character_limiter = 30; //is better to have the number 30 rather than the 0 value
+		}
+
+        if ($this->theme === null && !empty($this->config->default_theme)) {
+            $this->set_theme($this->config->default_theme);
+        }
+	}
+
+	protected function _set_primary_keys_to_model()
+	{
+		if(!empty($this->primary_keys))
+		{
+			foreach($this->primary_keys as $primary_key)
+			{
+				$this->basic_model->set_primary_key($primary_key['field_name'],$primary_key['table_name']);
+			}
+		}
+	}
+
+	/**
+	 * Initialize all the required libraries and variables before rendering
+	 */
+	protected function pre_render()
+	{
+		$this->_initialize_variables();
+		$this->_initialize_helpers();
+		$this->_load_language();
+		$this->state_code = $this->getStateCode();
+
+		if($this->basic_model === null)
+			$this->set_default_Model();
+
+		$this->set_basic_db_table($this->get_table());
+
+		$this->_load_date_format();
+
+		$this->_set_primary_keys_to_model();
+	}
+
+	/**
+	 *
+	 * Or else ... make it work! The web application takes decision of what to do and show it to the final user.
+	 * Without this function nothing works. Here is the core of grocery CRUD project.
+	 *
+	 * @access	public
+	 */
+	public function render()
+	{
+		$this->pre_render();
+
+		if( $this->state_code != 0 )
+		{
+			$this->state_info = $this->getStateInfo();
+		}
+		else
+		{
+			throw new Exception('The state is unknown , I don\'t know what I will do with your data!', 4);
+			die();
+		}
+
+		switch ($this->state_code) {
+			case 15://success
+			case 1://list
+				if($this->unset_list)
+				{
+					throw new Exception('You don\'t have permissions for this operation', 14);
+					die();
+				}
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$state_info = $this->getStateInfo();
+
+				$this->showList(false,$state_info);
+
+			break;
+
+			case 2://add
+				if($this->unset_add)
+				{
+					throw new Exception('You don\'t have permissions for this operation', 14);
+					die();
+				}
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$this->showAddForm();
+
+			break;
+
+			case 3://edit
+				if($this->unset_edit)
+				{
+					throw new Exception('You don\'t have permissions for this operation', 14);
+					die();
+				}
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$state_info = $this->getStateInfo();
+
+				$this->showEditForm($state_info);
+
+			break;
+
+			case 4://delete
+				if($this->unset_delete)
+				{
+					throw new Exception('This user is not allowed to do this operation', 14);
+					die();
+				}
+
+				$state_info = $this->getStateInfo();
+				$delete_result = $this->db_delete($state_info);
+
+				$this->delete_layout( $delete_result );
+			break;
+
+			case 5://insert
+				if($this->unset_add)
+				{
+					throw new Exception('This user is not allowed to do this operation', 14);
+					die();
+				}
+
+				$state_info = $this->getStateInfo();
+				$insert_result = $this->db_insert($state_info);
+
+				$this->insert_layout($insert_result);
+			break;
+
+			case 6://update
+				if($this->unset_edit)
+				{
+					throw new Exception('This user is not allowed to do this operation', 14);
+					die();
+				}
+
+				$state_info = $this->getStateInfo();
+				$update_result = $this->db_update($state_info);
+
+				$this->update_layout( $update_result,$state_info);
+			break;
+
+			case 7://ajax_list
+
+				if($this->unset_list)
+				{
+					throw new Exception('You don\'t have permissions for this operation', 14);
+					die();
+				}
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$state_info = $this->getStateInfo();
+				$this->set_ajax_list_queries($state_info);
+
+				$this->showList(true);
+
+			break;
+
+			case 8://ajax_list_info
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$state_info = $this->getStateInfo();
+				$this->set_ajax_list_queries($state_info);
+
+				$this->showListInfo();
+			break;
+
+			case 9://insert_validation
+
+				$validation_result = $this->db_insert_validation();
+
+				$this->validation_layout($validation_result);
+			break;
+
+			case 10://update_validation
+
+				$validation_result = $this->db_update_validation();
+
+				$this->validation_layout($validation_result);
+			break;
+
+			case 11://upload_file
+
+				$state_info = $this->getStateInfo();
+
+				$upload_result = $this->upload_file($state_info);
+
+				$this->upload_layout($upload_result, $state_info->field_name);
+			break;
+
+			case 12://delete_file
+				$state_info = $this->getStateInfo();
+
+				$delete_file_result = $this->delete_file($state_info);
+
+				$this->delete_file_layout($delete_file_result);
+			break;
+			/*
+			case 13: //ajax_relation
+				$state_info = $this->getStateInfo();
+
+				$ajax_relation_result = $this->ajax_relation($state_info);
+
+				$ajax_relation_result[""] = "";
+
+				echo json_encode($ajax_relation_result);
+				die();
+			break;
+
+			case 14: //ajax_relation_n_n
+				echo json_encode(array("34" => 'Johnny' , "78" => "Test"));
+				die();
+			break;
+			*/
+			case 16: //export to excel
+				//a big number just to ensure that the table characters will not be cutted.
+				$this->character_limiter = 1000000;
+
+				if($this->unset_export)
+				{
+					throw new Exception('You don\'t have permissions for this operation', 15);
+					die();
+				}
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$state_info = $this->getStateInfo();
+				$this->set_ajax_list_queries($state_info);
+				$this->exportToExcel($state_info);
+			break;
+
+			case 17: //print
+				//a big number just to ensure that the table characters will not be cutted.
+				$this->character_limiter = 1000000;
+
+				if($this->unset_print)
+				{
+					throw new Exception('You don\'t have permissions for this operation', 15);
+					die();
+				}
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$state_info = $this->getStateInfo();
+				$this->set_ajax_list_queries($state_info);
+				$this->print_webpage($state_info);
+				break;
+
+			case grocery_CRUD_States::STATE_READ:
+				if($this->unset_read)
+				{
+					throw new Exception('You don\'t have permissions for this operation', 14);
+					die();
+				}
+
+				if($this->theme === null)
+					$this->set_theme($this->default_theme);
+				$this->setThemeBasics();
+
+				$this->set_basic_Layout();
+
+				$state_info = $this->getStateInfo();
+
+				$this->showReadForm($state_info);
+
+    			break;
+
+            case grocery_CRUD_States::STATE_DELETE_MULTIPLE:
+
+				if($this->unset_delete)
+                {
+                    throw new Exception('This user is not allowed to do this operation');
+                    die();
+                }
+
+				$state_info = $this->getStateInfo();
+				$delete_result = $this->db_multiple_delete($state_info);
+
+				$this->delete_layout($delete_result);
+
+                break;
+
+		}
+
+		return $this->get_layout();
+	}
+
+	protected function get_common_data()
+	{
+		$data = (object)array();
+
+		$data->subject 				= $this->subject;
+		$data->subject_plural 		= $this->subject_plural;
+
+		return $data;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_before_insert($callback = null)
+	{
+		$this->callback_before_insert = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_after_insert($callback = null)
+	{
+		$this->callback_after_insert = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_insert($callback = null)
+	{
+		$this->callback_insert = $callback;
+
+		return $this;
+	}
+
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_before_update($callback = null)
+	{
+		$this->callback_before_update = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_after_update($callback = null)
+	{
+		$this->callback_after_update = $callback;
+
+		return $this;
+	}
+
+
+	/**
+	 *
+	 * Enter description here ...
+	 * @param mixed $callback
+	 */
+	public function callback_update($callback = null)
+	{
+		$this->callback_update = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_before_delete($callback = null)
+	{
+		$this->callback_before_delete = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_after_delete($callback = null)
+	{
+		$this->callback_after_delete = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 */
+	public function callback_delete($callback = null)
+	{
+		$this->callback_delete = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 * @param string $column
+	 * @param mixed $callback
+	 */
+	public function callback_column($column ,$callback = null)
+	{
+		$this->callback_column[$column] = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 * @param string $field
+	 * @param mixed $callback
+	 */
+	public function callback_field($field, $callback = null)
+	{
+		$this->callback_add_field[$field] = $callback;
+		$this->callback_edit_field[$field] = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 * @param string $field
+	 * @param mixed $callback
+	 */
+	public function callback_add_field($field, $callback = null)
+	{
+		$this->callback_add_field[$field] = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 * @param string $field
+	 * @param mixed $callback
+	 */
+	public function callback_edit_field($field, $callback = null)
+	{
+		$this->callback_edit_field[$field] = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Callback that replace the default auto uploader
+	 *
+	 * @param mixed $callback
+	 * @return grocery_CRUD
+	 */
+	public function callback_upload($callback = null)
+	{
+		$this->callback_upload = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * A callback that triggered before the upload functionality. This callback is suggested for validation checks
+	 * @param mixed $callback
+	 * @return grocery_CRUD
+	 */
+	public function callback_before_upload($callback = null)
+	{
+		$this->callback_before_upload = $callback;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * A callback that triggered after the upload functionality
+	 * @param mixed $callback
+	 * @return grocery_CRUD
+	 */
+	public function callback_after_upload($callback = null)
+	{
+		$this->callback_after_upload = $callback;
+
+		return $this;
+
+	}
+
+	/**
+	 *
+	 * Gets the basic database table of our crud.
+	 * @return string
+	 */
+	public function get_table()
+	{
+		if($this->basic_db_table_checked)
+		{
+			return $this->basic_db_table;
+		}
+		elseif( $this->basic_db_table !== null )
+		{
+			if(!$this->table_exists($this->basic_db_table))
+			{
+				throw new Exception('The table name does not exist. Please check you database and try again.',11);
+				die();
+			}
+			$this->basic_db_table_checked = true;
+			return $this->basic_db_table;
+		}
+		else
+		{
+			//Last try , try to find the table from your view / function name!!! Not suggested but it works .
+			$last_chance_table_name = $this->get_method_name();
+			if($this->table_exists($last_chance_table_name))
+			{
+				$this->set_table($last_chance_table_name);
+			}
+			$this->basic_db_table_checked = true;
+			return $this->basic_db_table;
+
+		}
+
+		return false;
+	}
+
+	/**
+	 *
+	 * The field names of the required fields
+	 */
+	public function required_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->required_fields = $args;
+
+		return $this;
+	}
+
+	/**
+	 * Add the fields that they are as UNIQUE in the database structure
+	 *
+	 * @return grocery_CRUD
+	 */
+	public function unique_fields()
+	{
+		$args = func_get_args();
+
+		if(isset($args[0]) && is_array($args[0]))
+		{
+			$args = $args[0];
+		}
+
+		$this->_unique_fields = $args;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Sets the basic database table that we will get our data.
+	 * @param string $table_name
+	 * @return grocery_CRUD
+	 */
+	public function set_table($table_name)
+	{
+		if(!empty($table_name) && $this->basic_db_table === null)
+		{
+			$this->basic_db_table = $table_name;
+		}
+		elseif(!empty($table_name))
+		{
+			throw new Exception('You have already insert a table name once...', 1);
+		}
+		else
+		{
+			throw new Exception('The table name cannot be empty.', 2);
+			die();
+		}
+
+		return $this;
+	}
+
+	/**
+	 * Set a full URL path to this method.
+	 *
+	 * This method is useful when the path is not specified correctly.
+	 * Especially when we are using routes.
+	 * For example:
+	 * Let's say we have the path http://www.example.com/ however the original url path is
+	 * http://www.example.com/example/index . We have to specify the url so we can have
+	 * all the CRUD operations correctly.
+	 * The url path has to be set from this method like this:
+	 * <code>
+	 * 		$crud->set_crud_url_path(site_url('example/index'));
+	 * </code>
+	 *
+	 * @param string $crud_url_path
+	 * @param string $list_url_path
+	 * @return grocery_CRUD
+	 */
+	public function set_crud_url_path($crud_url_path, $list_url_path = null)
+	{
+		$this->crud_url_path = $crud_url_path;
+
+		//If the list_url_path is empty so we are guessing that the list_url_path
+		//will be the same with crud_url_path
+		$this->list_url_path = !empty($list_url_path) ? $list_url_path : $crud_url_path;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Set a subject to understand what type of CRUD you use.
+     * ----------------------------------------------------------------------------------------------
+     * Subject_plural: Sets the subject to its plural form. For example the plural
+     * of "Customer" is "Customers", "Product" is "Products"... e.t.c.
+	 * @example In this CRUD we work with the table db_categories. The $subject will be the 'Category'
+     * and the $subject_plural will be 'Categories'
+	 * @param string $subject
+	 * @param string $subject_plural
+	 * @return grocery_CRUD
+	 */
+	public function set_subject($subject, $subject_plural = null)
+	{
+		$this->subject = $subject;
+        $this->subject_plural 	= $subject_plural === null ? $subject : $subject_plural;
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Enter description here ...
+	 * @param $title
+	 * @param $image_url
+	 * @param $url
+	 * @param $css_class
+	 * @param $url_callback
+	 */
+	public function add_action( $label, $image_url = '', $link_url = '', $css_class = '', $url_callback = null)
+	{
+		$unique_id = substr($label,0,1).substr(md5($label.$link_url),-8); //The unique id is used for class name so it must begin with a string
+
+		$this->actions[$unique_id]  = (object)array(
+			'label' 		=> $label,
+			'image_url' 	=> $image_url,
+			'link_url'		=> $link_url,
+			'css_class' 	=> $css_class,
+			'url_callback' 	=> $url_callback,
+			'url_has_http'	=> substr($link_url,0,7) == 'http://' || substr($link_url,0,8) == 'https://' ? true : false
+		);
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Set a simple 1-n foreign key relation
+	 * @param string $field_name
+	 * @param string $related_table
+	 * @param string $related_title_field
+	 * @param mixed $where_clause
+	 * @param string $order_by
+     * @return Grocery_CRUD
+	 */
+	public function set_relation($field_name , $related_table, $related_title_field, $where_clause = null, $order_by = null)
+	{
+		$this->relation[$field_name] = array($field_name, $related_table,$related_title_field, $where_clause, $order_by);
+		return $this;
+	}
+
+	/**
+	 *
+	 * Sets a relation with n-n relationship.
+	 * @param string $field_name
+	 * @param string $relation_table
+	 * @param string $selection_table
+	 * @param string $primary_key_alias_to_this_table
+	 * @param string $primary_key_alias_to_selection_table
+	 * @param string $title_field_selection_table
+	 * @param string $priority_field_relation_table
+	 * @param mixed $where_clause
+     * @return Grocery_CRUD
+	 */
+	public function set_relation_n_n($field_name, $relation_table, $selection_table, $primary_key_alias_to_this_table, $primary_key_alias_to_selection_table , $title_field_selection_table , $priority_field_relation_table = null, $where_clause = null)
+	{
+		$this->relation_n_n[$field_name] =
+			(object)array(
+				'field_name' => $field_name,
+				'relation_table' => $relation_table,
+				'selection_table' => $selection_table,
+				'primary_key_alias_to_this_table' => $primary_key_alias_to_this_table,
+				'primary_key_alias_to_selection_table' => $primary_key_alias_to_selection_table ,
+				'title_field_selection_table' => $title_field_selection_table ,
+				'priority_field_relation_table' => $priority_field_relation_table,
+				'where_clause' => $where_clause
+			);
+
+		return $this;
+	}
+
+	/**
+	 *
+	 * Transform a field to an upload field
+	 *
+	 * @param string $field_name
+	 * @param string $upload_path
+     * @return Grocery_CRUD
+	 */
+	public function set_field_upload($field_name, $upload_dir = '', $allowed_file_types = '')
+	{
+		$upload_dir = !empty($upload_dir) && substr($upload_dir,-1,1) == '/'
+						? substr($upload_dir,0,-1)
+						: $upload_dir;
+		$upload_dir = !empty($upload_dir) ? $upload_dir : 'assets/uploads/files';
+
+		/** Check if the upload Url folder exists. If not then throw an exception **/
+		if (!is_dir(FCPATH.$upload_dir)) {
+			throw new Exception("It seems that the folder \"".FCPATH.$upload_dir."\" for the field name
+					\"".$field_name."\" doesn't exists. Please create the folder and try again.");
+		}
+
+		$this->upload_fields[$field_name] = (object) array(
+				'field_name' => $field_name,
+				'upload_path' => $upload_dir,
+				'allowed_file_types' => $allowed_file_types,
+				'encrypted_field_name' => $this->_unique_field_name($field_name));
+		return $this;
+	}
+}
+
+if(defined('CI_VERSION'))
+{
+	$ci = &get_instance();
+	$ci->load->library('Form_validation');
+
+	class grocery_CRUD_Form_validation extends CI_Form_validation{
+
+		public $CI;
+		public $_field_data			= array();
+		public $_config_rules		= array();
+		public $_error_array		= array();
+		public $_error_messages		= array();
+		public $_error_prefix		= '<p>';
+		public $_error_suffix		= '</p>';
+		public $error_string		= '';
+		public $_safe_form_data		= FALSE;
+	}
+}
+
+/*
+ * jQuery File Upload Plugin PHP Example 5.5
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+class UploadHandler
+{
+    private $options;
+    public $default_config_path = null;
+
+    function __construct($options=null) {
+        $this->options = array(
+            'script_url' => $this->getFullUrl().'/'.basename(__FILE__),
+            'upload_dir' => dirname(__FILE__).'/files/',
+            'upload_url' => $this->getFullUrl().'/files/',
+            'param_name' => 'files',
+            // The php.ini settings upload_max_filesize and post_max_size
+            // take precedence over the following max_file_size setting:
+            'max_file_size' => null,
+            'min_file_size' => 1,
+            'accept_file_types' => '/.+$/i',
+            'max_number_of_files' => null,
+            // Set the following option to false to enable non-multipart uploads:
+            'discard_aborted_uploads' => true,
+            // Set to true to rotate images based on EXIF meta data, if available:
+            'orient_image' => false,
+            'image_versions' => array(
+                // Uncomment the following version to restrict the size of
+                // uploaded images. You can also add additional versions with
+                // their own upload directories:
+                /*
+                'large' => array(
+                    'upload_dir' => dirname(__FILE__).'/files/',
+                    'upload_url' => dirname($_SERVER['PHP_SELF']).'/files/',
+                    'max_width' => 1920,
+                    'max_height' => 1200
+                ),
+
+                'thumbnail' => array(
+                    'upload_dir' => dirname(__FILE__).'/thumbnails/',
+                    'upload_url' => $this->getFullUrl().'/thumbnails/',
+                    'max_width' => 80,
+                    'max_height' => 80
+                )
+                */
+            )
+        );
+        if ($options) {
+            // Or else for PHP >= 5.3.0 use: $this->options = array_replace_recursive($this->options, $options);
+            foreach($options as $option_name => $option)
+            {
+            	$this->options[$option_name] = $option;
+            }
+        }
+    }
+
+    function getFullUrl() {
+      	return
+        		(isset($_SERVER['HTTPS']) ? 'https://' : 'http://').
+        		(isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : '').
+        		(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME'].
+        		(isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] === 443 ||
+        		$_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))).
+        		substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/'));
+    }
+
+    private function get_file_object($file_name) {
+        $file_path = $this->options['upload_dir'].$file_name;
+        if (is_file($file_path) && $file_name[0] !== '.') {
+            $file = new stdClass();
+            $file->name = $file_name;
+            $file->size = filesize($file_path);
+            $file->url = $this->options['upload_url'].rawurlencode($file->name);
+            foreach($this->options['image_versions'] as $version => $options) {
+                if (is_file($options['upload_dir'].$file_name)) {
+                    $file->{$version.'_url'} = $options['upload_url']
+                        .rawurlencode($file->name);
+                }
+            }
+            $file->delete_url = $this->options['script_url']
+                .'?file='.rawurlencode($file->name);
+            $file->delete_type = 'DELETE';
+            return $file;
+        }
+        return null;
+    }
+
+    private function get_file_objects() {
+        return array_values(array_filter(array_map(
+            array($this, 'get_file_object'),
+            scandir($this->options['upload_dir'])
+        )));
+    }
+
+    private function create_scaled_image($file_name, $options) {
+        $file_path = $this->options['upload_dir'].$file_name;
+        $new_file_path = $options['upload_dir'].$file_name;
+        list($img_width, $img_height) = @getimagesize($file_path);
+        if (!$img_width || !$img_height) {
+            return false;
+        }
+        $scale = min(
+            $options['max_width'] / $img_width,
+            $options['max_height'] / $img_height
+        );
+        if ($scale > 1) {
+            $scale = 1;
+        }
+        $new_width = $img_width * $scale;
+        $new_height = $img_height * $scale;
+        $new_img = @imagecreatetruecolor($new_width, $new_height);
+        switch (strtolower(substr(strrchr($file_name, '.'), 1))) {
+            case 'jpg':
+            case 'jpeg':
+                $src_img = @imagecreatefromjpeg($file_path);
+                $write_image = 'imagejpeg';
+                break;
+            case 'gif':
+                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
+                $src_img = @imagecreatefromgif($file_path);
+                $write_image = 'imagegif';
+                break;
+            case 'png':
+                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
+                @imagealphablending($new_img, false);
+                @imagesavealpha($new_img, true);
+                $src_img = @imagecreatefrompng($file_path);
+                $write_image = 'imagepng';
+                break;
+            default:
+                $src_img = $image_method = null;
+        }
+        $success = $src_img && @imagecopyresampled(
+            $new_img,
+            $src_img,
+            0, 0, 0, 0,
+            $new_width,
+            $new_height,
+            $img_width,
+            $img_height
+        ) && $write_image($new_img, $new_file_path);
+        // Free up memory (imagedestroy does not delete files):
+        @imagedestroy($src_img);
+        @imagedestroy($new_img);
+        return $success;
+    }
+
+    private function has_error($uploaded_file, $file, $error) {
+        if ($error) {
+			switch($error) {
+				case UPLOAD_ERR_INI_SIZE:
+					return 'The uploaded file exceeds the upload_max_filesize directive in php.ini.';
+					break;
+				case UPLOAD_ERR_PARTIAL:
+					return 'The uploaded file was only partially uploaded.';
+					break;
+				case UPLOAD_ERR_NO_FILE:
+					return 'No file was uploaded.';
+					break;
+				case UPLOAD_ERR_CANT_WRITE:
+					return 'Failed to write file to disk.';
+					break;
+				case UPLOAD_ERR_EXTENSION:
+					return 'File upload stopped by extension.';
+					break;
+				default:
+					return $error;
+					break;
+			}
+        }
+        if (!preg_match($this->options['accept_file_types'], $file->name)) {
+            return 'acceptFileTypes';
+        }
+        if ($uploaded_file && is_uploaded_file($uploaded_file)) {
+            $file_size = filesize($uploaded_file);
+        } else {
+            $file_size = $_SERVER['CONTENT_LENGTH'];
+        }
+
+        if ($this->options['max_file_size'] && (
+                $file_size > $this->options['max_file_size'] ||
+                $file->size > $this->options['max_file_size'])
+            ) {
+            return 'maxFileSize';
+        }
+        if ($this->options['min_file_size'] &&
+            $file_size < $this->options['min_file_size']) {
+            return 'minFileSize';
+        }
+        if (is_int($this->options['max_number_of_files']) && (
+                count($this->get_file_objects()) >= $this->options['max_number_of_files'])
+            ) {
+            return 'maxNumberOfFiles';
+        }
+        return $error;
+    }
+
+    private function trim_file_name($name, $type) {
+        // Remove path information and dots around the filename, to prevent uploading
+        // into different directories or replacing hidden system files.
+        // Also remove control characters and spaces (\x00..\x20) around the filename:
+        $file_name = trim(basename(stripslashes($name)), ".\x00..\x20");
+        // Add missing file extension for known image types:
+        if (strpos($file_name, '.') === false &&
+            preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
+            $file_name .= '.'.$matches[1];
+        }
+
+        //Ensure that we don't have disallowed characters and add a unique id just to ensure that the file name will be unique
+        $file_name = substr(uniqid(),-5).'-'.$this->_transliterate_characters($file_name);
+
+        //all the characters has to be lowercase
+        $file_name = strtolower($file_name);
+
+        return $file_name;
+    }
+
+    private function _transliterate_characters($file_name)
+	{
+		include($this->default_config_path.'/translit_chars.php');
+		if ( isset($translit_characters))
+		{
+			$file_name = preg_replace(array_keys($translit_characters), array_values($translit_characters), $file_name);
+		}
+
+		$file_name = preg_replace("/([^a-zA-Z0-9\.\-\_]+?){1}/i", '-', $file_name);
+		$file_name = str_replace(" ", "-", $file_name);
+
+		return preg_replace('/\-+/', '-', trim($file_name, '-'));
+	}
+
+    private function orient_image($file_path) {
+      	$exif = exif_read_data($file_path);
+      	$orientation = intval(@$exif['Orientation']);
+      	if (!in_array($orientation, array(3, 6, 8))) {
+      	    return false;
+      	}
+      	$image = @imagecreatefromjpeg($file_path);
+      	switch ($orientation) {
+        	  case 3:
+          	    $image = @imagerotate($image, 180, 0);
+          	    break;
+        	  case 6:
+          	    $image = @imagerotate($image, 270, 0);
+          	    break;
+        	  case 8:
+          	    $image = @imagerotate($image, 90, 0);
+          	    break;
+          	default:
+          	    return false;
+      	}
+      	$success = imagejpeg($image, $file_path);
+      	// Free up memory (imagedestroy does not delete files):
+      	@imagedestroy($image);
+      	return $success;
+    }
+
+    private function handle_file_upload($uploaded_file, $name, $size, $type, $error) {
+        $file = new stdClass();
+        $file->name = $this->trim_file_name($name, $type);
+        $file->size = intval($size);
+        $file->type = $type;
+        $error = $this->has_error($uploaded_file, $file, $error);
+        if (!$error && $file->name) {
+            $file_path = $this->options['upload_dir'].$file->name;
+            $append_file = !$this->options['discard_aborted_uploads'] &&
+                is_file($file_path) && $file->size > filesize($file_path);
+            clearstatcache();
+            if ($uploaded_file && is_uploaded_file($uploaded_file)) {
+                // multipart/formdata uploads (POST method uploads)
+                if ($append_file) {
+                    file_put_contents(
+                        $file_path,
+                        fopen($uploaded_file, 'r'),
+                        FILE_APPEND
+                    );
+                } else {
+                    move_uploaded_file($uploaded_file, $file_path);
+                }
+            } else {
+                // Non-multipart uploads (PUT method support)
+                file_put_contents(
+                    $file_path,
+                    fopen('php://input', 'r'),
+                    $append_file ? FILE_APPEND : 0
+                );
+            }
+            $file_size = filesize($file_path);
+            if ($file_size === $file->size) {
+            		if ($this->options['orient_image']) {
+            		    $this->orient_image($file_path);
+            		}
+                $file->url = $this->options['upload_url'].rawurlencode($file->name);
+                foreach($this->options['image_versions'] as $version => $options) {
+                    if ($this->create_scaled_image($file->name, $options)) {
+                        $file->{$version.'_url'} = $options['upload_url']
+                            .rawurlencode($file->name);
+                    }
+                }
+            } else if ($this->options['discard_aborted_uploads']) {
+                unlink($file_path);
+                $file->error = "It seems that this user doesn't have permissions to upload to this folder";
+            }
+            $file->size = $file_size;
+            $file->delete_url = $this->options['script_url']
+                .'?file='.rawurlencode($file->name);
+            $file->delete_type = 'DELETE';
+        } else {
+            $file->error = $error;
+        }
+        return $file;
+    }
+
+    public function get() {
+        $file_name = isset($_REQUEST['file']) ?
+            basename(stripslashes($_REQUEST['file'])) : null;
+        if ($file_name) {
+            $info = $this->get_file_object($file_name);
+        } else {
+            $info = $this->get_file_objects();
+        }
+        header('Content-type: application/json');
+        echo json_encode($info);
+    }
+
+    public function post() {
+        if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') {
+            return $this->delete();
+        }
+        $upload = isset($_FILES[$this->options['param_name']]) ?
+            $_FILES[$this->options['param_name']] : null;
+        $info = array();
+        if ($upload && is_array($upload['tmp_name'])) {
+            foreach ($upload['tmp_name'] as $index => $value) {
+                $info[] = $this->handle_file_upload(
+                    $upload['tmp_name'][$index],
+                    isset($_SERVER['HTTP_X_FILE_NAME']) ?
+                        $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index],
+                    isset($_SERVER['HTTP_X_FILE_SIZE']) ?
+                        $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'][$index],
+                    isset($_SERVER['HTTP_X_FILE_TYPE']) ?
+                        $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'][$index],
+                    $upload['error'][$index]
+                );
+            }
+        } elseif ($upload || isset($_SERVER['HTTP_X_FILE_NAME'])) {
+            $info[] = $this->handle_file_upload(
+                isset($upload['tmp_name']) ? $upload['tmp_name'] : null,
+                isset($_SERVER['HTTP_X_FILE_NAME']) ?
+                    $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'],
+                isset($_SERVER['HTTP_X_FILE_SIZE']) ?
+                    $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'],
+                isset($_SERVER['HTTP_X_FILE_TYPE']) ?
+                    $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'],
+                isset($upload['error']) ? $upload['error'] : null
+            );
+        }
+        header('Vary: Accept');
+
+        $redirect = isset($_REQUEST['redirect']) ?
+            stripslashes($_REQUEST['redirect']) : null;
+        if ($redirect) {
+            header('Location: '.sprintf($redirect, rawurlencode($json)));
+            return;
+        }
+        if (isset($_SERVER['HTTP_ACCEPT']) &&
+            (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
+            header('Content-type: application/json');
+        } else {
+            header('Content-type: text/plain');
+        }
+        return $info;
+    }
+
+    public function delete() {
+        $file_name = isset($_REQUEST['file']) ?
+            basename(stripslashes($_REQUEST['file'])) : null;
+        $file_path = $this->options['upload_dir'].$file_name;
+        $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
+        if ($success) {
+            foreach($this->options['image_versions'] as $version => $options) {
+                $file = $options['upload_dir'].$file_name;
+                if (is_file($file)) {
+                    unlink($file);
+                }
+            }
+        }
+        header('Content-type: application/json');
+        echo json_encode($success);
+    }
+
+}

+ 1153 - 0
www/application/libraries/image_moo.php

@@ -0,0 +1,1153 @@
+<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
+/*
+ * Image_Moo library
+ *
+ * Written due to image_lib not being so nice when you have to do multiple things to a single image!
+ *
+ * @license		MIT License
+ * @author		Matthew Augier, aka Mat-Moo
+ * @link		http://www.dps.uk.com
+ * @docu		http://todo :)
+ * @email		matthew@dps.uk.com
+ *
+ * @file		image_moo.php
+ * @version		1.0.1
+ * @date		2010 Dec 13
+ *
+ * Copyright (c) 2010 Matthew Augier
+ *
+ * Requires PHP 5 and GD2!
+ *
+ * Example usage
+ *    $this->image_moo->load("file")->resize(64,40)->save("thumb")->resize(640,480)->save("medium");
+ *    if ($this->image_moo->errors) print $this->image_moo->display_errors();
+ *
+ * COLOURS!
+ * Any function that can take a colour as a parameter can take "#RGB", "#RRGGBB" or an array(R,G,B)
+ *
+ * image manipulation functions
+ * -----------------------------------------------------------------------------
+ * load($x) - Loads an image file specified by $x - JPG, PNG, GIF supported
+ * save($x) - Saved the manipulated image (if applicable) to file $x - JPG, PNG, GIF supported
+ * save_pa($prepend="", $append="", $overwrite=FALSE) - Saves using the original image name but with prepend and append text, e.g. load('moo.jpg')->save_pa('pre_','_app') would save as filename pre_moo_app.jpg
+ * save_dynamic($filename="") - Saves as a stream output, use filename to return png/jpg/gif etc., default is jpeg
+ * resize($x,$y,$pad=FALSE) - Proportioanlly resize original image using the bounds $x and $y, if padding is set return image is as defined centralised using BG colour
+ * resize_crop($x,$y) - Proportioanlly resize original image using the bounds $x and $y but cropped to fill dimensions
+ * stretch($x,$y) - Take the original image and stretch it to fill new dimensions $x $y
+ * crop($x1,$y1,$x2,$y2) - Crop the original image using Top left, $x1,$y1 to bottom right $x2,y2. New image size =$x2-x1 x $y2-y1
+ * rotate($angle) - Rotates the work image by X degrees, normally 90,180,270 can be any angle.Excess filled with background colour
+ * load_watermark($filename, $transparent_x=0, $transparent_y=0) - Loads the specified file as the watermark file, if using PNG32/24 use x,y to specify direct positions of colour to use as index
+ * make_watermark_text($text, $fontfile, $size=16, $colour="#ffffff", $angle=0) - Creates a text watermark
+ * watermark($position, $offset=8, $abs=FALSE) - Use the loaded watermark, or created text to place a watermark. $position works like NUM PAD key layout, e.g. 7=Top left, 3=Bottom right $offset is the padding/indentation, if $abs is true then use $positiona and $offset as direct values to watermark placement
+ * border($width,$colour="#000") - Draw a border around the output image X pixels wide in colour specified
+ * border_3d($width,$rot=0,$opacity=30) - Draw a 3d border (opaque) around the current image $width wise in 0-3 rot positions, $opacity allows you to change how much it effects the picture
+ * filter($function, $arg1=NULL, $arg2=NULL, $arg3=NULL, $arg4=NULL) -Runs the standard imagefilter GD2 command, see http://www.php.net/manual/en/function.imagefilter.php for details
+ * round($radius,$invert=FALSE,$corners(array[top left, top right, bottom right, bottom left of true or False)="") default is all on and normal rounding
+ * shadow($size=4, $direction=3, $colour="#444") - Size in pixels, note that the image will increase by this size, so resize(400,400)->shadoe(4) will give an image 404 pixels in size, Direction works on teh keypad basis like the watermark, so 3 is bottom right, $color if the colour of the shadow.
+ * -----------------------------------------------------------------------------
+ * image helper functions
+ * display_errors($open = '<p>', $close = '</p>') - Display errors as Ci standard style
+ * set_jpeg_quality($x) - quality to wrte jpeg files in for save, default 75 (1-100)
+ * set_watermark_transparency($x) - the opacity of the watermark 1-100, 1-just about see, 100=solid
+ * check_gd() - Run to see if you server can use this library
+ * clear_temp() - Call to clear the temp changes using the master image again
+ * clear() - Clears all images in memory
+ * -----------------------------------------------------------------------------
+ *
+ * KNOWN BUGS
+ * make_watermark_text does not deal with rotation angle correctly, box is cropped
+ *
+ * TO DO
+ *
+ * THANKS
+ * Matjaž for poiting out the save_pa bug (should of tested it!)
+ * Cahva for posting yet another bug in the save_pa (Man I can be silly sometimes!)
+ * Cole spotting the resize flaw and providing a fix
+ *
+ */
+
+class Image_moo
+{
+	// image vars
+	private $main_image="";
+ 	private $watermark_image;
+	private $temp_image;
+	private $jpeg_quality=75;
+	private $background_colour="#ffffff";
+	private $watermark_method;
+
+	// other
+	private $filename="";
+
+	// watermark stuff, opacity
+	private $watermark_transparency=50;
+
+	// reported errors
+	public $errors=FALSE;
+	private $error_msg = array();
+
+	// image info
+	public $width=0;
+	public $height=0;
+
+	function Image_moo()
+	//----------------------------------------------------------------------------------------------------------
+	// create stuff here as needed
+	//----------------------------------------------------------------------------------------------------------
+	{
+		log_message('debug', "Image Moo Class Initialized");
+	}
+
+	private function _clear_errors()
+	//----------------------------------------------------------------------------------------------------------
+	// load a resource
+	//----------------------------------------------------------------------------------------------------------
+	{
+		$this->error_msg = array();
+	}
+
+	private function set_error($msg)
+	//----------------------------------------------------------------------------------------------------------
+	// Set an error message
+	//----------------------------------------------------------------------------------------------------------
+	{
+		$this->errors = TRUE;
+		$this->error_msg[] = $msg;
+	}
+
+	public function display_errors($open = '<p>', $close = '</p>')
+	//----------------------------------------------------------------------------------------------------------
+	// returns the errors formatted as needed, same as CI doed
+	//----------------------------------------------------------------------------------------------------------
+	{
+		$str = '';
+		foreach ($this->error_msg as $val)
+		{
+			$str .= $open.$val.$close;
+		}
+		return $str;
+	}
+
+	public function check_gd()
+	//----------------------------------------------------------------------------------------------------------
+	// verification util to see if you can use image_moo
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if ( ! extension_loaded('gd'))
+		{
+			if ( ! dl('gd.so'))
+			{
+				$this->set_error('GD library does not appear to be loaded');
+				return FALSE;
+			}
+		}
+		if (function_exists('gd_info'))
+		{
+			$gdarray = @gd_info();
+			$versiontxt = ereg_replace('[[:alpha:][:space:]()]+', '', $gdarray['GD Version']);
+			$versionparts=explode('.',$versiontxt);
+			if ($versionparts[0]=="2")
+			{
+				return TRUE;
+			}
+			else
+			{
+				$this->set_error('Requires GD2, this reported as '.$versiontxt);
+				return FALSE;
+			}
+		}
+		else
+		{
+			$this->set_error('Could not verify GD version');
+			return FALSE;
+		}
+	}
+
+	private function _check_image()
+	//----------------------------------------------------------------------------------------------------------
+	// checks that we have an image loaded
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if (!is_resource($this->main_image))
+		{
+			$this->set_error("No main image loaded!");
+			return FALSE;
+		}
+		else
+		{
+			return TRUE;
+		}
+	}
+
+	function save_dynamic($filename="")
+	//----------------------------------------------------------------------------------------------------------
+	// Saves the temp image as a dynamic image
+	// e.g. direct output to the browser
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// ok, lets go!
+		if ($filename=="") $filename=rand(1000,999999).".jpg";					// send as jpeg
+		$ext = strtoupper(pathinfo($filename, PATHINFO_EXTENSION));
+		header("Content-disposition: filename=$filename;");
+		header('Content-transfer-Encoding: binary');
+		header('Last-modified: '.gmdate('D, d M Y H:i:s'));
+		switch ($ext)
+		{
+			case "GIF"  :
+				header("Content-type: image/gif");
+				imagegif($this->temp_image);
+				return $this;
+				break;
+			case "JPG" :
+			case "JPEG" :
+				header("Content-type: image/jpeg");
+				imagejpeg($this->temp_image, NULL, $this->jpeg_quality);
+				return $this;
+				break;
+			case "PNG" :
+				header("Content-type: image/png");
+				imagepng($this->temp_image);
+				return $this;
+				break;
+		}
+		$this->set_error('Unable to save, extension not GIF/JPEG/JPG/PNG');
+		return $this;
+	}
+
+	function save_pa($prepend="", $append="", $overwrite=FALSE)
+	//----------------------------------------------------------------------------------------------------------
+	// Saves the temp image as the filename specified,
+	// overwrite = true of false
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// get current file parts
+		$parts=pathinfo($this->filename);
+
+		// save
+		$this->save($parts["dirname"].'/'.$prepend.$parts['filename'].$append.'.'.$parts["extension"], $overwrite);
+
+		return $this;
+	}
+
+	function save($filename,$overwrite=FALSE)
+	//----------------------------------------------------------------------------------------------------------
+	// Saves the temp image as the filename specified,
+	// overwrite = true of false
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// check if it already exists
+		if (!$overwrite)
+		{
+			// don't overwrite, so check for file
+			if (file_exists($filename))
+			{
+				$this->set_error('File exists, overwrite is FALSE, could not save over file '.$filename);
+				return $this;
+			}
+		}
+
+		// find out the type of file to save
+		$ext = strtoupper(pathinfo($filename, PATHINFO_EXTENSION));
+		switch ($ext)
+		{
+			case "GIF"  :
+				imagegif($this->temp_image, $filename);
+				return $this;
+				break;
+			case "JPG" :
+			case "JPEG" :
+				imagejpeg($this->temp_image, $filename, $this->jpeg_quality);
+				return $this;
+				break;
+			case "PNG" :
+				imagepng($this->temp_image, $filename);
+				return $this;
+				break;
+		}
+
+		// invalid filetype?!
+		$this->set_error('Do no know what '.$ext.' filetype is in filename '.$filename);
+		return $this;
+	}
+
+	private function _load_image($filename)
+	//----------------------------------------------------------------------------------------------------------
+	// private function to load a resource
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// check the request file can be located
+		if (!file_exists($filename))
+		{
+			$this->set_error('Could not locate file '.$filename);
+			return FALSE;
+		}
+
+		// get image info about this file
+		$image_info=getimagesize($filename);
+
+		// load file depending on mimetype
+		switch ($image_info["mime"])
+		{
+			case "image/gif"  :
+				return imagecreatefromgif($filename);
+				break;
+			case "image/jpeg" :
+				return imagecreatefromjpeg($filename);
+				break;
+			case "image/png" :
+ 		        return imagecreatefrompng($filename);
+				break;
+		}
+
+		// invalid filetype?!
+		$this->set_error('Unable to load '.$filename.' filetype '.$image_info["mime"].'not recognised');
+		return FALSE;
+	}
+
+	public function load($filename)
+	//----------------------------------------------------------------------------------------------------------
+	// Load an image, public function
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// new image, reset error messages
+		$this->_clear_errors();
+
+		// remove temporary image stored
+		$this->clear_temp();
+
+		// save filename
+		$this->filename=$filename;
+
+		// reset width and height
+		$this->width = 0;
+		$this->height = 0;
+
+		// load it
+		$this->main_image = $this->_load_image($filename);
+
+		// no error, then get the dminesions set
+		if ($this->main_image <> FALSE)
+		{
+			$this->width = imageSX($this->main_image);
+			$this->height = imageSY($this->main_image);
+		}
+
+		// return the object
+		return $this;
+	}
+
+	public function load_watermark($filename, $transparent_x=NULL, $transparent_y=NULL)
+	//----------------------------------------------------------------------------------------------------------
+	// Load an image, public function
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if(is_resource($this->watermark_image)) imagedestroy($this->watermark_image);
+		$this->watermark_image = $this->_load_image($filename);
+
+		if(is_resource($this->watermark_image))
+		{
+			$this->watermark_method = 1;
+			if(($transparent_x <> NULL) AND ($transparent_y <> NULL))
+			{
+				// get the top left corner colour allocation
+				$tpcolour = imagecolorat($this->watermark_image, $transparent_x, $transparent_y);
+
+				// set this as the transparent colour
+				imagecolortransparent($this->watermark_image, $tpcolour);
+
+				// $set diff method
+				$this->watermark_method = 2;
+			}
+		}
+
+		// return this object
+		return $this;
+	}
+
+	public function set_watermark_transparency($transparency=50)
+	//----------------------------------------------------------------------------------------------------------
+	// Sets the quality that jpeg will be saved at
+	//----------------------------------------------------------------------------------------------------------
+	{
+		$this->watermark_transparency = $transparency;
+		return $this;
+	}
+
+	public function set_background_colour($colour="#ffffff")
+	//----------------------------------------------------------------------------------------------------------
+	// Sets teh background colour to use on rotation and padding for resize
+	//----------------------------------------------------------------------------------------------------------
+	{
+		$this->background_colour = $this->_html2rgb($colour);
+		return $this;
+	}
+
+	public function set_jpeg_quality($quality=75)
+	//----------------------------------------------------------------------------------------------------------
+	// Sets the quality that jpeg will be saved at
+	//----------------------------------------------------------------------------------------------------------
+	{
+		$this->jpeg_quality = $quality;
+		return $this;
+	}
+
+	private function _copy_to_temp_if_needed()
+	//----------------------------------------------------------------------------------------------------------
+	// If temp image is empty, e.g. not resized or done anything then just copy main image
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if (!is_resource($this->temp_image))
+		{
+			// create a temp based on new dimensions
+			$this->temp_image = imagecreatetruecolor($this->width, $this->height);
+
+			// check it
+			if(!is_resource($this->temp_image))
+			{
+				$this->set_error('Unable to create temp image sized '.$this->width.' x '.$this->height);
+				return FALSE;
+			}
+
+			// copy image to temp workspace
+			imagecopy($this->temp_image, $this->main_image, 0, 0, 0, 0, $this->width, $this->height);
+		}
+	}
+
+	public function clear()
+	//----------------------------------------------------------------------------------------------------------
+	// clear everything!
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if(is_resource($this->main_image)) imagedestroy($this->main_image);
+		if(is_resource($this->watermark_image)) imagedestroy($this->watermark_image);
+		if(is_resource($this->temp_image)) imagedestroy($this->temp_image);
+		return $this;
+	}
+
+	public function clear_temp()
+	//----------------------------------------------------------------------------------------------------------
+	// you may want to revert back to teh original image to work on, e.g. watermark, this clears temp
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if(is_resource($this->temp_image)) imagedestroy($this->temp_image);
+		return $this;
+	}
+
+	public function resize_crop($mw,$mh)
+	//----------------------------------------------------------------------------------------------------------
+	// take main image and resize to tempimage using EXACT boundaries mw,mh (max width and max height)
+	// this is proportional and crops the image centrally to fit
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if (!$this->_check_image()) return $this;
+
+		// clear temp image
+		$this->clear_temp();
+
+		// create a temp based on new dimensions
+		$this->temp_image = imagecreatetruecolor($mw,$mh);
+
+		// check it
+		if(!is_resource($this->temp_image))
+		{
+			$this->set_error('Unable to create temp image sized '.$mw.' x '.$mh);
+			return $this;
+		}
+
+		// work out best positions for copy
+		$wx=$this->width / $mw;
+		$wy=$this->height / $mh;
+		if ($wx >= $wy)
+		{
+			// use full height
+			$sy = 0;
+			$sy2 = $this->height;
+
+			// calcs
+			$calc_width = $mw * $wy;
+			$sx = ($this->width - $calc_width) / 2;
+			$sx2 = $calc_width;
+		}
+		else
+		{
+			// use full width
+			$sx = 0;
+			$sx2 = $this->width;
+
+			// calcs
+			$calc_height = $mh * $wx;
+			$sy = ($this->height - $calc_height) / 2;
+			$sy2 = $calc_height;
+		}
+
+		// copy section
+		imagecopyresampled($this->temp_image, $this->main_image, 0, 0, $sx, $sy, $mw, $mh, $sx2, $sy2);
+		return $this;
+	}
+
+	public function resize($mw, $mh, $pad=FALSE)
+	//----------------------------------------------------------------------------------------------------------
+	// take main image and resize to tempimage using boundaries mw,mh (max width or max height)
+	// this is proportional, pad to true will set it in the middle of area size
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if (!$this->_check_image()) return $this;
+
+		// calc new dimensions
+		if( $this->width > $mw || $this->height > $mh ) {
+//		    if( $this->width > $this->height ) { could calc wronf - Cole Thorsen swapped to his suggestion
+			if( ($this->width / $this->height) > ($mw / $mh) ) {
+		        $tnw = $mw;
+		        $tnh = $tnw * $this->height / $this->width;
+		    } else {
+		        $tnh = $mh;
+		        $tnw = $tnh * $this->width / $this->height;
+		    }
+		} else {
+		    $tnw = $this->width;
+		    $tnh = $this->height;
+		}
+		// clear temp image
+		$this->clear_temp();
+
+		// create a temp based on new dimensions
+		if ($pad)
+		{
+			$tx = $mw;
+			$ty = $mh;
+			$px = ($mw - $tnw) / 2;
+			$py = ($mh - $tnh) / 2;
+		}
+		else
+		{
+			$tx = $tnw;
+			$ty = $tnh;
+			$px = 0;
+			$py = 0;
+		}
+		$this->temp_image = imagecreatetruecolor($tx,$ty);
+
+		// check it
+		if(!is_resource($this->temp_image))
+		{
+			$this->set_error('Unable to create temp image sized '.$tx.' x '.$ty);
+			return $this;
+		}
+
+		// if padding, fill background
+		if ($pad)
+		{
+			$col = $this->_html2rgb($this->background_colour);
+			$bg = imagecolorallocate($this->temp_image, $col[0], $col[1], $col[2]);
+			imagefilledrectangle($this->temp_image, 0, 0, $tx, $ty, $bg);
+		}
+
+		// copy resized
+		imagecopyresampled($this->temp_image, $this->main_image, $px, $py, 0, 0, $tnw, $tnh, $this->width, $this->height);
+		return $this;
+	}
+
+	public function stretch($mw,$mh)
+	//----------------------------------------------------------------------------------------------------------
+	// take main image and resize to tempimage using boundaries mw,mh (max width or max height)
+	// does not retain proportions
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if (!$this->_check_image()) return $this;
+
+		// clear temp image
+		$this->clear_temp();
+
+		// create a temp based on new dimensions
+		$this->temp_image = imagecreatetruecolor($mw, $mh);
+
+		// check it
+		if(!is_resource($this->temp_image))
+		{
+			$this->set_error('Unable to create temp image sized '.$mh.' x '.$mw);
+			return $this;
+		}
+
+		// copy resized (stethced, proportions not kept);
+		imagecopyresampled($this->temp_image, $this->main_image, 0, 0, 0, 0, $mw, $mh, $this->width, $this->height);
+		return $this;
+	}
+
+	public function crop($x1, $y1, $x2, $y2)
+	//----------------------------------------------------------------------------------------------------------
+	// crop the main image to temp image using coords
+	//----------------------------------------------------------------------------------------------------------
+	{
+		if (!$this->_check_image()) return $this;
+
+		// clear temp image
+		$this->clear_temp();
+
+		// check dimensions
+		if ($x1 < 0 || $y1 < 0 || $x2 - $x1 > $this->width || $y2 - $y1 > $this->height)
+		{
+			$this->set_error('Invalid crop dimensions, either - passed or width/heigh too large '.$x1.'/'.$y1.' x '.$x2.'/'.$y2);
+			return $this;
+		}
+
+		// create a temp based on new dimensions
+		$this->temp_image = imagecreatetruecolor($x2-$x1, $y2-$y1);
+
+		// check it
+		if(!is_resource($this->temp_image))
+		{
+			$this->set_error('Unable to create temp image sized '.$x2-$x1.' x '.$y2-$y1);
+			return $this;
+		}
+
+		// copy cropped portion
+		imagecopy($this->temp_image, $this->main_image, 0, 0, $x1, $y1, $x2 - $x1, $y2 - $y1);
+		return $this;
+	}
+
+	private function _html2rgb($colour)
+	//----------------------------------------------------------------------------------------------------------
+	// convert #aa0011 to a php colour array
+	//----------------------------------------------------------------------------------------------------------
+    {
+    	if (is_array($colour))
+		{
+			if (count($colour)==3) return $colour;								// rgb sent as an array so use it
+			$this->set_error('Colour error, array sent not 3 elements, expected array(r,g,b)');
+			return false;
+		}
+        if ($colour[0] == '#')
+            $colour = substr($colour, 1);
+
+        if (strlen($colour) == 6)
+		{
+            list($r, $g, $b) = array($colour[0].$colour[1],
+                                     $colour[2].$colour[3],
+                                     $colour[4].$colour[5]);
+		}
+        elseif (strlen($colour) == 3)
+		{
+            list($r, $g, $b) = array($colour[0].$colour[0], $colour[1].$colour[1], $colour[2].$colour[2]);
+		}
+        else
+		{
+			$this->set_error('Colour error, value sent not #RRGGBB or RRGGBB, and not array(r,g,b)');
+            return false;
+		}
+
+        $r = hexdec($r); $g = hexdec($g); $b = hexdec($b);
+
+        return array($r, $g, $b);
+    }
+
+	public function rotate($angle)
+	//----------------------------------------------------------------------------------------------------------
+	// rotate an image bu 0 / 90 / 180 / 270 degrees
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// set the colour
+		$col = $this->_html2rgb($$this->background_colour);
+		$bg = imagecolorallocate($this->temp_image, $col[0], $col[1], $col[2]);
+
+		// rotate as needed
+		$this->temp_image = imagerotate($this->temp_image, $angle, $bg);
+		return $this;
+	}
+
+	public function make_watermark_text($text, $fontfile, $size=16, $colour="#ffffff", $angle=0)
+	//----------------------------------------------------------------------------------------------------------
+	// create an image from text that can be applied as a watermark
+	// text is the text to write, $fontile is a ttf file that will be used $size=font size, $colour is the colour of text
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// check font file can be found
+		if (!file_exists($fontfile))
+		{
+			$this->set_error('Could not locate font file "'.$fontfile.'"');
+			return $this;
+		}
+
+		// validate we loaded a main image
+		if (!$this->_check_image())
+		{
+			$remove = TRUE;
+			// no image loaded so make temp image to use
+			$this->main_image = imagecreatetruecolor(1000,1000);
+		}
+		else
+		{
+			$remove = FALSE;
+		}
+
+		// work out text dimensions
+		$bbox = imageftbbox($size, $angle, $fontfile, $text);
+		$bw = abs($bbox[4] - $bbox[0]) + 1;
+		$bh = abs($bbox[1] - $bbox[5]) + 1;
+		$bl = $bbox[1];
+
+		// use this to create watermark image
+		if(is_resource($this->watermark_image)) imagedestroy($this->watermark_image);
+		$this->watermark_image = imagecreatetruecolor($bw, $bh);
+
+		// set colours
+		$col = $this->_html2rgb($colour);
+		$font_col = imagecolorallocate($this->watermark_image, $col[0], $col[1], $col[2]);
+		$bg_col = imagecolorallocate($this->watermark_image, 127, 128, 126);
+
+		// set method to use
+		$this->watermark_method = 2;
+
+		// create bg
+		imagecolortransparent($this->watermark_image, $bg_col);
+		imagefilledrectangle($this->watermark_image, 0,0, $bw, $bh, $bg_col);
+
+		// write text to watermark
+		imagefttext($this->watermark_image, $size, $angle, 0, $bh-$bl, $font_col, $fontfile, $text);
+
+		if ($remove) imagedestroy($this->main_image);
+		return $this;
+	}
+
+	public function watermark($position, $offset=8, $abs=FALSE)
+	//----------------------------------------------------------------------------------------------------------
+	// add a watermark to the image
+	// position works like a keypad e.g.
+	// 7 8 9
+	// 4 5 6
+	// 1 2 3
+	// offset moves image inwards by x pixels
+	// if abs is set then $position, $offset = direct placement coords
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// validate we have a watermark
+		if(!is_resource($this->watermark_image))
+		{
+			$this->set_error("Can't watermark image, no watermark loaded/created");
+			return $this;
+		}
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// get watermark width
+		$wm_w = imageSX($this->watermark_image);
+		$wm_h = imageSY($this->watermark_image);
+
+		// get temp widths
+		$temp_w = imageSX($this->temp_image);
+		$temp_h = imageSY($this->temp_image);
+
+		// check watermark will fit!
+		if ($wm_w > $temp_w || $wm_h > $temp_h)
+		{
+			$this->set_error("Watermark is larger than image. WM: $wm_w x $wm_h Temp image: $temp_w x $temp_h");
+			return $this;
+		}
+
+		if ($abs)
+		{
+			// direct placement
+			$dest_x = $position;
+			$dest_y = $offset;
+		}
+		else
+		{
+			// do X position
+			switch ($position)
+			{
+				// x left
+				case "7":
+				case "4":
+				case "1":
+					$dest_x = $offset;
+					break;
+				// x middle
+				case "8":
+				case "5":
+				case "2":
+					$dest_x = ($temp_w - $wm_w) /2 ;
+					break;
+				// x right
+				case "9":
+				case "6":
+				case "3":
+					$dest_x = $temp_w - $offset - $wm_w;
+					break;
+				default:
+					$dest_x = $offset;
+					$this->set_error("Watermark position $position not in vlaid range 7,8,9 - 4,5,6 - 1,2,3");
+			}
+			// do y position
+			switch ($position)
+			{
+				// y top
+				case "7":
+				case "8":
+				case "9":
+					$dest_y = $offset;
+					break;
+				// y middle
+				case "4":
+				case "5":
+				case "6":
+					$dest_y = ($temp_h - $wm_h) /2 ;
+					break;
+				// y bottom
+				case "1":
+				case "2":
+				case "3":
+					$dest_y = $temp_h - $offset - $wm_h;
+					break;
+				default:
+					$dest_y = $offset;
+					$this->set_error("Watermark position $position not in vlaid range 7,8,9 - 4,5,6 - 1,2,3");
+			}
+
+		}
+
+		// copy over temp image to desired location
+		if ($this->watermark_method == 1)
+		{
+			// use back methods to do this, taken from php help files
+			//$this->imagecopymerge_alpha($this->temp_image, $this->watermark_image, $dest_x, $dest_y, 0, 0, $wm_w, $wm_h, $this->watermark_transparency);
+
+	        $opacity=$this->watermark_transparency;
+
+	        // creating a cut resource
+	        $cut = imagecreatetruecolor($wm_w, $wm_h);
+
+	        // copying that section of the background to the cut
+	        imagecopy($cut, $this->temp_image, 0, 0, $dest_x, $dest_y, $wm_w, $wm_h);
+
+	        // inverting the opacity
+	        $opacity = 100 - $opacity;
+
+	        // placing the watermark now
+	        imagecopy($cut, $this->watermark_image, 0, 0, 0, 0, $wm_w, $wm_h);
+	        imagecopymerge($this->temp_image, $cut, $dest_x, $dest_y, 0, 0, $wm_w, $wm_h, $opacity);
+
+		}
+		else
+		{
+			// use normal with selected transparency colour
+			imagecopymerge($this->temp_image, $this->watermark_image, $dest_x, $dest_y, 0, 0, $wm_w, $wm_h, $this->watermark_transparency);
+		}
+
+        return $this;
+	}
+
+	public function border($width=5,$colour="#000")
+	//----------------------------------------------------------------------------------------------------------
+	// add a solidborder  frame, coloured $colour to the image
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// get colour set for temp image
+		$col = $this->_html2rgb($colour);
+		$border_col = imagecolorallocate($this->temp_image, $col[0], $col[1], $col[2]);
+
+		// get temp widths
+		$temp_w = imageSX($this->temp_image);
+		$temp_h = imageSY($this->temp_image);
+
+		// do border
+		for($x=0;$x<$width;$x++)
+		{
+			imagerectangle($this->temp_image, $x, $x, $temp_w-$x-1, $temp_h-$x-1, $border_col);
+		}
+
+		// return object
+		return $this;
+	}
+
+	public function border_3d($width=5,$rot=0,$opacity=30)
+	//----------------------------------------------------------------------------------------------------------
+	// overlay a black white border to make it look 3d
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// get temp widths
+		$temp_w = imageSX($this->temp_image);
+		$temp_h = imageSY($this->temp_image);
+
+		// create temp canvas to merge
+		$border_image = imagecreatetruecolor($temp_w, $temp_h);
+
+		// create colours
+		$black = imagecolorallocate($border_image, 0, 0, 0);
+		$white = imagecolorallocate($border_image, 255, 255, 255);
+		switch ($rot)
+		{
+			case 1 :
+				$cols=array($white,$black,$white,$black);
+				break;
+			case 2 :
+				$cols=array($black,$black,$white,$white);
+				break;
+			case 3 :
+				$cols=array($black,$white,$black,$white);
+				break;
+			default :
+				$cols=array($white,$white,$black,$black);
+		}
+		$bg_col = imagecolorallocate($border_image, 127, 128, 126);
+
+		// create bg
+		imagecolortransparent($border_image, $bg_col);
+		imagefilledrectangle($border_image, 0,0, $temp_w, $temp_h, $bg_col);
+
+		// do border
+		for($x=0;$x<$width;$x++)
+		{
+			// top
+			imageline($border_image, $x, $x, $temp_w-$x-1, $x, $cols[0]);
+			// left
+			imageline($border_image, $x, $x, $x, $temp_w-$x-1, $cols[1]);
+			// bottom
+			imageline($border_image, $x, $temp_h-$x-1, $temp_w-1-$x, $temp_h-$x-1, $cols[3]);
+			// right
+			imageline($border_image, $temp_w-$x-1, $x, $temp_w-$x-1, $temp_h-$x-1, $cols[2]);
+		}
+
+		// merg with temp image
+		imagecopymerge($this->temp_image, $border_image, 0, 0, 0, 0, $temp_w, $temp_h, $opacity);
+
+		// clean up
+		imagedestroy($border_image);
+
+		// return object
+		return $this;
+	}
+
+	public function shadow($size=4, $direction=3, $colour="#444")
+	//----------------------------------------------------------------------------------------------------------
+	// add a shadow to an image, this will INCREASE the size of the image
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// get the current size
+		$sx = imagesx($this->temp_image);
+		$sy = imagesy($this->temp_image);
+
+		// new image
+		$bu_image = imagecreatetruecolor($sx, $sy);
+
+		// check it
+		if(!is_resource($bu_image))
+		{
+			$this->set_error('Unable to create shadow temp image sized '.$this->width.' x '.$this->height);
+			return FALSE;
+		}
+
+		// copy the current image to memory
+		imagecopy($bu_image, $this->temp_image, 0, 0, 0, 0, $sx, $sy);
+
+		imagedestroy($this->temp_image);
+		$this->temp_image = imagecreatetruecolor($sx+$size, $sy+$size);
+
+		// fill background colour
+		$col = $this->_html2rgb($this->background_colour);
+		$bg = imagecolorallocate($this->temp_image, $col[0], $col[1], $col[2]);
+		imagefilledrectangle($this->temp_image, 0, 0, $sx+$size, $sy+$size, $bg);
+
+		// work out position
+		// do X position
+		switch ($direction)
+		{
+			// x left
+			case "7":
+			case "4":
+			case "1":
+				$sh_x = 0;
+				$pic_x = $size;
+				break;
+			// x middle
+			case "8":
+			case "5":
+			case "2":
+				$sh_x = $size / 2;
+				$pic_x = $size / 2;
+				break;
+			// x right
+			case "9":
+			case "6":
+			case "3":
+				$sh_x = $size;
+				$pic_x = 0;
+				break;
+			default:
+				$sh_x = $size;
+				$pic_x = 0;
+				$this->set_error("Shadow position $position not in vlaid range 7,8,9 - 4,5,6 - 1,2,3");
+		}
+		// do y position
+		switch ($direction)
+		{
+			// y top
+			case "7":
+			case "8":
+			case "9":
+				$sh_y = 0;
+				$pic_y = $size;
+				break;
+			// y middle
+			case "4":
+			case "5":
+			case "6":
+				$sh_y = $size / 2;
+				$pic_y = $size / 2;
+				break;
+			// y bottom
+			case "1":
+			case "2":
+			case "3":
+				$sh_y = $size;
+				$pic_y = 0;
+				break;
+			default:
+				$sh_y = $size;
+				$pic_y = 0;
+				$this->set_error("Shadow position $position not in vlaid range 7,8,9 - 4,5,6 - 1,2,3");
+		}
+
+		// create the shadow
+		$shadowcolour = $this->_html2rgb($colour);
+		$shadow = imagecolorallocate($this->temp_image, $shadowcolour[0], $shadowcolour[1], $shadowcolour[2]);
+		imagefilledrectangle($this->temp_image, $sh_x, $sh_y, $sh_x+$sx-1, $sh_y+$sy-1, $shadow);
+
+		// copy current image to correct location
+		imagecopy($this->temp_image, $bu_image, $pic_x, $pic_y, 0, 0, $sx, $sy);
+
+		// clean up and desstroy temp image
+		imagedestroy($bu_image);
+
+		//return object
+		return $this;
+	}
+
+	public function filter($function, $arg1=NULL, $arg2=NULL, $arg3=NULL, $arg4=NULL)
+	//----------------------------------------------------------------------------------------------------------
+	// allows you to use the inbulit gd2 image filters
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		if (!imagefilter($this->temp_image, $function, $arg1, $arg2, $arg3, $arg4))
+		{
+			$this->set_error("Filter $function failed");
+		}
+
+		// return object
+		return $this;
+	}
+
+	public function round($radius=5,$invert=False,$corners="")
+	//----------------------------------------------------------------------------------------------------------
+	// adds rounded corners to the output
+	// using a quarter and rotating as you can end up with odd roudning if you draw a whole and use parts
+	//----------------------------------------------------------------------------------------------------------
+	{
+		// validate we loaded a main image
+		if (!$this->_check_image()) return $this;
+
+		// if no operations, copy it for temp save
+		$this->_copy_to_temp_if_needed();
+
+		// check input
+		if ($corners=="") $corners=array(True,True,True,True);
+		if (!is_array($corners) || count($corners)<>4)
+		{
+			$this->set_error("Round failed, expected an array of 4 items round(radius,tl,tr,br,bl)");
+			return $this;
+		}
+
+		// create corner
+		$corner = imagecreatetruecolor($radius, $radius);
+
+		// turn on aa make it nicer
+		imageantialias($corner, true);
+		$col = $this->_html2rgb($this->background_colour);
+
+		// use bg col for corners
+		$bg = imagecolorallocate($corner, $col[0], $col[1], $col[2]);
+
+		// create our transparent colour
+		$xparent = imagecolorallocate($corner, 127, 128, 126);
+		imagecolortransparent($corner, $xparent);
+		if ($invert)
+		{
+			// fill and clear bits
+			imagefilledrectangle($corner, 0, 0, $radius, $radius, $xparent);
+			imagefilledellipse($corner, 0, 0, ($radius * 2)-1, ($radius * 2)-1, $bg);
+		}
+		else
+		{
+			// fill and clear bits
+			imagefilledrectangle($corner, 0, 0, $radius, $radius, $bg);
+			imagefilledellipse($corner, $radius, $radius, ($radius * 2) , ($radius * 2) , $xparent);
+		}
+
+		// get temp widths
+		$temp_w = imageSX($this->temp_image);
+		$temp_h = imageSY($this->temp_image);
+
+		// do corners
+		if ($corners[0]) imagecopymerge($this->temp_image, $corner, 0, 0, 0, 0, $radius, $radius, 100);
+		$corner = imagerotate($corner, 270, 0);
+		if ($corners[1]) imagecopymerge($this->temp_image, $corner, $temp_w-$radius, 0, 0, 0, $radius, $radius, 100);
+		$corner = imagerotate($corner, 270, 0);
+		if ($corners[2]) imagecopymerge($this->temp_image, $corner, $temp_w-$radius, $temp_h-$radius, 0, 0, $radius, $radius, 100);
+		$corner = imagerotate($corner, 270, 0);
+		if ($corners[3]) imagecopymerge($this->temp_image, $corner, 0, $temp_h-$radius, 0, 0, $radius, $radius, 100);
+
+		// return object
+		return $this;
+	}
+
+
+}
+/* End of file image_moo.php */
+/* Location: .system/application/libraries/image_moo.php */

+ 11 - 0
www/application/libraries/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/logs/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 72 - 0
www/application/models/Calculadora_model.php

@@ -0,0 +1,72 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+class calculadora_model extends CI_Model {
+    function getDistribuidoras() {
+        $data = array();
+        $query = $this->db->query('select * from distribuidoras');
+        if ($query->num_rows() > 0) {
+        //  print_r($query);
+            foreach ($query->result_array() as $row){
+                    $data[] = $row;
+                }
+        }
+        $query->free_result();
+        return $data;
+    }
+
+    function getDepartamentos() {
+        $data = array();
+        $query = $this->db->query('select * from datos_x_depto');
+        if ($query->num_rows() > 0) {
+        //  print_r($query);
+            foreach ($query->result_array() as $row){
+                    $data[] = $row;
+                }
+        }
+        $query->free_result();
+        return $data;
+    }
+
+    function getDepartamento($nombreDepto) {
+        $data = array();
+        $query = $this->db->query('select * from datos_x_depto where departamento = ?',array($nombreDepto));
+        if ($query->num_rows() > 0) {
+        //  print_r($query);
+            foreach ($query->result_array() as $row){
+                    $data[] = $row;
+                }
+        }
+        $query->free_result();
+        return $data;
+    }
+
+    function getDatoPanel($datoPanel) {
+        $data = array();
+        $query = $this->db->query('select * from datosPanel where parametro = ?',array($datoPanel));
+        if ($query->num_rows() > 0) {
+        //  print_r($query);
+            foreach ($query->result_array() as $row){
+                    $data[] = $row;
+                }
+        }
+        $query->free_result();
+        return $data;
+    }
+
+    function getDistribuidora($distribuidora) {
+        $data = array();
+        $query = $this->db->query('select * from distribuidoras where distribuidora = ?', array($distribuidora));
+        if ($query->num_rows() > 0) {
+        //  print_r($query);
+            foreach ($query->result_array() as $row){
+                    $data[] = $row;
+                }
+        }
+        $query->free_result();
+        return $data;
+    }
+
+
+}
+?>

+ 587 - 0
www/application/models/Grocery_crud_model.php

@@ -0,0 +1,587 @@
+<?php
+/**
+ * PHP grocery CRUD
+ *
+ * LICENSE
+ *
+ * Grocery CRUD is released with dual licensing, using the GPL v3 (license-gpl3.txt) and the MIT license (license-mit.txt).
+ * You don't have to do anything special to choose one license or the other and you don't have to notify anyone which license you are using.
+ * Please see the corresponding license file for details of these licenses.
+ * You are free to use, modify and distribute this software, but all copyright information must remain.
+ *
+ * @package    	grocery CRUD
+ * @copyright  	Copyright (c) 2010 through 2012, John Skoumbourdis
+ * @license    	https://github.com/scoumbourdis/grocery-crud/blob/master/license-grocery-crud.txt
+ * @version    	1.4.2
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Grocery CRUD Model
+ *
+ *
+ * @package    	grocery CRUD
+ * @author     	John Skoumbourdis <scoumbourdisj@gmail.com>
+ * @version    	1.5.6
+ * @link		http://www.grocerycrud.com/documentation
+ */
+class Grocery_crud_model  extends CI_Model  {
+
+	protected $primary_key = null;
+	protected $table_name = null;
+	protected $relation = array();
+	protected $relation_n_n = array();
+	protected $primary_keys = array();
+
+	function __construct()
+    {
+        parent::__construct();
+    }
+
+    function db_table_exists($table_name = null)
+    {
+    	return $this->db->table_exists($table_name);
+    }
+
+    function get_list()
+    {
+    	if($this->table_name === null)
+    		return false;
+
+    	$select = "`{$this->table_name}`.*";
+
+    	//set_relation special queries
+    	if(!empty($this->relation))
+    	{
+    		foreach($this->relation as $relation)
+    		{
+    			list($field_name , $related_table , $related_field_title) = $relation;
+    			$unique_join_name = $this->_unique_join_name($field_name);
+    			$unique_field_name = $this->_unique_field_name($field_name);
+
+				if(strstr($related_field_title,'{'))
+				{
+					$related_field_title = str_replace(" ","&nbsp;",$related_field_title);
+    				$select .= ", CONCAT('".str_replace(array('{','}'),array("',COALESCE({$unique_join_name}.",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $unique_field_name";
+				}
+    			else
+    			{
+    				$select .= ", $unique_join_name.$related_field_title AS $unique_field_name";
+    			}
+
+    			if($this->field_exists($related_field_title))
+    				$select .= ", `{$this->table_name}`.$related_field_title AS '{$this->table_name}.$related_field_title'";
+    		}
+    	}
+
+    	//set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
+    	if(!empty($this->relation_n_n))
+    	{
+			$select = $this->relation_n_n_queries($select);
+    	}
+
+    	$this->db->select($select, false);
+
+    	$results = $this->db->get($this->table_name)->result();
+
+    	return $results;
+    }
+
+    public function get_row($table_name = null)
+    {
+    	$table_name = $table_name === null ? $this->table_name : $table_name;
+
+    	return $this->db->get($table_name)->row();
+    }
+
+    public function set_primary_key($field_name, $table_name = null)
+    {
+    	$table_name = $table_name === null ? $this->table_name : $table_name;
+
+    	$this->primary_keys[$table_name] = $field_name;
+    }
+
+    protected function relation_n_n_queries($select)
+    {
+    	$this_table_primary_key = $this->get_primary_key();
+    	foreach($this->relation_n_n as $relation_n_n)
+    	{
+    		list($field_name, $relation_table, $selection_table, $primary_key_alias_to_this_table,
+    					$primary_key_alias_to_selection_table, $title_field_selection_table, $priority_field_relation_table) = array_values((array)$relation_n_n);
+
+    		$primary_key_selection_table = $this->get_primary_key($selection_table);
+
+	    	$field = "";
+	    	$use_template = strpos($title_field_selection_table,'{') !== false;
+	    	$field_name_hash = $this->_unique_field_name($title_field_selection_table);
+	    	if($use_template)
+	    	{
+	    		$title_field_selection_table = str_replace(" ", "&nbsp;", $title_field_selection_table);
+	    		$field .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$title_field_selection_table))."')";
+	    	}
+	    	else
+	    	{
+	    		$field .= "$selection_table.$title_field_selection_table";
+	    	}
+
+    		//Sorry Codeigniter but you cannot help me with the subquery!
+    		$select .= ", (SELECT GROUP_CONCAT(DISTINCT $field) FROM $selection_table "
+    			."LEFT JOIN $relation_table ON $relation_table.$primary_key_alias_to_selection_table = $selection_table.$primary_key_selection_table "
+    			."WHERE $relation_table.$primary_key_alias_to_this_table = `{$this->table_name}`.$this_table_primary_key GROUP BY $relation_table.$primary_key_alias_to_this_table) AS $field_name";
+    	}
+
+    	return $select;
+    }
+
+    function order_by($order_by , $direction)
+    {
+    	$this->db->order_by( $order_by , $direction );
+    }
+
+    function where($key, $value = NULL, $escape = TRUE)
+    {
+    	$this->db->where( $key, $value, $escape);
+    }
+
+    function or_where($key, $value = NULL, $escape = TRUE)
+    {
+    	$this->db->or_where( $key, $value, $escape);
+    }
+
+    function having($key, $value = NULL, $escape = TRUE)
+    {
+    	$this->db->having( $key, $value, $escape);
+    }
+
+    function or_having($key, $value = NULL, $escape = TRUE)
+    {
+    	$this->db->or_having( $key, $value, $escape);
+    }
+
+    function like($field, $match = '', $side = 'both')
+    {
+    	$this->db->like($field, $match, $side);
+    }
+
+    function or_like($field, $match = '', $side = 'both')
+    {
+    	$this->db->or_like($field, $match, $side);
+    }
+
+    function limit($value, $offset = '')
+    {
+    	$this->db->limit( $value , $offset );
+    }
+
+    function get_total_results()
+    {
+        // A fast way to calculate the total results
+        $key = $this->get_primary_key();
+
+    	//set_relation_n_n special queries. We prefer sub queries from a simple join for the relation_n_n as it is faster and more stable on big tables.
+    	if(!empty($this->relation_n_n))
+    	{
+    		$select = "{$this->table_name}." . $key;
+    		$select = $this->relation_n_n_queries($select);
+
+    		$this->db->select($select,false);
+    	} else {
+            $this->db->select($this->table_name . '.' . $key);
+        }
+        
+        return $this->db->get($this->table_name)->num_rows();
+    }
+
+    function set_basic_table($table_name = null)
+    {
+    	if( !($this->db->table_exists($table_name)) )
+    		return false;
+
+    	$this->table_name = $table_name;
+
+    	return true;
+    }
+
+    function get_edit_values($primary_key_value)
+    {
+    	$primary_key_field = $this->get_primary_key();
+    	$this->db->where($primary_key_field,$primary_key_value);
+    	$result = $this->db->get($this->table_name)->row();
+    	return $result;
+    }
+
+    function join_relation($field_name , $related_table , $related_field_title)
+    {
+		$related_primary_key = $this->get_primary_key($related_table);
+
+		if($related_primary_key !== false)
+		{
+			$unique_name = $this->_unique_join_name($field_name);
+			$this->db->join( $related_table.' as '.$unique_name , "$unique_name.$related_primary_key = {$this->table_name}.$field_name",'left');
+
+			$this->relation[$field_name] = array($field_name , $related_table , $related_field_title);
+
+			return true;
+		}
+
+    	return false;
+    }
+
+    function set_relation_n_n_field($field_info)
+    {
+		$this->relation_n_n[$field_info->field_name] = $field_info;
+    }
+
+    protected function _unique_join_name($field_name)
+    {
+    	return 'j'.substr(md5($field_name),0,8); //This j is because is better for a string to begin with a letter and not with a number
+    }
+
+    protected function _unique_field_name($field_name)
+    {
+    	return 's'.substr(md5($field_name),0,8); //This s is because is better for a string to begin with a letter and not with a number
+    }
+
+    function get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, $limit = null, $search_like = null)
+    {
+    	$relation_array = array();
+    	$field_name_hash = $this->_unique_field_name($field_name);
+
+    	$related_primary_key = $this->get_primary_key($related_table);
+
+    	$select = "$related_table.$related_primary_key, ";
+
+    	if(strstr($related_field_title,'{'))
+    	{
+    		$related_field_title = str_replace(" ", "&nbsp;", $related_field_title);
+    		$select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
+    	}
+    	else
+    	{
+	    	$select .= "$related_table.$related_field_title as $field_name_hash";
+    	}
+
+    	$this->db->select($select,false);
+    	if($where_clause !== null)
+    		$this->db->where($where_clause);
+
+    	if($where_clause !== null)
+    		$this->db->where($where_clause);
+
+    	if($limit !== null)
+    		$this->db->limit($limit);
+
+    	if($search_like !== null)
+    		$this->db->having("$field_name_hash LIKE '%".$this->db->escape_like_str($search_like)."%'");
+
+    	$order_by !== null
+    		? $this->db->order_by($order_by)
+    		: $this->db->order_by($field_name_hash);
+
+    	$results = $this->db->get($related_table)->result();
+
+    	foreach($results as $row)
+    	{
+    		$relation_array[$row->$related_primary_key] = $row->$field_name_hash;
+    	}
+
+    	return $relation_array;
+    }
+
+    function get_ajax_relation_array($search, $field_name , $related_table , $related_field_title, $where_clause, $order_by)
+    {
+    	return $this->get_relation_array($field_name , $related_table , $related_field_title, $where_clause, $order_by, 10 , $search);
+    }
+
+    function get_relation_total_rows($field_name , $related_table , $related_field_title, $where_clause)
+    {
+    	if($where_clause !== null)
+    		$this->db->where($where_clause);
+
+    	return $this->db->count_all_results($related_table);
+    }
+
+    function get_relation_n_n_selection_array($primary_key_value, $field_info)
+    {
+    	$select = "";
+    	$related_field_title = $field_info->title_field_selection_table;
+    	$use_template = strpos($related_field_title,'{') !== false;;
+    	$field_name_hash = $this->_unique_field_name($related_field_title);
+    	if($use_template)
+    	{
+    		$related_field_title = str_replace(" ", "&nbsp;", $related_field_title);
+    		$select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
+    	}
+    	else
+    	{
+    		$select .= "$related_field_title as $field_name_hash";
+    	}
+    	$this->db->select('*, '.$select,false);
+
+    	$selection_primary_key = $this->get_primary_key($field_info->selection_table);
+
+    	if(empty($field_info->priority_field_relation_table))
+    	{
+    		if(!$use_template){
+    			$this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
+    		}
+    	}
+    	else
+    	{
+    		$this->db->order_by("{$field_info->relation_table}.{$field_info->priority_field_relation_table}");
+    	}
+    	$this->db->where($field_info->primary_key_alias_to_this_table, $primary_key_value);
+    	$this->db->join(
+    			$field_info->selection_table,
+    			"{$field_info->relation_table}.{$field_info->primary_key_alias_to_selection_table} = {$field_info->selection_table}.{$selection_primary_key}"
+    		);
+    	$results = $this->db->get($field_info->relation_table)->result();
+
+    	$results_array = array();
+    	foreach($results as $row)
+    	{
+    		$results_array[$row->{$field_info->primary_key_alias_to_selection_table}] = $row->{$field_name_hash};
+    	}
+
+    	return $results_array;
+    }
+
+    function get_relation_n_n_unselected_array($field_info, $selected_values)
+    {
+    	$use_where_clause = !empty($field_info->where_clause);
+
+    	$select = "";
+    	$related_field_title = $field_info->title_field_selection_table;
+    	$use_template = strpos($related_field_title,'{') !== false;
+    	$field_name_hash = $this->_unique_field_name($related_field_title);
+
+    	if($use_template)
+    	{
+    		$related_field_title = str_replace(" ", "&nbsp;", $related_field_title);
+    		$select .= "CONCAT('".str_replace(array('{','}'),array("',COALESCE(",", ''),'"),str_replace("'","\\'",$related_field_title))."') as $field_name_hash";
+    	}
+    	else
+    	{
+    		$select .= "$related_field_title as $field_name_hash";
+    	}
+    	$this->db->select('*, '.$select,false);
+
+    	if($use_where_clause){
+    		$this->db->where($field_info->where_clause);
+    	}
+
+    	$selection_primary_key = $this->get_primary_key($field_info->selection_table);
+        if(!$use_template)
+        	$this->db->order_by("{$field_info->selection_table}.{$field_info->title_field_selection_table}");
+        $results = $this->db->get($field_info->selection_table)->result();
+
+        $results_array = array();
+        foreach($results as $row)
+        {
+            if(!isset($selected_values[$row->$selection_primary_key]))
+                $results_array[$row->$selection_primary_key] = $row->{$field_name_hash};
+        }
+
+        return $results_array;
+    }
+
+    function db_relation_n_n_update($field_info, $post_data ,$main_primary_key)
+    {
+    	$this->db->where($field_info->primary_key_alias_to_this_table, $main_primary_key);
+    	if(!empty($post_data))
+    		$this->db->where_not_in($field_info->primary_key_alias_to_selection_table , $post_data);
+    	$this->db->delete($field_info->relation_table);
+
+    	$counter = 0;
+    	if(!empty($post_data))
+    	{
+    		foreach($post_data as $primary_key_value)
+	    	{
+				$where_array = array(
+	    			$field_info->primary_key_alias_to_this_table => $main_primary_key,
+	    			$field_info->primary_key_alias_to_selection_table => $primary_key_value,
+	    		);
+
+	    		$this->db->where($where_array);
+				$count = $this->db->from($field_info->relation_table)->count_all_results();
+
+				if($count == 0)
+				{
+					if(!empty($field_info->priority_field_relation_table))
+						$where_array[$field_info->priority_field_relation_table] = $counter;
+
+					$this->db->insert($field_info->relation_table, $where_array);
+
+				}elseif($count >= 1 && !empty($field_info->priority_field_relation_table))
+				{
+					$this->db->update( $field_info->relation_table, array($field_info->priority_field_relation_table => $counter) , $where_array);
+				}
+
+				$counter++;
+	    	}
+    	}
+    }
+
+    function db_relation_n_n_delete($field_info, $main_primary_key)
+    {
+    	$this->db->where($field_info->primary_key_alias_to_this_table, $main_primary_key);
+    	$this->db->delete($field_info->relation_table);
+    }
+
+    function get_field_types_basic_table()
+    {
+    	$db_field_types = array();
+    	foreach($this->db->query("SHOW COLUMNS FROM `{$this->table_name}`")->result() as $db_field_type)
+    	{
+    		$type = explode("(",$db_field_type->Type);
+    		$db_type = $type[0];
+
+    		if(isset($type[1]))
+    		{
+    			if(substr($type[1],-1) == ')')
+    			{
+    				$length = substr($type[1],0,-1);
+    			}
+    			else
+    			{
+    				list($length) = explode(" ",$type[1]);
+    				$length = substr($length,0,-1);
+    			}
+    		}
+    		else
+    		{
+    			$length = '';
+    		}
+    		$db_field_types[$db_field_type->Field]['db_max_length'] = $length;
+    		$db_field_types[$db_field_type->Field]['db_type'] = $db_type;
+    		$db_field_types[$db_field_type->Field]['db_null'] = $db_field_type->Null == 'YES' ? true : false;
+    		$db_field_types[$db_field_type->Field]['db_extra'] = $db_field_type->Extra;
+    	}
+
+    	$results = $this->db->field_data($this->table_name);
+    	foreach($results as $num => $row)
+    	{
+    		$row = (array)$row;
+    		$results[$num] = (object)( array_merge($row, $db_field_types[$row['name']])  );
+    	}
+
+    	return $results;
+    }
+
+    function get_field_types($table_name)
+    {
+    	$results = $this->db->field_data($table_name);
+
+    	return $results;
+    }
+
+    function db_update($post_array, $primary_key_value)
+    {
+    	$primary_key_field = $this->get_primary_key();
+    	return $this->db->update($this->table_name,$post_array, array( $primary_key_field => $primary_key_value));
+    }
+
+    function db_insert($post_array)
+    {
+    	$insert = $this->db->insert($this->table_name,$post_array);
+    	if($insert)
+    	{
+    		return $this->db->insert_id();
+    	}
+    	return false;
+    }
+
+    function db_delete($primary_key_value)
+    {
+    	$primary_key_field = $this->get_primary_key();
+
+    	if($primary_key_field === false)
+    		return false;
+
+    	$this->db->limit(1);
+    	$this->db->delete($this->table_name,array( $primary_key_field => $primary_key_value));
+    	if( $this->db->affected_rows() != 1)
+    		return false;
+    	else
+    		return true;
+    }
+
+    function db_file_delete($field_name, $filename)
+    {
+    	if( $this->db->update($this->table_name,array($field_name => ''),array($field_name => $filename)) )
+    	{
+    		return true;
+    	}
+    	else
+    	{
+    		return false;
+    	}
+    }
+
+    function field_exists($field,$table_name = null)
+    {
+    	if(empty($table_name))
+    	{
+    		$table_name = $this->table_name;
+    	}
+    	return $this->db->field_exists($field,$table_name);
+    }
+
+    function get_primary_key($table_name = null)
+    {
+    	if($table_name == null)
+    	{
+    		if(isset($this->primary_keys[$this->table_name]))
+    		{
+    			return $this->primary_keys[$this->table_name];
+    		}
+
+	    	if(empty($this->primary_key))
+	    	{
+		    	$fields = $this->get_field_types_basic_table();
+
+		    	foreach($fields as $field)
+		    	{
+		    		if($field->primary_key == 1)
+		    		{
+		    			return $field->name;
+		    		}
+		    	}
+
+		    	return false;
+	    	}
+	    	else
+	    	{
+	    		return $this->primary_key;
+	    	}
+    	}
+    	else
+    	{
+    		if(isset($this->primary_keys[$table_name]))
+    		{
+    			return $this->primary_keys[$table_name];
+    		}
+
+	    	$fields = $this->get_field_types($table_name);
+
+	    	foreach($fields as $field)
+	    	{
+	    		if($field->primary_key == 1)
+	    		{
+	    			return $field->name;
+	    		}
+	    	}
+
+	    	return false;
+    	}
+
+    }
+
+    function escape_str($value)
+    {
+    	return $this->db->escape_str($value);
+    }
+
+}

+ 11 - 0
www/application/models/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/third_party/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 63 - 0
www/application/views/calculadora.php

@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <title>Calculadora de costos</title>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+</head>
+<body>
+
+<style>
+body {
+  background-color: #FAAD22
+}
+</style>
+
+<div class="container">
+  <!-- <h2>Datos del Panel Solar</h2>
+  <h3>Datos para Canadian Solar CS6xP</h3> -->
+  <form action="<?php echo site_url('publico/calculo');?>" method="post" class="form-inline">
+
+    <div class="form-group">
+      <label for="consumo">Consumo Promedio en los ultimos Seis meses :</label>
+      <input type="text" class="form-control" id="consumo" name="consumo">
+    </div>
+    <div class="form-group">
+      <label for="Departamento">Departamento:</label>
+      <?php
+      echo "<select name='departamento' id='departamento'>";
+      if (count($departamentos)) {
+          foreach ($departamentos as $list) {
+              echo "<option value='". $list['departamento'] . "'>" . $list['departamento'] . "</option>";
+          }
+      }
+      echo "</select>";
+      ?>
+
+
+
+    </div>
+    <div class="form-group">
+      <label for="Distribuidora">Distribuidora:</label>
+      <?php
+      echo "<select name='Distribuidora' id='Distribuidora'>";
+      if (count($distribuidoras)) {
+          foreach ($distribuidoras as $list) {
+              echo "<option value='". $list['distribuidora'] . "'>" . $list['distribuidora'] . "</option>";
+          }
+      }
+      echo "</select>";
+      ?>
+    </div>
+    <p><small>*Esta estimacion puede variar según las condiciones del lugar de instalacion</small></p>
+    
+<div class="clear-both"></div>
+    <button type="submit" class="btn btn-default">Calcular</button>
+  </form>
+</div>
+
+</body>
+</html>

+ 8 - 0
www/application/views/errors/cli/error_404.php

@@ -0,0 +1,8 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+echo "\nERROR: ",
+	$heading,
+	"\n\n",
+	$message,
+	"\n\n";

+ 8 - 0
www/application/views/errors/cli/error_db.php

@@ -0,0 +1,8 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+echo "\nDatabase error: ",
+	$heading,
+	"\n\n",
+	$message,
+	"\n\n";

+ 21 - 0
www/application/views/errors/cli/error_exception.php

@@ -0,0 +1,21 @@
+<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>
+
+An uncaught Exception was encountered
+
+Type:        <?php echo get_class($exception), "\n"; ?>
+Message:     <?php echo $message, "\n"; ?>
+Filename:    <?php echo $exception->getFile(), "\n"; ?>
+Line Number: <?php echo $exception->getLine(); ?>
+
+<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
+
+Backtrace:
+<?php	foreach ($exception->getTrace() as $error): ?>
+<?php		if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
+	File: <?php echo $error['file'], "\n"; ?>
+	Line: <?php echo $error['line'], "\n"; ?>
+	Function: <?php echo $error['function'], "\n\n"; ?>
+<?php		endif ?>
+<?php	endforeach ?>
+
+<?php endif ?>

+ 8 - 0
www/application/views/errors/cli/error_general.php

@@ -0,0 +1,8 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+
+echo "\nERROR: ",
+	$heading,
+	"\n\n",
+	$message,
+	"\n\n";

+ 21 - 0
www/application/views/errors/cli/error_php.php

@@ -0,0 +1,21 @@
+<?php defined('BASEPATH') OR exit('No direct script access allowed'); ?>
+
+A PHP Error was encountered
+
+Severity:    <?php echo $severity, "\n"; ?>
+Message:     <?php echo $message, "\n"; ?>
+Filename:    <?php echo $filepath, "\n"; ?>
+Line Number: <?php echo $line; ?>
+
+<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
+
+Backtrace:
+<?php	foreach (debug_backtrace() as $error): ?>
+<?php		if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
+	File: <?php echo $error['file'], "\n"; ?>
+	Line: <?php echo $error['line'], "\n"; ?>
+	Function: <?php echo $error['function'], "\n\n"; ?>
+<?php		endif ?>
+<?php	endforeach ?>
+
+<?php endif ?>

+ 11 - 0
www/application/views/errors/cli/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 64 - 0
www/application/views/errors/html/error_404.php

@@ -0,0 +1,64 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+?><!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>404 Page Not Found</title>
+<style type="text/css">
+
+::selection { background-color: #E13300; color: white; }
+::-moz-selection { background-color: #E13300; color: white; }
+
+body {
+	background-color: #fff;
+	margin: 40px;
+	font: 13px/20px normal Helvetica, Arial, sans-serif;
+	color: #4F5155;
+}
+
+a {
+	color: #003399;
+	background-color: transparent;
+	font-weight: normal;
+}
+
+h1 {
+	color: #444;
+	background-color: transparent;
+	border-bottom: 1px solid #D0D0D0;
+	font-size: 19px;
+	font-weight: normal;
+	margin: 0 0 14px 0;
+	padding: 14px 15px 10px 15px;
+}
+
+code {
+	font-family: Consolas, Monaco, Courier New, Courier, monospace;
+	font-size: 12px;
+	background-color: #f9f9f9;
+	border: 1px solid #D0D0D0;
+	color: #002166;
+	display: block;
+	margin: 14px 0 14px 0;
+	padding: 12px 10px 12px 10px;
+}
+
+#container {
+	margin: 10px;
+	border: 1px solid #D0D0D0;
+	box-shadow: 0 0 8px #D0D0D0;
+}
+
+p {
+	margin: 12px 15px 12px 15px;
+}
+</style>
+</head>
+<body>
+	<div id="container">
+		<h1><?php echo $heading; ?></h1>
+		<?php echo $message; ?>
+	</div>
+</body>
+</html>

+ 64 - 0
www/application/views/errors/html/error_db.php

@@ -0,0 +1,64 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+?><!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>Database Error</title>
+<style type="text/css">
+
+::selection { background-color: #E13300; color: white; }
+::-moz-selection { background-color: #E13300; color: white; }
+
+body {
+	background-color: #fff;
+	margin: 40px;
+	font: 13px/20px normal Helvetica, Arial, sans-serif;
+	color: #4F5155;
+}
+
+a {
+	color: #003399;
+	background-color: transparent;
+	font-weight: normal;
+}
+
+h1 {
+	color: #444;
+	background-color: transparent;
+	border-bottom: 1px solid #D0D0D0;
+	font-size: 19px;
+	font-weight: normal;
+	margin: 0 0 14px 0;
+	padding: 14px 15px 10px 15px;
+}
+
+code {
+	font-family: Consolas, Monaco, Courier New, Courier, monospace;
+	font-size: 12px;
+	background-color: #f9f9f9;
+	border: 1px solid #D0D0D0;
+	color: #002166;
+	display: block;
+	margin: 14px 0 14px 0;
+	padding: 12px 10px 12px 10px;
+}
+
+#container {
+	margin: 10px;
+	border: 1px solid #D0D0D0;
+	box-shadow: 0 0 8px #D0D0D0;
+}
+
+p {
+	margin: 12px 15px 12px 15px;
+}
+</style>
+</head>
+<body>
+	<div id="container">
+		<h1><?php echo $heading; ?></h1>
+		<?php echo $message; ?>
+	</div>
+</body>
+</html>

+ 32 - 0
www/application/views/errors/html/error_exception.php

@@ -0,0 +1,32 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+?>
+
+<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
+
+<h4>An uncaught Exception was encountered</h4>
+
+<p>Type: <?php echo get_class($exception); ?></p>
+<p>Message: <?php echo $message; ?></p>
+<p>Filename: <?php echo $exception->getFile(); ?></p>
+<p>Line Number: <?php echo $exception->getLine(); ?></p>
+
+<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
+
+	<p>Backtrace:</p>
+	<?php foreach ($exception->getTrace() as $error): ?>
+
+		<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
+
+			<p style="margin-left:10px">
+			File: <?php echo $error['file']; ?><br />
+			Line: <?php echo $error['line']; ?><br />
+			Function: <?php echo $error['function']; ?>
+			</p>
+		<?php endif ?>
+
+	<?php endforeach ?>
+
+<?php endif ?>
+
+</div>

+ 64 - 0
www/application/views/errors/html/error_general.php

@@ -0,0 +1,64 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+?><!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>Error</title>
+<style type="text/css">
+
+::selection { background-color: #E13300; color: white; }
+::-moz-selection { background-color: #E13300; color: white; }
+
+body {
+	background-color: #fff;
+	margin: 40px;
+	font: 13px/20px normal Helvetica, Arial, sans-serif;
+	color: #4F5155;
+}
+
+a {
+	color: #003399;
+	background-color: transparent;
+	font-weight: normal;
+}
+
+h1 {
+	color: #444;
+	background-color: transparent;
+	border-bottom: 1px solid #D0D0D0;
+	font-size: 19px;
+	font-weight: normal;
+	margin: 0 0 14px 0;
+	padding: 14px 15px 10px 15px;
+}
+
+code {
+	font-family: Consolas, Monaco, Courier New, Courier, monospace;
+	font-size: 12px;
+	background-color: #f9f9f9;
+	border: 1px solid #D0D0D0;
+	color: #002166;
+	display: block;
+	margin: 14px 0 14px 0;
+	padding: 12px 10px 12px 10px;
+}
+
+#container {
+	margin: 10px;
+	border: 1px solid #D0D0D0;
+	box-shadow: 0 0 8px #D0D0D0;
+}
+
+p {
+	margin: 12px 15px 12px 15px;
+}
+</style>
+</head>
+<body>
+	<div id="container">
+		<h1><?php echo $heading; ?></h1>
+		<?php echo $message; ?>
+	</div>
+</body>
+</html>

+ 33 - 0
www/application/views/errors/html/error_php.php

@@ -0,0 +1,33 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+?>
+
+<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">
+
+<h4>A PHP Error was encountered</h4>
+
+<p>Severity: <?php echo $severity; ?></p>
+<p>Message:  <?php echo $message; ?></p>
+<p>Filename: <?php echo $filepath; ?></p>
+<p>Line Number: <?php echo $line; ?></p>
+
+<?php if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === TRUE): ?>
+
+	<p>Backtrace:</p>
+	<?php foreach (debug_backtrace() as $error): ?>
+
+		<?php if (isset($error['file']) && strpos($error['file'], realpath(BASEPATH)) !== 0): ?>
+
+			<p style="margin-left:10px">
+			File: <?php echo $error['file'] ?><br />
+			Line: <?php echo $error['line'] ?><br />
+			Function: <?php echo $error['function'] ?>
+			</p>
+
+		<?php endif ?>
+
+	<?php endforeach ?>
+
+<?php endif ?>
+
+</div>

+ 11 - 0
www/application/views/errors/html/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 11 - 0
www/application/views/errors/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 25 - 0
www/application/views/example.php

@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+<?php
+foreach($css_files as $file): ?>
+	<link type="text/css" rel="stylesheet" href="<?php echo $file; ?>" />
+<?php endforeach; ?>
+<?php foreach($js_files as $file): ?>
+	<script src="<?php echo $file; ?>"></script>
+<?php endforeach; ?>
+</head>
+<body>
+	<div>
+		<a href='<?php echo site_url('/admin/deptos')?>'>Datos Departamento</a> |
+		<a href='<?php echo site_url('/admin/distribuidoras')?>'>Distribuidoras</a> |
+		<a href='<?php echo site_url('/admin/datospanel')?>'>Datos Panel</a> |
+	</div>
+	<div style='height:20px;'></div>
+    <div>
+		<?php echo $output; ?>
+    </div>
+</body>
+</html>

+ 11 - 0
www/application/views/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 34 - 0
www/application/views/resultado.php

@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <title>Calculadora de costos</title>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
+  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+</head>
+<body>
+
+<style>
+body {
+  background-color: #FAAD22
+}
+</style>
+
+<div class="container">
+  <h2>Resultados</h2>
+  <div class="form-group">
+    <label for="kwpRequeridos">Cantidad de kWp:</label>
+    <input type="text" readonly class="form-control" id="kwpRequeridos" name="kwpRequeridos" value="<?php echo round($kwpRequeridos, 2)?>">
+  </div>
+
+  <div class="form-group">
+    <label for="ahorroMensual">Ahorro mensual aproximado:</label>
+    <input type="text" class="form-control" readonly id="ahorroMensual" name="ahorroMensual"  value="<?php echo round($ahorroMensual,2)?>">
+  </div>
+</div>
+<a href="<?php echo site_url();?>">Realizar otro calculo</a>
+
+  </body>
+  </html>

+ 89 - 0
www/application/views/welcome_message.php

@@ -0,0 +1,89 @@
+<?php
+defined('BASEPATH') OR exit('No direct script access allowed');
+?><!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="utf-8">
+	<title>Welcome to CodeIgniter</title>
+
+	<style type="text/css">
+
+	::selection { background-color: #E13300; color: white; }
+	::-moz-selection { background-color: #E13300; color: white; }
+
+	body {
+		background-color: #fff;
+		margin: 40px;
+		font: 13px/20px normal Helvetica, Arial, sans-serif;
+		color: #4F5155;
+	}
+
+	a {
+		color: #003399;
+		background-color: transparent;
+		font-weight: normal;
+	}
+
+	h1 {
+		color: #444;
+		background-color: transparent;
+		border-bottom: 1px solid #D0D0D0;
+		font-size: 19px;
+		font-weight: normal;
+		margin: 0 0 14px 0;
+		padding: 14px 15px 10px 15px;
+	}
+
+	code {
+		font-family: Consolas, Monaco, Courier New, Courier, monospace;
+		font-size: 12px;
+		background-color: #f9f9f9;
+		border: 1px solid #D0D0D0;
+		color: #002166;
+		display: block;
+		margin: 14px 0 14px 0;
+		padding: 12px 10px 12px 10px;
+	}
+
+	#body {
+		margin: 0 15px 0 15px;
+	}
+
+	p.footer {
+		text-align: right;
+		font-size: 11px;
+		border-top: 1px solid #D0D0D0;
+		line-height: 32px;
+		padding: 0 10px 0 10px;
+		margin: 20px 0 0 0;
+	}
+
+	#container {
+		margin: 10px;
+		border: 1px solid #D0D0D0;
+		box-shadow: 0 0 8px #D0D0D0;
+	}
+	</style>
+</head>
+<body>
+
+<div id="container">
+	<h1>Welcome to CodeIgniter!</h1>
+
+	<div id="body">
+		<p>The page you are looking at is being generated dynamically by CodeIgniter.</p>
+
+		<p>If you would like to edit this page you'll find it located at:</p>
+		<code>application/views/welcome_message.php</code>
+
+		<p>The corresponding controller for this page is found at:</p>
+		<code>application/controllers/Welcome.php</code>
+
+		<p>If you are exploring CodeIgniter for the very first time, you should start by reading the <a href="user_guide/">User Guide</a>.</p>
+	</div>
+
+	<p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds. <?php echo  (ENVIRONMENT === 'development') ?  'CodeIgniter Version <strong>' . CI_VERSION . '</strong>' : '' ?></p>
+</div>
+
+</body>
+</html>

+ 10 - 0
www/assets/grocery_crud/config/index.html

@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 33 - 0
www/assets/grocery_crud/config/language_alias.php

@@ -0,0 +1,33 @@
+<?php
+
+$language_alias = array(
+    'afrikaans'         => 'af',
+    'arabic'            => 'ar',
+    'bengali'           => 'bn', // Timepicker is not avaliable yet
+    'bulgarian'         => 'bg',
+    'chinese'           => 'zh-cn',
+    'czech'             => 'cs',
+    'danish'            => 'da', // Timepicker is not avaliable yet
+    'dutch'             => 'nl',
+    'french'            => 'fr',
+    'german'            => 'de',
+    'greek'             => 'el',
+    'hungarian'         => 'hu',
+    'indonesian'        => 'id',
+    'italian'           => 'it',
+    'japanese'          => 'ja',
+    'korean'            => 'ko',
+    'norwegian'         => 'no',
+    'persian'           => 'fa', // Timepicker is not avaliable yet
+    'polish'            => 'pl',
+    'pt-br.portuguese'  => 'pt-br',
+    'pt-pt.portuguese'  => 'pt',
+    'romanian'          => 'ro',
+    'russian'           => 'ru',
+    'slovak'            => 'sk',
+    'spanish'           => 'es',
+    'thai'              => 'th', // Timepicker is not avaliable yet
+    'turkish'           => 'tr',
+    'ukrainian'         => 'uk',
+    'vietnamese'        => 'vi'
+);

+ 169 - 0
www/assets/grocery_crud/config/translit_chars.php

@@ -0,0 +1,169 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/*
+| -------------------------------------------------------------------
+| Transliteration characters
+| -------------------------------------------------------------------
+| This file based on ./application/config/foreign_chars.php file 
+| of Codeigniter's Framework and contains an array of foreign 
+| characters for transliteration conversion used by grocery CRUD library
+|
+*/
+$translit_characters = array(
+
+	// Aa
+	'/Α|Ά|А|À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
+	'/α|ά|а|à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
+
+	// Bb
+	'/Β|Б/' => 'B',
+	'/β|б/' => 'b',
+
+	// Cc
+	'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
+	'/ç|ć|ĉ|ċ|č/' => 'c',
+
+	// Dd
+	'/Δ|Д|Ð|Ď|Đ/' => 'D',
+	'/δ|д|ð|ď|đ/' => 'd',
+
+	// Ee
+	'/Ε|Έ|Е|Э|Є|È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
+	'/ε|έ|е|э|є|è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
+
+	// Ff
+	'/Φ|Ф/' => 'F',
+	'/φ|ф|ƒ/' => 'f',
+
+	// Gg
+	'/Γ|Г|Ĝ|Ğ|Ġ|Ģ/' => 'G',
+	'/γ|г|ĝ|ğ|ġ|ģ/' => 'g',
+
+	// Hh
+	'/Х|Ĥ|Ħ/' => 'H',
+	'/х|ĥ|ħ/' => 'h',
+
+	// Ii
+	'/Η|Ή|Ι|Ί|И|Ы|І|Ї|Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
+	'/η|ή|ι|ί|и|ы|і|ї|ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
+
+	// Jj
+	'/Ĵ/' => 'J',
+	'/ĵ/' => 'j',
+
+	// Kk
+	'/Κ|К|Ķ/' => 'K',
+	'/κ|к|ķ/' => 'k',
+
+	// Ll
+	'/Λ|Л|Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
+	'/λ|л|ĺ|ļ|ľ|ŀ|ł/' => 'l',
+
+	// Mm
+	'/Μ|М/' => 'M',
+	'/μ|м/' => 'm',
+
+	// Nn
+	'/Ν|Н|Ñ|Ń|Ņ|Ň/' => 'N',
+	'/ν|н|ñ|ń|ņ|ň|ʼn/' => 'n',
+
+	// Oo
+	'/Ο|Ό|О|Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
+	'/ο|ό|о|ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
+
+	// Pp
+	'/Π|П/' => 'P',
+	'/π|п/' => 'p',
+
+	// Qq
+	// '//' => 'Q',
+	// '//' => 'q',
+
+	// Rr
+	'/Ρ|Р|Ŕ|Ŗ|Ř/' => 'R',
+	'/ρ|р|ŕ|ŗ|ř/' => 'r',
+
+	// Ss
+	'/Σ|С|Ś|Ŝ|Ş|Š/' => 'S',
+	'/σ|ς|с|ś|ŝ|ş|š|ſ/' => 's',
+
+	// Tt
+	'/Τ|Т|Ţ|Ť|Ŧ/' => 'T',
+	'/τ|т|ţ|ť|ŧ/' => 't',
+
+	// Uu
+	'/У|Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
+	'/у|ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
+
+	// Vv
+	'/В/' => 'V',
+	'/в/' => 'v',
+
+	// Ww
+	'/Ω|Ώ|Ŵ/' => 'W',
+	'/ω|ώ|ŵ/' => 'w',
+
+	// Xx
+	'/Χ/' => 'X',
+	'/χ/' => 'x',
+
+	// Yy
+	'/Υ|Ύ|Ψ|Й|Ý|Ÿ|Ŷ/' => 'Y',
+	'/υ|ύ|ψ|й|ý|ÿ|ŷ/' => 'y',
+
+	// Zz
+	'/Ζ|З|Ź|Ż|Ž/' => 'Z',
+	'/ζ|з|ź|ż|ž/' => 'z',
+
+	'/Θ/' => 'Th',
+	'/θ/' => 'th',
+
+	'/Ξ/' => 'Ks',
+	'/ξ/' => 'ks',
+
+	'/Ё/' => 'Yo',
+	'/ё/' => 'yo',
+
+	'/Ж/' => 'Zh',
+	'/ж/' => 'zh',
+
+	'/Ц/' => 'Ts',
+	'/ц/' => 'ts',
+
+	'/Ч/' => 'Ch',
+	'/ч/' => 'ch',
+
+	'/Ш/' => 'Sh',
+	'/ш/' => 'sh',
+
+	'/Щ/' => 'Sch',
+	'/щ/' => 'sch',
+
+	'/Ь|Ъ/' => '',
+	'/ь|ъ/' => '',
+
+	'/Ю/' => 'Yu',
+	'/ю/' => 'yu',
+
+	'/Я/' => 'Ya',
+	'/я/' => 'ya',
+
+	'/Æ|Ǽ/' => 'AE',
+	'/Ä/' => 'Ae',
+	'/ä|æ|ǽ/' => 'ae',
+
+	'/Œ/' => 'OE',
+	'/Ö/' => 'Oe',
+	'/ö|œ/' => 'oe',
+
+	'/Ü/' => 'Ue',
+	'/ü/' => 'ue',
+
+	'/IJ/' => 'IJ',
+	'/ij/' => 'ij',
+
+	'/ß/'=> 'ss',
+
+);
+
+/* End of file translit_chars.php */
+/* Location: ./assets/grocery_crud/translit_chars.php */

+ 10 - 0
www/assets/grocery_crud/css/index.html

@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

二進制
www/assets/grocery_crud/css/jquery_plugins/chosen/chosen-sprite.png


二進制
www/assets/grocery_crud/css/jquery_plugins/chosen/chosen-sprite@2x.png


+ 450 - 0
www/assets/grocery_crud/css/jquery_plugins/chosen/chosen.css

@@ -0,0 +1,450 @@
+/*!
+Chosen, a Select Box Enhancer for jQuery and Prototype
+by Patrick Filler for Harvest, http://getharvest.com
+
+Version 1.4.2
+Full source at https://github.com/harvesthq/chosen
+Copyright (c) 2011-2015 Harvest http://getharvest.com
+
+MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
+This file is generated by `grunt build`, do not edit it by hand.
+*/
+
+/* @group Base */
+.chosen-container {
+  position: relative;
+  display: inline-block;
+  vertical-align: middle;
+  font-size: 13px;
+  zoom: 1;
+  *display: inline;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  user-select: none;
+}
+.chosen-container * {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.chosen-container .chosen-drop {
+  position: absolute;
+  top: 100%;
+  left: -9999px;
+  z-index: 1010;
+  width: 100%;
+  border: 1px solid #aaa;
+  border-top: 0;
+  background: #fff;
+  box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
+}
+.chosen-container.chosen-with-drop .chosen-drop {
+  left: 0;
+}
+.chosen-container a {
+  cursor: pointer;
+}
+.chosen-container .search-choice .group-name, .chosen-container .chosen-single .group-name {
+  margin-right: 4px;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  font-weight: normal;
+  color: #999999;
+}
+.chosen-container .search-choice .group-name:after, .chosen-container .chosen-single .group-name:after {
+  content: ":";
+  padding-left: 2px;
+  vertical-align: top;
+}
+
+/* @end */
+/* @group Single Chosen */
+.chosen-container-single .chosen-single {
+  position: relative;
+  display: block;
+  overflow: hidden;
+  padding: 0 0 0 8px;
+  height: 25px;
+  border: 1px solid #aaa;
+  border-radius: 5px;
+  background-color: #fff;
+  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
+  background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+  background-clip: padding-box;
+  box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
+  color: #444;
+  text-decoration: none;
+  white-space: nowrap;
+  line-height: 24px;
+}
+.chosen-container-single .chosen-default {
+  color: #999;
+}
+.chosen-container-single .chosen-single span {
+  display: block;
+  overflow: hidden;
+  margin-right: 26px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.chosen-container-single .chosen-single-with-deselect span {
+  margin-right: 38px;
+}
+.chosen-container-single .chosen-single abbr {
+  position: absolute;
+  top: 6px;
+  right: 26px;
+  display: block;
+  width: 12px;
+  height: 12px;
+  background: url('chosen-sprite.png') -42px 1px no-repeat;
+  font-size: 1px;
+}
+.chosen-container-single .chosen-single abbr:hover {
+  background-position: -42px -10px;
+}
+.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
+  background-position: -42px -10px;
+}
+.chosen-container-single .chosen-single div {
+  position: absolute;
+  top: 0;
+  right: 0;
+  display: block;
+  width: 18px;
+  height: 100%;
+}
+.chosen-container-single .chosen-single div b {
+  display: block;
+  width: 100%;
+  height: 100%;
+  background: url('chosen-sprite.png') no-repeat 0px 2px;
+}
+.chosen-container-single .chosen-search {
+  position: relative;
+  z-index: 1010;
+  margin: 0;
+  padding: 3px 4px;
+  white-space: nowrap;
+}
+.chosen-container-single .chosen-search input[type="text"] {
+  margin: 1px 0;
+  padding: 4px 20px 4px 5px;
+  width: 100%;
+  height: auto;
+  outline: 0;
+  border: 1px solid #aaa;
+  background: white url('chosen-sprite.png') no-repeat 100% -20px;
+  background: url('chosen-sprite.png') no-repeat 100% -20px;
+  font-size: 1em;
+  font-family: sans-serif;
+  line-height: normal;
+  border-radius: 0;
+}
+.chosen-container-single .chosen-drop {
+  margin-top: -1px;
+  border-radius: 0 0 4px 4px;
+  background-clip: padding-box;
+}
+.chosen-container-single.chosen-container-single-nosearch .chosen-search {
+  position: absolute;
+  left: -9999px;
+}
+
+/* @end */
+/* @group Results */
+.chosen-container .chosen-results {
+  color: #444;
+  position: relative;
+  overflow-x: hidden;
+  overflow-y: auto;
+  margin: 0 4px 4px 0;
+  padding: 0 0 0 4px;
+  max-height: 240px;
+  -webkit-overflow-scrolling: touch;
+}
+.chosen-container .chosen-results li {
+  display: none;
+  margin: 0;
+  padding: 5px 6px;
+  list-style: none;
+  line-height: 15px;
+  word-wrap: break-word;
+  -webkit-touch-callout: none;
+}
+.chosen-container .chosen-results li.active-result {
+  display: list-item;
+  cursor: pointer;
+}
+.chosen-container .chosen-results li.disabled-result {
+  display: list-item;
+  color: #ccc;
+  cursor: default;
+}
+.chosen-container .chosen-results li.highlighted {
+  background-color: #3875d7;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
+  background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
+  background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
+  background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
+  background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
+  color: #fff;
+}
+.chosen-container .chosen-results li.no-results {
+  color: #777;
+  display: list-item;
+  background: #f4f4f4;
+}
+.chosen-container .chosen-results li.group-result {
+  display: list-item;
+  font-weight: bold;
+  cursor: default;
+}
+.chosen-container .chosen-results li.group-option {
+  padding-left: 15px;
+}
+.chosen-container .chosen-results li em {
+  font-style: normal;
+  text-decoration: underline;
+}
+
+/* @end */
+/* @group Multi Chosen */
+.chosen-container-multi .chosen-choices {
+  position: relative;
+  overflow: hidden;
+  margin: 0;
+  padding: 0 5px;
+  width: 100%;
+  height: auto !important;
+  height: 1%;
+  border: 1px solid #aaa;
+  background-color: #fff;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
+  background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
+  background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
+  background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
+  background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
+  cursor: text;
+}
+.chosen-container-multi .chosen-choices li {
+  float: left;
+  list-style: none;
+}
+.chosen-container-multi .chosen-choices li.search-field {
+  margin: 0;
+  padding: 0;
+  white-space: nowrap;
+}
+.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
+  margin: 1px 0;
+  padding: 0;
+  height: 25px;
+  outline: 0;
+  border: 0 !important;
+  background: transparent !important;
+  box-shadow: none;
+  color: #999;
+  font-size: 100%;
+  font-family: sans-serif;
+  line-height: normal;
+  border-radius: 0;
+}
+.chosen-container-multi .chosen-choices li.search-choice {
+  position: relative;
+  margin: 3px 5px 3px 0;
+  padding: 3px 20px 3px 5px;
+  border: 1px solid #aaa;
+  max-width: 100%;
+  border-radius: 3px;
+  background-color: #eeeeee;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+  background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-size: 100% 19px;
+  background-repeat: repeat-x;
+  background-clip: padding-box;
+  box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+  color: #333;
+  line-height: 13px;
+  cursor: default;
+}
+.chosen-container-multi .chosen-choices li.search-choice span {
+  word-wrap: break-word;
+}
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
+  position: absolute;
+  top: 4px;
+  right: 3px;
+  display: block;
+  width: 12px;
+  height: 12px;
+  background: url('chosen-sprite.png') -42px 1px no-repeat;
+  font-size: 1px;
+}
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
+  background-position: -42px -10px;
+}
+.chosen-container-multi .chosen-choices li.search-choice-disabled {
+  padding-right: 5px;
+  border: 1px solid #ccc;
+  background-color: #e4e4e4;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+  background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+  color: #666;
+}
+.chosen-container-multi .chosen-choices li.search-choice-focus {
+  background: #d4d4d4;
+}
+.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
+  background-position: -42px -10px;
+}
+.chosen-container-multi .chosen-results {
+  margin: 0;
+  padding: 0;
+}
+.chosen-container-multi .chosen-drop .result-selected {
+  display: list-item;
+  color: #ccc;
+  cursor: default;
+}
+
+/* @end */
+/* @group Active  */
+.chosen-container-active .chosen-single {
+  border: 1px solid #5897fb;
+  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+}
+.chosen-container-active.chosen-with-drop .chosen-single {
+  border: 1px solid #aaa;
+  -moz-border-radius-bottomright: 0;
+  border-bottom-right-radius: 0;
+  -moz-border-radius-bottomleft: 0;
+  border-bottom-left-radius: 0;
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
+  background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
+  background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
+  background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
+  background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
+  box-shadow: 0 1px 0 #fff inset;
+}
+.chosen-container-active.chosen-with-drop .chosen-single div {
+  border-left: none;
+  background: transparent;
+}
+.chosen-container-active.chosen-with-drop .chosen-single div b {
+  background-position: -18px 2px;
+}
+.chosen-container-active .chosen-choices {
+  border: 1px solid #5897fb;
+  box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+}
+.chosen-container-active .chosen-choices li.search-field input[type="text"] {
+  color: #222 !important;
+}
+
+/* @end */
+/* @group Disabled Support */
+.chosen-disabled {
+  opacity: 0.5 !important;
+  cursor: default;
+}
+.chosen-disabled .chosen-single {
+  cursor: default;
+}
+.chosen-disabled .chosen-choices .search-choice .search-choice-close {
+  cursor: default;
+}
+
+/* @end */
+/* @group Right to Left */
+.chosen-rtl {
+  text-align: right;
+}
+.chosen-rtl .chosen-single {
+  overflow: visible;
+  padding: 0 8px 0 0;
+}
+.chosen-rtl .chosen-single span {
+  margin-right: 0;
+  margin-left: 26px;
+  direction: rtl;
+}
+.chosen-rtl .chosen-single-with-deselect span {
+  margin-left: 38px;
+}
+.chosen-rtl .chosen-single div {
+  right: auto;
+  left: 3px;
+}
+.chosen-rtl .chosen-single abbr {
+  right: auto;
+  left: 26px;
+}
+.chosen-rtl .chosen-choices li {
+  float: right;
+}
+.chosen-rtl .chosen-choices li.search-field input[type="text"] {
+  direction: rtl;
+}
+.chosen-rtl .chosen-choices li.search-choice {
+  margin: 3px 5px 3px 0;
+  padding: 3px 5px 3px 19px;
+}
+.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
+  right: auto;
+  left: 4px;
+}
+.chosen-rtl.chosen-container-single-nosearch .chosen-search,
+.chosen-rtl .chosen-drop {
+  left: 9999px;
+}
+.chosen-rtl.chosen-container-single .chosen-results {
+  margin: 0 0 4px 4px;
+  padding: 0 4px 0 0;
+}
+.chosen-rtl .chosen-results li.group-option {
+  padding-right: 15px;
+  padding-left: 0;
+}
+.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
+  border-right: none;
+}
+.chosen-rtl .chosen-search input[type="text"] {
+  padding: 4px 5px 4px 20px;
+  background: white url('chosen-sprite.png') no-repeat -30px -20px;
+  background: url('chosen-sprite.png') no-repeat -30px -20px;
+  direction: rtl;
+}
+.chosen-rtl.chosen-container-single .chosen-single div b {
+  background-position: 6px 2px;
+}
+.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
+  background-position: -12px 2px;
+}
+
+/* @end */
+/* @group Retina compatibility */
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi), only screen and (min-resolution: 1.5dppx) {
+  .chosen-rtl .chosen-search input[type="text"],
+  .chosen-container-single .chosen-single abbr,
+  .chosen-container-single .chosen-single div b,
+  .chosen-container-single .chosen-search input[type="text"],
+  .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
+  .chosen-container .chosen-results-scroll-down span,
+  .chosen-container .chosen-results-scroll-up span {
+    background-image: url('chosen-sprite@2x.png') !important;
+    background-size: 52px 37px !important;
+    background-repeat: no-repeat !important;
+  }
+}
+/* @end */

文件差異過大導致無法顯示
+ 2 - 0
www/assets/grocery_crud/css/jquery_plugins/chosen/chosen.min.css


+ 10 - 0
www/assets/grocery_crud/css/jquery_plugins/chosen/index.html

@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/blank.gif


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_close.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_loading.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_nav_left.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_nav_right.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_e.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_n.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_ne.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_nw.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_s.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_se.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_sw.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_shadow_w.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_left.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_main.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_over.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancy_title_right.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancybox-x.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancybox-y.png


二進制
www/assets/grocery_crud/css/jquery_plugins/fancybox/fancybox.png


+ 359 - 0
www/assets/grocery_crud/css/jquery_plugins/fancybox/jquery.fancybox.css

@@ -0,0 +1,359 @@
+/*
+ * FancyBox - jQuery Plugin
+ * Simple and fancy lightbox alternative
+ *
+ * Examples and documentation at: http://fancybox.net
+ * 
+ * Copyright (c) 2008 - 2010 Janis Skarnelis
+ * That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
+ * 
+ * Version: 1.3.4 (11/11/2010)
+ * Requires: jQuery v1.3+
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ */
+
+#fancybox-loading {
+	position: fixed;
+	top: 50%;
+	left: 50%;
+	width: 40px;
+	height: 40px;
+	margin-top: -20px;
+	margin-left: -20px;
+	cursor: pointer;
+	overflow: hidden;
+	z-index: 1104;
+	display: none;
+}
+
+#fancybox-loading div {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 40px;
+	height: 480px;
+	background-image: url('fancybox.png');
+}
+
+#fancybox-overlay {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	z-index: 1100;
+	display: none;
+}
+
+#fancybox-tmp {
+	padding: 0;
+	margin: 0;
+	border: 0;
+	overflow: auto;
+	display: none;
+}
+
+#fancybox-wrap {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: 20px;
+	z-index: 1101;
+	outline: none;
+	display: none;
+}
+
+#fancybox-outer {
+	position: relative;
+	width: 100%;
+	height: 100%;
+	background: #fff;
+}
+
+#fancybox-content {
+	width: 0;
+	height: 0;
+	padding: 0;
+	outline: none;
+	position: relative;
+	overflow: hidden;
+	z-index: 1102;
+	border: 0px solid #fff;
+}
+
+#fancybox-hide-sel-frame {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background: transparent;
+	z-index: 1101;
+}
+
+#fancybox-close {
+	position: absolute;
+	top: -15px;
+	right: -15px;
+	width: 30px;
+	height: 30px;
+	background: transparent url('fancybox.png') -40px 0px;
+	cursor: pointer;
+	z-index: 1103;
+	display: none;
+}
+
+#fancybox-error {
+	color: #444;
+	font: normal 12px/20px Arial;
+	padding: 14px;
+	margin: 0;
+}
+
+#fancybox-img {
+	width: 100%;
+	height: 100%;
+	padding: 0;
+	margin: 0;
+	border: none;
+	outline: none;
+	line-height: 0;
+	vertical-align: top;
+}
+
+#fancybox-frame {
+	width: 100%;
+	height: 100%;
+	border: none;
+	display: block;
+}
+
+#fancybox-left, #fancybox-right {
+	position: absolute;
+	bottom: 0px;
+	height: 100%;
+	width: 35%;
+	cursor: pointer;
+	outline: none;
+	background: transparent url('blank.gif');
+	z-index: 1102;
+	display: none;
+}
+
+#fancybox-left {
+	left: 0px;
+}
+
+#fancybox-right {
+	right: 0px;
+}
+
+#fancybox-left-ico, #fancybox-right-ico {
+	position: absolute;
+	top: 50%;
+	left: -9999px;
+	width: 30px;
+	height: 30px;
+	margin-top: -15px;
+	cursor: pointer;
+	z-index: 1102;
+	display: block;
+}
+
+#fancybox-left-ico {
+	background-image: url('fancybox.png');
+	background-position: -40px -30px;
+}
+
+#fancybox-right-ico {
+	background-image: url('fancybox.png');
+	background-position: -40px -60px;
+}
+
+#fancybox-left:hover, #fancybox-right:hover {
+	visibility: visible; /* IE6 */
+}
+
+#fancybox-left:hover span {
+	left: 20px;
+}
+
+#fancybox-right:hover span {
+	left: auto;
+	right: 20px;
+}
+
+.fancybox-bg {
+	position: absolute;
+	padding: 0;
+	margin: 0;
+	border: 0;
+	width: 20px;
+	height: 20px;
+	z-index: 1001;
+}
+
+#fancybox-bg-n {
+	top: -20px;
+	left: 0;
+	width: 100%;
+	background-image: url('fancybox-x.png');
+}
+
+#fancybox-bg-ne {
+	top: -20px;
+	right: -20px;
+	background-image: url('fancybox.png');
+	background-position: -40px -162px;
+}
+
+#fancybox-bg-e {
+	top: 0;
+	right: -20px;
+	height: 100%;
+	background-image: url('fancybox-y.png');
+	background-position: -20px 0px;
+}
+
+#fancybox-bg-se {
+	bottom: -20px;
+	right: -20px;
+	background-image: url('fancybox.png');
+	background-position: -40px -182px; 
+}
+
+#fancybox-bg-s {
+	bottom: -20px;
+	left: 0;
+	width: 100%;
+	background-image: url('fancybox-x.png');
+	background-position: 0px -20px;
+}
+
+#fancybox-bg-sw {
+	bottom: -20px;
+	left: -20px;
+	background-image: url('fancybox.png');
+	background-position: -40px -142px;
+}
+
+#fancybox-bg-w {
+	top: 0;
+	left: -20px;
+	height: 100%;
+	background-image: url('fancybox-y.png');
+}
+
+#fancybox-bg-nw {
+	top: -20px;
+	left: -20px;
+	background-image: url('fancybox.png');
+	background-position: -40px -122px;
+}
+
+#fancybox-title {
+	font-family: Helvetica;
+	font-size: 12px;
+	z-index: 1102;
+}
+
+.fancybox-title-inside {
+	padding-bottom: 10px;
+	text-align: center;
+	color: #333;
+	background: #fff;
+	position: relative;
+}
+
+.fancybox-title-outside {
+	padding-top: 10px;
+	color: #fff;
+}
+
+.fancybox-title-over {
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	color: #FFF;
+	text-align: left;
+}
+
+#fancybox-title-over {
+	padding: 10px;
+	background-image: url('fancy_title_over.png');
+	display: block;
+}
+
+.fancybox-title-float {
+	position: absolute;
+	left: 0;
+	bottom: -20px;
+	height: 32px;
+}
+
+#fancybox-title-float-wrap {
+	border: none;
+	border-collapse: collapse;
+	width: auto;
+}
+
+#fancybox-title-float-wrap td {
+	border: none;
+	white-space: nowrap;
+}
+
+#fancybox-title-float-left {
+	padding: 0 0 0 15px;
+	background: url('fancybox.png') -40px -90px no-repeat;
+}
+
+#fancybox-title-float-main {
+	color: #FFF;
+	line-height: 29px;
+	font-weight: bold;
+	padding: 0 0 3px 0;
+	background: url('fancybox-x.png') 0px -40px;
+}
+
+#fancybox-title-float-right {
+	padding: 0 0 0 15px;
+	background: url('fancybox.png') -55px -90px no-repeat;
+}
+
+/* IE6 */
+
+.fancybox-ie6 #fancybox-close { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_close.png', sizingMethod='scale'); }
+
+.fancybox-ie6 #fancybox-left-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_nav_left.png', sizingMethod='scale'); }
+.fancybox-ie6 #fancybox-right-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_nav_right.png', sizingMethod='scale'); }
+
+.fancybox-ie6 #fancybox-title-over { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_over.png', sizingMethod='scale'); zoom: 1; }
+.fancybox-ie6 #fancybox-title-float-left { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_left.png', sizingMethod='scale'); }
+.fancybox-ie6 #fancybox-title-float-main { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_main.png', sizingMethod='scale'); }
+.fancybox-ie6 #fancybox-title-float-right { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_title_right.png', sizingMethod='scale'); }
+
+.fancybox-ie6 #fancybox-bg-w, .fancybox-ie6 #fancybox-bg-e, .fancybox-ie6 #fancybox-left, .fancybox-ie6 #fancybox-right, #fancybox-hide-sel-frame {
+	height: expression(this.parentNode.clientHeight + "px");
+}
+
+#fancybox-loading.fancybox-ie6 {
+	position: absolute; margin-top: 0;
+	top: expression( (-20 + (document.documentElement.clientHeight ? document.documentElement.clientHeight/2 : document.body.clientHeight/2 ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop )) + 'px');
+}
+
+#fancybox-loading.fancybox-ie6 div	{ background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_loading.png', sizingMethod='scale'); }
+
+/* IE6, IE7, IE8 */
+
+.fancybox-ie .fancybox-bg { background: transparent !important; }
+
+.fancybox-ie #fancybox-bg-n { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_n.png', sizingMethod='scale'); }
+.fancybox-ie #fancybox-bg-ne { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_ne.png', sizingMethod='scale'); }
+.fancybox-ie #fancybox-bg-e { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_e.png', sizingMethod='scale'); }
+.fancybox-ie #fancybox-bg-se { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_se.png', sizingMethod='scale'); }
+.fancybox-ie #fancybox-bg-s { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_s.png', sizingMethod='scale'); }
+.fancybox-ie #fancybox-bg-sw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_sw.png', sizingMethod='scale'); }
+.fancybox-ie #fancybox-bg-w { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_w.png', sizingMethod='scale'); }
+.fancybox-ie #fancybox-bg-nw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_nw.png', sizingMethod='scale'); }

+ 360 - 0
www/assets/grocery_crud/css/jquery_plugins/file_upload/bootstrap.min.css

@@ -0,0 +1,360 @@
+html,body{margin:0;padding:0;}
+h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,cite,code,del,dfn,em,img,q,s,samp,small,strike,strong,sub,sup,tt,var,dd,dl,dt,li,ol,ul,fieldset,form,label,legend,button,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;font-weight:normal;font-style:normal;font-size:100%;line-height:1;font-family:inherit;}
+table{border-collapse:collapse;border-spacing:0;}
+ol,ul{list-style:none;}
+q:before,q:after,blockquote:before,blockquote:after{content:"";}
+html{overflow-y:scroll;font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}
+a:focus{outline:thin dotted;}
+a:hover,a:active{outline:0;}
+article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}
+audio,canvas,video{display:inline-block;*display:inline;*zoom:1;}
+audio:not([controls]){display:none;}
+sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}
+sup{top:-0.5em;}
+sub{bottom:-0.25em;}
+img{border:0;-ms-interpolation-mode:bicubic;}
+button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;}
+button,input{line-height:normal;*overflow:visible;}
+button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
+button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;}
+input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;}
+input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}
+textarea{overflow:auto;vertical-align:top;}
+body{background-color:#ffffff;margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:18px;color:#404040;}
+.container{width:940px;margin-left:auto;margin-right:auto;zoom:1;}.container:before,.container:after{display:table;content:"";zoom:1;}
+.container:after{clear:both;}
+.container-fluid{position:relative;min-width:940px;padding-left:20px;padding-right:20px;zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";zoom:1;}
+.container-fluid:after{clear:both;}
+.container-fluid>.sidebar{position:absolute;top:0;left:20px;width:220px;}
+.container-fluid>.content{margin-left:240px;}
+a{color:#0069d6;text-decoration:none;line-height:inherit;font-weight:inherit;}a:hover{color:#00438a;text-decoration:underline;}
+.pull-right{float:right;}
+.pull-left{float:left;}
+.hide{display:none;}
+.show{display:block;}
+.row{zoom:1;margin-left:-20px;}.row:before,.row:after{display:table;content:"";zoom:1;}
+.row:after{clear:both;}
+.row>[class*="span"]{display:inline;float:left;margin-left:20px;}
+.span1{width:40px;}
+.span2{width:100px;}
+.span3{width:160px;}
+.span4{width:220px;}
+.span5{width:280px;}
+.span6{width:340px;}
+.span7{width:400px;}
+.span8{width:460px;}
+.span9{width:520px;}
+.span10{width:580px;}
+.span11{width:640px;}
+.span12{width:700px;}
+.span13{width:760px;}
+.span14{width:820px;}
+.span15{width:880px;}
+.span16{width:940px;}
+.span17{width:1000px;}
+.span18{width:1060px;}
+.span19{width:1120px;}
+.span20{width:1180px;}
+.span21{width:1240px;}
+.span22{width:1300px;}
+.span23{width:1360px;}
+.span24{width:1420px;}
+.row>.offset1{margin-left:80px;}
+.row>.offset2{margin-left:140px;}
+.row>.offset3{margin-left:200px;}
+.row>.offset4{margin-left:260px;}
+.row>.offset5{margin-left:320px;}
+.row>.offset6{margin-left:380px;}
+.row>.offset7{margin-left:440px;}
+.row>.offset8{margin-left:500px;}
+.row>.offset9{margin-left:560px;}
+.row>.offset10{margin-left:620px;}
+.row>.offset11{margin-left:680px;}
+.row>.offset12{margin-left:740px;}
+.span-one-third{width:300px;}
+.span-two-thirds{width:620px;}
+.row>.offset-one-third{margin-left:340px;}
+.row>.offset-two-thirds{margin-left:660px;}
+p{font-size:13px;font-weight:normal;line-height:18px;margin-bottom:9px;}p small{font-size:11px;color:#bfbfbf;}
+h1,h2,h3,h4,h5,h6{font-weight:bold;color:#404040;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:#bfbfbf;}
+h1{margin-bottom:18px;font-size:30px;line-height:36px;}h1 small{font-size:18px;}
+h2{font-size:24px;line-height:36px;}h2 small{font-size:14px;}
+h3,h4,h5,h6{line-height:36px;}
+h3{font-size:18px;}h3 small{font-size:14px;}
+h4{font-size:16px;}h4 small{font-size:12px;}
+h5{font-size:14px;}
+h6{font-size:13px;color:#bfbfbf;text-transform:uppercase;}
+ul,ol{margin:0 0 18px 25px;}
+ul ul,ul ol,ol ol,ol ul{margin-bottom:0;}
+ul{list-style:disc;}
+ol{list-style:decimal;}
+li{line-height:18px;color:#808080;}
+ul.unstyled{list-style:none;margin-left:0;}
+dl{margin-bottom:18px;}dl dt,dl dd{line-height:18px;}
+dl dt{font-weight:bold;}
+dl dd{margin-left:9px;}
+hr{margin:20px 0 19px;border:0;border-bottom:1px solid #eee;}
+strong{font-style:inherit;font-weight:bold;}
+em{font-style:italic;font-weight:inherit;line-height:inherit;}
+.muted{color:#bfbfbf;}
+blockquote{margin-bottom:18px;border-left:5px solid #eee;padding-left:15px;}blockquote p{font-size:14px;font-weight:300;line-height:18px;margin-bottom:0;}
+blockquote small{display:block;font-size:12px;font-weight:300;line-height:18px;color:#bfbfbf;}blockquote small:before{content:'\2014 \00A0';}
+address{display:block;line-height:18px;margin-bottom:18px;}
+code,pre{padding:0 3px 2px;font-family:Monaco, Andale Mono, Courier New, monospace;font-size:12px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+code{background-color:#fee9cc;color:rgba(0, 0, 0, 0.75);padding:1px 3px;}
+pre{background-color:#f5f5f5;display:block;padding:8.5px;margin:0 0 18px;line-height:18px;font-size:12px;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;white-space:pre;white-space:pre-wrap;word-wrap:break-word;}
+form{margin-bottom:18px;}
+fieldset{margin-bottom:18px;padding-top:18px;}fieldset legend{display:block;padding-left:150px;font-size:19.5px;line-height:1;color:#404040;*padding:0 0 5px 145px;*line-height:1.5;}
+form .clearfix{margin-bottom:18px;zoom:1;}form .clearfix:before,form .clearfix:after{display:table;content:"";zoom:1;}
+form .clearfix:after{clear:both;}
+label,input,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:normal;}
+label{padding-top:6px;font-size:13px;line-height:18px;float:left;width:130px;text-align:right;color:#404040;}
+form .input{margin-left:150px;}
+input[type=checkbox],input[type=radio]{cursor:pointer;}
+input,textarea,select,.uneditable-input{display:inline-block;width:210px;height:18px;padding:4px;font-size:13px;line-height:18px;color:#808080;border:1px solid #ccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
+select{padding:initial;}
+input[type=checkbox],input[type=radio]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;border:none;}
+input[type=file]{background-color:#ffffff;padding:initial;border:initial;line-height:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
+input[type=button],input[type=reset],input[type=submit]{width:auto;height:auto;}
+select,input[type=file]{height:27px;*height:auto;line-height:27px;*margin-top:4px;}
+select[multiple]{height:inherit;background-color:#ffffff;}
+textarea{height:auto;}
+.uneditable-input{background-color:#ffffff;display:block;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;}
+:-moz-placeholder{color:#bfbfbf;}
+::-webkit-input-placeholder{color:#bfbfbf;}
+input,textarea{-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;-webkit-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1);}
+input:focus,textarea:focus{outline:0;border-color:rgba(82, 168, 236, 0.8);-webkit-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1),0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1),0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 3px rgba(0, 0, 0, 0.1),0 0 8px rgba(82, 168, 236, 0.6);}
+input[type=file]:focus,input[type=checkbox]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;outline:1px dotted #666;}
+form .clearfix.error>label,form .clearfix.error .help-block,form .clearfix.error .help-inline{color:#b94a48;}
+form .clearfix.error input,form .clearfix.error textarea{color:#b94a48;border-color:#ee5f5b;}form .clearfix.error input:focus,form .clearfix.error textarea:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;}
+form .clearfix.error .input-prepend .add-on,form .clearfix.error .input-append .add-on{color:#b94a48;background-color:#fce6e6;border-color:#b94a48;}
+form .clearfix.warning>label,form .clearfix.warning .help-block,form .clearfix.warning .help-inline{color:#c09853;}
+form .clearfix.warning input,form .clearfix.warning textarea{color:#c09853;border-color:#ccae64;}form .clearfix.warning input:focus,form .clearfix.warning textarea:focus{border-color:#be9a3f;-webkit-box-shadow:0 0 6px #e5d6b1;-moz-box-shadow:0 0 6px #e5d6b1;box-shadow:0 0 6px #e5d6b1;}
+form .clearfix.warning .input-prepend .add-on,form .clearfix.warning .input-append .add-on{color:#c09853;background-color:#d2b877;border-color:#c09853;}
+form .clearfix.success>label,form .clearfix.success .help-block,form .clearfix.success .help-inline{color:#468847;}
+form .clearfix.success input,form .clearfix.success textarea{color:#468847;border-color:#57a957;}form .clearfix.success input:focus,form .clearfix.success textarea:focus{border-color:#458845;-webkit-box-shadow:0 0 6px #9acc9a;-moz-box-shadow:0 0 6px #9acc9a;box-shadow:0 0 6px #9acc9a;}
+form .clearfix.success .input-prepend .add-on,form .clearfix.success .input-append .add-on{color:#468847;background-color:#bcddbc;border-color:#468847;}
+.input-mini,input.mini,textarea.mini,select.mini{width:60px;}
+.input-small,input.small,textarea.small,select.small{width:90px;}
+.input-medium,input.medium,textarea.medium,select.medium{width:150px;}
+.input-large,input.large,textarea.large,select.large{width:210px;}
+.input-xlarge,input.xlarge,textarea.xlarge,select.xlarge{width:270px;}
+.input-xxlarge,input.xxlarge,textarea.xxlarge,select.xxlarge{width:530px;}
+textarea.xxlarge{overflow-y:auto;}
+input.span1,textarea.span1{display:inline-block;float:none;width:30px;margin-left:0;}
+input.span2,textarea.span2{display:inline-block;float:none;width:90px;margin-left:0;}
+input.span3,textarea.span3{display:inline-block;float:none;width:150px;margin-left:0;}
+input.span4,textarea.span4{display:inline-block;float:none;width:210px;margin-left:0;}
+input.span5,textarea.span5{display:inline-block;float:none;width:270px;margin-left:0;}
+input.span6,textarea.span6{display:inline-block;float:none;width:330px;margin-left:0;}
+input.span7,textarea.span7{display:inline-block;float:none;width:390px;margin-left:0;}
+input.span8,textarea.span8{display:inline-block;float:none;width:450px;margin-left:0;}
+input.span9,textarea.span9{display:inline-block;float:none;width:510px;margin-left:0;}
+input.span10,textarea.span10{display:inline-block;float:none;width:570px;margin-left:0;}
+input.span11,textarea.span11{display:inline-block;float:none;width:630px;margin-left:0;}
+input.span12,textarea.span12{display:inline-block;float:none;width:690px;margin-left:0;}
+input.span13,textarea.span13{display:inline-block;float:none;width:750px;margin-left:0;}
+input.span14,textarea.span14{display:inline-block;float:none;width:810px;margin-left:0;}
+input.span15,textarea.span15{display:inline-block;float:none;width:870px;margin-left:0;}
+input.span16,textarea.span16{display:inline-block;float:none;width:930px;margin-left:0;}
+input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{background-color:#f5f5f5;border-color:#ddd;cursor:not-allowed;}
+.actions{background:#f5f5f5;margin-top:18px;margin-bottom:18px;padding:17px 20px 18px 150px;border-top:1px solid #ddd;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;}.actions .secondary-action{float:right;}.actions .secondary-action a{line-height:30px;}.actions .secondary-action a:hover{text-decoration:underline;}
+.help-inline,.help-block{font-size:13px;line-height:18px;color:#bfbfbf;}
+.help-inline{padding-left:5px;*position:relative;*top:-5px;}
+.help-block{display:block;max-width:600px;}
+.inline-inputs{color:#808080;}.inline-inputs span{padding:0 2px 0 1px;}
+.input-prepend input,.input-append input{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}
+.input-prepend .add-on,.input-append .add-on{position:relative;background:#f5f5f5;border:1px solid #ccc;z-index:2;float:left;display:block;width:auto;min-width:16px;height:18px;padding:4px 4px 4px 5px;margin-right:-1px;font-weight:normal;line-height:18px;color:#bfbfbf;text-align:center;text-shadow:0 1px 0 #ffffff;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
+.input-prepend .active,.input-append .active{background:#a9dba9;border-color:#46a546;}
+.input-prepend .add-on{*margin-top:1px;}
+.input-append input{float:left;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;}
+.input-append .add-on{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;margin-right:0;margin-left:-1px;}
+.inputs-list{margin:0 0 5px;width:100%;}.inputs-list li{display:block;padding:0;width:100%;}
+.inputs-list label{display:block;float:none;width:auto;padding:0;margin-left:20px;line-height:18px;text-align:left;white-space:normal;}.inputs-list label strong{color:#808080;}
+.inputs-list label small{font-size:11px;font-weight:normal;}
+.inputs-list .inputs-list{margin-left:25px;margin-bottom:10px;padding-top:0;}
+.inputs-list:first-child{padding-top:6px;}
+.inputs-list li+li{padding-top:2px;}
+.inputs-list input[type=radio],.inputs-list input[type=checkbox]{margin-bottom:0;margin-left:-20px;float:left;}
+.form-stacked{padding-left:20px;}.form-stacked fieldset{padding-top:9px;}
+.form-stacked legend{padding-left:0;}
+.form-stacked label{display:block;float:none;width:auto;font-weight:bold;text-align:left;line-height:20px;padding-top:0;}
+.form-stacked .clearfix{margin-bottom:9px;}.form-stacked .clearfix div.input{margin-left:0;}
+.form-stacked .inputs-list{margin-bottom:0;}.form-stacked .inputs-list li{padding-top:0;}.form-stacked .inputs-list li label{font-weight:normal;padding-top:0;}
+.form-stacked div.clearfix.error{padding-top:10px;padding-bottom:10px;padding-left:10px;margin-top:0;margin-left:-10px;}
+.form-stacked .actions{margin-left:-20px;padding-left:20px;}
+table{width:100%;margin-bottom:18px;padding:0;font-size:13px;border-collapse:collapse;}table th,table td{padding:10px 10px 9px;line-height:18px;text-align:left;}
+table th{padding-top:9px;font-weight:bold;vertical-align:middle;}
+table td{vertical-align:top;border-top:1px solid #ddd;}
+table tbody th{border-top:1px solid #ddd;vertical-align:top;}
+.condensed-table th,.condensed-table td{padding:5px 5px 4px;}
+.bordered-table{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.bordered-table th+th,.bordered-table td+td,.bordered-table th+td{border-left:1px solid #ddd;}
+.bordered-table thead tr:first-child th:first-child,.bordered-table tbody tr:first-child td:first-child{-webkit-border-radius:4px 0 0 0;-moz-border-radius:4px 0 0 0;border-radius:4px 0 0 0;}
+.bordered-table thead tr:first-child th:last-child,.bordered-table tbody tr:first-child td:last-child{-webkit-border-radius:0 4px 0 0;-moz-border-radius:0 4px 0 0;border-radius:0 4px 0 0;}
+.bordered-table tbody tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;}
+.bordered-table tbody tr:last-child td:last-child{-webkit-border-radius:0 0 4px 0;-moz-border-radius:0 0 4px 0;border-radius:0 0 4px 0;}
+table .span1{width:20px;}
+table .span2{width:60px;}
+table .span3{width:100px;}
+table .span4{width:140px;}
+table .span5{width:180px;}
+table .span6{width:220px;}
+table .span7{width:260px;}
+table .span8{width:300px;}
+table .span9{width:340px;}
+table .span10{width:380px;}
+table .span11{width:420px;}
+table .span12{width:460px;}
+table .span13{width:500px;}
+table .span14{width:540px;}
+table .span15{width:580px;}
+table .span16{width:620px;}
+.zebra-striped tbody tr:nth-child(odd) td,.zebra-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;}
+.zebra-striped tbody tr:hover td,.zebra-striped tbody tr:hover th{background-color:#f5f5f5;}
+table .header{cursor:pointer;}table .header:after{content:"";float:right;margin-top:7px;border-width:0 4px 4px;border-style:solid;border-color:#000 transparent;visibility:hidden;}
+table .headerSortUp,table .headerSortDown{background-color:rgba(141, 192, 219, 0.25);text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);}
+table .header:hover:after{visibility:visible;}
+table .headerSortDown:after,table .headerSortDown:hover:after{visibility:visible;filter:alpha(opacity=60);-khtml-opacity:0.6;-moz-opacity:0.6;opacity:0.6;}
+table .headerSortUp:after{border-bottom:none;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000;visibility:visible;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:alpha(opacity=60);-khtml-opacity:0.6;-moz-opacity:0.6;opacity:0.6;}
+table .blue{color:#049cdb;border-bottom-color:#049cdb;}
+table .headerSortUp.blue,table .headerSortDown.blue{background-color:#ade6fe;}
+table .green{color:#46a546;border-bottom-color:#46a546;}
+table .headerSortUp.green,table .headerSortDown.green{background-color:#cdeacd;}
+table .red{color:#9d261d;border-bottom-color:#9d261d;}
+table .headerSortUp.red,table .headerSortDown.red{background-color:#f4c8c5;}
+table .yellow{color:#ffc40d;border-bottom-color:#ffc40d;}
+table .headerSortUp.yellow,table .headerSortDown.yellow{background-color:#fff6d9;}
+table .orange{color:#f89406;border-bottom-color:#f89406;}
+table .headerSortUp.orange,table .headerSortDown.orange{background-color:#fee9cc;}
+table .purple{color:#7a43b6;border-bottom-color:#7a43b6;}
+table .headerSortUp.purple,table .headerSortDown.purple{background-color:#e2d5f0;}
+.topbar{height:40px;position:fixed;top:0;left:0;right:0;z-index:10000;overflow:visible;}.topbar a{color:#bfbfbf;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}
+.topbar h3 a:hover,.topbar .brand:hover,.topbar ul .active>a{background-color:#333;background-color:rgba(255, 255, 255, 0.05);color:#ffffff;text-decoration:none;}
+.topbar h3{position:relative;}
+.topbar h3 a,.topbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;color:#ffffff;font-size:20px;font-weight:200;line-height:1;}
+.topbar p{margin:0;line-height:40px;}.topbar p a:hover{background-color:transparent;color:#ffffff;}
+.topbar form{float:left;margin:5px 0 0 0;position:relative;filter:alpha(opacity=100);-khtml-opacity:1;-moz-opacity:1;opacity:1;}
+.topbar form.pull-right{float:right;}
+.topbar input{background-color:#444;background-color:rgba(255, 255, 255, 0.3);font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:normal;font-weight:13px;line-height:1;padding:4px 9px;color:#ffffff;color:rgba(255, 255, 255, 0.75);border:1px solid #111;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.25);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.25);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.25);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.topbar input:-moz-placeholder{color:#e6e6e6;}
+.topbar input::-webkit-input-placeholder{color:#e6e6e6;}
+.topbar input:hover{background-color:#bfbfbf;background-color:rgba(255, 255, 255, 0.5);color:#ffffff;}
+.topbar input:focus,.topbar input.focused{outline:0;background-color:#ffffff;color:#404040;text-shadow:0 1px 0 #ffffff;border:0;padding:5px 10px;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);}
+.topbar-inner,.topbar .fill{background-color:#222;background-color:#222222;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#333333), to(#222222));background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #333333), color-stop(100%, #222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);}
+.topbar div>ul,.nav{display:block;float:left;margin:0 10px 0 0;position:relative;left:0;}.topbar div>ul>li,.nav>li{display:block;float:left;}
+.topbar div>ul a,.nav a{display:block;float:none;padding:10px 10px 11px;line-height:19px;text-decoration:none;}.topbar div>ul a:hover,.nav a:hover{color:#ffffff;text-decoration:none;}
+.topbar div>ul .active>a,.nav .active>a{background-color:#222;background-color:rgba(0, 0, 0, 0.5);}
+.topbar div>ul.secondary-nav,.nav.secondary-nav{float:right;margin-left:10px;margin-right:0;}.topbar div>ul.secondary-nav .menu-dropdown,.nav.secondary-nav .menu-dropdown,.topbar div>ul.secondary-nav .dropdown-menu,.nav.secondary-nav .dropdown-menu{right:0;border:0;}
+.topbar div>ul a.menu:hover,.nav a.menu:hover,.topbar div>ul li.open .menu,.nav li.open .menu,.topbar div>ul .dropdown-toggle:hover,.nav .dropdown-toggle:hover,.topbar div>ul .dropdown.open .dropdown-toggle,.nav .dropdown.open .dropdown-toggle{background:#444;background:rgba(255, 255, 255, 0.05);}
+.topbar div>ul .menu-dropdown,.nav .menu-dropdown,.topbar div>ul .dropdown-menu,.nav .dropdown-menu{background-color:#333;}.topbar div>ul .menu-dropdown a.menu,.nav .menu-dropdown a.menu,.topbar div>ul .dropdown-menu a.menu,.nav .dropdown-menu a.menu,.topbar div>ul .menu-dropdown .dropdown-toggle,.nav .menu-dropdown .dropdown-toggle,.topbar div>ul .dropdown-menu .dropdown-toggle,.nav .dropdown-menu .dropdown-toggle{color:#ffffff;}.topbar div>ul .menu-dropdown a.menu.open,.nav .menu-dropdown a.menu.open,.topbar div>ul .dropdown-menu a.menu.open,.nav .dropdown-menu a.menu.open,.topbar div>ul .menu-dropdown .dropdown-toggle.open,.nav .menu-dropdown .dropdown-toggle.open,.topbar div>ul .dropdown-menu .dropdown-toggle.open,.nav .dropdown-menu .dropdown-toggle.open{background:#444;background:rgba(255, 255, 255, 0.05);}
+.topbar div>ul .menu-dropdown li a,.nav .menu-dropdown li a,.topbar div>ul .dropdown-menu li a,.nav .dropdown-menu li a{color:#999;text-shadow:0 1px 0 rgba(0, 0, 0, 0.5);}.topbar div>ul .menu-dropdown li a:hover,.nav .menu-dropdown li a:hover,.topbar div>ul .dropdown-menu li a:hover,.nav .dropdown-menu li a:hover{background-color:#191919;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919));background-image:-moz-linear-gradient(top, #292929, #191919);background-image:-ms-linear-gradient(top, #292929, #191919);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919));background-image:-webkit-linear-gradient(top, #292929, #191919);background-image:-o-linear-gradient(top, #292929, #191919);background-image:linear-gradient(top, #292929, #191919);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0);color:#ffffff;}
+.topbar div>ul .menu-dropdown .active a,.nav .menu-dropdown .active a,.topbar div>ul .dropdown-menu .active a,.nav .dropdown-menu .active a{color:#ffffff;}
+.topbar div>ul .menu-dropdown .divider,.nav .menu-dropdown .divider,.topbar div>ul .dropdown-menu .divider,.nav .dropdown-menu .divider{background-color:#222;border-color:#444;}
+.topbar ul .menu-dropdown li a,.topbar ul .dropdown-menu li a{padding:4px 15px;}
+li.menu,.dropdown{position:relative;}
+a.menu:after,.dropdown-toggle:after{width:0;height:0;display:inline-block;content:"&darr;";text-indent:-99999px;vertical-align:top;margin-top:8px;margin-left:4px;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #ffffff;filter:alpha(opacity=50);-khtml-opacity:0.5;-moz-opacity:0.5;opacity:0.5;}
+.menu-dropdown,.dropdown-menu{background-color:#ffffff;float:left;display:none;position:absolute;top:40px;z-index:900;min-width:160px;max-width:220px;_width:160px;margin-left:0;margin-right:0;padding:6px 0;zoom:1;border-color:#999;border-color:rgba(0, 0, 0, 0.2);border-style:solid;border-width:0 1px 1px;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:0 2px 4px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 2px 4px rgba(0, 0, 0, 0.2);box-shadow:0 2px 4px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.menu-dropdown li,.dropdown-menu li{float:none;display:block;background-color:none;}
+.menu-dropdown .divider,.dropdown-menu .divider{height:1px;margin:5px 0;overflow:hidden;background-color:#eee;border-bottom:1px solid #ffffff;}
+.topbar .dropdown-menu a,.dropdown-menu a{display:block;padding:4px 15px;clear:both;font-weight:normal;line-height:18px;color:#808080;text-shadow:0 1px 0 #ffffff;}.topbar .dropdown-menu a:hover,.dropdown-menu a:hover,.topbar .dropdown-menu a.hover,.dropdown-menu a.hover{background-color:#dddddd;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#eeeeee), to(#dddddd));background-image:-moz-linear-gradient(top, #eeeeee, #dddddd);background-image:-ms-linear-gradient(top, #eeeeee, #dddddd);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #eeeeee), color-stop(100%, #dddddd));background-image:-webkit-linear-gradient(top, #eeeeee, #dddddd);background-image:-o-linear-gradient(top, #eeeeee, #dddddd);background-image:linear-gradient(top, #eeeeee, #dddddd);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#dddddd', GradientType=0);color:#404040;text-decoration:none;-webkit-box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.025),inset 0 -1px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.025),inset 0 -1px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 0 rgba(0, 0, 0, 0.025),inset 0 -1px rgba(0, 0, 0, 0.025);}
+.open .menu,.dropdown.open .menu,.open .dropdown-toggle,.dropdown.open .dropdown-toggle{color:#ffffff;background:#ccc;background:rgba(0, 0, 0, 0.3);}
+.open .menu-dropdown,.dropdown.open .menu-dropdown,.open .dropdown-menu,.dropdown.open .dropdown-menu{display:block;}
+.tabs,.pills{margin:0 0 18px;padding:0;list-style:none;zoom:1;}.tabs:before,.pills:before,.tabs:after,.pills:after{display:table;content:"";zoom:1;}
+.tabs:after,.pills:after{clear:both;}
+.tabs>li,.pills>li{float:left;}.tabs>li>a,.pills>li>a{display:block;}
+.tabs{border-color:#ddd;border-style:solid;border-width:0 0 1px;}.tabs>li{position:relative;margin-bottom:-1px;}.tabs>li>a{padding:0 15px;margin-right:2px;line-height:34px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.tabs>li>a:hover{text-decoration:none;background-color:#eee;border-color:#eee #eee #ddd;}
+.tabs .active>a,.tabs .active>a:hover{color:#808080;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;}
+.tabs .menu-dropdown,.tabs .dropdown-menu{top:35px;border-width:1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}
+.tabs a.menu:after,.tabs .dropdown-toggle:after{border-top-color:#999;margin-top:15px;margin-left:5px;}
+.tabs li.open.menu .menu,.tabs .open.dropdown .dropdown-toggle{border-color:#999;}
+.tabs li.open a.menu:after,.tabs .dropdown.open .dropdown-toggle:after{border-top-color:#555;}
+.pills a{margin:5px 3px 5px 0;padding:0 15px;line-height:30px;text-shadow:0 1px 1px #ffffff;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}.pills a:hover{color:#ffffff;text-decoration:none;text-shadow:0 1px 1px rgba(0, 0, 0, 0.25);background-color:#00438a;}
+.pills .active a{color:#ffffff;text-shadow:0 1px 1px rgba(0, 0, 0, 0.25);background-color:#0069d6;}
+.pills-vertical>li{float:none;}
+.tab-content>.tab-pane,.pill-content>.pill-pane,.tab-content>div,.pill-content>div{display:none;}
+.tab-content>.active,.pill-content>.active{display:block;}
+.breadcrumb{padding:7px 14px;margin:0 0 18px;background-color:#f5f5f5;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#ffffff), to(#f5f5f5));background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100%, #f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline;text-shadow:0 1px 0 #ffffff;}
+.breadcrumb .divider{padding:0 5px;color:#bfbfbf;}
+.breadcrumb .active a{color:#404040;}
+.hero-unit{background-color:#f5f5f5;margin-bottom:30px;padding:60px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;}
+.hero-unit p{font-size:18px;font-weight:200;line-height:27px;}
+footer{margin-top:17px;padding-top:17px;border-top:1px solid #eee;}
+.page-header{margin-bottom:17px;border-bottom:1px solid #ddd;-webkit-box-shadow:0 1px 0 rgba(255, 255, 255, 0.5);-moz-box-shadow:0 1px 0 rgba(255, 255, 255, 0.5);box-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}.page-header h1{margin-bottom:8px;}
+.btn.danger,.alert-message.danger,.btn.danger:hover,.alert-message.danger:hover,.btn.error,.alert-message.error,.btn.error:hover,.alert-message.error:hover,.btn.success,.alert-message.success,.btn.success:hover,.alert-message.success:hover,.btn.info,.alert-message.info,.btn.info:hover,.alert-message.info:hover{color:#ffffff;}
+.btn .close,.alert-message .close{font-family:Arial,sans-serif;line-height:18px;}
+.btn.danger,.alert-message.danger,.btn.error,.alert-message.error{background-color:#c43c35;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#ee5f5b), to(#c43c35));background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #ee5f5b), color-stop(100%, #c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#c43c35 #c43c35 #882a25;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);}
+.btn.success,.alert-message.success{background-color:#57a957;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#62c462), to(#57a957));background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #62c462), color-stop(100%, #57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#57a957 #57a957 #3d773d;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);}
+.btn.info,.alert-message.info{background-color:#339bb9;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#5bc0de), to(#339bb9));background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #5bc0de), color-stop(100%, #339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#339bb9 #339bb9 #22697d;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);}
+.btn{cursor:pointer;display:inline-block;background-color:#e6e6e6;background-repeat:no-repeat;background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), color-stop(25%, #ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:-moz-linear-gradient(top, #ffffff, #ffffff 25%, #e6e6e6);background-image:-ms-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:-o-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);background-image:linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);padding:5px 14px 6px;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);color:#333;font-size:13px;line-height:normal;border:1px solid #ccc;border-bottom-color:#bbb;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-webkit-transition:0.1s linear all;-moz-transition:0.1s linear all;-ms-transition:0.1s linear all;-o-transition:0.1s linear all;transition:0.1s linear all;}.btn:hover{background-position:0 -15px;color:#333;text-decoration:none;}
+.btn:focus{outline:1px dotted #666;}
+.btn.primary{color:#ffffff;background-color:#0064cd;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));background-image:-moz-linear-gradient(top, #049cdb, #0064cd);background-image:-ms-linear-gradient(top, #049cdb, #0064cd);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));background-image:-webkit-linear-gradient(top, #049cdb, #0064cd);background-image:-o-linear-gradient(top, #049cdb, #0064cd);background-image:linear-gradient(top, #049cdb, #0064cd);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#049cdb', endColorstr='#0064cd', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#0064cd #0064cd #003f81;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);}
+.btn.active,.btn:active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.25),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.25),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.25),0 1px 2px rgba(0, 0, 0, 0.05);}
+.btn.disabled{cursor:default;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=65);-khtml-opacity:0.65;-moz-opacity:0.65;opacity:0.65;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
+.btn[disabled]{cursor:default;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=65);-khtml-opacity:0.65;-moz-opacity:0.65;opacity:0.65;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}
+.btn.large{font-size:15px;line-height:normal;padding:9px 14px 9px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
+.btn.small{padding:7px 9px 7px;font-size:11px;}
+:root .alert-message,:root .btn{border-radius:0 \0;}
+button.btn::-moz-focus-inner,input[type=submit].btn::-moz-focus-inner{padding:0;border:0;}
+.close{float:right;color:#000000;font-size:20px;font-weight:bold;line-height:13.5px;text-shadow:0 1px 0 #ffffff;filter:alpha(opacity=25);-khtml-opacity:0.25;-moz-opacity:0.25;opacity:0.25;}.close:hover{color:#000000;text-decoration:none;filter:alpha(opacity=40);-khtml-opacity:0.4;-moz-opacity:0.4;opacity:0.4;}
+.alert-message{position:relative;padding:7px 15px;margin-bottom:18px;color:#404040;background-color:#eedc94;background-repeat:repeat-x;background-image:-khtml-gradient(linear, left top, left bottom, from(#fceec1), to(#eedc94));background-image:-moz-linear-gradient(top, #fceec1, #eedc94);background-image:-ms-linear-gradient(top, #fceec1, #eedc94);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fceec1), color-stop(100%, #eedc94));background-image:-webkit-linear-gradient(top, #fceec1, #eedc94);background-image:-o-linear-gradient(top, #fceec1, #eedc94);background-image:linear-gradient(top, #fceec1, #eedc94);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fceec1', endColorstr='#eedc94', GradientType=0);text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);border-color:#eedc94 #eedc94 #e4c652;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);border-width:1px;border-style:solid;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.25);}.alert-message .close{margin-top:1px;*margin-top:0;}
+.alert-message a{font-weight:bold;color:#404040;}
+.alert-message.danger p a,.alert-message.error p a,.alert-message.success p a,.alert-message.info p a{color:#ffffff;}
+.alert-message h5{line-height:18px;}
+.alert-message p{margin-bottom:0;}
+.alert-message div{margin-top:5px;margin-bottom:2px;line-height:28px;}
+.alert-message .btn{-webkit-box-shadow:0 1px 0 rgba(255, 255, 255, 0.25);-moz-box-shadow:0 1px 0 rgba(255, 255, 255, 0.25);box-shadow:0 1px 0 rgba(255, 255, 255, 0.25);}
+.alert-message.block-message{background-image:none;background-color:#fdf5d9;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);padding:14px;border-color:#fceec1;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}.alert-message.block-message ul,.alert-message.block-message p{margin-right:30px;}
+.alert-message.block-message ul{margin-bottom:0;}
+.alert-message.block-message li{color:#404040;}
+.alert-message.block-message .alert-actions{margin-top:5px;}
+.alert-message.block-message.error,.alert-message.block-message.success,.alert-message.block-message.info{color:#404040;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}
+.alert-message.block-message.error{background-color:#fddfde;border-color:#fbc7c6;}
+.alert-message.block-message.success{background-color:#d1eed1;border-color:#bfe7bf;}
+.alert-message.block-message.info{background-color:#ddf4fb;border-color:#c6edf9;}
+.alert-message.block-message.danger p a,.alert-message.block-message.error p a,.alert-message.block-message.success p a,.alert-message.block-message.info p a{color:#404040;}
+.pagination{height:36px;margin:18px 0;}.pagination ul{float:left;margin:0;border:1px solid #ddd;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);}
+.pagination li{display:inline;}
+.pagination a{float:left;padding:0 14px;line-height:34px;border-right:1px solid;border-right-color:#ddd;border-right-color:rgba(0, 0, 0, 0.15);*border-right-color:#ddd;text-decoration:none;}
+.pagination a:hover,.pagination .active a{background-color:#c7eefe;}
+.pagination .disabled a,.pagination .disabled a:hover{background-color:transparent;color:#bfbfbf;}
+.pagination .next a{border:0;}
+.well{background-color:#f5f5f5;margin-bottom:20px;padding:19px;min-height:20px;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}
+.modal-backdrop{background-color:#000000;position:fixed;top:0;left:0;right:0;bottom:0;z-index:10000;}.modal-backdrop.fade{opacity:0;}
+.modal-backdrop,.modal-backdrop.fade.in{filter:alpha(opacity=80);-khtml-opacity:0.8;-moz-opacity:0.8;opacity:0.8;}
+.modal{position:fixed;top:50%;left:50%;z-index:11000;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal .close{margin-top:7px;}
+.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;}
+.modal.fade.in{top:50%;}
+.modal-header{border-bottom:1px solid #eee;padding:5px 15px;}
+.modal-body{padding:15px;}
+.modal-body form{margin-bottom:0;}
+.modal-footer{background-color:#f5f5f5;padding:14px 15px 15px;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;zoom:1;margin-bottom:0;}.modal-footer:before,.modal-footer:after{display:table;content:"";zoom:1;}
+.modal-footer:after{clear:both;}
+.modal-footer .btn{float:right;margin-left:5px;}
+.modal .popover,.modal .twipsy{z-index:12000;}
+.twipsy{display:block;position:absolute;visibility:visible;padding:5px;font-size:11px;z-index:1000;filter:alpha(opacity=80);-khtml-opacity:0.8;-moz-opacity:0.8;opacity:0.8;}.twipsy.fade.in{filter:alpha(opacity=80);-khtml-opacity:0.8;-moz-opacity:0.8;opacity:0.8;}
+.twipsy.above .twipsy-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;}
+.twipsy.left .twipsy-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;}
+.twipsy.below .twipsy-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;}
+.twipsy.right .twipsy-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;}
+.twipsy-inner{padding:3px 8px;background-color:#000000;color:white;text-align:center;max-width:200px;text-decoration:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}
+.twipsy-arrow{position:absolute;width:0;height:0;}
+.popover{position:absolute;top:0;left:0;z-index:1000;padding:5px;display:none;}.popover.above .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;}
+.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;}
+.popover.below .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;}
+.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;}
+.popover .arrow{position:absolute;width:0;height:0;}
+.popover .inner{background:#000000;background:rgba(0, 0, 0, 0.8);padding:3px;overflow:hidden;width:280px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);}
+.popover .title{background-color:#f5f5f5;padding:9px 15px;line-height:1;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;border-bottom:1px solid #eee;}
+.popover .content{background-color:#ffffff;padding:14px;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover .content p,.popover .content ul,.popover .content ol{margin-bottom:0;}
+.fade{-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;opacity:0;}.fade.in{opacity:1;}
+.label{padding:1px 3px 2px;font-size:9.75px;font-weight:bold;color:#ffffff;text-transform:uppercase;white-space:nowrap;background-color:#bfbfbf;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}.label.important{background-color:#c43c35;}
+.label.warning{background-color:#f89406;}
+.label.success{background-color:#46a546;}
+.label.notice{background-color:#62cffc;}
+.media-grid{margin-left:-20px;margin-bottom:0;zoom:1;}.media-grid:before,.media-grid:after{display:table;content:"";zoom:1;}
+.media-grid:after{clear:both;}
+.media-grid li{display:inline;}
+.media-grid a{float:left;padding:4px;margin:0 0 18px 20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);}.media-grid a img{display:block;}
+.media-grid a:hover{border-color:#0069d6;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);}
+
+/* grocery CRUD extra */
+input,textarea,select,.uneditable-input{color:#444444;}
+/* ------------------ */

+ 29 - 0
www/assets/grocery_crud/css/jquery_plugins/file_upload/file-uploader.css

@@ -0,0 +1,29 @@
+.qq-upload-button {
+    display:block; /* or inline-block */
+    padding: 7px 15px; 
+    text-align:center;
+	border:1px solid #AAA;
+	color: #555555;
+	border-radius: 5px;
+	float:left;
+	
+	background: #ccc;
+	background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
+	background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+	background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+	background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
+	background-image: -ms-linear-gradient(top, #cccccc 0%,#eeeeee 60%);
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 );
+	background-image: linear-gradient(top, #cccccc 0%,#eeeeee 60%);		
+}
+.qq-upload-button:hover {
+	  background: #bbb;
+	  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #bbb), color-stop(0.6, #ddd));
+	  background-image: -webkit-linear-gradient(center bottom, #bbb 0%, #ddd 60%);
+	  background-image: -moz-linear-gradient(center bottom, #bbb 0%, #ddd 60%);
+	  background-image: -o-linear-gradient(bottom, #bbb 0%, #ddd 60%);
+	  background-image: -ms-linear-gradient(top, #bbbbbb 0%,#dddddd 60%);
+	  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#bbbbbb', endColorstr='#dddddd',GradientType=0 );
+	  background-image: linear-gradient(top, #bbbbbb 0%,#dddddd 60%);
+}
+.qq-upload-button:focus {outline:1px dotted black;}

+ 71 - 0
www/assets/grocery_crud/css/jquery_plugins/file_upload/fileuploader.css

@@ -0,0 +1,71 @@
+.qq-uploader { position:relative; width: 100%;}
+
+.qq-upload-button {
+    display:block; /* or inline-block */
+    padding: 7px 15px; 
+    text-align:center;    
+	border:1px solid #AAA;
+	color: #555555;
+	border-radius: 5px;
+	float:left;
+}
+.qq-upload-button-hover {
+
+}
+.qq-upload-button-focus {outline:1px dotted black;}
+
+.qq-upload-drop-area {
+    position:absolute; top:0; left:0; width: 510px; height: 35px; z-index:2;
+    background:#FF9797; text-align:center; 
+}
+.qq-upload-drop-area span {
+    display:block; position:absolute; top: 50%; width:100%; margin-top:-8px; font-size:16px;
+}
+.qq-upload-drop-area-active {background:#FF7171;}
+
+.qq-upload-list {margin: 10px 5px 0px 10px; padding:0; list-style: none; float:left;}
+.qq-upload-list li { margin:0; padding:0; line-height:15px; font-size:12px; float:left;}
+.qq-upload-file, .qq-upload-spinner, .qq-upload-size, .qq-upload-cancel, .qq-upload-failed-text {
+    margin-right: 7px;
+}
+.qq-upload-file {}
+.qq-upload-spinner {display:inline-block; background: url("loading.gif"); width:15px; height:15px; vertical-align:text-bottom;}
+.qq-upload-size,.qq-upload-cancel {font-size:11px;}
+
+.qq-upload-failed-text {display:none;}
+.qq-upload-fail .qq-upload-failed-text {display:inline;}
+
+a.qq-upload-cancel
+{
+	color: red !important;	
+}
+
+/* Grocery CRUD extras */
+a.open-file
+{
+	color: #000;
+	font-weight: bold;
+	text-decoration: none;
+}
+a.open-file:hover
+{
+	text-decoration: underline;
+}
+a.delete-anchor
+{
+	color: red !important;	
+}
+.image-thumbnail img
+{
+	cursor: -moz-zoom-in;
+	cursor: -webkit-zoom-in;
+}
+.form-field-box.even .image-thumbnail img
+{
+	border: 4px solid #fff;
+}
+.form-field-box.odd .image-thumbnail img
+{
+	border: 4px solid #ddd;
+}
+/* ------------------- */

+ 56 - 0
www/assets/grocery_crud/css/jquery_plugins/file_upload/jquery.fileupload-ui.css

@@ -0,0 +1,56 @@
+@charset 'UTF-8';
+/*
+ * jQuery File Upload UI Plugin CSS 6.0
+ * https://github.com/blueimp/jQuery-File-Upload
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://www.opensource.org/licenses/MIT
+ */
+
+.fileinput-button input {
+  position: absolute;
+  top: 0;
+  right: 0;
+  margin: 0;
+  border: solid transparent;
+  border-width: 0 0 100px 200px;
+  opacity: 0;
+  filter: alpha(opacity=0);
+  -moz-transform: translate(-300px, 0) scale(4);
+  direction: ltr;
+  cursor: pointer;
+}
+
+.fileinput-button {
+  position: relative;
+  overflow: hidden;
+  float: left;
+  margin-right: 4px;
+}
+
+.progressbar,
+.progressbar div {
+  width: 200px;
+  height: 20px;
+  -webkit-border-radius: 4px;
+     -moz-border-radius: 4px;
+          border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.3);
+     -moz-box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.3);
+          box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.3);
+  background: #fff;
+}
+
+.progressbar div {
+  width: auto;
+  background: url(progressbar.gif);
+}
+
+.fileupload-progressbar {
+  float: right;
+  width: 400px;
+  margin-top: 4px;
+}

二進制
www/assets/grocery_crud/css/jquery_plugins/file_upload/loading.gif


二進制
www/assets/grocery_crud/css/jquery_plugins/file_upload/progressbar.gif


+ 10 - 0
www/assets/grocery_crud/css/jquery_plugins/index.html

@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

+ 10 - 0
www/assets/grocery_crud/css/jquery_plugins/jquery-ui-timepicker-addon.css

@@ -0,0 +1,10 @@
+.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
+.ui-timepicker-div dl { text-align: left; }
+.ui-timepicker-div dl dt { height: 25px; margin-bottom: -25px; }
+.ui-timepicker-div dl dd { margin: 0 10px 10px 86px; }
+.ui-timepicker-div td { font-size: 90%; }
+.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
+
+.ui-timepicker-rtl{ direction: rtl; }
+.ui-timepicker-rtl dl { text-align: right; }
+.ui-timepicker-rtl dl dd { margin: 0 65px 10px 10px; }

+ 116 - 0
www/assets/grocery_crud/css/jquery_plugins/jquery.ui.datetime.css

@@ -0,0 +1,116 @@
+@CHARSET "UTF-8";
+
+ /*demo page css*/
+
+
+            .demoHeaders {
+                margin-top: 2em;
+            }
+
+            #dialog_link {
+                padding: .4em 1em .4em 20px;
+                text-decoration: none;
+                position: relative;
+            }
+
+            #dialog_link span.ui-icon {
+                margin: 0 5px 0 0;
+                position: absolute;
+                left: .2em;
+                top: 50%;
+                margin-top: -8px;
+            }
+
+            ul#icons {
+                margin: 0;
+                padding: 0;
+            }
+
+            ul#icons li {
+                margin: 2px;
+                position: relative;
+                padding: 4px 0;
+                cursor: pointer;
+                float: left;
+                list-style: none;
+            }
+
+            ul#icons span.ui-icon {
+                float: left;
+                margin: 0 4px;
+            }
+
+            
+           	.selHrs, .selMins {
+           		width:2.5em;
+           	}
+           	.selHrs {
+           		margin-left:5px;
+           	}
+           	.dayPeriod {
+           		display:inline-block;
+           		width:20px;
+           	}
+           	.slider {
+           		height:120px; 
+           		float:left; 
+           		margin:10px
+           	}
+           	
+           	#tpSelectedTime {
+           		margin-bottom:0;
+           		border-bottom:1px solid #aaa;
+           		padding:5px;
+           		color:#000;
+           		background:#fff;
+           		text-transform:none;
+           		
+           	}
+           	#tpSelectedTime span {
+           		fon-weight:bold;
+           	}
+           	#datepicker {
+           		
+           	}
+           	#pickerplug {
+           		overflow:hidden;
+           		display:none;          		
+           		position:absolute;
+           		top:200px;
+           		left:300px; 
+					padding:0;
+					margin:0;
+           		z-index:500;	
+           	}
+           	#pickerplug li {
+           		display:block;
+           		float:left;
+           	}
+           	#timepicker {
+           		border:1px solid #aaa;           		
+           		background:#fff;
+           	}
+           	#timepicker ul {
+           		overflow:hidden;
+           		padding:5px;
+           	}
+           	#timepicker ul li {
+           		position:relative;
+           		display:block;
+           		float:left;
+           		width:50px;
+           		        		
+           	}
+           	#timepicker ul li h4 {
+           		width:100%;
+           		background:transparent;
+           		color:#000;
+				text-align:center;           		           		
+           	}
+           	#timepicker ul li .slider {
+           		position:relative;
+           		left:10px;
+           		
+           	/*	background:#FBF9EE url(images/ui-bg_glass_55_fbf9ee_1x400.png) repeat-x scroll 50% 50%;
+				border:1px solid #FCEFA1;*/
+           	}

+ 32 - 0
www/assets/grocery_crud/css/jquery_plugins/ui.multiselect.css

@@ -0,0 +1,32 @@
+/* Multiselect
+----------------------------------*/
+
+.ui-multiselect { border: solid 1px; font-size: 0.8em; }
+.ui-multiselect ul { -moz-user-select: none; }
+.ui-multiselect li { margin: 0; padding: 0; cursor: default; line-height: 20px; height: 20px; font-size: 11px; list-style: none; }
+.ui-multiselect li a { color: #999; text-decoration: none; padding: 0; display: block; float: left; cursor: pointer;}
+.ui-multiselect li.ui-draggable-dragging { padding-left: 10px; }
+
+.ui-multiselect div.selected { position: relative; padding: 0; margin: 0; border: 0; float:left; }
+.ui-multiselect ul.selected { position: relative; padding: 0; overflow: auto; overflow-x: hidden; background: #fff; margin: 0; list-style: none; border: 0; position: relative; width: 100%; }
+.ui-multiselect ul.selected li { }
+
+.ui-multiselect div.available { position: relative; padding: 0; margin: 0; border: 0; float:left; border-left: 1px solid; }
+.ui-multiselect ul.available { position: relative; padding: 0; overflow: auto; overflow-x: hidden; background: #fff; margin: 0; list-style: none; border: 0; width: 100%; }
+.ui-multiselect ul.available li { padding-left: 10px; }
+ 
+.ui-multiselect .ui-state-default { border: none; margin-bottom: 1px; position: relative; padding-left: 20px;}
+.ui-multiselect .ui-state-hover { border: none; }
+.ui-multiselect .ui-widget-header {border: none; font-size: 11px; margin-bottom: 1px;}
+ 
+.ui-multiselect .add-all { float: right; padding: 10px 7px 10px 0; font-size: 11px; }
+.ui-multiselect .remove-all { float: right; padding: 10px 7px 11px 0; font-size: 11px; }
+.ui-multiselect .search { float: left; padding:0;}
+.ui-multiselect .count { float: left; padding: 10px 7px;}
+
+.ui-multiselect li span.ui-icon-arrowthick-2-n-s { position: absolute; left: 2px; }
+.ui-multiselect li a.action { position: absolute; right: 2px; top: 2px; }
+ 
+.ui-multiselect input.search { height: 20px !important; padding: 2px !important; opacity: 0.5 !important; margin: 4px !important; width: 150px !important; }
+
+select.multiselect{ width:704px; }

+ 10 - 0
www/assets/grocery_crud/css/ui/index.html

@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>

二進制
www/assets/grocery_crud/css/ui/simple/images/animated-overlay.gif


二進制
www/assets/grocery_crud/css/ui/simple/images/ui-bg_flat_0_aaaaaa_40x100.png


部分文件因文件數量過多而無法顯示